- File:
-
- 1 edited
-
src/InitTweak/FixGlobalInit.cpp (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixGlobalInit.cpp
r13481af0 rc92bdcc 10 10 // Created On : Mon May 04 15:14:56 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 2 16:39:52 202613 // Update Count : 3512 // Last Modified On : Fri Dec 13 23:41:10 2019 13 // Update Count : 19 14 14 // 15 15 16 16 #include "FixGlobalInit.hpp" 17 17 18 #include <set>19 18 #include <cassert> // for assert 20 19 #include <stddef.h> // for NULL … … 41 40 void previsit(const ast::TypeDecl *) { visit_children = false; } 42 41 43 bool pass = false;44 42 std::list< ast::ptr<ast::Stmt> > initStmts; 45 43 std::list< ast::ptr<ast::Stmt> > destroyStmts; 46 std::set< std::string > constDeclsMnames;47 44 }; 48 45 … … 50 47 auto mutDecl = mutate(objDecl); 51 48 assertf(mutDecl == objDecl, "Global object decl must be unique"); 52 if ( ! pass ) { // pass 1 53 auto ctorInit = objDecl->init.as<ast::ConstructorInit>(); 54 if ( nullptr == ctorInit ) return; 49 auto ctorInit = objDecl->init.as<ast::ConstructorInit>(); 50 if ( nullptr == ctorInit ) return; 55 51 56 // a decision should have been made by the resolver, so ctor and init are not both non-NULL57 assert( !ctorInit->ctor || !ctorInit->init );52 // a decision should have been made by the resolver, so ctor and init are not both non-NULL 53 assert( !ctorInit->ctor || !ctorInit->init ); 58 54 59 const ast::Stmt * dtor = ctorInit->dtor; 60 if ( dtor && !isIntrinsicSingleArgCallStmt( dtor ) ) { 61 // don't need to call intrinsic dtor, because it does nothing, but 62 // non-intrinsic dtors must be called 63 destroyStmts.push_front( dtor ); 64 } // if 65 if ( const ast::Stmt * ctor = ctorInit->ctor ) { 66 if ( mutDecl->type->is_const() ) { 67 // Store names of all declarations with const qualifier and initializer for second pass. 68 constDeclsMnames.emplace( mutDecl->mangleName ); 69 } 70 initStmts.push_back( ctor ); 71 mutDecl->init = nullptr; 72 } else if ( const ast::Init * init = ctorInit->init ) { 73 mutDecl->init = init; 74 } else { 75 // no constructor and no initializer, which is okay 76 mutDecl->init = nullptr; 77 } 78 } else { // pass 2 79 // Remove const qualifier from matching names, covering all forward declaration(s) and definition. 80 if ( constDeclsMnames.find( objDecl->mangleName ) != constDeclsMnames.end() ) { 81 ast::Type * fred = const_cast<ast::Type *>(mutDecl->get_type()); 82 fred->set_const( false ); 83 } // if 55 const ast::Stmt * dtor = ctorInit->dtor; 56 if ( dtor && !isIntrinsicSingleArgCallStmt( dtor ) ) { 57 // don't need to call intrinsic dtor, because it does nothing, but 58 // non-intrinsic dtors must be called 59 destroyStmts.push_front( dtor ); 60 } // if 61 if ( const ast::Stmt * ctor = ctorInit->ctor ) { 62 addDataSectionAttribute(mutDecl); 63 initStmts.push_back( ctor ); 64 mutDecl->init = nullptr; 65 } else if ( const ast::Init * init = ctorInit->init ) { 66 mutDecl->init = init; 67 } else { 68 // no constructor and no initializer, which is okay 69 mutDecl->init = nullptr; 84 70 } 85 71 } … … 89 75 void fixGlobalInit(ast::TranslationUnit & translationUnit, bool inLibrary) { 90 76 ast::Pass<GlobalFixer> fixer; 91 92 // First pass fixes global initialization. 93 accept_all( translationUnit, fixer ); 77 accept_all(translationUnit, fixer); 94 78 95 79 // Say these magic declarations come at the end of the file. … … 119 103 translationUnit.decls.emplace_back(destroyFunction); 120 104 } // if 121 122 fixer.core.pass = ! fixer.core.pass;123 // Second pass, removes const qualifiers so declarations appear in mutable .data section.124 // Note, the resolver has already checked for const-ness, so C only has to get the initialization correct.125 accept_all(translationUnit, fixer);126 105 } 127 106
Note:
See TracChangeset
for help on using the changeset viewer.