Changes in src/InitTweak/FixInit.cc [f9cebb5:4e06c1e]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixInit.cc
rf9cebb5 r4e06c1e 18 18 #include <iterator> 19 19 #include <algorithm> 20 #include "FixInit.h" 20 21 #include "InitTweak.h" 21 #include "FixInit.h"22 #include "FixGlobalInit.h"23 22 #include "ResolvExpr/Resolver.h" 24 23 #include "ResolvExpr/typeops.h" … … 26 25 #include "SynTree/Type.h" 27 26 #include "SynTree/Expression.h" 28 #include "SynTree/Attribute.h"29 27 #include "SynTree/Statement.h" 30 28 #include "SynTree/Initializer.h" … … 85 83 }; 86 84 87 // debug88 85 struct printSet { 89 86 typedef ObjDeclCollector::ObjectSet ObjectSet; … … 162 159 163 160 virtual DeclarationWithType * mutate( ObjectDecl *objDecl ); 164 165 std::list< Declaration * > staticDtorDecls;166 161 }; 167 162 … … 176 171 } // namespace 177 172 178 void fix( std::list< Declaration * > & translationUnit, const std::string & filename, bool inLibrary ) { 179 // fixes ConstructorInit for global variables. should happen before fixInitializers. 180 InitTweak::fixGlobalInit( translationUnit, filename, inLibrary ); 181 173 void fix( std::list< Declaration * > & translationUnit ) { 182 174 InsertImplicitCalls::insert( translationUnit ); 183 175 ResolveCopyCtors::resolveImplicitCalls( translationUnit ); … … 202 194 void FixInit::fixInitializers( std::list< Declaration * > & translationUnit ) { 203 195 FixInit fixer; 204 205 // can't use mutateAll, because need to insert declarations at top-level 206 // can't use DeclMutator, because sometimes need to insert IfStmt, etc. 207 SemanticError errors; 208 for ( std::list< Declaration * >::iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) { 209 try { 210 *i = maybeMutate( *i, fixer ); 211 translationUnit.splice( i, fixer.staticDtorDecls ); 212 } catch( SemanticError &e ) { 213 errors.append( e ); 214 } // try 215 } // for 216 if ( ! errors.isEmpty() ) { 217 throw errors; 218 } // if 196 mutateAll( translationUnit, fixer ); 219 197 } 220 198 … … 444 422 if ( Statement * ctor = ctorInit->get_ctor() ) { 445 423 if ( objDecl->get_storageClass() == DeclarationNode::Static ) { 446 // originally wanted to take advantage of gcc nested functions, but447 // we get memory errors with this approach. To remedy this, the static448 // variable is hoisted when the destructor needs to be called.449 //450 424 // generate: 451 // static T __objName_static_varN; 452 // void __objName_dtor_atexitN() { 453 // __dtor__...; 425 // static bool __objName_uninitialized = true; 426 // if (__objName_uninitialized) { 427 // __ctor(__objName); 428 // void dtor_atexit() { 429 // __dtor(__objName); 430 // } 431 // on_exit(dtorOnExit, &__objName); 432 // __objName_uninitialized = false; 454 433 // } 455 // int f(...) { 456 // ... 457 // static bool __objName_uninitialized = true; 458 // if (__objName_uninitialized) { 459 // __ctor(__objName); 460 // __objName_uninitialized = false; 461 // atexit(__objName_dtor_atexitN); 462 // } 463 // ... 464 // } 465 466 static UniqueName dtorCallerNamer( "_dtor_atexit" ); 467 468 // static bool __objName_uninitialized = true 434 435 // generate first line 469 436 BasicType * boolType = new BasicType( Type::Qualifiers(), BasicType::Bool ); 470 437 SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant( boolType->clone(), "1" ) ), noDesignators ); … … 472 439 isUninitializedVar->fixUniqueId(); 473 440 441 // void dtor_atexit(...) {...} 442 FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + "_dtor_atexit", DeclarationNode::NoStorageClass, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false ); 443 dtorCaller->fixUniqueId(); 444 dtorCaller->get_statements()->get_kids().push_back( ctorInit->get_dtor()->clone() ); 445 446 // on_exit(dtor_atexit); 447 UntypedExpr * callAtexit = new UntypedExpr( new NameExpr( "atexit" ) ); 448 callAtexit->get_args().push_back( new VariableExpr( dtorCaller ) ); 449 474 450 // __objName_uninitialized = false; 475 451 UntypedExpr * setTrue = new UntypedExpr( new NameExpr( "?=?" ) ); … … 481 457 std::list< Statement * > & body = initStmts->get_kids(); 482 458 body.push_back( ctor ); 459 body.push_back( new DeclStmt( noLabels, dtorCaller ) ); 460 body.push_back( new ExprStmt( noLabels, callAtexit ) ); 483 461 body.push_back( new ExprStmt( noLabels, setTrue ) ); 484 462 … … 487 465 stmtsToAddAfter.push_back( new DeclStmt( noLabels, isUninitializedVar ) ); 488 466 stmtsToAddAfter.push_back( ifStmt ); 489 490 if ( ctorInit->get_dtor() ) {491 // if the object has a non-trivial destructor, have to492 // hoist it and the object into the global space and493 // 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 scope509 staticDtorDecls.push_back( objDecl );510 staticDtorDecls.push_back( dtorCaller );511 512 // need to rename object uniquely since it now appears513 // at global scope and there could be multiple function-scoped514 // 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 scope523 // create a new object which is never used524 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 }528 467 } else { 529 468 stmtsToAddAfter.push_back( ctor ); … … 585 524 assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() ); 586 525 Statement * dtor = ctorInit->get_dtor(); 587 if ( dtor && ! isIn trinsicSingleArgCallStmt( dtor ) ) {526 if ( dtor && ! isInstrinsicSingleArgCallStmt( dtor ) ) { 588 527 // don't need to call intrinsic dtor, because it does nothing, but 589 528 // non-intrinsic dtors must be called
Note:
See TracChangeset
for help on using the changeset viewer.