Changeset 8024bc8 for src/InitTweak/FixInit.cc
- Timestamp:
- Sep 18, 2017, 11:02:23 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:
- 6994d8c
- Parents:
- ed235b6 (diff), 5f782f7 (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/InitTweak/FixInit.cc
red235b6 r8024bc8 70 70 namespace InitTweak { 71 71 namespace { 72 typedef std::unordered_map< Expression *, TypeSubstitution * > EnvMap;73 72 typedef std::unordered_map< int, int > UnqCount; 74 73 75 class InsertImplicitCalls : public WithTypeSubstitution { 76 public: 74 struct InsertImplicitCalls : public WithTypeSubstitution { 77 75 /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which 78 76 /// function calls need their parameters to be copy constructed 79 static void insert( std::list< Declaration * > & translationUnit, EnvMap & envMap ); 80 81 InsertImplicitCalls( EnvMap & envMap ) : envMap( envMap ) {} 77 static void insert( std::list< Declaration * > & translationUnit ); 82 78 83 79 Expression * postmutate( ApplicationExpr * appExpr ); 84 void premutate( StmtExpr * stmtExpr );85 86 // collects environments for relevant nodes87 EnvMap & envMap;88 80 }; 89 81 90 class ResolveCopyCtors final : public SymTab::Indexer { 91 public: 82 struct ResolveCopyCtors final : public WithIndexer, public WithShortCircuiting, public WithTypeSubstitution { 92 83 /// generate temporary ObjectDecls for each argument and return value of each ImplicitCopyCtorExpr, 93 84 /// generate/resolve copy construction expressions for each, and generate/resolve destructors for both 94 85 /// arguments and return value temporaries 95 static void resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap, UnqCount & unqCount ); 96 97 typedef SymTab::Indexer Parent; 98 using Parent::visit; 99 100 ResolveCopyCtors( const EnvMap & envMap, UnqCount & unqCount ) : envMap( envMap ), unqCount( unqCount ) {} 101 102 virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override; 103 virtual void visit( UniqueExpr * unqExpr ) override; 104 virtual void visit( StmtExpr * stmtExpr ) override; 86 static void resolveImplicitCalls( std::list< Declaration * > & translationUnit, UnqCount & unqCount ); 87 88 ResolveCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ) {} 89 90 void postvisit( ImplicitCopyCtorExpr * impCpCtorExpr ); 91 void postvisit( StmtExpr * stmtExpr ); 92 void previsit( UniqueExpr * unqExpr ); 93 void postvisit( UniqueExpr * unqExpr ); 105 94 106 95 /// create and resolve ctor/dtor expression: fname(var, [cpArg]) … … 111 100 void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr ); 112 101 113 TypeSubstitution * env;114 const EnvMap & envMap;115 102 UnqCount & unqCount; // count the number of times each unique expr ID appears 103 std::unordered_set< int > vars; 116 104 }; 117 105 … … 238 226 }; 239 227 240 class GenStructMemberCalls final : public SymTab::Indexer { 241 public: 242 typedef Indexer Parent; 228 struct GenStructMemberCalls final : public WithGuards, public WithShortCircuiting, public WithIndexer { 243 229 /// generate default/copy ctor and dtor calls for user-defined struct ctor/dtors 244 230 /// for any member that is missing a corresponding ctor/dtor call. … … 246 232 static void generate( std::list< Declaration * > & translationUnit ); 247 233 248 using Parent::visit; 249 250 virtual void visit( FunctionDecl * funcDecl ) override; 251 252 virtual void visit( MemberExpr * memberExpr ) override; 253 virtual void visit( ApplicationExpr * appExpr ) override; 234 void previsit( FunctionDecl * funcDecl ); 235 void postvisit( FunctionDecl * funcDecl ); 236 237 void previsit( MemberExpr * memberExpr ); 238 void previsit( ApplicationExpr * appExpr ); 254 239 255 240 SemanticError errors; … … 295 280 InitTweak::fixGlobalInit( translationUnit, filename, inLibrary ); 296 281 297 EnvMap envMap;298 282 UnqCount unqCount; 299 283 300 InsertImplicitCalls::insert( translationUnit , envMap);301 ResolveCopyCtors::resolveImplicitCalls( translationUnit, envMap,unqCount );284 InsertImplicitCalls::insert( translationUnit ); 285 ResolveCopyCtors::resolveImplicitCalls( translationUnit, unqCount ); 302 286 InsertDtors::insert( translationUnit ); 303 287 FixInit::fixInitializers( translationUnit ); … … 318 302 319 303 namespace { 320 void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit , EnvMap & envMap) {321 PassVisitor<InsertImplicitCalls> inserter ( envMap );304 void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit ) { 305 PassVisitor<InsertImplicitCalls> inserter; 322 306 mutateAll( translationUnit, inserter ); 323 307 } 324 308 325 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap,UnqCount & unqCount ) {326 ResolveCopyCtors resolver( envMap,unqCount );309 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, UnqCount & unqCount ) { 310 PassVisitor<ResolveCopyCtors> resolver( unqCount ); 327 311 acceptAll( translationUnit, resolver ); 328 312 } … … 360 344 361 345 void GenStructMemberCalls::generate( std::list< Declaration * > & translationUnit ) { 362 GenStructMemberCallswarner;346 PassVisitor<GenStructMemberCalls> warner; 363 347 acceptAll( translationUnit, warner ); 364 348 } … … 398 382 // wrap each function call so that it is easy to identify nodes that have to be copy constructed 399 383 ImplicitCopyCtorExpr * expr = new ImplicitCopyCtorExpr( appExpr ); 400 // save the type substitution into the envMap so that it is easy to find.384 // Move the type substitution to the new top-level, if it is attached to the appExpr. 401 385 // Ensure it is not deleted with the ImplicitCopyCtorExpr by removing it before deletion. 402 386 // The substitution is needed to obtain the type of temporary variables so that copy constructor 403 // calls can be resolved. Normally this is what PolyMutator is for, but the pass that resolves 404 // copy constructor calls must be an Indexer. We could alternatively make a PolyIndexer which 405 // saves the environment, or compute the types of temporaries here, but it's much simpler to 406 // save the environment here, and more cohesive to compute temporary variables and resolve copy 407 // constructor calls together. 387 // calls can be resolved. 408 388 assert( env ); 409 envMap[expr] = env;389 std::swap( expr->env, appExpr->env ); 410 390 return expr; 411 }412 413 void InsertImplicitCalls::premutate( StmtExpr * stmtExpr ) {414 assert( env );415 envMap[stmtExpr] = env;416 391 } 417 392 … … 431 406 // (VariableExpr and already resolved expression) 432 407 CP_CTOR_PRINT( std::cerr << "ResolvingCtorDtor " << untyped << std::endl; ) 433 Expression * resolved = ResolvExpr::findVoidExpression( untyped, *this);408 Expression * resolved = ResolvExpr::findVoidExpression( untyped, indexer ); 434 409 assert( resolved ); 435 410 if ( resolved->get_env() ) { … … 480 455 } 481 456 482 void ResolveCopyCtors:: visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {457 void ResolveCopyCtors::postvisit( ImplicitCopyCtorExpr *impCpCtorExpr ) { 483 458 CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; ) 484 Parent::visit( impCpCtorExpr );485 env = envMap.at(impCpCtorExpr);486 assert( env );487 459 488 460 ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr(); … … 513 485 } 514 486 515 void ResolveCopyCtors::visit( StmtExpr * stmtExpr ) { 516 Parent::visit( stmtExpr ); 517 env = envMap.at(stmtExpr); 487 void ResolveCopyCtors::postvisit( StmtExpr * stmtExpr ) { 488 assert( env ); 518 489 assert( stmtExpr->get_result() ); 519 490 Type * result = stmtExpr->get_result(); … … 537 508 stmtExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) ); 538 509 } // if 539 540 } 541 542 void ResolveCopyCtors::visit( UniqueExpr * unqExpr ) { 543 static std::unordered_set< int > vars; 510 } 511 512 void ResolveCopyCtors::previsit( UniqueExpr * unqExpr ) { 544 513 unqCount[ unqExpr->get_id() ]++; // count the number of unique expressions for each ID 545 514 if ( vars.count( unqExpr->get_id() ) ) { 546 515 // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated 516 visit_children = false; 517 } 518 } 519 520 void ResolveCopyCtors::postvisit( UniqueExpr * unqExpr ) { 521 if ( vars.count( unqExpr->get_id() ) ) { 522 // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated 547 523 return; 548 524 } 549 525 550 Parent::visit( unqExpr );551 526 // it should never be necessary to wrap a void-returning expression in a UniqueExpr - if this assumption changes, this needs to be rethought 552 527 assert( unqExpr->get_result() ); … … 585 560 586 561 // xxx - update to work with multiple return values 587 ObjectDecl * returnDecl = returnDecls.empty() ? NULL: returnDecls.front();562 ObjectDecl * returnDecl = returnDecls.empty() ? nullptr : returnDecls.front(); 588 563 Expression * callExpr = impCpCtorExpr->get_callExpr(); 589 564 … … 594 569 tempDecls.clear(); 595 570 returnDecls.clear(); 596 impCpCtorExpr->set_callExpr( NULL ); 597 impCpCtorExpr->set_env( NULL ); 571 impCpCtorExpr->set_callExpr( nullptr ); 572 std::swap( impCpCtorExpr->env, callExpr->env ); 573 assert( impCpCtorExpr->env == nullptr ); 598 574 delete impCpCtorExpr; 599 575 … … 978 954 } 979 955 980 void GenStructMemberCalls:: visit( FunctionDecl * funcDecl ) {981 ValueGuard< FunctionDecl * > oldFunction( funcDecl );982 ValueGuard< std::set< DeclarationWithType * > > oldUnhandled( unhandled );983 ValueGuard< std::map< DeclarationWithType *, CodeLocation > > oldUsedUninit( usedUninit );984 ValueGuard< ObjectDecl * > oldThisParam( thisParam );985 ValueGuard< bool > oldIsCtor( isCtor );986 ValueGuard< StructDecl * > oldStructDecl( structDecl );956 void GenStructMemberCalls::previsit( FunctionDecl * funcDecl ) { 957 GuardValue( funcDecl ); 958 GuardValue( unhandled ); 959 GuardValue( usedUninit ); 960 GuardValue( thisParam ); 961 GuardValue( isCtor ); 962 GuardValue( structDecl ); 987 963 errors = SemanticError(); // clear previous errors 988 964 … … 1010 986 } 1011 987 } 1012 Parent::visit( function ); 1013 988 } 989 990 void addIds( SymTab::Indexer & indexer, const std::list< DeclarationWithType * > & decls ) { 991 for ( auto d : decls ) { 992 indexer.addId( d ); 993 } 994 } 995 996 void addTypes( SymTab::Indexer & indexer, const std::list< TypeDecl * > & tds ) { 997 for ( auto td : tds ) { 998 indexer.addType( td ); 999 addIds( indexer, td->assertions ); 1000 } 1001 } 1002 1003 void GenStructMemberCalls::postvisit( FunctionDecl * funcDecl ) { 1014 1004 // remove the unhandled objects from usedUninit, because a call is inserted 1015 1005 // to handle them - only objects that are later constructed are used uninitialized. … … 1032 1022 if ( ! unhandled.empty() ) { 1033 1023 // need to explicitly re-add function parameters to the indexer in order to resolve copy constructors 1034 enterScope(); 1035 maybeAccept( function->get_functionType(), *this ); 1024 auto guard = makeFuncGuard( [this]() { indexer.enterScope(); }, [this]() { indexer.leaveScope(); } ); 1025 addTypes( indexer, function->type->forall ); 1026 addIds( indexer, function->type->returnVals ); 1027 addIds( indexer, function->type->parameters ); 1036 1028 1037 1029 // need to iterate through members in reverse in order for … … 1063 1055 Statement * callStmt = stmt.front(); 1064 1056 1065 MutatingResolver resolver( *this);1057 MutatingResolver resolver( indexer ); 1066 1058 try { 1067 1059 callStmt->acceptMutator( resolver ); … … 1077 1069 } 1078 1070 } 1079 leaveScope();1080 1071 } 1081 1072 if (! errors.isEmpty()) { … … 1107 1098 } 1108 1099 1109 void GenStructMemberCalls::visit( ApplicationExpr * appExpr ) { 1110 if ( ! checkWarnings( function ) ) return; 1100 void GenStructMemberCalls::previsit( ApplicationExpr * appExpr ) { 1101 if ( ! checkWarnings( function ) ) { 1102 visit_children = false; 1103 return; 1104 } 1111 1105 1112 1106 std::string fname = getFunctionName( appExpr ); … … 1127 1121 } 1128 1122 } 1129 Parent::visit( appExpr ); 1130 } 1131 1132 void GenStructMemberCalls::visit( MemberExpr * memberExpr ) { 1133 if ( ! checkWarnings( function ) ) return; 1134 if ( ! isCtor ) return; 1123 } 1124 1125 void GenStructMemberCalls::previsit( MemberExpr * memberExpr ) { 1126 if ( ! checkWarnings( function ) || ! isCtor ) { 1127 visit_children = false; 1128 return; 1129 } 1135 1130 1136 1131 if ( isThisExpression( memberExpr->get_aggregate(), thisParam ) ) { … … 1140 1135 } 1141 1136 } 1142 Parent::visit( memberExpr );1143 1137 } 1144 1138 … … 1161 1155 // in generated code. If this changes, add mutate methods for entities with 1162 1156 // scope and call {enter,leave}Scope explicitly. 1163 objectDecl->accept( indexer);1157 indexer.addId( objectDecl ); 1164 1158 return objectDecl; 1165 1159 }
Note: See TracChangeset
for help on using the changeset viewer.