Ignore:
Timestamp:
Jul 2, 2026, 5:07:05 PM (3 days ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
7886a92f
Parents:
16d862d
Message:

remove addDataSectionAttribute hack and handle dynamic initialization of const definitions by removing the const after resolution

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixGlobalInit.cpp

    r16d862d r13481af0  
    1010// Created On       : Mon May 04 15:14:56 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Dec 13 23:41:10 2019
    13 // Update Count     : 19
     12// Last Modified On : Thu Jul  2 16:39:52 2026
     13// Update Count     : 35
    1414//
    1515
    1616#include "FixGlobalInit.hpp"
    1717
     18#include <set>
    1819#include <cassert>                 // for assert
    1920#include <stddef.h>                // for NULL
     
    4041        void previsit(const ast::TypeDecl *) { visit_children = false; }
    4142
     43        bool pass = false;
    4244        std::list< ast::ptr<ast::Stmt> > initStmts;
    4345        std::list< ast::ptr<ast::Stmt> > destroyStmts;
     46        std::set< std::string > constDeclsMnames;
    4447};
    4548
     
    4750        auto mutDecl = mutate(objDecl);
    4851        assertf(mutDecl == objDecl, "Global object decl must be unique");
    49         auto ctorInit = objDecl->init.as<ast::ConstructorInit>();
    50         if ( nullptr == ctorInit ) return;
     52        if ( ! pass ) {                                                                         // pass 1
     53                auto ctorInit = objDecl->init.as<ast::ConstructorInit>();
     54                if ( nullptr == ctorInit ) return;
    5155
    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 );
     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 );
    5458
    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;
     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
    7084        }
    7185}
     
    7589void fixGlobalInit(ast::TranslationUnit & translationUnit, bool inLibrary) {
    7690        ast::Pass<GlobalFixer> fixer;
    77         accept_all(translationUnit, fixer);
     91
     92        // First pass fixes global initialization.
     93        accept_all( translationUnit, fixer );
    7894
    7995        // Say these magic declarations come at the end of the file.
     
    103119                translationUnit.decls.emplace_back(destroyFunction);
    104120        } // 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);
    105126}
    106127
Note: See TracChangeset for help on using the changeset viewer.