Changeset f0121d7


Ignore:
Timestamp:
Oct 26, 2016, 10:56:46 AM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
a1e67dd
Parents:
bf32bb8
Message:

refactor genCtorInit, generate ConstructorInit? for UniqueExpr?

Location:
src
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    rbf32bb8 rf0121d7  
    3535#include "GenPoly/DeclMutator.h"
    3636#include "SynTree/AddStmtVisitor.h"
    37 #include "CodeGen/GenType.h"  // for warnings
    38 
    39 bool ctordtorp = false;
    40 bool ctorp = false;
    41 bool cpctorp = false;
    42 bool dtorp = false;
     37#include "CodeGen/GenType.h"  // for warning/error messages
     38
     39bool ctordtorp = false; // print all debug
     40bool ctorp = false; // print ctor debug
     41bool cpctorp = false; // print copy ctor debug
     42bool dtorp = false; // print dtor debug
    4343#define PRINT( text ) if ( ctordtorp ) { text }
    4444#define CP_CTOR_PRINT( text ) if ( ctordtorp || cpctorp ) { text }
     
    4747namespace InitTweak {
    4848        namespace {
    49                 const std::list<Label> noLabels;
    50                 const std::list<Expression*> noDesignators;
    51 
    5249                class InsertImplicitCalls : public GenPoly::PolyMutator {
    5350                public:
     
    957954                Expression * FixCtorExprs::mutate( ConstructorExpr * ctorExpr ) {
    958955                        static UniqueName tempNamer( "_tmp_ctor_expr" );
     956                        // xxx - is the size check necessary?
    959957                        assert( ctorExpr->has_result() && ctorExpr->get_result()->size() == 1 );
    960958                        ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, ctorExpr->get_result()->clone(), nullptr );
  • src/InitTweak/GenInit.cc

    rbf32bb8 rf0121d7  
    265265        }
    266266
     267        ConstructorInit * genCtorInit( ObjectDecl * objDecl ) {
     268                // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor
     269                // for each constructable object
     270                std::list< Statement * > ctor;
     271                std::list< Statement * > dtor;
     272
     273                InitExpander srcParam( objDecl->get_init() );
     274                InitExpander nullParam( (Initializer *)NULL );
     275                SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl );
     276                SymTab::genImplicitCall( nullParam, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false );
     277
     278                // Currently genImplicitCall produces a single Statement - a CompoundStmt
     279                // which  wraps everything that needs to happen. As such, it's technically
     280                // possible to use a Statement ** in the above calls, but this is inherently
     281                // unsafe, so instead we take the slightly less efficient route, but will be
     282                // immediately informed if somehow the above assumption is broken. In this case,
     283                // we could always wrap the list of statements at this point with a CompoundStmt,
     284                // but it seems reasonable at the moment for this to be done by genImplicitCall
     285                // itself. It is possible that genImplicitCall produces no statements (e.g. if
     286                // an array type does not have a dimension). In this case, it's fine to ignore
     287                // the object for the purposes of construction.
     288                assert( ctor.size() == dtor.size() && ctor.size() <= 1 );
     289                if ( ctor.size() == 1 ) {
     290                        // need to remember init expression, in case no ctors exist
     291                        // if ctor does exist, want to use ctor expression instead of init
     292                        // push this decision to the resolver
     293                        assert( dynamic_cast< ImplicitCtorDtorStmt * > ( ctor.front() ) && dynamic_cast< ImplicitCtorDtorStmt * > ( dtor.front() ) );
     294                        return new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() );
     295                }
     296                return nullptr;
     297        }
     298
    267299        DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) {
    268300                handleDWT( objDecl );
     
    275307                        if ( ! checkInitDepth( objDecl ) ) throw SemanticError( "Managed object's initializer is too deep ", objDecl );
    276308
    277                         // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor
    278                         // for each constructable object
    279                         std::list< Statement * > ctor;
    280                         std::list< Statement * > dtor;
    281 
    282                         InitExpander srcParam( objDecl->get_init() );
    283                         InitExpander nullParam( (Initializer *)NULL );
    284                         SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl );
    285                         SymTab::genImplicitCall( nullParam, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false );
    286 
    287                         // Currently genImplicitCall produces a single Statement - a CompoundStmt
    288                         // which  wraps everything that needs to happen. As such, it's technically
    289                         // possible to use a Statement ** in the above calls, but this is inherently
    290                         // unsafe, so instead we take the slightly less efficient route, but will be
    291                         // immediately informed if somehow the above assumption is broken. In this case,
    292                         // we could always wrap the list of statements at this point with a CompoundStmt,
    293                         // but it seems reasonable at the moment for this to be done by genImplicitCall
    294                         // itself. It is possible that genImplicitCall produces no statements (e.g. if
    295                         // an array type does not have a dimension). In this case, it's fine to ignore
    296                         // the object for the purposes of construction.
    297                         assert( ctor.size() == dtor.size() && ctor.size() <= 1 );
    298                         if ( ctor.size() == 1 ) {
    299                                 // need to remember init expression, in case no ctors exist
    300                                 // if ctor does exist, want to use ctor expression instead of init
    301                                 // push this decision to the resolver
    302                                 assert( dynamic_cast< ImplicitCtorDtorStmt * > ( ctor.front() ) && dynamic_cast< ImplicitCtorDtorStmt * > ( dtor.front() ) );
    303                                 objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) );
    304                         }
     309                        objDecl->set_init( genCtorInit( objDecl ) );
    305310                }
    306311                return Parent::mutate( objDecl );
  • src/InitTweak/GenInit.h

    rbf32bb8 rf0121d7  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // RemoveInit.h --
     7// GenInit.h --
    88//
    99// Author           : Rodolfo G. Esteves
     
    2727        /// Adds return value temporaries and wraps Initializers in ConstructorInit nodes
    2828        void genInit( std::list< Declaration * > & translationUnit );
     29
     30        /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer
     31        ConstructorInit * genCtorInit( ObjectDecl * objDecl );
    2932} // namespace
    3033
  • src/SynTree/Initializer.h

    rbf32bb8 rf0121d7  
    2323
    2424#include <cassert>
     25
     26const std::list<Expression*> noDesignators;
    2527
    2628// Initializer: base class for object initializers (provide default values)
  • src/Tuples/TupleExpansion.cc

    rbf32bb8 rf0121d7  
    2828#include "Common/ScopedMap.h"
    2929#include "ResolvExpr/typeops.h"
     30#include "InitTweak/GenInit.h"
    3031
    3132namespace Tuples {
     
    133134                        return tupleExpr;
    134135                } else {
    135                         return memberExpr;
     136                        // there may be a tuple expr buried in the aggregate
     137                        // xxx - this is a memory leak
     138                        return new UntypedMemberExpr( memberExpr->get_member()->clone(), memberExpr->get_aggregate()->acceptMutator( *this ) );
    136139                }
    137140        }
     
    142145                if ( ! decls.count( unqExpr->get_id() ) ) {
    143146                        // xxx - it's possible (likely?) that expressions can appear in the wrong order because of this. Need to ensure they're placed in the correct location.
    144                         // xxx - is it possible to make the decl's type const?
    145                         ObjectDecl * decl = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, unqExpr->get_result()->clone(), new SingleInit( unqExpr->get_expr()->clone() ) );
    146                         decls[unqExpr->get_id()] = decl;
    147                         addDeclaration( decl );
     147
     148                        // xxx - this doesn't work, because it would need to be placed after fixInit, but fixInit doesn't know (and shouldn't have to know) about the existance of UniqueExprs - i.e. it will visit them twice
     149                        // need to construct/destruct unique exprs in general - maybe it's not worth it and fixInit should handle UniqueExpr explicitly?
     150                        // currently, tmp is being destructed before unqExpr is used, which suggests there should be a separate lifetime for unqExpr from the tmp_ret
     151
     152                        // if ( CommaExpr * commaExpr = dynamic_cast< CommaExpr * >( unqExpr->get_expr() ) ) {
     153                        //      if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( commaExpr->get_arg2() ) ) {
     154                        //              // steal existing decl from expr
     155                        //              if ( ObjectDecl * decl = dynamic_cast< ObjectDecl * >( varExpr->get_var() ) ) {
     156                        //                      decls[unqExpr->get_id()] = decl;
     157                        //                      return unqExpr->get_expr()->clone();
     158                        //              }
     159                        //      }
     160                        // }
     161
     162                        // xxx - attach a resolved ConstructorInit node?
     163                        // xxx - is it possible to make the objDecl's type const?
     164                        ObjectDecl * objDecl = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, nullptr, unqExpr->get_result()->clone(), nullptr );
     165                        // must be done on two lines because genCtorInit accesses objDecl's fields
     166                        objDecl->set_init( InitTweak::genCtorInit( objDecl ) );
     167
     168                        decls[unqExpr->get_id()] = objDecl;
     169                        addDeclaration( objDecl );
    148170                }
    149171                return new VariableExpr( decls[unqExpr->get_id()] );
  • src/main.cc

    rbf32bb8 rf0121d7  
    251251                } // if
    252252
    253                 OPTPRINT( "expandUniqueExpr" ); // xxx - is this the right place for this?
     253                OPTPRINT( "expandUniqueExpr" ); // xxx - is this the right place for this? want to expand ASAP so that subsequent passes don't need to worry about double-visiting a unique expr
    254254                Tuples::expandUniqueExpr( translationUnit );
    255255
Note: See TracChangeset for help on using the changeset viewer.