Changeset 6cf27a07 for src/InitTweak/GenInit.cc
- Timestamp:
- Jul 21, 2016, 2:07:01 PM (9 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:
- ccb447e
- Parents:
- b81adcc4
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/GenInit.cc
rb81adcc4 r6cf27a07 61 61 static void generateCtorDtor( std::list< Declaration * > &translationUnit ); 62 62 63 CtorDtor() : inFunction( false ) {}64 65 63 virtual DeclarationWithType * mutate( ObjectDecl * ); 66 64 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ); … … 77 75 78 76 protected: 79 bool inFunction;80 77 }; 81 78 … … 216 213 217 214 DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) { 218 // hands off if designated or if @=215 // hands off if designated, if @=, or if extern 219 216 if ( tryConstruct( objDecl ) ) { 220 if ( inFunction ) { 221 if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) { 222 // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array 223 // TODO: walk initializers and generate appropriate ctor if element has initializer. 224 // Initializer could be nested (depends on the depth of the array type on the object) 225 226 std::list< Expression * > args = makeInitList( objDecl->get_init() ); 227 if ( args.empty() ) { 228 std::list< Statement * > ctor; 229 std::list< Statement * > dtor; 230 231 SymTab::genImplicitCall( NULL, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl ); 232 SymTab::genImplicitCall( NULL, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false ); 233 234 // Currently genArrayCall produces a single Statement - a CompoundStmt 235 // which wraps everything that needs to happen. As such, it's technically 236 // possible to use a Statement ** in the above calls, but this is inherently 237 // unsafe, so instead we take the slightly less efficient route, but will be 238 // immediately informed if somehow the above assumption is broken. In this case, 239 // we could always wrap the list of statements at this point with a CompoundStmt, 240 // but it seems reasonable at the moment for this to be done by genArrayCall 241 // itself 242 assert( ctor.size() == 1 && dynamic_cast< ImplicitCtorDtorStmt * >( ctor.front() ) ); 243 assert( dtor.size() == 1 && dynamic_cast< ImplicitCtorDtorStmt * >( dtor.front() ) ); 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 SymTab::genImplicitCall( NULL, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl ); 228 SymTab::genImplicitCall( NULL, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false ); 229 230 // Currently genImplicitCall produces a single Statement - a CompoundStmt 231 // which wraps everything that needs to happen. As such, it's technically 232 // possible to use a Statement ** in the above calls, but this is inherently 233 // unsafe, so instead we take the slightly less efficient route, but will be 234 // immediately informed if somehow the above assumption is broken. In this case, 235 // we could always wrap the list of statements at this point with a CompoundStmt, 236 // but it seems reasonable at the moment for this to be done by genImplicitCall 237 // itself. It is possible that genImplicitCall produces no statements (e.g. if 238 // an array type does not have a dimension). In this case, it's fine to ignore 239 // the object for the purposes of construction. 240 assert( ctor.size() == dtor.size() && ctor.size() <= 1 ); 241 if ( ctor.size() == 1 ) { 242 assert( dynamic_cast< ImplicitCtorDtorStmt * > ( ctor.front() ) && dynamic_cast< ImplicitCtorDtorStmt * > ( dtor.front() ) ); 244 243 objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) ); 245 } else {246 // array came with an initializer list: initialize each element247 // may have more initializers than elements in the array - need to check at each index that248 // we haven't exceeded size. This requires precomputing the size because it might be a side-effecting249 // computation.250 // may have fewer initializers than elements in the array - need to default construct251 // remaining elements.252 // might be able to merge this with the case above.253 254 244 } 255 245 } else { 256 // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer 257 Expression * ctor = makeCtorDtorExpr( "?{}", objDecl, makeInitList( objDecl->get_init() ) ); 258 Expression * dtor = makeCtorDtorExpr( "^?{}", objDecl, std::list< Expression * >() ); 259 260 // need to remember init expression, in case no ctors exist 261 // if ctor does exist, want to use ctor expression instead of init 262 // push this decision to the resolver 263 ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor ); 264 ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor ); 265 objDecl->set_init( new ConstructorInit( new ImplicitCtorDtorStmt( ctorStmt ), new ImplicitCtorDtorStmt( dtorStmt ), objDecl->get_init() ) ); 246 // array came with an initializer list: initialize each element 247 // may have more initializers than elements in the array - need to check at each index that 248 // we haven't exceeded size. This requires precomputing the size because it might be a side-effecting 249 // computation. 250 // may have fewer initializers than elements in the array - need to default construct 251 // remaining elements. 252 // might be able to merge this with the case above. 253 266 254 } 255 } else { 256 // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer 257 Expression * ctor = makeCtorDtorExpr( "?{}", objDecl, makeInitList( objDecl->get_init() ) ); 258 Expression * dtor = makeCtorDtorExpr( "^?{}", objDecl, std::list< Expression * >() ); 259 260 // need to remember init expression, in case no ctors exist 261 // if ctor does exist, want to use ctor expression instead of init 262 // push this decision to the resolver 263 ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor ); 264 ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor ); 265 objDecl->set_init( new ConstructorInit( new ImplicitCtorDtorStmt( ctorStmt ), new ImplicitCtorDtorStmt( dtorStmt ), objDecl->get_init() ) ); 267 266 } 268 267 } … … 272 271 DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) { 273 272 // parameters should not be constructed and destructed, so don't mutate FunctionType 274 bool oldInFunc = inFunction;275 273 mutateAll( functionDecl->get_oldDecls(), *this ); 276 inFunction = true;277 274 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) ); 278 inFunction = oldInFunc;279 275 return functionDecl; 280 276 }
Note: See TracChangeset
for help on using the changeset viewer.