Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixGlobalInit.cpp

    r13481af0 rc92bdcc  
    1010// Created On       : Mon May 04 15:14:56 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul  2 16:39:52 2026
    13 // Update Count     : 35
     12// Last Modified On : Fri Dec 13 23:41:10 2019
     13// Update Count     : 19
    1414//
    1515
    1616#include "FixGlobalInit.hpp"
    1717
    18 #include <set>
    1918#include <cassert>                 // for assert
    2019#include <stddef.h>                // for NULL
     
    4140        void previsit(const ast::TypeDecl *) { visit_children = false; }
    4241
    43         bool pass = false;
    4442        std::list< ast::ptr<ast::Stmt> > initStmts;
    4543        std::list< ast::ptr<ast::Stmt> > destroyStmts;
    46         std::set< std::string > constDeclsMnames;
    4744};
    4845
     
    5047        auto mutDecl = mutate(objDecl);
    5148        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;
    5551
    56                 // a decision should have been made by the resolver, so ctor and init are not both non-NULL
    57                 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 );
    5854
    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;
    8470        }
    8571}
     
    8975void fixGlobalInit(ast::TranslationUnit & translationUnit, bool inLibrary) {
    9076        ast::Pass<GlobalFixer> fixer;
    91 
    92         // First pass fixes global initialization.
    93         accept_all( translationUnit, fixer );
     77        accept_all(translationUnit, fixer);
    9478
    9579        // Say these magic declarations come at the end of the file.
     
    119103                translationUnit.decls.emplace_back(destroyFunction);
    120104        } // 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);
    126105}
    127106
Note: See TracChangeset for help on using the changeset viewer.