Changes in src/InitTweak/FixGlobalInit.cc [6fbe9a5:490fb92e]
- File:
-
- 1 edited
-
src/InitTweak/FixGlobalInit.cc (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixGlobalInit.cc
r6fbe9a5 r490fb92e 34 34 #include "SynTree/Visitor.h" // for acceptAll, Visitor 35 35 36 #include "AST/Expr.hpp" 37 #include "AST/Node.hpp" 38 #include "AST/Pass.hpp" 39 36 40 namespace InitTweak { 37 41 class GlobalFixer : public WithShortCircuiting { … … 50 54 FunctionDecl * initFunction; 51 55 FunctionDecl * destroyFunction; 56 }; 57 58 class GlobalFixer_new : public ast::WithShortCircuiting { 59 public: 60 void previsit (const ast::ObjectDecl *); 61 void previsit (const ast::FunctionDecl *) { visit_children = false; } 62 void previsit (const ast::StructDecl *) { visit_children = false; } 63 void previsit (const ast::UnionDecl *) { visit_children = false; } 64 void previsit (const ast::EnumDecl *) { visit_children = false; } 65 void previsit (const ast::TraitDecl *) { visit_children = false; } 66 void previsit (const ast::TypeDecl *) { visit_children = false; } 67 68 std::list< ast::ptr<ast::Stmt> > initStmts; 69 std::list< ast::ptr<ast::Stmt> > destroyStmts; 52 70 }; 53 71 … … 91 109 } 92 110 111 void fixGlobalInit(std::list<ast::ptr<ast::Decl>> & translationUnit, bool inLibrary) { 112 ast::Pass<GlobalFixer_new> fixer; 113 accept_all(translationUnit, fixer); 114 115 if ( !fixer.core.initStmts.empty() ) { 116 std::vector<ast::ptr<ast::Expr>> ctorParams; 117 if (inLibrary) ctorParams.emplace_back(ast::ConstantExpr::from_int({}, 200)); 118 auto initFunction = new ast::FunctionDecl({}, "__global_init__", {}, {}, {}, new ast::CompoundStmt({}, std::move(fixer.core.initStmts)), 119 ast::Storage::Static, ast::Linkage::C, {new ast::Attribute("constructor", std::move(ctorParams))}); 120 121 translationUnit.emplace_back( initFunction ); 122 } // if 123 124 if ( !fixer.core.destroyStmts.empty() ) { 125 std::vector<ast::ptr<ast::Expr>> dtorParams; 126 if (inLibrary) dtorParams.emplace_back(ast::ConstantExpr::from_int({}, 200)); 127 auto destroyFunction = new ast::FunctionDecl({}, "__global_destroy__", {}, {}, {}, new ast::CompoundStmt({}, std::move(fixer.core.destroyStmts)), 128 ast::Storage::Static, ast::Linkage::C, {new ast::Attribute("destructor", std::move(dtorParams))}); 129 130 translationUnit.emplace_back(destroyFunction); 131 } // if 132 } 133 93 134 void GlobalFixer::previsit( ObjectDecl *objDecl ) { 94 135 std::list< Statement * > & initStatements = initFunction->get_statements()->get_kids(); … … 112 153 } // if 113 154 if ( Statement * ctor = ctorInit->ctor ) { 114 // Translation 1: Add this attribute on the global declaration:115 // __attribute__((section (".data#")))116 // which makes gcc put the global in the data section,117 // so that the global is writeable (via a const cast) in the init function.118 // The trailing # is an injected assembly comment, to suppress the "a" in119 // .section .data,"a"120 // .section .data#,"a"121 // to avoid assembler warning "ignoring changed section attributes for .data"122 Type *strLitT = new PointerType( Type::Qualifiers( ),123 new BasicType( Type::Qualifiers( ), BasicType::Char ) );124 std::list< Expression * > attr_params;125 attr_params.push_back(126 new ConstantExpr( Constant( strLitT, "\".data#\"", std::nullopt ) ) );127 objDecl->attributes.push_back(new Attribute("section", attr_params));128 // Translation 2: Move the initizliation off the global declaration,129 // into the startup function.130 155 initStatements.push_back( ctor ); 131 156 objDecl->init = nullptr; … … 142 167 } 143 168 169 void GlobalFixer_new::previsit(const ast::ObjectDecl * objDecl) { 170 auto mutDecl = mutate(objDecl); 171 assertf(mutDecl == objDecl, "Global object decl must be unique"); 172 if ( auto ctorInit = objDecl->init.as<ast::ConstructorInit>() ) { 173 // a decision should have been made by the resolver, so ctor and init are not both non-NULL 174 assert( ! ctorInit->ctor || ! ctorInit->init ); 175 176 const ast::Stmt * dtor = ctorInit->dtor; 177 if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) { 178 // don't need to call intrinsic dtor, because it does nothing, but 179 // non-intrinsic dtors must be called 180 destroyStmts.push_front( dtor ); 181 // ctorInit->dtor = nullptr; 182 } // if 183 if ( const ast::Stmt * ctor = ctorInit->ctor ) { 184 initStmts.push_back( ctor ); 185 mutDecl->init = nullptr; 186 // ctorInit->ctor = nullptr; 187 } else if ( const ast::Init * init = ctorInit->init ) { 188 mutDecl->init = init; 189 // ctorInit->init = nullptr; 190 } else { 191 // no constructor and no initializer, which is okay 192 mutDecl->init = nullptr; 193 } // if 194 // delete ctorInit; 195 } // if 196 } 197 144 198 // only modify global variables 145 199 void GlobalFixer::previsit( FunctionDecl * ) { visit_children = false; }
Note:
See TracChangeset
for help on using the changeset viewer.