Ignore:
Timestamp:
Jul 21, 2016, 2:07:01 PM (6 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
ccb447e
Parents:
b81adcc
Message:

reorganize global init so that it is simpler and generates less unnecessary code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixGlobalInit.cc

    rb81adcc r6cf27a07  
    9797                std::list< Statement * > & destroyStatements = destroyFunction->get_statements()->get_kids();
    9898
    99                 if ( ! tryConstruct( objDecl ) ) return; // don't construct @= or designated objects
    100                 if ( objDecl->get_storageClass() == DeclarationNode::Extern ) return;
    10199                // C allows you to initialize objects with constant expressions
    102100                // xxx - this is an optimization. Need to first resolve constructors before we decide
     
    104102                // if ( isConstExpr( objDecl->get_init() ) ) return;
    105103
    106                 if ( dynamic_cast< ArrayType * > ( objDecl->get_type() ) ) {
    107                         // xxx - initialize each element of the array
    108                 } else {
    109                         // insert constructor for objDecl into global init function
    110                         UntypedExpr * init = new UntypedExpr( new NameExpr( "?{}" ) );
    111                         init->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
    112                         init->get_args().splice( init->get_args().end(), makeInitList( objDecl->get_init() ) );
    113                         objDecl->set_init( NULL );
    114                         initStatements.push_back( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, init ) ) );
     104                if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) {
     105                        // a decision should have been made by the resolver, so ctor and init are not both non-NULL
     106                        assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
    115107
    116                         // add destructor calls to global destroy function
    117                         UntypedExpr * destroy = new UntypedExpr( new NameExpr( "^?{}" ) );
    118                         destroy->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
    119                         destroyStatements.push_front( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, destroy ) ) );
     108                        Statement * dtor = ctorInit->get_dtor();
     109                        if ( dtor && ! isInstrinsicSingleArgCallStmt( dtor ) ) {
     110                                // don't need to call intrinsic dtor, because it does nothing, but
     111                                // non-intrinsic dtors must be called
     112                                destroyStatements.push_front( dtor );
     113                                ctorInit->set_dtor( NULL );
     114                        } // if
     115                        if ( Statement * ctor = ctorInit->get_ctor() ) {
     116                                initStatements.push_back( ctor );
     117                                objDecl->set_init( NULL );
     118                                ctorInit->set_ctor( NULL );
     119                        } else if ( Initializer * init = ctorInit->get_init() ) {
     120                                objDecl->set_init( init );
     121                                ctorInit->set_init( NULL );
     122                        } else {
     123                                // no constructor and no initializer, which is okay
     124                                objDecl->set_init( NULL );
     125                        } // if
     126                        delete ctorInit;
    120127                } // if
    121128        }
Note: See TracChangeset for help on using the changeset viewer.