- Timestamp:
- Sep 12, 2017, 10:45:01 AM (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:
- 93389c1
- Parents:
- 1395748
- Location:
- src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Common/utility.h
r1395748 r108f3cdb 370 370 } 371 371 372 // ----------------------------------------------------------------------------- 373 // Helper struct and function to support 374 // for ( val : lazy_map( container1, f ) ) {} 375 // syntax to have a for each that iterates a container, mapping each element by applying f 376 template< typename T, typename Func > 377 struct lambda_iterate_t { 378 T & ref; 379 Func f; 380 381 struct iterator { 382 typedef decltype(begin(ref)) Iter; 383 Iter it; 384 Func f; 385 iterator( Iter it, Func f ) : it(it), f(f) {} 386 iterator & operator++() { 387 ++it; return *this; 388 } 389 bool operator!=( const iterator &other ) const { return it != other.it; } 390 auto operator*() const -> decltype(f(*it)) { return f(*it); } 391 }; 392 393 lambda_iterate_t( T & ref, Func f ) : ref(ref), f(f) {} 394 395 auto begin() const -> decltype(iterator(std::begin(ref), f)) { return iterator(std::begin(ref), f); } 396 auto end() const -> decltype(iterator(std::end(ref), f)) { return iterator(std::end(ref), f); } 397 }; 398 399 template< typename... Args > 400 lambda_iterate_t<Args...> lazy_map( Args &&... args ) { 401 return lambda_iterate_t<Args...>(std::forward<Args>( args )...); 402 } 403 404 405 372 406 // Local Variables: // 373 407 // tab-width: 4 // -
src/ResolvExpr/CastCost.cc
r1395748 r108f3cdb 45 45 } 46 46 } else if ( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) { 47 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );48 47 // all typedefs should be gone by this point 49 assert( type );48 TypeDecl *type = safe_dynamic_cast< TypeDecl* >( namedType ); 50 49 if ( type->get_base() ) { 51 50 return castCost( src, type->get_base(), indexer, env ) + Cost::safe; -
src/ResolvExpr/ConversionCost.cc
r1395748 r108f3cdb 92 92 93 93 Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) { 94 PRINT( std::cerr << "convert to reference cost... "<< std::endl; )94 PRINT( std::cerr << "convert to reference cost... diff " << diff << std::endl; ) 95 95 if ( diff > 0 ) { 96 96 // TODO: document this … … 128 128 ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest ); 129 129 assert( diff == -1 && destAsRef ); 130 PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; ) 130 131 if ( typesCompatibleIgnoreQualifiers( src, destAsRef->get_base(), indexer, env ) ) { 131 132 PRINT( std::cerr << "converting compatible base type" << std::endl; ) -
src/SymTab/Autogen.cc
r1395748 r108f3cdb 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 = safe_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.