Changeset 982832e for src/SymTab/Autogen.cc
- 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. - File:
-
- 1 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
Note: See TracChangeset
for help on using the changeset viewer.