Changeset 982832e for src/SymTab
- Timestamp:
- Sep 13, 2017, 2:44:01 PM (7 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:
- ba54f7d, c935c3a
- Parents:
- e3e16bc (diff), 7dc09294 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src/SymTab
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Autogen.cc
re3e16bc r982832e 163 163 // Routines at global scope marked "static" to prevent multiple definitions in separate translation units 164 164 // because each unit generates copies of the default routines for each aggregate. 165 // DeclarationNode::StorageClass sc = functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static;166 165 Type::StorageClasses scs = functionNesting > 0 ? Type::StorageClasses() : Type::StorageClasses( Type::Static ); 167 166 LinkageSpec::Spec spec = isIntrinsic ? LinkageSpec::Intrinsic : LinkageSpec::AutoGen; … … 186 185 /// using map and t, determines if is constructable, etc. 187 186 bool lookup( const TypeMap & map, Type * t ) { 187 assertf( t, "Autogenerate lookup was given non-type: %s", toString( t ).c_str() ); 188 188 if ( dynamic_cast< PointerType * >( t ) ) { 189 189 // will need more complicated checking if we want this to work with pointer types, since currently … … 200 200 201 201 /// using map and aggr, examines each member to determine if constructor, etc. should be generated 202 template<typename AggrDecl> 203 bool shouldGenerate( const TypeMap & map, AggrDecl * aggr ) { 204 for ( Declaration * dcl : aggr->get_members() ) { 205 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( dcl ) ) { 206 if ( ! lookup( map, dwt->get_type() ) ) return false; 207 } 202 template<typename Container> 203 bool shouldGenerate( const TypeMap & map, const Container & container ) { 204 for ( Type * t : container ) { 205 if ( ! lookup( map, t ) ) return false; 208 206 } 209 207 return true; … … 211 209 212 210 /// data structure for abstracting the generation of special functions 213 template< typename OutputIterator >211 template< typename OutputIterator, typename Container > 214 212 struct FuncGenerator { 215 StructDecl *aggregateDecl;216 StructInstType *refType;213 const Container & container; 214 Type *refType; 217 215 unsigned int functionNesting; 218 216 const std::list< TypeDecl* > & typeParams; 219 217 OutputIterator out; 220 FuncGenerator( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) : aggregateDecl( aggregateDecl), refType( refType ), functionNesting( functionNesting ), typeParams( typeParams ), out( out ) {}218 FuncGenerator( const Container & container, Type *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) : container( container ), refType( refType ), functionNesting( functionNesting ), typeParams( typeParams ), out( out ) {} 221 219 222 220 /// generates a function (?{}, ?=?, ^?{}) based on the data argument and members. If function is generated, inserts the type into the map. 223 221 void gen( const FuncData & data, bool concurrent_type ) { 224 if ( ! shouldGenerate( data.map, aggregateDecl) ) return;222 if ( ! shouldGenerate( data.map, container ) ) return; 225 223 FunctionType * ftype = data.genType( refType ); 226 224 227 225 if(concurrent_type && CodeGen::isDestructor( data.fname )) { 228 ftype-> get_parameters().front()->get_type()->set_mutex( true );229 } 230 231 cloneAll( typeParams, ftype-> get_forall());226 ftype->parameters.front()->get_type()->set_mutex( true ); 227 } 228 229 cloneAll( typeParams, ftype->forall ); 232 230 *out++ = genFunc( data.fname, ftype, functionNesting ); 233 231 data.map.insert( Mangler::mangleType( refType ), true ); … … 235 233 }; 236 234 237 template< typename OutputIterator >238 FuncGenerator<OutputIterator > makeFuncGenerator( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) {239 return FuncGenerator<OutputIterator >( aggregateDecl, refType, functionNesting, typeParams, out );235 template< typename OutputIterator, typename Container > 236 FuncGenerator<OutputIterator, Container> makeFuncGenerator( const Container & container, Type *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) { 237 return FuncGenerator<OutputIterator, Container>( container, refType, functionNesting, typeParams, out ); 240 238 } 241 239 … … 393 391 } 394 392 393 Type * declToType( Declaration * decl ) { 394 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 395 return dwt->get_type(); 396 } 397 return nullptr; 398 } 399 395 400 /// generates struct constructors, destructor, and assignment functions 396 401 void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) { … … 406 411 // generate each of the functions based on the supplied FuncData objects 407 412 std::list< FunctionDecl * > newFuncs; 408 auto generator = makeFuncGenerator( aggregateDecl, refType, functionNesting, typeParams, back_inserter( newFuncs ) ); 413 // structure that iterates aggregate decl members, returning their types 414 auto generator = makeFuncGenerator( lazy_map( aggregateDecl->members, declToType ), refType, functionNesting, typeParams, back_inserter( newFuncs ) ); 409 415 for ( const FuncData & d : data ) { 410 416 generator.gen( d, aggregateDecl->is_thread() || aggregateDecl->is_monitor() ); … … 605 611 } 606 612 613 Type * declToTypeDeclBase( Declaration * decl ) { 614 if ( TypeDecl * td = dynamic_cast< TypeDecl * >( decl ) ) { 615 return td->base; 616 } 617 return nullptr; 618 } 619 620 // generate ctor/dtors/assign for typedecls, e.g., otype T = int *; 607 621 void AutogenerateRoutines::visit( TypeDecl *typeDecl ) { 608 TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false ); 609 typeInst->set_baseType( typeDecl ); 610 ObjectDecl *src = new ObjectDecl( "_src", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, typeInst->clone(), nullptr ); 611 ObjectDecl *dst = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), typeInst->clone() ), nullptr ); 612 613 std::list< Statement * > stmts; 614 if ( typeDecl->get_base() ) { 615 // xxx - generate ctor/dtors for typedecls, e.g. 616 // otype T = int *; 617 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); 618 assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) ); 619 assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) ); 620 stmts.push_back( new ReturnStmt( std::list< Label >(), assign ) ); 621 } // if 622 FunctionType *type = new FunctionType( Type::Qualifiers(), false ); 623 type->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, typeInst, 0 ) ); 624 type->get_parameters().push_back( dst ); 625 type->get_parameters().push_back( src ); 626 FunctionDecl *func = genFunc( "?=?", type, functionNesting ); 627 func->get_statements()->get_kids() = stmts; 628 declsToAddAfter.push_back( func ); 622 if ( ! typeDecl->base ) return; 623 624 // generate each of the functions based on the supplied FuncData objects 625 std::list< FunctionDecl * > newFuncs; 626 std::list< Declaration * > tds { typeDecl }; 627 std::list< TypeDecl * > typeParams; 628 TypeInstType refType( Type::Qualifiers(), typeDecl->name, typeDecl ); 629 auto generator = makeFuncGenerator( lazy_map( tds, declToTypeDeclBase ), &refType, functionNesting, typeParams, back_inserter( newFuncs ) ); 630 for ( const FuncData & d : data ) { 631 generator.gen( d, false ); 632 } 633 634 if ( functionNesting == 0 ) { 635 // forward declare if top-level struct, so that 636 // type is complete as soon as its body ends 637 // Note: this is necessary if we want structs which contain 638 // generic (otype) structs as members. 639 for ( FunctionDecl * dcl : newFuncs ) { 640 addForwardDecl( dcl, declsToAddAfter ); 641 } 642 } 643 644 for ( FunctionDecl * dcl : newFuncs ) { 645 FunctionType * ftype = dcl->type; 646 assertf( ftype->parameters.size() == 1 || ftype->parameters.size() == 2, "Incorrect number of parameters in autogenerated typedecl function: %zd", ftype->parameters.size() ); 647 DeclarationWithType * dst = ftype->parameters.front(); 648 DeclarationWithType * src = ftype->parameters.size() == 2 ? ftype->parameters.back() : nullptr; 649 // generate appropriate calls to member ctor, assignment 650 // destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor 651 UntypedExpr * expr = new UntypedExpr( new NameExpr( dcl->name ) ); 652 expr->args.push_back( new CastExpr( new VariableExpr( dst ), new ReferenceType( Type::Qualifiers(), typeDecl->base->clone() ) ) ); 653 if ( src ) expr->args.push_back( new CastExpr( new VariableExpr( src ), typeDecl->base->clone() ) ); 654 dcl->statements->kids.push_back( new ExprStmt( noLabels, expr ) ); 655 if ( CodeGen::isAssignment( dcl->get_name() ) ) { 656 // assignment needs to return a value 657 FunctionType * assignType = dcl->type; 658 assert( assignType->parameters.size() == 2 ); 659 ObjectDecl * srcParam = strict_dynamic_cast< ObjectDecl * >( assignType->parameters.back() ); 660 dcl->statements->kids.push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 661 } 662 declsToAddAfter.push_back( dcl ); 663 } 629 664 } 630 665 -
src/SymTab/Validate.cc
re3e16bc r982832e 176 176 }; 177 177 178 class EliminateTypedef : public Mutator { 179 public: 178 struct EliminateTypedef final : public WithVisitorRef<EliminateTypedef>, public WithGuards { 180 179 EliminateTypedef() : scopeLevel( 0 ) {} 181 180 /// Replaces typedefs by forward declarations 182 181 static void eliminateTypedef( std::list< Declaration * > &translationUnit ); 182 183 Type * postmutate( TypeInstType * aggregateUseType ); 184 Declaration * postmutate( TypedefDecl * typeDecl ); 185 void premutate( TypeDecl * typeDecl ); 186 void premutate( FunctionDecl * funcDecl ); 187 void premutate( ObjectDecl * objDecl ); 188 DeclarationWithType * postmutate( ObjectDecl * objDecl ); 189 190 void premutate( CastExpr * castExpr ); 191 192 void premutate( CompoundStmt * compoundStmt ); 193 CompoundStmt * postmutate( CompoundStmt * compoundStmt ); 194 195 void premutate( StructDecl * structDecl ); 196 Declaration * postmutate( StructDecl * structDecl ); 197 void premutate( UnionDecl * unionDecl ); 198 Declaration * postmutate( UnionDecl * unionDecl ); 199 void premutate( EnumDecl * enumDecl ); 200 Declaration * postmutate( EnumDecl * enumDecl ); 201 Declaration * postmutate( TraitDecl * contextDecl ); 202 183 203 private: 184 virtual Declaration *mutate( TypedefDecl *typeDecl );185 virtual TypeDecl *mutate( TypeDecl *typeDecl );186 virtual DeclarationWithType *mutate( FunctionDecl *funcDecl );187 virtual DeclarationWithType *mutate( ObjectDecl *objDecl );188 virtual CompoundStmt *mutate( CompoundStmt *compoundStmt );189 virtual Type *mutate( TypeInstType *aggregateUseType );190 virtual Expression *mutate( CastExpr *castExpr );191 192 virtual Declaration *mutate( StructDecl * structDecl );193 virtual Declaration *mutate( UnionDecl * unionDecl );194 virtual Declaration *mutate( EnumDecl * enumDecl );195 virtual Declaration *mutate( TraitDecl * contextDecl );196 197 204 template<typename AggDecl> 198 205 AggDecl *handleAggregate( AggDecl * aggDecl ); … … 667 674 668 675 void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) { 669 EliminateTypedefeliminator;676 PassVisitor<EliminateTypedef> eliminator; 670 677 mutateAll( translationUnit, eliminator ); 671 if ( eliminator. typedefNames.count( "size_t" ) ) {678 if ( eliminator.pass.typedefNames.count( "size_t" ) ) { 672 679 // grab and remember declaration of size_t 673 SizeType = eliminator. typedefNames["size_t"].first->get_base()->clone();680 SizeType = eliminator.pass.typedefNames["size_t"].first->get_base()->clone(); 674 681 } else { 675 682 // xxx - missing global typedef for size_t - default to long unsigned int, even though that may be wrong … … 681 688 } 682 689 683 Type * EliminateTypedef::mutate( TypeInstType * typeInst ) {690 Type * EliminateTypedef::postmutate( TypeInstType * typeInst ) { 684 691 // instances of typedef types will come here. If it is an instance 685 692 // of a typdef type, link the instance to its actual type. … … 696 703 rtt->get_parameters().clear(); 697 704 cloneAll( typeInst->get_parameters(), rtt->get_parameters() ); 698 mutateAll( rtt->get_parameters(), * this); // recursively fix typedefs on parameters705 mutateAll( rtt->get_parameters(), *visitor ); // recursively fix typedefs on parameters 699 706 } // if 700 707 delete typeInst; … … 708 715 } 709 716 710 Declaration *EliminateTypedef::mutate( TypedefDecl * tyDecl ) { 711 Declaration *ret = Mutator::mutate( tyDecl ); 712 717 Declaration *EliminateTypedef::postmutate( TypedefDecl * tyDecl ) { 713 718 if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) { 714 719 // typedef to the same name from the same scope … … 741 746 return new EnumDecl( enumDecl->get_name(), noAttributes, tyDecl->get_linkage() ); 742 747 } else { 743 return ret->clone();744 } // if 745 } 746 747 TypeDecl *EliminateTypedef::mutate( TypeDecl * typeDecl ) {748 return tyDecl->clone(); 749 } // if 750 } 751 752 void EliminateTypedef::premutate( TypeDecl * typeDecl ) { 748 753 TypedefMap::iterator i = typedefNames.find( typeDecl->get_name() ); 749 754 if ( i != typedefNames.end() ) { … … 752 757 753 758 typedeclNames[ typeDecl->get_name() ] = typeDecl; 754 return Mutator::mutate( typeDecl ); 755 } 756 757 DeclarationWithType *EliminateTypedef::mutate( FunctionDecl * funcDecl ) { 758 typedefNames.beginScope(); 759 DeclarationWithType *ret = Mutator::mutate( funcDecl ); 760 typedefNames.endScope(); 761 return ret; 762 } 763 764 DeclarationWithType *EliminateTypedef::mutate( ObjectDecl * objDecl ) { 765 typedefNames.beginScope(); 766 DeclarationWithType *ret = Mutator::mutate( objDecl ); 767 typedefNames.endScope(); 768 769 if ( FunctionType *funtype = dynamic_cast<FunctionType *>( ret->get_type() ) ) { // function type? 759 } 760 761 void EliminateTypedef::premutate( FunctionDecl * ) { 762 GuardScope( typedefNames ); 763 } 764 765 void EliminateTypedef::premutate( ObjectDecl * ) { 766 GuardScope( typedefNames ); 767 } 768 769 DeclarationWithType *EliminateTypedef::postmutate( ObjectDecl * objDecl ) { 770 if ( FunctionType *funtype = dynamic_cast<FunctionType *>( objDecl->get_type() ) ) { // function type? 770 771 // replace the current object declaration with a function declaration 771 FunctionDecl * newDecl = new FunctionDecl( ret->get_name(), ret->get_storageClasses(), ret->get_linkage(), funtype, 0, objDecl->get_attributes(), ret->get_funcSpec() );772 FunctionDecl * newDecl = new FunctionDecl( objDecl->get_name(), objDecl->get_storageClasses(), objDecl->get_linkage(), funtype, 0, objDecl->get_attributes(), objDecl->get_funcSpec() ); 772 773 objDecl->get_attributes().clear(); 773 774 objDecl->set_type( nullptr ); … … 775 776 return newDecl; 776 777 } // if 777 return ret; 778 } 779 780 Expression *EliminateTypedef::mutate( CastExpr * castExpr ) { 781 typedefNames.beginScope(); 782 Expression *ret = Mutator::mutate( castExpr ); 783 typedefNames.endScope(); 784 return ret; 785 } 786 787 CompoundStmt *EliminateTypedef::mutate( CompoundStmt * compoundStmt ) { 788 typedefNames.beginScope(); 778 return objDecl; 779 } 780 781 void EliminateTypedef::premutate( CastExpr * ) { 782 GuardScope( typedefNames ); 783 } 784 785 void EliminateTypedef::premutate( CompoundStmt * ) { 786 GuardScope( typedefNames ); 789 787 scopeLevel += 1; 790 CompoundStmt *ret = Mutator::mutate( compoundStmt ); 791 scopeLevel -= 1; 788 GuardAction( [this](){ scopeLevel -= 1; } ); 789 } 790 791 CompoundStmt *EliminateTypedef::postmutate( CompoundStmt * compoundStmt ) { 792 792 // remove and delete decl stmts 793 793 filter( compoundStmt->kids, [](Statement * stmt) { … … 799 799 return false; 800 800 }, true); 801 typedefNames.endScope(); 802 return ret; 801 return compoundStmt; 803 802 } 804 803 … … 827 826 } 828 827 829 Declaration *EliminateTypedef::mutate( StructDecl * structDecl ) {828 void EliminateTypedef::premutate( StructDecl * structDecl ) { 830 829 addImplicitTypedef( structDecl ); 831 Mutator::mutate( structDecl ); 830 } 831 832 833 Declaration *EliminateTypedef::postmutate( StructDecl * structDecl ) { 832 834 return handleAggregate( structDecl ); 833 835 } 834 836 835 Declaration *EliminateTypedef::mutate( UnionDecl * unionDecl ) {837 void EliminateTypedef::premutate( UnionDecl * unionDecl ) { 836 838 addImplicitTypedef( unionDecl ); 837 Mutator::mutate( unionDecl ); 839 } 840 841 Declaration *EliminateTypedef::postmutate( UnionDecl * unionDecl ) { 838 842 return handleAggregate( unionDecl ); 839 843 } 840 844 841 Declaration *EliminateTypedef::mutate( EnumDecl * enumDecl ) {845 void EliminateTypedef::premutate( EnumDecl * enumDecl ) { 842 846 addImplicitTypedef( enumDecl ); 843 Mutator::mutate( enumDecl ); 847 } 848 849 Declaration *EliminateTypedef::postmutate( EnumDecl * enumDecl ) { 844 850 return handleAggregate( enumDecl ); 845 851 } 846 852 847 Declaration *EliminateTypedef::mutate( TraitDecl * contextDecl ) { 848 Mutator::mutate( contextDecl ); 849 return handleAggregate( contextDecl ); 853 Declaration *EliminateTypedef::postmutate( TraitDecl * traitDecl ) { 854 return handleAggregate( traitDecl ); 850 855 } 851 856
Note: See TracChangeset
for help on using the changeset viewer.