Changes in src/InitTweak/FixGlobalInit.cc [490fb92e:6fbe9a5]
- File:
-
- 1 edited
-
src/InitTweak/FixGlobalInit.cc (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixGlobalInit.cc
r490fb92e r6fbe9a5 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 40 36 namespace InitTweak { 41 37 class GlobalFixer : public WithShortCircuiting { … … 54 50 FunctionDecl * initFunction; 55 51 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;70 52 }; 71 53 … … 109 91 } 110 92 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 } // if123 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 } // if132 }133 134 93 void GlobalFixer::previsit( ObjectDecl *objDecl ) { 135 94 std::list< Statement * > & initStatements = initFunction->get_statements()->get_kids(); … … 153 112 } // if 154 113 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" in 119 // .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. 155 130 initStatements.push_back( ctor ); 156 131 objDecl->init = nullptr; … … 164 139 } // if 165 140 delete ctorInit; 166 } // if167 }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-NULL174 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, but179 // non-intrinsic dtors must be called180 destroyStmts.push_front( dtor );181 // ctorInit->dtor = nullptr;182 } // if183 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 okay192 mutDecl->init = nullptr;193 } // if194 // delete ctorInit;195 141 } // if 196 142 }
Note:
See TracChangeset
for help on using the changeset viewer.