Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/GenInit.cc

    r7b3f66b ra0fdbd5  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri May 13 11:37:48 2016
     12// Last Modified On : Thu Apr 28 12:26:47 2016
    1313// Update Count     : 166
    1414//
     
    1717#include <list>
    1818#include "GenInit.h"
    19 #include "InitTweak.h"
    2019#include "SynTree/Declaration.h"
    2120#include "SynTree/Type.h"
     
    131130
    132131        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
    133139                Expression * makeCtorDtorExpr( std::string name, ObjectDecl * objDecl, std::list< Expression * > args ) {
    134140                        UntypedExpr * expr = new UntypedExpr( new NameExpr( name ) );
     
    136142                        expr->get_args().splice( expr->get_args().end(), args );
    137143                        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;
    138171                }
    139172        }
     
    146179                                        // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array
    147180                                        // TODO: walk initializer and generate appropriate copy ctor if element has initializer
    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                                         }
     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() ) );
    177199                                } else {
    178200                                        // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer
     
    187209                                        objDecl->set_init( new ConstructorInit( ctorStmt, dtorStmt, objDecl->get_init() ) );
    188210                                }
     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
    189218                        }
    190219                }
Note: See TracChangeset for help on using the changeset viewer.