Changes in src/InitTweak/FixGlobalInit.cc [f9cebb5:ca35c51]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/FixGlobalInit.cc
rf9cebb5 rca35c51 46 46 FunctionDecl * destroyFunction; 47 47 }; 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 } 48 91 49 92 void fixGlobalInit( std::list< Declaration * > & translationUnit, const std::string & name, bool inLibrary ) { … … 97 140 std::list< Statement * > & destroyStatements = destroyFunction->get_statements()->get_kids(); 98 141 142 if ( ! tryConstruct( objDecl ) ) return; // don't construct @= or designated objects 143 if ( objDecl->get_storageClass() == DeclarationNode::Extern ) return; 99 144 // C allows you to initialize objects with constant expressions 100 145 // xxx - this is an optimization. Need to first resolve constructors before we decide … … 102 147 // if ( isConstExpr( objDecl->get_init() ) ) return; 103 148 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() ); 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 ) ); 107 156 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; 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 ) ) ); 127 167 } // if 128 168 }
Note:
See TracChangeset
for help on using the changeset viewer.