Changeset 1486116 for src/SymTab
- Timestamp:
- Dec 14, 2016, 3:21:54 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 9facf3b
- Parents:
- a64644c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Autogen.cc
ra64644c r1486116 24 24 #include "MakeLibCfa.h" 25 25 #include "Autogen.h" 26 #include "GenPoly/ScopedSet.h" 27 #include "SymTab/Mangler.h" 28 #include "GenPoly/DeclMutator.h" 26 29 27 30 namespace SymTab { … … 29 32 30 33 class AutogenerateRoutines : public Visitor { 31 34 public: 32 35 std::list< Declaration * > &get_declsToAdd() { return declsToAdd; } 33 36 … … 48 51 virtual void visit( SwitchStmt *switchStmt ); 49 52 50 AutogenerateRoutines() : functionNesting( 0 ) {} 51 private: 53 private: 52 54 template< typename StmtClass > void visitStatement( StmtClass *stmt ); 53 55 54 56 std::list< Declaration * > declsToAdd; 55 57 std::set< std::string > structsDone; 56 unsigned int functionNesting ; // current level of nested functions58 unsigned int functionNesting = 0; // current level of nested functions 57 59 }; 58 60 61 /// generates routines for tuple types. 62 /// Doesn't really need to be a mutator, but it's easier to reuse DeclMutator than it is to use AddVisit 63 /// or anything we currently have that supports adding new declarations for visitors 64 class AutogenTupleRoutines : public GenPoly::DeclMutator { 65 public: 66 typedef GenPoly::DeclMutator Parent; 67 using Parent::mutate; 68 69 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ); 70 71 virtual Type * mutate( TupleType *tupleType ); 72 73 virtual CompoundStmt * mutate( CompoundStmt *compoundStmt ); 74 75 private: 76 unsigned int functionNesting = 0; // current level of nested functions 77 GenPoly::ScopedSet< std::string > seenTuples; 78 }; 79 59 80 void autogenerateRoutines( std::list< Declaration * > &translationUnit ) { 60 AutogenerateRoutines visitor; 61 acceptAndAdd( translationUnit, visitor, false ); 81 AutogenerateRoutines generator; 82 acceptAndAdd( translationUnit, generator, false ); 83 84 // needs to be done separately because AutogenerateRoutines skips types that appear as function arguments, etc. 85 // AutogenTupleRoutines tupleGenerator; 86 // tupleGenerator.mutateDeclarationList( translationUnit ); 62 87 } 63 88 … … 93 118 94 119 /// given type T, generate type of assignment, i.e. function type T (*) (T *, T) 95 FunctionType * genAssignType( Type * paramType , const std::list< Expression* > & params = std::list< Expression* >()) {120 FunctionType * genAssignType( Type * paramType ) { 96 121 FunctionType *ftype = genCopyType( paramType ); 97 122 ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, paramType->clone(), nullptr ); … … 173 198 copyCtorDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, genEnumAssign( copyCtorType, assignDecl ) ) ); 174 199 175 declsToAdd.push_back( assignDecl );176 200 declsToAdd.push_back( ctorDecl ); 177 201 declsToAdd.push_back( copyCtorDecl ); 178 202 declsToAdd.push_back( dtorDecl ); 203 declsToAdd.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return 179 204 } 180 205 … … 311 336 // forward declare if top-level struct, so that 312 337 // type is complete as soon as its body ends 338 // Note: this is necessary if we want structs which contain 339 // generic (otype) structs as members. 313 340 addForwardDecl( assignDecl, declsToAdd ); 314 341 addForwardDecl( ctorDecl, declsToAdd ); … … 352 379 makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dtorDecl, isDynamicLayout, false ); 353 380 354 if ( ! isDynamicLayout ) { 355 assert( assignType->get_parameters().size() == 2 ); 356 ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( assignType->get_parameters().back() ); 357 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 358 } 359 360 declsToAdd.push_back( assignDecl ); 381 assert( assignType->get_parameters().size() == 2 ); 382 ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( assignType->get_parameters().back() ); 383 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 384 361 385 declsToAdd.push_back( ctorDecl ); 362 386 declsToAdd.push_back( copyCtorDecl ); 363 387 declsToAdd.push_back( dtorDecl ); 388 declsToAdd.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return 364 389 declsToAdd.splice( declsToAdd.end(), memCtors ); 365 390 } … … 402 427 // void ?{}(T *); void ^?{}(T *); 403 428 FunctionType *ctorType = genDefaultType( refType ); 404 cloneAll( typeParams, ctorType->get_forall() );405 429 FunctionType *dtorType = genDefaultType( refType ); 406 cloneAll( typeParams, dtorType->get_forall() );407 430 408 431 // copy ctor needs both parameters 409 432 // void ?{}(T *, T); 410 433 FunctionType *copyCtorType = genCopyType( refType ); 411 cloneAll( typeParams, copyCtorType->get_forall() );412 434 413 435 // assignment needs both and return value 414 436 // T ?=?(T *, T); 415 437 FunctionType *assignType = genAssignType( refType ); 438 439 cloneAll( typeParams, ctorType->get_forall() ); 440 cloneAll( typeParams, dtorType->get_forall() ); 441 cloneAll( typeParams, copyCtorType->get_forall() ); 416 442 cloneAll( typeParams, assignType->get_forall() ); 417 443 … … 448 474 } 449 475 450 declsToAdd.push_back( assignDecl );451 476 declsToAdd.push_back( ctorDecl ); 452 477 declsToAdd.push_back( copyCtorDecl ); 453 478 declsToAdd.push_back( dtorDecl ); 479 declsToAdd.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return 454 480 declsToAdd.splice( declsToAdd.end(), memCtors ); 455 481 } … … 552 578 visitStatement( switchStmt ); 553 579 } 580 581 void makeTupleFunctionBody( FunctionDecl * function ) { 582 FunctionType * ftype = function->get_functionType(); 583 assertf( ftype->get_parameters().size() == 1 || ftype->get_parameters().size() == 2, "too many parameters in generated tuple function" ); 584 585 UntypedExpr * untyped = new UntypedExpr( new NameExpr( function->get_name() ) ); 586 587 /// xxx - &* is used to make this easier for later passes to handle 588 untyped->get_args().push_back( new AddressExpr( UntypedExpr::createDeref( new VariableExpr( ftype->get_parameters().front() ) ) ) ); 589 if ( ftype->get_parameters().size() == 2 ) { 590 untyped->get_args().push_back( new VariableExpr( ftype->get_parameters().back() ) ); 591 } 592 function->get_statements()->get_kids().push_back( new ExprStmt( noLabels, untyped ) ); 593 function->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, UntypedExpr::createDeref( new VariableExpr( ftype->get_parameters().front() ) ) ) ); 594 } 595 596 Type * AutogenTupleRoutines::mutate( TupleType * tupleType ) { 597 tupleType = safe_dynamic_cast< TupleType * >( Parent::mutate( tupleType ) ); 598 std::string mangleName = SymTab::Mangler::mangleType( tupleType ); 599 if ( seenTuples.find( mangleName ) != seenTuples.end() ) return tupleType; 600 seenTuples.insert( mangleName ); 601 602 // T ?=?(T *, T); 603 FunctionType *assignType = genAssignType( tupleType ); 604 605 // void ?{}(T *); void ^?{}(T *); 606 FunctionType *ctorType = genDefaultType( tupleType ); 607 FunctionType *dtorType = genDefaultType( tupleType ); 608 609 // void ?{}(T *, T); 610 FunctionType *copyCtorType = genCopyType( tupleType ); 611 612 std::set< TypeDecl* > done; 613 std::list< TypeDecl * > typeParams; 614 for ( Type * t : *tupleType ) { 615 if ( TypeInstType * ty = dynamic_cast< TypeInstType * >( t ) ) { 616 if ( ! done.count( ty->get_baseType() ) ) { 617 TypeDecl * newDecl = new TypeDecl( ty->get_baseType()->get_name(), DeclarationNode::NoStorageClass, nullptr, TypeDecl::Any ); 618 TypeInstType * inst = new TypeInstType( Type::Qualifiers(), newDecl->get_name(), newDecl ); 619 newDecl->get_assertions().push_back( new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, genAssignType( inst ), nullptr, true, false ) ); 620 newDecl->get_assertions().push_back( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, genDefaultType( inst ), nullptr, true, false ) ); 621 newDecl->get_assertions().push_back( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, genCopyType( inst ), nullptr, true, false ) ); 622 newDecl->get_assertions().push_back( new FunctionDecl( "^?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, genDefaultType( inst ), nullptr, true, false ) ); 623 typeParams.push_back( newDecl ); 624 done.insert( ty->get_baseType() ); 625 } 626 } 627 } 628 cloneAll( typeParams, ctorType->get_forall() ); 629 cloneAll( typeParams, dtorType->get_forall() ); 630 cloneAll( typeParams, copyCtorType->get_forall() ); 631 cloneAll( typeParams, assignType->get_forall() ); 632 633 FunctionDecl *assignDecl = genFunc( "?=?", assignType, functionNesting ); 634 FunctionDecl *ctorDecl = genFunc( "?{}", ctorType, functionNesting ); 635 FunctionDecl *copyCtorDecl = genFunc( "?{}", copyCtorType, functionNesting ); 636 FunctionDecl *dtorDecl = genFunc( "^?{}", dtorType, functionNesting ); 637 638 makeTupleFunctionBody( assignDecl ); 639 makeTupleFunctionBody( ctorDecl ); 640 makeTupleFunctionBody( copyCtorDecl ); 641 makeTupleFunctionBody( dtorDecl ); 642 643 addDeclaration( ctorDecl ); 644 addDeclaration( copyCtorDecl ); 645 addDeclaration( dtorDecl ); 646 addDeclaration( assignDecl ); // assignment should come last since it uses copy constructor in return 647 648 return tupleType; 649 } 650 651 DeclarationWithType * AutogenTupleRoutines::mutate( FunctionDecl *functionDecl ) { 652 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) ); 653 mutateAll( functionDecl->get_oldDecls(), *this ); 654 functionNesting += 1; 655 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) ); 656 functionNesting -= 1; 657 return functionDecl; 658 } 659 660 CompoundStmt * AutogenTupleRoutines::mutate( CompoundStmt *compoundStmt ) { 661 seenTuples.beginScope(); 662 compoundStmt = safe_dynamic_cast< CompoundStmt * >( Parent::mutate( compoundStmt ) ); 663 seenTuples.endScope(); 664 return compoundStmt; 665 } 554 666 } // SymTab
Note: See TracChangeset
for help on using the changeset viewer.