Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixGlobalInit.cc

    r7d651a66 r07de76b  
    3434#include "SynTree/Visitor.h"       // for acceptAll, Visitor
    3535
    36 #include "AST/Expr.hpp"
    37 #include "AST/Node.hpp"
    38 #include "AST/Pass.hpp"
    39 
    4036namespace InitTweak {
    4137        class GlobalFixer : public WithShortCircuiting {
     
    5450                FunctionDecl * initFunction;
    5551                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;
    7052        };
    7153
     
    10991        }
    11092
    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 
    13493        void GlobalFixer::previsit( ObjectDecl *objDecl ) {
    13594                std::list< Statement * > & initStatements = initFunction->get_statements()->get_kids();
     
    153112                        } // if
    154113                        if ( Statement * ctor = ctorInit->ctor ) {
    155                                 addDataSectonAttribute( objDecl );
    156114                                initStatements.push_back( ctor );
    157115                                objDecl->init = nullptr;
     
    165123                        } // if
    166124                        delete ctorInit;
    167                 } // if
    168         }
    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;
    197125                } // if
    198126        }
Note: See TracChangeset for help on using the changeset viewer.