Changeset 58fe85a for src/InitTweak/FixGlobalInit.cc
- Timestamp:
- Jan 7, 2021, 3:27:00 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 2b4daf2, 64aeca0
- Parents:
- 3c64c668 (diff), eef8dfb (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixGlobalInit.cc
r3c64c668 r58fe85a 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(ast::TranslationUnit & 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.decls.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.decls.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 ) { 155 addDataSectonAttribute( objDecl ); 114 156 initStatements.push_back( ctor ); 115 157 objDecl->init = nullptr; … … 126 168 } 127 169 170 void GlobalFixer_new::previsit(const ast::ObjectDecl * objDecl) { 171 auto mutDecl = mutate(objDecl); 172 assertf(mutDecl == objDecl, "Global object decl must be unique"); 173 if ( auto ctorInit = objDecl->init.as<ast::ConstructorInit>() ) { 174 // a decision should have been made by the resolver, so ctor and init are not both non-NULL 175 assert( ! ctorInit->ctor || ! ctorInit->init ); 176 177 const ast::Stmt * dtor = ctorInit->dtor; 178 if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) { 179 // don't need to call intrinsic dtor, because it does nothing, but 180 // non-intrinsic dtors must be called 181 destroyStmts.push_front( dtor ); 182 // ctorInit->dtor = nullptr; 183 } // if 184 if ( const ast::Stmt * ctor = ctorInit->ctor ) { 185 addDataSectionAttribute(mutDecl); 186 initStmts.push_back( ctor ); 187 mutDecl->init = nullptr; 188 // ctorInit->ctor = nullptr; 189 } else if ( const ast::Init * init = ctorInit->init ) { 190 mutDecl->init = init; 191 // ctorInit->init = nullptr; 192 } else { 193 // no constructor and no initializer, which is okay 194 mutDecl->init = nullptr; 195 } // if 196 // delete ctorInit; 197 } // if 198 } 199 128 200 // only modify global variables 129 201 void GlobalFixer::previsit( FunctionDecl * ) { visit_children = false; }
Note:
See TracChangeset
for help on using the changeset viewer.