Ignore:
Timestamp:
Jan 7, 2021, 3:27:00 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
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.
Message:

Merge branch 'master' into park_unpark

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixGlobalInit.cc

    r3c64c668 r58fe85a  
    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
    3640namespace InitTweak {
    3741        class GlobalFixer : public WithShortCircuiting {
     
    5054                FunctionDecl * initFunction;
    5155                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;
    5270        };
    5371
     
    91109        }
    92110
     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
    93134        void GlobalFixer::previsit( ObjectDecl *objDecl ) {
    94135                std::list< Statement * > & initStatements = initFunction->get_statements()->get_kids();
     
    112153                        } // if
    113154                        if ( Statement * ctor = ctorInit->ctor ) {
     155                                addDataSectonAttribute( objDecl );
    114156                                initStatements.push_back( ctor );
    115157                                objDecl->init = nullptr;
     
    126168        }
    127169
     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
    128200        // only modify global variables
    129201        void GlobalFixer::previsit( FunctionDecl * ) { visit_children = false; }
Note: See TracChangeset for help on using the changeset viewer.