Changes in src/InitTweak/FixGlobalInit.cc [720f2fe2:0bd3faf]
- File:
-
- 1 edited
-
src/InitTweak/FixGlobalInit.cc (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixGlobalInit.cc
r720f2fe2 r0bd3faf 20 20 #include <algorithm> // for replace_if 21 21 22 #include "Common/PassVisitor.h"23 #include "Common/UniqueName.h" // for UniqueName24 #include "InitTweak.h" // for isIntrinsicSingleArgCallStmt25 #include "SynTree/LinkageSpec.h" // for C26 #include "SynTree/Attribute.h" // for Attribute27 #include "SynTree/Constant.h" // for Constant28 #include "SynTree/Declaration.h" // for FunctionDecl, ObjectDecl, Declaration29 #include "SynTree/Expression.h" // for ConstantExpr, Expression (ptr only)30 #include "SynTree/Initializer.h" // for ConstructorInit, Initializer31 #include "SynTree/Label.h" // for Label32 #include "SynTree/Statement.h" // for CompoundStmt, Statement (ptr only)33 #include "SynTree/Type.h" // for Type, Type::StorageClasses, Functi...34 #include "SynTree/Visitor.h" // for acceptAll, Visitor35 36 22 #include "AST/Expr.hpp" 37 23 #include "AST/Node.hpp" 38 24 #include "AST/Pass.hpp" 25 #include "Common/UniqueName.h" // for UniqueName 26 #include "InitTweak.h" // for isIntrinsicSingleArgCallStmt 39 27 40 28 namespace InitTweak { 41 class GlobalFixer : public WithShortCircuiting { 42 public: 43 GlobalFixer( bool inLibrary ); 44 45 void previsit( ObjectDecl *objDecl ); 46 void previsit( FunctionDecl *functionDecl ); 47 void previsit( StructDecl *aggregateDecl ); 48 void previsit( UnionDecl *aggregateDecl ); 49 void previsit( EnumDecl *aggregateDecl ); 50 void previsit( TraitDecl *aggregateDecl ); 51 void previsit( TypeDecl *typeDecl ); 52 53 UniqueName tempNamer; 54 FunctionDecl * initFunction; 55 FunctionDecl * destroyFunction; 56 }; 57 58 class GlobalFixer_new : public ast::WithShortCircuiting { 29 class GlobalFixer : public ast::WithShortCircuiting { 59 30 public: 60 31 void previsit (const ast::ObjectDecl *); … … 70 41 }; 71 42 72 void fixGlobalInit( std::list< Declaration * > & translationUnit, bool inLibrary ) {73 PassVisitor<GlobalFixer> visitor( inLibrary );74 acceptAll( translationUnit, visitor );75 GlobalFixer & fixer = visitor.pass;76 // don't need to include function if it's empty77 if ( fixer.initFunction->get_statements()->get_kids().empty() ) {78 delete fixer.initFunction;79 } else {80 translationUnit.push_back( fixer.initFunction );81 } // if82 83 if ( fixer.destroyFunction->get_statements()->get_kids().empty() ) {84 delete fixer.destroyFunction;85 } else {86 translationUnit.push_back( fixer.destroyFunction );87 } // if88 }89 90 GlobalFixer::GlobalFixer( bool inLibrary ) : tempNamer( "_global_init" ) {91 std::list< Expression * > ctorParameters;92 std::list< Expression * > dtorParameters;93 if ( inLibrary ) {94 // Constructor/destructor attributes take a single parameter which95 // is the priority, with lower numbers meaning higher priority.96 // Functions specified with priority are guaranteed to run before97 // functions without a priority. To ensure that constructors and destructors98 // for library code are run before constructors and destructors for user code,99 // specify a priority when building the library. Priorities 0-100 are reserved by gcc.100 // Priorities 101-200 are reserved by cfa, so use priority 200 for CFA library globals,101 // allowing room for overriding with a higher priority.102 ctorParameters.push_back( new ConstantExpr( Constant::from_int( 200 ) ) );103 dtorParameters.push_back( new ConstantExpr( Constant::from_int( 200 ) ) );104 }105 initFunction = new FunctionDecl( "__global_init__", Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() );106 initFunction->get_attributes().push_back( new Attribute( "constructor", ctorParameters ) );107 destroyFunction = new FunctionDecl( "__global_destroy__", Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() );108 destroyFunction->get_attributes().push_back( new Attribute( "destructor", dtorParameters ) );109 }110 111 43 void fixGlobalInit(ast::TranslationUnit & translationUnit, bool inLibrary) { 112 ast::Pass<GlobalFixer _new> fixer;44 ast::Pass<GlobalFixer> fixer; 113 45 accept_all(translationUnit, fixer); 114 46 … … 141 73 } 142 74 143 void GlobalFixer::previsit( ObjectDecl *objDecl ) { 144 std::list< Statement * > & initStatements = initFunction->get_statements()->get_kids(); 145 std::list< Statement * > & destroyStatements = destroyFunction->get_statements()->get_kids(); 146 147 // C allows you to initialize objects with constant expressions 148 // xxx - this is an optimization. Need to first resolve constructors before we decide 149 // to keep C-style initializer. 150 // if ( isConstExpr( objDecl->get_init() ) ) return; 151 152 if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) { 153 // a decision should have been made by the resolver, so ctor and init are not both non-NULL 154 assert( ! ctorInit->ctor || ! ctorInit->init ); 155 156 Statement * dtor = ctorInit->dtor; 157 if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) { 158 // don't need to call intrinsic dtor, because it does nothing, but 159 // non-intrinsic dtors must be called 160 destroyStatements.push_front( dtor ); 161 ctorInit->dtor = nullptr; 162 } // if 163 if ( Statement * ctor = ctorInit->ctor ) { 164 addDataSectionAttribute( objDecl ); 165 initStatements.push_back( ctor ); 166 objDecl->init = nullptr; 167 ctorInit->ctor = nullptr; 168 } else if ( Initializer * init = ctorInit->init ) { 169 objDecl->init = init; 170 ctorInit->init = nullptr; 171 } else { 172 // no constructor and no initializer, which is okay 173 objDecl->init = nullptr; 174 } // if 175 delete ctorInit; 176 } // if 177 } 178 179 void GlobalFixer_new::previsit(const ast::ObjectDecl * objDecl) { 75 void GlobalFixer::previsit(const ast::ObjectDecl * objDecl) { 180 76 auto mutDecl = mutate(objDecl); 181 77 assertf(mutDecl == objDecl, "Global object decl must be unique"); … … 207 103 } 208 104 209 // only modify global variables210 void GlobalFixer::previsit( FunctionDecl * ) { visit_children = false; }211 void GlobalFixer::previsit( StructDecl * ) { visit_children = false; }212 void GlobalFixer::previsit( UnionDecl * ) { visit_children = false; }213 void GlobalFixer::previsit( EnumDecl * ) { visit_children = false; }214 void GlobalFixer::previsit( TraitDecl * ) { visit_children = false; }215 void GlobalFixer::previsit( TypeDecl * ) { visit_children = false; }216 217 105 } // namespace InitTweak 218 106
Note:
See TracChangeset
for help on using the changeset viewer.