Ignore:
Timestamp:
Aug 2, 2016, 6:37:08 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
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
Message:

major reorganization of constructor generation from initializer list so that it now works with multi-dimensional arrays

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/GenInit.cc

    r39f84a4 r4d2434a  
    154154        }
    155155
     156        // precompute array dimension expression, because constructor generation may duplicate it,
     157        // which would be incorrect if it is a side-effecting computation.
    156158        void HoistArrayDimension::hoistArrayDimension( std::list< Declaration * > & translationUnit ) {
    157159                HoistArrayDimension hoister;
     
    215217                // hands off if designated, if @=, or if extern
    216218                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 ) {
    261241                                // need to remember init expression, in case no ctors exist
    262242                                // if ctor does exist, want to use ctor expression instead of init
    263243                                // 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() ) );
    267246                        }
    268247                }
Note: See TracChangeset for help on using the changeset viewer.