Changeset 31f379c for src/InitTweak
- Timestamp:
- Dec 13, 2016, 6:16:21 PM (8 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:
- cce9429
- Parents:
- d5556a3
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified src/InitTweak/FixInit.cc ¶
rd5556a3 r31f379c 49 49 namespace InitTweak { 50 50 namespace { 51 typedef std::unordered_map< Expression *, TypeSubstitution * > EnvMap; 52 51 53 class InsertImplicitCalls final : public GenPoly::PolyMutator { 52 54 public: 53 55 /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which 54 56 /// function calls need their parameters to be copy constructed 55 static void insert( std::list< Declaration * > & translationUnit ); 56 57 using GenPoly::PolyMutator::mutate; 57 static void insert( std::list< Declaration * > & translationUnit, EnvMap & envMap ); 58 59 InsertImplicitCalls( EnvMap & envMap ) : envMap( envMap ) {} 60 typedef GenPoly::PolyMutator Parent; 61 using Parent::mutate; 58 62 virtual Expression * mutate( ApplicationExpr * appExpr ) override; 63 virtual Expression * mutate( StmtExpr * stmtExpr ) override; 64 65 // collects environments for relevant nodes 66 EnvMap & envMap; 59 67 }; 60 68 … … 64 72 /// generate/resolve copy construction expressions for each, and generate/resolve destructors for both 65 73 /// arguments and return value temporaries 66 static void resolveImplicitCalls( std::list< Declaration * > & translationUnit );74 static void resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap ); 67 75 68 76 typedef SymTab::Indexer Parent; 69 77 using Parent::visit; 70 78 79 ResolveCopyCtors( const EnvMap & envMap ) : envMap( envMap ) {} 80 71 81 virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override; 72 virtual void visit( UniqueExpr * unqExpr ); 82 virtual void visit( UniqueExpr * unqExpr ) override; 83 virtual void visit( StmtExpr * stmtExpr ) override; 73 84 74 85 /// create and resolve ctor/dtor expression: fname(var, [cpArg]) … … 79 90 void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ); 80 91 void destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr ); 81 private: 92 82 93 TypeSubstitution * env; 94 const EnvMap & envMap; 83 95 }; 84 96 … … 174 186 static void fixInitializers( std::list< Declaration * > &translationUnit ); 175 187 176 using GenPoly::PolyMutator::mutate; 188 typedef GenPoly::PolyMutator Parent; 189 using Parent::mutate; 177 190 virtual DeclarationWithType * mutate( ObjectDecl *objDecl ) override; 178 191 … … 186 199 static void fixCopyCtors( std::list< Declaration * > &translationUnit ); 187 200 188 using GenPoly::PolyMutator::mutate; 201 typedef GenPoly::PolyMutator Parent; 202 using Parent::mutate; 189 203 virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) override; 190 204 virtual Expression * mutate( UniqueExpr * unqExpr ) override; 205 virtual Expression * mutate( StmtExpr * stmtExpr ) override; 191 206 }; 192 207 … … 248 263 InitTweak::fixGlobalInit( translationUnit, filename, inLibrary ); 249 264 250 251 InsertImplicitCalls::insert( translationUnit ); 252 ResolveCopyCtors::resolveImplicitCalls( translationUnit ); 265 EnvMap envMap; 266 267 InsertImplicitCalls::insert( translationUnit, envMap ); 268 ResolveCopyCtors::resolveImplicitCalls( translationUnit, envMap ); 253 269 InsertDtors::insert( translationUnit ); 254 270 FixInit::fixInitializers( translationUnit ); … … 269 285 270 286 namespace { 271 void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit ) {272 InsertImplicitCalls inserter ;287 void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit, EnvMap & envMap ) { 288 InsertImplicitCalls inserter( envMap ); 273 289 mutateAll( translationUnit, inserter ); 274 290 } 275 291 276 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit ) {277 ResolveCopyCtors resolver ;292 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, const EnvMap & envMap ) { 293 ResolveCopyCtors resolver( envMap ); 278 294 acceptAll( translationUnit, resolver ); 279 295 } … … 326 342 327 343 Expression * InsertImplicitCalls::mutate( ApplicationExpr * appExpr ) { 328 appExpr = dynamic_cast< ApplicationExpr * >( Mutator::mutate( appExpr ) );344 appExpr = dynamic_cast< ApplicationExpr * >( Parent::mutate( appExpr ) ); 329 345 assert( appExpr ); 330 346 … … 339 355 Type * t1 = ftype->get_parameters().front()->get_type(); 340 356 Type * t2 = ftype->get_parameters().back()->get_type(); 341 PointerType * ptrType = dynamic_cast< PointerType * > ( t1 ); 342 assert( ptrType ); 357 PointerType * ptrType = safe_dynamic_cast< PointerType * > ( t1 ); 343 358 344 359 if ( ResolvExpr::typesCompatible( ptrType->get_base(), t2, SymTab::Indexer() ) ) { … … 357 372 // wrap each function call so that it is easy to identify nodes that have to be copy constructed 358 373 ImplicitCopyCtorExpr * expr = new ImplicitCopyCtorExpr( appExpr ); 359 // save the type substitution onto the new nodeso that it is easy to find.374 // save the type substitution into the envMap so that it is easy to find. 360 375 // Ensure it is not deleted with the ImplicitCopyCtorExpr by removing it before deletion. 361 376 // The substitution is needed to obtain the type of temporary variables so that copy constructor … … 366 381 // constructor calls together. 367 382 assert( env ); 368 e xpr->set_env( env );383 envMap[expr] = env; 369 384 return expr; 385 } 386 387 Expression * InsertImplicitCalls::mutate( StmtExpr * stmtExpr ) { 388 assert( env ); 389 envMap[stmtExpr] = env; 390 return Parent::mutate( stmtExpr ); 370 391 } 371 392 … … 392 413 assert( resolved ); 393 414 if ( resolved->get_env() ) { 415 // Extract useful information and discard new environments. Keeping them causes problems in PolyMutator passes. 394 416 env->add( *resolved->get_env() ); 417 delete resolved->get_env(); 418 resolved->set_env( nullptr ); 395 419 } // if 396 420 … … 401 425 void ResolveCopyCtors::copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ) { 402 426 static UniqueName tempNamer("_tmp_cp"); 403 CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *impCpCtorExpr->get_env() << std::endl; ) 427 assert( env ); 428 CP_CTOR_PRINT( std::cerr << "Type Substitution: " << *env << std::endl; ) 404 429 assert( arg->has_result() ); 405 430 Type * result = arg->get_result(); … … 408 433 // type may involve type variables, so apply type substitution to get temporary variable's actual type 409 434 result = result->clone(); 410 impCpCtorExpr->get_env()->apply( result );435 env->apply( result ); 411 436 ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 ); 412 437 tmp->get_type()->set_isConst( false ); … … 437 462 CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; ) 438 463 Parent::visit( impCpCtorExpr ); 439 env = impCpCtorExpr->get_env(); // xxx - maybe we really should just have a PolyIndexer... 464 env = envMap.at(impCpCtorExpr); 465 assert( env ); 440 466 441 467 ApplicationExpr * appExpr = impCpCtorExpr->get_callExpr(); … … 448 474 // each return value from the call needs to be connected with an ObjectDecl at the call site, which is 449 475 // initialized with the return value and is destructed later 450 // xxx - handle multiple return values 451 ApplicationExpr * callExpr = impCpCtorExpr->get_callExpr(); 452 // xxx - is this right? callExpr may not have the right environment, because it was attached at a higher 453 // level. Trying to pass that environment along. 454 callExpr->set_env( impCpCtorExpr->get_env()->clone() ); 476 // xxx - handle named return values? 455 477 Type * result = appExpr->get_result(); 456 478 if ( ! result->isVoid() ) { 457 479 static UniqueName retNamer("_tmp_cp_ret"); 458 480 result = result->clone(); 459 impCpCtorExpr->get_env()->apply( result );481 env->apply( result ); 460 482 ObjectDecl * ret = new ObjectDecl( retNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 ); 461 483 ret->get_type()->set_isConst( false ); … … 468 490 } // for 469 491 CP_CTOR_PRINT( std::cerr << "after Resolving: " << impCpCtorExpr << std::endl; ) 492 } 493 494 void ResolveCopyCtors::visit( StmtExpr * stmtExpr ) { 495 Parent::visit( stmtExpr ); 496 env = envMap.at(stmtExpr); 497 assert( stmtExpr->get_result() ); 498 Type * result = stmtExpr->get_result(); 499 if ( ! result->isVoid() ) { 500 static UniqueName retNamer("_tmp_stmtexpr_ret"); 501 502 // create variable that will hold the result of the stmt expr 503 result = result->clone(); 504 env->apply( result ); 505 ObjectDecl * ret = new ObjectDecl( retNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, result, 0 ); 506 ret->get_type()->set_isConst( false ); 507 stmtExpr->get_returnDecls().push_front( ret ); 508 509 // must have a non-empty body, otherwise it wouldn't have a result 510 CompoundStmt * body = stmtExpr->get_statements(); 511 assert( ! body->get_kids().empty() ); 512 // must be an ExprStmt, otherwise it wouldn't have a result 513 ExprStmt * last = safe_dynamic_cast< ExprStmt * >( body->get_kids().back() ); 514 last->set_expr( makeCtorDtor( "?{}", ret, last->get_expr() ) ); 515 516 stmtExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( new VariableExpr( ret ) ) ) ); 517 } // if 518 470 519 } 471 520 … … 492 541 } 493 542 494 495 543 Expression * FixCopyCtors::mutate( ImplicitCopyCtorExpr * impCpCtorExpr ) { 496 544 CP_CTOR_PRINT( std::cerr << "FixCopyCtors: " << impCpCtorExpr << std::endl; ) 497 545 498 impCpCtorExpr = dynamic_cast< ImplicitCopyCtorExpr * >( Mutator::mutate( impCpCtorExpr ) ); 499 assert( impCpCtorExpr ); 500 546 impCpCtorExpr = safe_dynamic_cast< ImplicitCopyCtorExpr * >( Parent::mutate( impCpCtorExpr ) ); 501 547 std::list< ObjectDecl * > & tempDecls = impCpCtorExpr->get_tempDecls(); 502 548 std::list< ObjectDecl * > & returnDecls = impCpCtorExpr->get_returnDecls(); … … 558 604 retExpr = UntypedExpr::createDeref( retExpr ); 559 605 } // if 560 retExpr->set_env( env->clone() ); 606 // move env from callExpr to retExpr 607 retExpr->set_env( callExpr->get_env() ); 608 callExpr->set_env( nullptr ); 561 609 return retExpr; 562 610 } else { … … 565 613 } 566 614 615 Expression * FixCopyCtors::mutate( StmtExpr * stmtExpr ) { 616 stmtExpr = safe_dynamic_cast< StmtExpr * >( Parent::mutate( stmtExpr ) ); 617 assert( stmtExpr->get_result() ); 618 Type * result = stmtExpr->get_result(); 619 if ( ! result->isVoid() ) { 620 for ( ObjectDecl * obj : stmtExpr->get_returnDecls() ) { 621 stmtsToAdd.push_back( new DeclStmt( noLabels, obj ) ); 622 } // for 623 // add destructors after current statement 624 for ( Expression * dtor : stmtExpr->get_dtors() ) { 625 stmtsToAddAfter.push_back( new ExprStmt( noLabels, dtor ) ); 626 } // for 627 // must have a non-empty body, otherwise it wouldn't have a result 628 CompoundStmt * body = stmtExpr->get_statements(); 629 assert( ! body->get_kids().empty() ); 630 assert( ! stmtExpr->get_returnDecls().empty() ); 631 body->get_kids().push_back( new ExprStmt( noLabels, new VariableExpr( stmtExpr->get_returnDecls().front() ) ) ); 632 } 633 stmtExpr->get_returnDecls().clear(); 634 stmtExpr->get_dtors().clear(); 635 return stmtExpr; 636 } 637 567 638 Expression * FixCopyCtors::mutate( UniqueExpr * unqExpr ) { 568 639 static std::unordered_map< int, UniqueExpr * > unqMap; 569 640 static std::unordered_set< int > addDeref; 570 641 // has to be done to clean up ImplicitCopyCtorExpr nodes, even when this node was skipped in previous passes 571 unqExpr = safe_dynamic_cast< UniqueExpr * >( Parent::mutate( unqExpr ) );572 642 if ( unqMap.count( unqExpr->get_id() ) ) { 573 643 // take data from other UniqueExpr to ensure consistency … … 582 652 return unqExpr; 583 653 } 654 unqExpr = safe_dynamic_cast< UniqueExpr * >( Parent::mutate( unqExpr ) ); // stmtexprs contained should not be separately fixed, so this must occur after the lookup 584 655 unqMap[unqExpr->get_id()] = unqExpr; 585 656 if ( UntypedExpr * deref = dynamic_cast< UntypedExpr * >( unqExpr->get_expr() ) ) { … … 599 670 // first recursively handle pieces of ObjectDecl so that they aren't missed by other visitors when the init 600 671 // is removed from the ObjectDecl 601 objDecl = dynamic_cast< ObjectDecl * >( Mutator::mutate( objDecl ) ); 602 672 objDecl = dynamic_cast< ObjectDecl * >( Parent::mutate( objDecl ) ); 603 673 if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) { 604 674 // a decision should have been made by the resolver, so ctor and init are not both non-NULL
Note: See TracChangeset
for help on using the changeset viewer.