Ignore:
Timestamp:
Aug 16, 2016, 3:20:06 PM (9 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
1f6d4624
Parents:
950f7a7 (diff), 7880579 (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' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixGlobalInit.cc

    r950f7a7 r7527e63  
    4646                FunctionDecl * destroyFunction;
    4747        };
    48 
    49         class ConstExprChecker : public Visitor {
    50         public:
    51                 ConstExprChecker() : isConstExpr( true ) {}
    52 
    53                 virtual void visit( ApplicationExpr *applicationExpr ) { isConstExpr = false; }
    54                 virtual void visit( UntypedExpr *untypedExpr ) { isConstExpr = false; }
    55                 virtual void visit( NameExpr *nameExpr ) { isConstExpr = false; }
    56                 virtual void visit( CastExpr *castExpr ) { isConstExpr = false; }
    57                 virtual void visit( LabelAddressExpr *labAddressExpr ) { isConstExpr = false; }
    58                 virtual void visit( UntypedMemberExpr *memberExpr ) { isConstExpr = false; }
    59                 virtual void visit( MemberExpr *memberExpr ) { isConstExpr = false; }
    60                 virtual void visit( VariableExpr *variableExpr ) { isConstExpr = false; }
    61                 virtual void visit( ConstantExpr *constantExpr ) { /* bottom out */ }
    62                 // these might be okay?
    63                 // virtual void visit( SizeofExpr *sizeofExpr );
    64                 // virtual void visit( AlignofExpr *alignofExpr );
    65                 // virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    66                 // virtual void visit( OffsetofExpr *offsetofExpr );
    67                 // virtual void visit( OffsetPackExpr *offsetPackExpr );
    68                 // virtual void visit( AttrExpr *attrExpr );
    69                 // virtual void visit( CommaExpr *commaExpr );
    70                 // virtual void visit( LogicalExpr *logicalExpr );
    71                 // virtual void visit( ConditionalExpr *conditionalExpr );
    72                 virtual void visit( TupleExpr *tupleExpr ) { isConstExpr = false; }
    73                 virtual void visit( SolvedTupleExpr *tupleExpr ) { isConstExpr = false; }
    74                 virtual void visit( TypeExpr *typeExpr ) { isConstExpr = false; }
    75                 virtual void visit( AsmExpr *asmExpr ) { isConstExpr = false; }
    76                 virtual void visit( UntypedValofExpr *valofExpr ) { isConstExpr = false; }
    77                 virtual void visit( CompoundLiteralExpr *compLitExpr ) { isConstExpr = false; }
    78 
    79                 bool isConstExpr;
    80         };
    81 
    82         bool isConstExpr( Initializer * init ) {
    83                 if ( init ) {
    84                         ConstExprChecker checker;
    85                         init->accept( checker );
    86                         return checker.isConstExpr;
    87                 } // if
    88                 // for all intents and purposes, no initializer means const expr
    89                 return true;
    90         }
    9148
    9249        void fixGlobalInit( std::list< Declaration * > & translationUnit, const std::string & name, bool inLibrary ) {
     
    14097                std::list< Statement * > & destroyStatements = destroyFunction->get_statements()->get_kids();
    14198
    142                 if ( ! tryConstruct( objDecl ) ) return; // don't construct @= or designated objects
    143                 if ( objDecl->get_storageClass() == DeclarationNode::Extern ) return;
    14499                // C allows you to initialize objects with constant expressions
    145100                // xxx - this is an optimization. Need to first resolve constructors before we decide
     
    147102                // if ( isConstExpr( objDecl->get_init() ) ) return;
    148103
    149                 if ( dynamic_cast< ArrayType * > ( objDecl->get_type() ) ) {
    150                         // xxx - initialize each element of the array
    151                 } else {
    152                         // steal initializer from object and attach it to a new temporary
    153                         ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, objDecl->get_type()->clone(), objDecl->get_init() );
    154                         objDecl->set_init( NULL );
    155                         initStatements.push_back( new DeclStmt( noLabels, newObj ) );
     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() );
    156107
    157                         // copy construct objDecl using temporary
    158                         UntypedExpr * init = new UntypedExpr( new NameExpr( "?{}" ) );
    159                         init->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
    160                         init->get_args().push_back( new VariableExpr( newObj ) );
    161                         initStatements.push_back( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, init ) ) );
    162 
    163                         // add destructor calls to global destroy function
    164                         UntypedExpr * destroy = new UntypedExpr( new NameExpr( "^?{}" ) );
    165                         destroy->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
    166                         destroyStatements.push_front( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, destroy ) ) );
     108                        Statement * dtor = ctorInit->get_dtor();
     109                        if ( dtor && ! isIntrinsicSingleArgCallStmt( 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;
    167127                } // if
    168128        }
Note: See TracChangeset for help on using the changeset viewer.