Changes in src/SymTab/Autogen.cc [a139c11:4e8949f]
- File:
-
- 1 edited
-
src/SymTab/Autogen.cc (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Autogen.cc
ra139c11 r4e8949f 16 16 #include "Autogen.h" 17 17 18 #include <cstddef> // for NULL 18 19 #include <algorithm> // for count_if 19 20 #include <cassert> // for strict_dynamic_cast, assert, assertf … … 26 27 #include "AddVisit.h" // for addVisit 27 28 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign 28 #include "Common/PassVisitor.h" // for PassVisitor29 29 #include "Common/ScopedMap.h" // for ScopedMap<>::const_iterator, Scope... 30 30 #include "Common/utility.h" // for cloneAll, operator+ 31 #include "GenPoly/DeclMutator.h" // for DeclMutator 31 32 #include "GenPoly/ScopedSet.h" // for ScopedSet, ScopedSet<>::iterator 32 #include "InitTweak/GenInit.h" // for fixReturnStatements33 #include "ResolvExpr/Resolver.h" // for resolveDecl34 33 #include "SymTab/Mangler.h" // for Mangler 35 34 #include "SynTree/Attribute.h" // For Attribute … … 54 53 }; 55 54 56 struct AutogenerateRoutines final : public WithDeclsToAdd, public WithVisitorRef<AutogenerateRoutines>, public WithGuards, public WithShortCircuiting { 55 class AutogenerateRoutines final : public Visitor { 56 template< typename Visitor > 57 friend void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor ); 58 template< typename Visitor > 59 friend void addVisitStatementList( std::list< Statement* > &stmts, Visitor &visitor ); 60 public: 61 std::list< Declaration * > &get_declsToAdd() { return declsToAdd; } 62 63 typedef Visitor Parent; 64 using Parent::visit; 65 57 66 AutogenerateRoutines(); 58 67 59 void previsit( EnumDecl * enumDecl ); 60 void previsit( StructDecl * structDecl ); 61 void previsit( UnionDecl * structDecl ); 62 void previsit( TypeDecl * typeDecl ); 63 void previsit( TraitDecl * traitDecl ); 64 void previsit( FunctionDecl * functionDecl ); 65 66 void previsit( FunctionType * ftype ); 67 void previsit( PointerType * ptype ); 68 69 void previsit( CompoundStmt * compoundStmt ); 68 virtual void visit( EnumDecl *enumDecl ); 69 virtual void visit( StructDecl *structDecl ); 70 virtual void visit( UnionDecl *structDecl ); 71 virtual void visit( TypeDecl *typeDecl ); 72 virtual void visit( TraitDecl *ctxDecl ); 73 virtual void visit( FunctionDecl *functionDecl ); 74 75 virtual void visit( FunctionType *ftype ); 76 virtual void visit( PointerType *ftype ); 77 78 virtual void visit( CompoundStmt *compoundStmt ); 79 virtual void visit( SwitchStmt *switchStmt ); 70 80 71 81 private: 72 GenPoly::ScopedSet< std::string > structsDone; 82 template< typename StmtClass > void visitStatement( StmtClass *stmt ); 83 84 std::list< Declaration * > declsToAdd, declsToAddAfter; 85 std::set< std::string > structsDone; 73 86 unsigned int functionNesting = 0; // current level of nested functions 74 87 /// Note: the following maps could be ScopedSets, but it should be easier to work … … 80 93 81 94 /// generates routines for tuple types. 82 struct AutogenTupleRoutines : public WithDeclsToAdd, public WithVisitorRef<AutogenTupleRoutines>, public WithGuards, public WithShortCircuiting { 83 void previsit( FunctionDecl *functionDecl ); 84 85 void postvisit( TupleType *tupleType ); 86 87 void previsit( CompoundStmt *compoundStmt ); 95 /// Doesn't really need to be a mutator, but it's easier to reuse DeclMutator than it is to use AddVisit 96 /// or anything we currently have that supports adding new declarations for visitors 97 class AutogenTupleRoutines : public GenPoly::DeclMutator { 98 public: 99 typedef GenPoly::DeclMutator Parent; 100 using Parent::mutate; 101 102 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ); 103 104 virtual Type * mutate( TupleType *tupleType ); 105 106 virtual CompoundStmt * mutate( CompoundStmt *compoundStmt ); 88 107 89 108 private: … … 93 112 94 113 void autogenerateRoutines( std::list< Declaration * > &translationUnit ) { 95 PassVisitor<AutogenerateRoutines>generator;96 acceptA ll( translationUnit, generator );114 AutogenerateRoutines generator; 115 acceptAndAdd( translationUnit, generator ); 97 116 98 117 // needs to be done separately because AutogenerateRoutines skips types that appear as function arguments, etc. 99 118 // AutogenTupleRoutines tupleGenerator; 100 // acceptAll( translationUnit, tupleGenerator);119 // tupleGenerator.mutateDeclarationList( translationUnit ); 101 120 } 102 121 103 122 bool isUnnamedBitfield( ObjectDecl * obj ) { 104 return obj != nullptr && obj->get_name() == "" && obj->get_bitfieldWidth() != nullptr;123 return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL; 105 124 } 106 125 … … 109 128 FunctionDecl * decl = functionDecl->clone(); 110 129 delete decl->get_statements(); 111 decl->set_statements( nullptr);130 decl->set_statements( NULL ); 112 131 declsToAdd.push_back( decl ); 113 132 decl->fixUniqueId(); … … 320 339 assert( ! func->get_functionType()->get_parameters().empty() ); 321 340 ObjectDecl * dstParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().front() ); 322 ObjectDecl * srcParam = nullptr;341 ObjectDecl * srcParam = NULL; 323 342 if ( func->get_functionType()->get_parameters().size() == 2 ) { 324 343 srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() ); … … 327 346 assert( dstParam ); 328 347 329 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : nullptr;348 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL; 330 349 makeStructMemberOp( dstParam, srcselect, field, func, forward ); 331 350 } // if … … 366 385 } else { 367 386 // no matching parameter, initialize field with default ctor 368 makeStructMemberOp( dstParam, nullptr, field, func );387 makeStructMemberOp( dstParam, NULL, field, func ); 369 388 } 370 389 } … … 382 401 void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) { 383 402 // Builtins do not use autogeneration. 384 if ( LinkageSpec::isBuiltin( aggregateDecl->get_linkage() ) ) { 403 if ( aggregateDecl->get_linkage() == LinkageSpec::BuiltinCFA || 404 aggregateDecl->get_linkage() == LinkageSpec::BuiltinC ) { 385 405 return; 386 406 } 387 407 388 408 // Make function polymorphic in same parameters as generic struct, if applicable 389 const std::list< TypeDecl * > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions409 const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions 390 410 391 411 // generate each of the functions based on the supplied FuncData objects … … 552 572 // the order here determines the order that these functions are generated. 553 573 // assignment should come last since it uses copy constructor in return. 554 data.emplace_back( "?{}", genDefaultType, constructable ); 555 data.emplace_back( "?{}", genCopyType, copyable ); 556 data.emplace_back( "^?{}", genDefaultType, destructable ); 557 data.emplace_back( "?=?", genAssignType, assignable ); 558 } 559 560 void AutogenerateRoutines::previsit( EnumDecl * enumDecl ) { 561 visit_children = false; 574 data.push_back( FuncData( "?{}", genDefaultType, constructable ) ); 575 data.push_back( FuncData( "?{}", genCopyType, copyable ) ); 576 data.push_back( FuncData( "^?{}", genDefaultType, destructable ) ); 577 data.push_back( FuncData( "?=?", genAssignType, assignable ) ); 578 } 579 580 void AutogenerateRoutines::visit( EnumDecl *enumDecl ) { 562 581 if ( ! enumDecl->get_members().empty() ) { 563 582 EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() ); … … 567 586 } 568 587 569 void AutogenerateRoutines::previsit( StructDecl * structDecl ) { 570 visit_children = false; 571 if ( structDecl->has_body() && structsDone.find( structDecl->name ) == structsDone.end() ) { 572 StructInstType structInst( Type::Qualifiers(), structDecl->name ); 573 for ( TypeDecl * typeDecl : structDecl->parameters ) { 588 void AutogenerateRoutines::visit( StructDecl *structDecl ) { 589 if ( structDecl->has_body() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) { 590 StructInstType structInst( Type::Qualifiers(), structDecl->get_name() ); 591 for ( TypeDecl * typeDecl : structDecl->get_parameters() ) { 574 592 // need to visit assertions so that they are added to the appropriate maps 575 acceptAll( typeDecl-> assertions, *visitor);576 structInst. parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) );593 acceptAll( typeDecl->get_assertions(), *this ); 594 structInst.get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) ); 577 595 } 578 596 structInst.set_baseStruct( structDecl ); 579 597 makeStructFunctions( structDecl, &structInst, functionNesting, declsToAddAfter, data ); 580 structsDone.insert( structDecl-> name);598 structsDone.insert( structDecl->get_name() ); 581 599 } // if 582 600 } 583 601 584 void AutogenerateRoutines::previsit( UnionDecl * unionDecl ) { 585 visit_children = false; 602 void AutogenerateRoutines::visit( UnionDecl *unionDecl ) { 586 603 if ( ! unionDecl->get_members().empty() ) { 587 604 UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() ); … … 602 619 603 620 // generate ctor/dtors/assign for typedecls, e.g., otype T = int *; 604 void AutogenerateRoutines::previsit( TypeDecl * typeDecl ) { 605 visit_children = false; 621 void AutogenerateRoutines::visit( TypeDecl *typeDecl ) { 606 622 if ( ! typeDecl->base ) return; 607 623 … … 648 664 } 649 665 650 void AutogenerateRoutines::previsit( FunctionType *) { 666 void addDecls( std::list< Declaration * > &declsToAdd, std::list< Statement * > &statements, std::list< Statement * >::iterator i ) { 667 for ( std::list< Declaration * >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) { 668 statements.insert( i, new DeclStmt( noLabels, *decl ) ); 669 } // for 670 declsToAdd.clear(); 671 } 672 673 void AutogenerateRoutines::visit( FunctionType *) { 651 674 // ensure that we don't add assignment ops for types defined as part of the function 652 visit_children = false; 653 } 654 655 void AutogenerateRoutines::previsit( PointerType *) { 675 } 676 677 void AutogenerateRoutines::visit( PointerType *) { 656 678 // ensure that we don't add assignment ops for types defined as part of the pointer 657 visit_children = false; 658 } 659 660 void AutogenerateRoutines::previsit( TraitDecl * ) { 679 } 680 681 void AutogenerateRoutines::visit( TraitDecl *) { 661 682 // ensure that we don't add assignment ops for types defined as part of the trait 662 visit_children = false; 663 } 664 665 void AutogenerateRoutines::previsit( FunctionDecl * functionDecl ) { 666 visit_children = false; 683 } 684 685 template< typename StmtClass > 686 inline void AutogenerateRoutines::visitStatement( StmtClass *stmt ) { 687 std::set< std::string > oldStructs = structsDone; 688 addVisit( stmt, *this ); 689 structsDone = oldStructs; 690 } 691 692 void AutogenerateRoutines::visit( FunctionDecl *functionDecl ) { 667 693 // record the existence of this function as appropriate 668 694 insert( functionDecl, constructable, InitTweak::isDefaultConstructor ); … … 671 697 insert( functionDecl, destructable, InitTweak::isDestructor ); 672 698 673 maybeAccept( functionDecl-> type, *visitor);699 maybeAccept( functionDecl->get_functionType(), *this ); 674 700 functionNesting += 1; 675 maybeAccept( functionDecl-> statements, *visitor);701 maybeAccept( functionDecl->get_statements(), *this ); 676 702 functionNesting -= 1; 677 703 } 678 704 679 void AutogenerateRoutines::previsit( CompoundStmt * ) { 680 GuardScope( constructable ); 681 GuardScope( assignable ); 682 GuardScope( copyable ); 683 GuardScope( destructable ); 684 GuardScope( structsDone ); 705 void AutogenerateRoutines::visit( CompoundStmt *compoundStmt ) { 706 constructable.beginScope(); 707 assignable.beginScope(); 708 copyable.beginScope(); 709 destructable.beginScope(); 710 visitStatement( compoundStmt ); 711 constructable.endScope(); 712 assignable.endScope(); 713 copyable.endScope(); 714 destructable.endScope(); 715 } 716 717 void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) { 718 visitStatement( switchStmt ); 685 719 } 686 720 … … 700 734 } 701 735 702 void AutogenTupleRoutines::postvisit( TupleType * tupleType ) { 736 Type * AutogenTupleRoutines::mutate( TupleType * tupleType ) { 737 tupleType = strict_dynamic_cast< TupleType * >( Parent::mutate( tupleType ) ); 703 738 std::string mangleName = SymTab::Mangler::mangleType( tupleType ); 704 if ( seenTuples.find( mangleName ) != seenTuples.end() ) return ;739 if ( seenTuples.find( mangleName ) != seenTuples.end() ) return tupleType; 705 740 seenTuples.insert( mangleName ); 706 741 … … 750 785 makeTupleFunctionBody( dtorDecl ); 751 786 752 declsToAddBefore.push_back( ctorDecl ); 753 declsToAddBefore.push_back( copyCtorDecl ); 754 declsToAddBefore.push_back( dtorDecl ); 755 declsToAddBefore.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return 756 } 757 758 void AutogenTupleRoutines::previsit( FunctionDecl *functionDecl ) { 759 visit_children = false; 760 maybeAccept( functionDecl->type, *visitor ); 787 addDeclaration( ctorDecl ); 788 addDeclaration( copyCtorDecl ); 789 addDeclaration( dtorDecl ); 790 addDeclaration( assignDecl ); // assignment should come last since it uses copy constructor in return 791 792 return tupleType; 793 } 794 795 DeclarationWithType * AutogenTupleRoutines::mutate( FunctionDecl *functionDecl ) { 796 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) ); 761 797 functionNesting += 1; 762 maybeAccept( functionDecl->statements, *visitor);798 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) ); 763 799 functionNesting -= 1; 764 } 765 766 void AutogenTupleRoutines::previsit( CompoundStmt * ) { 767 GuardScope( seenTuples ); 800 return functionDecl; 801 } 802 803 CompoundStmt * AutogenTupleRoutines::mutate( CompoundStmt *compoundStmt ) { 804 seenTuples.beginScope(); 805 compoundStmt = strict_dynamic_cast< CompoundStmt * >( Parent::mutate( compoundStmt ) ); 806 seenTuples.endScope(); 807 return compoundStmt; 768 808 } 769 809 } // SymTab
Note:
See TracChangeset
for help on using the changeset viewer.