Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/GenInit.cc

    ra0fdbd5 r7b3f66b  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Thu Apr 28 12:26:47 2016
     12// Last Modified On : Fri May 13 11:37:48 2016
    1313// Update Count     : 166
    1414//
     
    1717#include <list>
    1818#include "GenInit.h"
     19#include "InitTweak.h"
    1920#include "SynTree/Declaration.h"
    2021#include "SynTree/Type.h"
     
    130131
    131132        namespace {
    132                 bool tryConstruct( ObjectDecl * objDecl ) {
    133                         // xxx - handle designations
    134                         return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
    135                                 (objDecl->get_init() == NULL ||
    136                                 ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() ));
    137                 }
    138 
    139133                Expression * makeCtorDtorExpr( std::string name, ObjectDecl * objDecl, std::list< Expression * > args ) {
    140134                        UntypedExpr * expr = new UntypedExpr( new NameExpr( name ) );
     
    142136                        expr->get_args().splice( expr->get_args().end(), args );
    143137                        return expr;
    144                 }
    145 
    146                 class InitExpander : public Visitor {
    147                   public:
    148                   InitExpander() {}
    149                   // ~InitExpander() {}
    150                         virtual void visit( SingleInit * singleInit );
    151                         virtual void visit( ListInit * listInit );
    152                         std::list< Expression * > argList;
    153                 };
    154 
    155                 void InitExpander::visit( SingleInit * singleInit ) {
    156                         argList.push_back( singleInit->get_value()->clone() );
    157                 }
    158 
    159                 void InitExpander::visit( ListInit * listInit ) {
    160                         // xxx - for now, assume no nested list inits
    161                         std::list<Initializer*>::iterator it = listInit->begin_initializers();
    162                         for ( ; it != listInit->end_initializers(); ++it ) {
    163                                 (*it)->accept( *this );
    164                         }
    165                 }
    166 
    167                 std::list< Expression * > makeInitList( Initializer * init ) {
    168                         InitExpander expander;
    169                         maybeAccept( init, expander );
    170                         return expander.argList;
    171138                }
    172139        }
     
    179146                                        // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array
    180147                                        // TODO: walk initializer and generate appropriate copy ctor if element has initializer
    181                                         std::list< Statement * > ctor;
    182                                         std::list< Statement * > dtor;
    183 
    184                                         SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "?{}", back_inserter( ctor ) );
    185                                         SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "^?{}", front_inserter( dtor ), false );
    186 
    187                                         // Currently makeArrayFunction produces a single Statement - a CompoundStmt
    188                                         // which  wraps everything that needs to happen. As such, it's technically
    189                                         // possible to use a Statement ** in the above calls, but this is inherently
    190                                         // unsafe, so instead we take the slightly less efficient route, but will be
    191                                         // immediately informed if somehow the above assumption is broken. In this case,
    192                                         // we could always wrap the list of statements at this point with a CompoundStmt,
    193                                         // but it seems reasonable at the moment for this to be done by makeArrayFunction
    194                                         // itself
    195                                         assert( ctor.size() == 1 );
    196                                         assert( dtor.size() == 1 );
    197 
    198                                         objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) );
     148                                        std::list< Expression * > args = makeInitList( objDecl->get_init() );
     149                                        if ( args.empty() ) {
     150                                                std::list< Statement * > ctor;
     151                                                std::list< Statement * > dtor;
     152
     153                                                SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "?{}", back_inserter( ctor ) );
     154                                                SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "^?{}", front_inserter( dtor ), false );
     155
     156                                                // Currently makeArrayFunction produces a single Statement - a CompoundStmt
     157                                                // which  wraps everything that needs to happen. As such, it's technically
     158                                                // possible to use a Statement ** in the above calls, but this is inherently
     159                                                // unsafe, so instead we take the slightly less efficient route, but will be
     160                                                // immediately informed if somehow the above assumption is broken. In this case,
     161                                                // we could always wrap the list of statements at this point with a CompoundStmt,
     162                                                // but it seems reasonable at the moment for this to be done by makeArrayFunction
     163                                                // itself
     164                                                assert( ctor.size() == 1 );
     165                                                assert( dtor.size() == 1 );
     166
     167                                                objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) );
     168                                        } else {
     169                                                // array came with an initializer list: initialize each element
     170                                                // may have more initializers than elements in the array - need to check at each index that
     171                                                // we haven't exceeded size. This requires precomputing the size because it might be a side-effecting
     172                                                // computation.
     173                                                // may have fewer initializers than eleemnts in the array - need to default construct
     174                                                // remaining elements.
     175                                                // might be able to merge this with the case above.
     176                                        }
    199177                                } else {
    200178                                        // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer
     
    209187                                        objDecl->set_init( new ConstructorInit( ctorStmt, dtorStmt, objDecl->get_init() ) );
    210188                                }
    211                         } else {
    212                                 // xxx - find a way to construct/destruct globals
    213                                 // hack: implicit "static" initialization routine for each struct type? or something similar?
    214                                 // --ties into module system
    215                                 // this can be done by mangling main and replacing it with our own main which calls each
    216                                 // module initialization routine in some decided order (order given in link command?)
    217                                 // and finally calls mangled main
    218189                        }
    219190                }
Note: See TracChangeset for help on using the changeset viewer.