Changeset e0323a2


Ignore:
Timestamp:
Mar 31, 2016, 10:28:54 AM (6 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
39786813
Parents:
5b2f5bb
Message:

routine scoped static variables are constructed once the first time the routine is called, and destructed once at the end of the program using atexit

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r5b2f5bb re0323a2  
    1010// Created On       : Wed Jan 13 16:29:30 2016
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Mar 30 14:34:46 2016
     12// Last Modified On : Thu Mar 31 10:08:49 2016
    1313// Update Count     : 30
    1414//
     
    2828        namespace {
    2929                const std::list<Label> noLabels;
     30                const std::list<Expression*> noDesignators;
    3031        }
    3132
     
    5657                        assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
    5758                        if ( Statement * ctor = ctorInit->get_ctor() ) {
    58                                 stmtsToAddAfter.push_back( ctor );
    59                                 dtorStmts.push_front( ctorInit->get_dtor() );
     59                                if ( objDecl->get_storageClass() == DeclarationNode::Static ) {
     60                                        // generate:
     61                                        // static bool __objName_uninitialized = true;
     62                                        // if (__objName_uninitialized) {
     63                                        //   __ctor(__objName);
     64                                        //   void dtor_atexit() {
     65                                        //     __dtor(__objName);
     66                                        //   }
     67                                        //   on_exit(dtorOnExit, &__objName);
     68                                        //   __objName_uninitialized = false;
     69                                        // }
     70
     71                                        // generate first line
     72                                        BasicType * boolType = new BasicType( Type::Qualifiers(), BasicType::Bool );
     73                                        SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant( boolType->clone(), "1" ) ), noDesignators );
     74                                        ObjectDecl * isUninitializedVar = new ObjectDecl( objDecl->get_mangleName() + "_uninitialized", DeclarationNode::Static, LinkageSpec::Cforall, 0, boolType, boolInitExpr );
     75                                        isUninitializedVar->fixUniqueId();
     76
     77                                        // void dtor_atexit(...) {...}
     78                                        FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + "_dtor_atexit", DeclarationNode::NoStorageClass, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );
     79                                        dtorCaller->fixUniqueId();
     80                                        dtorCaller->get_statements()->get_kids().push_back( ctorInit->get_dtor() );
     81
     82                                        // on_exit(dtor_atexit);
     83                                        UntypedExpr * callAtexit = new UntypedExpr( new NameExpr( "atexit" ) );
     84                                        callAtexit->get_args().push_back( new VariableExpr( dtorCaller ) );
     85
     86                                        // __objName_uninitialized = false;
     87                                        UntypedExpr * setTrue = new UntypedExpr( new NameExpr( "?=?" ) );
     88                                        setTrue->get_args().push_back( new VariableExpr( isUninitializedVar ) );
     89                                        setTrue->get_args().push_back( new ConstantExpr( Constant( boolType->clone(), "0" ) ) );
     90
     91                                        // generate body of if
     92                                        CompoundStmt * initStmts = new CompoundStmt( noLabels );
     93                                        std::list< Statement * > & body = initStmts->get_kids();
     94                                        body.push_back( ctor );
     95                                        body.push_back( new DeclStmt( noLabels, dtorCaller ) );
     96                                        body.push_back( new ExprStmt( noLabels, callAtexit ) );
     97                                        body.push_back( new ExprStmt( noLabels, setTrue ) );
     98
     99                                        // put it all together
     100                                        IfStmt * ifStmt = new IfStmt( noLabels, new VariableExpr( isUninitializedVar ), initStmts, 0 );
     101                                        stmtsToAddAfter.push_back( new DeclStmt( noLabels, isUninitializedVar ) );
     102                                        stmtsToAddAfter.push_back( ifStmt );
     103                                } else {
     104                                        stmtsToAddAfter.push_back( ctor );
     105                                        dtorStmts.push_front( ctorInit->get_dtor() );
     106                                }
    60107                                objDecl->set_init( NULL );
    61108                                ctorInit->set_ctor( NULL );
Note: See TracChangeset for help on using the changeset viewer.