Changeset f9cebb5 for src/InitTweak/FixInit.cc
- Timestamp:
- Aug 4, 2016, 4:10:06 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 4819cac
- Parents:
- 73bf8cf2
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
r73bf8cf2 rf9cebb5 26 26 #include "SynTree/Type.h" 27 27 #include "SynTree/Expression.h" 28 #include "SynTree/Attribute.h" 28 29 #include "SynTree/Statement.h" 29 30 #include "SynTree/Initializer.h" … … 208 209 try { 209 210 *i = maybeMutate( *i, fixer ); 210 // if (! fixer.staticDtorDecls.empty() ) { 211 translationUnit.splice( i, fixer.staticDtorDecls ); 212 // } 211 translationUnit.splice( i, fixer.staticDtorDecls ); 213 212 } catch( SemanticError &e ) { 214 213 errors.append( e ); … … 446 445 if ( objDecl->get_storageClass() == DeclarationNode::Static ) { 447 446 // originally wanted to take advantage of gcc nested functions, but 448 // we get memory errors with this approach. To remedy this, create a 449 // global static pointer that is set to refer to the object and make 450 // the dtor-caller function global so that. 447 // we get memory errors with this approach. To remedy this, the static 448 // variable is hoisted when the destructor needs to be called. 451 449 // 452 450 // generate: 453 // T * __objName_static_ptrN;451 // static T __objName_static_varN; 454 452 // void __objName_dtor_atexitN() { 455 // __dtor (__objName_static_ptrN);453 // __dtor__...; 456 454 // } 457 455 // int f(...) { 458 456 // ... 459 // static T __objName;460 457 // static bool __objName_uninitialized = true; 461 458 // if (__objName_uninitialized) { 462 // __objName_ptr = &__objName;463 459 // __ctor(__objName); 464 // on_exit(__objName_dtor_atexitN, &__objName);465 460 // __objName_uninitialized = false; 461 // atexit(__objName_dtor_atexitN); 466 462 // } 467 463 // ... 468 464 // } 469 465 470 static UniqueName ptrNamer( "_static_ptr" );471 466 static UniqueName dtorCallerNamer( "_dtor_atexit" ); 472 473 // T * __objName_ptrN474 ObjectDecl * objPtr = new ObjectDecl( objDecl->get_mangleName() + ptrNamer.newName(), DeclarationNode::Static, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), objDecl->get_type()->clone() ), 0 );475 objPtr->fixUniqueId();476 477 // void __objName_dtor_atexitN(...) {...}478 // need to modify dtor call so that it refers to objPtr, since function will be global479 Statement * dtorStmt = ctorInit->get_dtor()->clone();480 ApplicationExpr * dtor = dynamic_cast< ApplicationExpr * >( InitTweak::getCtorDtorCall( dtorStmt ) );481 assert( dtor );482 delete dtor->get_args().front();483 dtor->get_args().front() = new VariableExpr( objPtr );484 485 FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + dtorCallerNamer.newName(), DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );486 dtorCaller->fixUniqueId();487 dtorCaller->get_statements()->get_kids().push_back( dtorStmt );488 467 489 468 // static bool __objName_uninitialized = true … … 493 472 isUninitializedVar->fixUniqueId(); 494 473 495 // __objName_static_ptrN = &__objName;496 UntypedExpr * ptrAssign = new UntypedExpr( new NameExpr( "?=?" ) );497 ptrAssign->get_args().push_back( new VariableExpr( objPtr ) );498 ptrAssign->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );499 500 // atexit(dtor_atexit);501 UntypedExpr * callAtexit = new UntypedExpr( new NameExpr( "atexit" ) );502 callAtexit->get_args().push_back( new VariableExpr( dtorCaller ) );503 504 474 // __objName_uninitialized = false; 505 475 UntypedExpr * setTrue = new UntypedExpr( new NameExpr( "?=?" ) ); … … 511 481 std::list< Statement * > & body = initStmts->get_kids(); 512 482 body.push_back( ctor ); 513 body.push_back( new ExprStmt( noLabels, ptrAssign ) );514 body.push_back( new ExprStmt( noLabels, callAtexit ) );515 483 body.push_back( new ExprStmt( noLabels, setTrue ) ); 516 484 … … 520 488 stmtsToAddAfter.push_back( ifStmt ); 521 489 522 // add pointer and dtor caller decls to list of decls that will be added into global scope 523 staticDtorDecls.push_back( objPtr ); 524 staticDtorDecls.push_back( dtorCaller ); 490 if ( ctorInit->get_dtor() ) { 491 // if the object has a non-trivial destructor, have to 492 // hoist it and the object into the global space and 493 // call the destructor function with atexit. 494 495 Statement * dtorStmt = ctorInit->get_dtor()->clone(); 496 497 // void __objName_dtor_atexitN(...) {...} 498 FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + dtorCallerNamer.newName(), DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false ); 499 dtorCaller->fixUniqueId(); 500 dtorCaller->get_statements()->get_kids().push_back( dtorStmt ); 501 502 // atexit(dtor_atexit); 503 UntypedExpr * callAtexit = new UntypedExpr( new NameExpr( "atexit" ) ); 504 callAtexit->get_args().push_back( new VariableExpr( dtorCaller ) ); 505 506 body.push_back( new ExprStmt( noLabels, callAtexit ) ); 507 508 // hoist variable and dtor caller decls to list of decls that will be added into global scope 509 staticDtorDecls.push_back( objDecl ); 510 staticDtorDecls.push_back( dtorCaller ); 511 512 // need to rename object uniquely since it now appears 513 // at global scope and there could be multiple function-scoped 514 // static variables with the same name in different functions. 515 static UniqueName staticNamer( "_static_var" ); 516 objDecl->set_mangleName( objDecl->get_mangleName() + staticNamer.newName() ); 517 518 objDecl->set_init( NULL ); 519 ctorInit->set_ctor( NULL ); 520 delete ctorInit; 521 522 // xxx - temporary hack: need to return a declaration, but want to hoist the current object out of this scope 523 // create a new object which is never used 524 static UniqueName dummyNamer( "_dummy" ); 525 ObjectDecl * dummy = new ObjectDecl( dummyNamer.newName(), DeclarationNode::Static, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), 0, std::list< Attribute * >{ new Attribute("unused") } ); 526 return dummy; 527 } 525 528 } else { 526 529 stmtsToAddAfter.push_back( ctor ); … … 582 585 assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() ); 583 586 Statement * dtor = ctorInit->get_dtor(); 584 if ( dtor && ! isIn strinsicSingleArgCallStmt( dtor ) ) {587 if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) { 585 588 // don't need to call intrinsic dtor, because it does nothing, but 586 589 // non-intrinsic dtors must be called
Note: See TracChangeset
for help on using the changeset viewer.