Changes in src/InitTweak/FixGlobalInit.cc [03e5d14:7b3f66b]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixGlobalInit.cc
r03e5d14 r7b3f66b 10 10 // Created On : Mon May 04 15:14:56 2016 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri May 06 15:40:48201612 // Last Modified On : Fri May 13 11:37:30 2016 13 13 // Update Count : 2 14 14 // 15 15 16 16 #include "FixGlobalInit.h" 17 #include "InitTweak.h" 17 18 #include "SynTree/Declaration.h" 18 19 #include "SynTree/Type.h" … … 42 43 UniqueName tempNamer; 43 44 FunctionDecl * initFunction; 45 FunctionDecl * destroyFunction; 44 46 }; 45 47 … … 90 92 GlobalFixer fixer( name, inLibrary ); 91 93 acceptAll( translationUnit, fixer ); 92 translationUnit.push_back( fixer.initFunction ); 94 // don't need to include function if it's empty 95 if ( fixer.initFunction->get_statements()->get_kids().empty() ) { 96 delete fixer.initFunction; 97 } else { 98 translationUnit.push_back( fixer.initFunction ); 99 } 100 if ( fixer.destroyFunction->get_statements()->get_kids().empty() ) { 101 delete fixer.destroyFunction; 102 } else { 103 translationUnit.push_back( fixer.destroyFunction ); 104 } 93 105 } 94 106 95 std::string initName( const std::string & name ) {107 std::string globalFunctionName( const std::string & name ) { 96 108 // get basename 97 109 std::string ret = name.substr( 0, name.find( '.' ) ); … … 99 111 static std::string invalid = "/-"; 100 112 replace_if( ret.begin(), ret.end(), []( char c ) { return invalid.find(c) != std::string::npos; }, '_' ); 101 return "_init_" +ret;113 return ret; 102 114 } 103 115 104 116 GlobalFixer::GlobalFixer( const std::string & name, bool inLibrary ) : tempNamer( "_global_init" ) { 105 initFunction = new FunctionDecl( initName( name ), DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false, FunctionDecl::Attribute( FunctionDecl::Attribute::Constructor, inLibrary ? FunctionDecl::Attribute::High : FunctionDecl::Attribute::Default ) ); 117 std::string fixedName = globalFunctionName( name ); 118 initFunction = new FunctionDecl( "_init_" + fixedName, DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false, FunctionDecl::Attribute( FunctionDecl::Attribute::Constructor, inLibrary ? FunctionDecl::Attribute::High : FunctionDecl::Attribute::Default ) ); 119 120 destroyFunction = new FunctionDecl( "_destroy_" + fixedName, DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false, FunctionDecl::Attribute( FunctionDecl::Attribute::Destructor, inLibrary ? FunctionDecl::Attribute::High : FunctionDecl::Attribute::Default ) ); 106 121 } 107 122 108 123 void GlobalFixer::visit( ObjectDecl *objDecl ) { 109 std::list< Statement * > & statements = initFunction->get_statements()->get_kids(); 124 std::list< Statement * > & initStatements = initFunction->get_statements()->get_kids(); 125 std::list< Statement * > & destroyStatements = destroyFunction->get_statements()->get_kids(); 110 126 111 if ( objDecl->get_init() == NULL ) return; 127 // if ( objDecl->get_init() == NULL ) return; 128 if ( ! tryConstruct( objDecl ) ) return; // don't construct @= or designated objects 112 129 if ( objDecl->get_type()->get_isConst() ) return; // temporary: can't assign to a const variable 130 if ( objDecl->get_storageClass() == DeclarationNode::Extern ) return; 113 131 // C allows you to initialize objects with constant expressions 114 132 // xxx - this is an optimization. Need to first resolve constructors before we decide … … 116 134 // if ( isConstExpr( objDecl->get_init() ) ) return; 117 135 118 // steal initializer from object and attach it to a new temporary 119 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, objDecl->get_type()->clone(), objDecl->get_init() ); 120 objDecl->set_init( NULL ); 121 statements.push_back( new DeclStmt( noLabels, newObj ) ); 136 if ( ArrayType * at = dynamic_cast< ArrayType * > ( objDecl->get_type() ) ) { 137 // xxx - initialize each element of the array 138 } else { 139 // steal initializer from object and attach it to a new temporary 140 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, objDecl->get_type()->clone(), objDecl->get_init() ); 141 objDecl->set_init( NULL ); 142 initStatements.push_back( new DeclStmt( noLabels, newObj ) ); 122 143 123 // assign (later: copy construct)objDecl using temporary124 UntypedExpr * init = new UntypedExpr( new NameExpr( "?=?" ) );125 init->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );126 init->get_args().push_back( new VariableExpr( newObj ) );127 statements.push_back( new ExprStmt( noLabels, init ) );144 // copy construct objDecl using temporary 145 UntypedExpr * init = new UntypedExpr( new NameExpr( "?{}" ) ); 146 init->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) ); 147 init->get_args().push_back( new VariableExpr( newObj ) ); 148 initStatements.push_back( new ExprStmt( noLabels, init ) ); 128 149 129 // xxx- need to destruct objDecl atexit 150 // add destructor calls to global destroy function 151 UntypedExpr * destroy = new UntypedExpr( new NameExpr( "^?{}" ) ); 152 destroy->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) ); 153 destroyStatements.push_front( new ExprStmt( noLabels, destroy ) ); 154 } 130 155 } 131 156
Note: See TracChangeset
for help on using the changeset viewer.