Changeset 4d2434a for src/InitTweak/GenInit.cc
- Timestamp:
- Aug 2, 2016, 6:37:08 PM (8 years ago)
- 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:
- 8a443f4
- Parents:
- 39f84a4
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/GenInit.cc
r39f84a4 r4d2434a 154 154 } 155 155 156 // precompute array dimension expression, because constructor generation may duplicate it, 157 // which would be incorrect if it is a side-effecting computation. 156 158 void HoistArrayDimension::hoistArrayDimension( std::list< Declaration * > & translationUnit ) { 157 159 HoistArrayDimension hoister; … … 215 217 // hands off if designated, if @=, or if extern 216 218 if ( tryConstruct( objDecl ) ) { 217 if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) { 218 // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array 219 // TODO: walk initializers and generate appropriate ctor if element has initializer. 220 // Initializer could be nested (depends on the depth of the array type on the object) 221 222 std::list< Expression * > args = makeInitList( objDecl->get_init() ); 223 if ( args.empty() ) { 224 std::list< Statement * > ctor; 225 std::list< Statement * > dtor; 226 227 InitExpander srcParam( (Expression *)NULL ); 228 SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl ); 229 SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false ); 230 231 // Currently genImplicitCall produces a single Statement - a CompoundStmt 232 // which wraps everything that needs to happen. As such, it's technically 233 // possible to use a Statement ** in the above calls, but this is inherently 234 // unsafe, so instead we take the slightly less efficient route, but will be 235 // immediately informed if somehow the above assumption is broken. In this case, 236 // we could always wrap the list of statements at this point with a CompoundStmt, 237 // but it seems reasonable at the moment for this to be done by genImplicitCall 238 // itself. It is possible that genImplicitCall produces no statements (e.g. if 239 // an array type does not have a dimension). In this case, it's fine to ignore 240 // the object for the purposes of construction. 241 assert( ctor.size() == dtor.size() && ctor.size() <= 1 ); 242 if ( ctor.size() == 1 ) { 243 assert( dynamic_cast< ImplicitCtorDtorStmt * > ( ctor.front() ) && dynamic_cast< ImplicitCtorDtorStmt * > ( dtor.front() ) ); 244 objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) ); 245 } 246 } else { 247 // array came with an initializer list: initialize each element 248 // may have more initializers than elements in the array - need to check at each index that 249 // we haven't exceeded size. This requires precomputing the size because it might be a side-effecting 250 // computation. 251 // may have fewer initializers than elements in the array - need to default construct 252 // remaining elements. 253 // might be able to merge this with the case above. 254 255 } 256 } else { 257 // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer 258 Expression * ctor = makeCtorDtorExpr( "?{}", objDecl, makeInitList( objDecl->get_init() ) ); 259 Expression * dtor = makeCtorDtorExpr( "^?{}", objDecl, std::list< Expression * >() ); 260 219 // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor 220 // for each constructable object 221 std::list< Statement * > ctor; 222 std::list< Statement * > dtor; 223 224 InitExpander srcParam( objDecl->get_init() ); 225 InitExpander nullParam( (Initializer *)NULL ); 226 SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl ); 227 SymTab::genImplicitCall( nullParam, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false ); 228 229 // Currently genImplicitCall produces a single Statement - a CompoundStmt 230 // which wraps everything that needs to happen. As such, it's technically 231 // possible to use a Statement ** in the above calls, but this is inherently 232 // unsafe, so instead we take the slightly less efficient route, but will be 233 // immediately informed if somehow the above assumption is broken. In this case, 234 // we could always wrap the list of statements at this point with a CompoundStmt, 235 // but it seems reasonable at the moment for this to be done by genImplicitCall 236 // itself. It is possible that genImplicitCall produces no statements (e.g. if 237 // an array type does not have a dimension). In this case, it's fine to ignore 238 // the object for the purposes of construction. 239 assert( ctor.size() == dtor.size() && ctor.size() <= 1 ); 240 if ( ctor.size() == 1 ) { 261 241 // need to remember init expression, in case no ctors exist 262 242 // if ctor does exist, want to use ctor expression instead of init 263 243 // push this decision to the resolver 264 ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor ); 265 ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor ); 266 objDecl->set_init( new ConstructorInit( new ImplicitCtorDtorStmt( ctorStmt ), new ImplicitCtorDtorStmt( dtorStmt ), objDecl->get_init() ) ); 244 assert( dynamic_cast< ImplicitCtorDtorStmt * > ( ctor.front() ) && dynamic_cast< ImplicitCtorDtorStmt * > ( dtor.front() ) ); 245 objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) ); 267 246 } 268 247 }
Note: See TracChangeset
for help on using the changeset viewer.