Changes in / [2a7b3ca:579263a]


Ignore:
Location:
src
Files:
2 added
24 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r2a7b3ca r579263a  
    288288        }
    289289
    290         void CodeGenerator::printDesignators( std::list< Expression * > & designators ) {
    291                 typedef std::list< Expression * > DesignatorList;
     290        void CodeGenerator::visit( Designation * designation ) {
     291                std::list< Expression * > designators = designation->get_designators();
    292292                if ( designators.size() == 0 ) return;
    293                 for ( DesignatorList::iterator iter = designators.begin(); iter != designators.end(); ++iter ) {
    294                         if ( dynamic_cast< NameExpr * >( *iter ) ) {
    295                                 // if expression is a name, then initializing aggregate member
     293                for ( Expression * des : designators ) {
     294                        if ( dynamic_cast< ConstantExpr * >( des ) ) {
     295                                // if expression is a ConstantExpr, then initializing array element
     296                                output << "[";
     297                                des->accept( *this );
     298                                output << "]";
     299                        } else {
     300                                // if not a ConstantExpr, it has to be a NameExpr or VariableExpr, initializing aggregate member
    296301                                output << ".";
    297                                 (*iter)->accept( *this );
    298                         } else {
    299                                 // if not a simple name, it has to be a constant expression, i.e. an array designator
    300                                 output << "[";
    301                                 (*iter)->accept( *this );
    302                                 output << "]";
     302                                des->accept( *this );
    303303                        } // if
    304304                } // for
     
    307307
    308308        void CodeGenerator::visit( SingleInit * init ) {
    309                 printDesignators( init->get_designators() );
    310309                init->get_value()->accept( *this );
    311310        }
    312311
    313312        void CodeGenerator::visit( ListInit * init ) {
    314                 printDesignators( init->get_designators() );
     313                auto initBegin = init->begin();
     314                auto initEnd = init->end();
     315                auto desigBegin = init->get_designations().begin();
     316                auto desigEnd = init->get_designations().end();
     317
    315318                output << "{ ";
    316                 genCommaList( init->begin(), init->end() );
     319                for ( ; initBegin != initEnd && desigBegin != desigEnd; ) {
     320                        (*desigBegin)->accept( *this );
     321                        (*initBegin)->accept( *this );
     322                        ++initBegin, ++desigBegin;
     323                        if ( initBegin != initEnd ) {
     324                                output << ", ";
     325                        }
     326                }
    317327                output << " }";
     328                assertf( initBegin == initEnd && desigBegin == desigEnd, "Initializers and designators not the same length. %s", toString( init ).c_str() );
    318329        }
    319330
     
    716727
    717728        void CodeGenerator::visit( TypeExpr * typeExpr ) {
    718                 assertf( ! genC, "TypeExpr should not reach code generation." );
    719                 output<< genType( typeExpr->get_type(), "", pretty, genC );
     729                // if ( genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl;
     730                // assertf( ! genC, "TypeExpr should not reach code generation." );
     731                if ( ! genC ) {
     732                        output<< genType( typeExpr->get_type(), "", pretty, genC );
     733                }
    720734        }
    721735
  • src/CodeGen/CodeGenerator.h

    r2a7b3ca r579263a  
    4747
    4848                //*** Initializer
     49                virtual void visit( Designation * );
    4950                virtual void visit( SingleInit * );
    5051                virtual void visit( ListInit * );
     
    137138                bool lineMarks = false;
    138139
    139                 void printDesignators( std::list< Expression * > & );
    140140                void handleStorageClass( DeclarationWithType *decl );
    141141                void handleAggregate( AggregateDecl *aggDecl, const std::string & kind );
  • src/Common/utility.h

    r2a7b3ca r579263a  
    305305// for ( val : group_iterate( container1, container2, ... ) ) {}
    306306// syntax to have a for each that iterates multiple containers of the same length
    307 // TODO: update to use variadic arguments
     307// TODO: update to use variadic arguments, perfect forwarding
    308308
    309309template< typename T1, typename T2 >
  • src/InitTweak/FixInit.cc

    r2a7b3ca r579263a  
    724724                                                // static bool __objName_uninitialized = true
    725725                                                BasicType * boolType = new BasicType( Type::Qualifiers(), BasicType::Bool );
    726                                                 SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant::from_int( 1 ) ), noDesignators );
     726                                                SingleInit * boolInitExpr = new SingleInit( new ConstantExpr( Constant::from_int( 1 ) ) );
    727727                                                ObjectDecl * isUninitializedVar = new ObjectDecl( objDecl->get_mangleName() + "_uninitialized", Type::StorageClasses( Type::Static ), LinkageSpec::Cforall, 0, boolType, boolInitExpr );
    728728                                                isUninitializedVar->fixUniqueId();
  • src/InitTweak/InitTweak.cc

    r2a7b3ca r579263a  
    1414                public:
    1515                        bool hasDesignations = false;
    16                         template<typename Init>
    17                         void handleInit( Init * init ) {
    18                                 if ( ! init->get_designators().empty() ) hasDesignations = true;
    19                                 else Visitor::visit( init );
    20                         }
    21                         virtual void visit( SingleInit * singleInit ) { handleInit( singleInit); }
    22                         virtual void visit( ListInit * listInit ) { handleInit( listInit); }
     16                        virtual void visit( Designation * des ) {
     17                                if ( ! des->get_designators().empty() ) hasDesignations = true;
     18                                else Visitor::visit( des );
     19                        }
    2320                };
    2421
  • src/MakeLibCfa.cc

    r2a7b3ca r579263a  
    9292                assert( ! objDecl->get_init() );
    9393                std::list< Expression* > noDesignators;
    94                 objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), noDesignators, false ) ); // cannot be constructed
     94                objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), false ) ); // cannot be constructed
    9595                newDecls.push_back( objDecl );
    9696        }
  • src/Makefile.in

    r2a7b3ca r579263a  
    161161        ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT) \
    162162        ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) \
     163        ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT) \
    163164        SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) \
    164165        SymTab/driver_cfa_cpp-Mangler.$(OBJEXT) \
     
    414415        ResolvExpr/RenameVars.cc ResolvExpr/FindOpenVars.cc \
    415416        ResolvExpr/PolyCost.cc ResolvExpr/Occurs.cc \
    416         ResolvExpr/TypeEnvironment.cc SymTab/Indexer.cc \
    417         SymTab/Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \
    418         SymTab/ImplementationType.cc SymTab/TypeEquality.cc \
    419         SymTab/Autogen.cc SynTree/Type.cc SynTree/VoidType.cc \
    420         SynTree/BasicType.cc SynTree/PointerType.cc \
    421         SynTree/ArrayType.cc SynTree/FunctionType.cc \
    422         SynTree/ReferenceToType.cc SynTree/TupleType.cc \
    423         SynTree/TypeofType.cc SynTree/AttrType.cc \
     417        ResolvExpr/TypeEnvironment.cc ResolvExpr/CurrentObject.cc \
     418        SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \
     419        SymTab/FixFunction.cc SymTab/ImplementationType.cc \
     420        SymTab/TypeEquality.cc SymTab/Autogen.cc SynTree/Type.cc \
     421        SynTree/VoidType.cc SynTree/BasicType.cc \
     422        SynTree/PointerType.cc SynTree/ArrayType.cc \
     423        SynTree/FunctionType.cc SynTree/ReferenceToType.cc \
     424        SynTree/TupleType.cc SynTree/TypeofType.cc SynTree/AttrType.cc \
    424425        SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \
    425426        SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \
     
    721722        ResolvExpr/$(am__dirstamp) \
    722723        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     724ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT):  \
     725        ResolvExpr/$(am__dirstamp) \
     726        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    723727SymTab/$(am__dirstamp):
    724728        @$(MKDIR_P) SymTab
     
    890894        -rm -f ResolvExpr/driver_cfa_cpp-CommonType.$(OBJEXT)
    891895        -rm -f ResolvExpr/driver_cfa_cpp-ConversionCost.$(OBJEXT)
     896        -rm -f ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT)
    892897        -rm -f ResolvExpr/driver_cfa_cpp-FindOpenVars.$(OBJEXT)
    893898        -rm -f ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT)
     
    10021007@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Po@am__quote@
    10031008@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Po@am__quote@
     1009@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po@am__quote@
    10041010@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Po@am__quote@
    10051011@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Po@am__quote@
     
    19431949@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj `if test -f 'ResolvExpr/TypeEnvironment.cc'; then $(CYGPATH_W) 'ResolvExpr/TypeEnvironment.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/TypeEnvironment.cc'; fi`
    19441950
     1951ResolvExpr/driver_cfa_cpp-CurrentObject.o: ResolvExpr/CurrentObject.cc
     1952@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CurrentObject.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.o `test -f 'ResolvExpr/CurrentObject.cc' || echo '$(srcdir)/'`ResolvExpr/CurrentObject.cc
     1953@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po
     1954@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/CurrentObject.cc' object='ResolvExpr/driver_cfa_cpp-CurrentObject.o' libtool=no @AMDEPBACKSLASH@
     1955@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1956@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.o `test -f 'ResolvExpr/CurrentObject.cc' || echo '$(srcdir)/'`ResolvExpr/CurrentObject.cc
     1957
     1958ResolvExpr/driver_cfa_cpp-CurrentObject.obj: ResolvExpr/CurrentObject.cc
     1959@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CurrentObject.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.obj `if test -f 'ResolvExpr/CurrentObject.cc'; then $(CYGPATH_W) 'ResolvExpr/CurrentObject.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CurrentObject.cc'; fi`
     1960@am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po
     1961@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/CurrentObject.cc' object='ResolvExpr/driver_cfa_cpp-CurrentObject.obj' libtool=no @AMDEPBACKSLASH@
     1962@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1963@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.obj `if test -f 'ResolvExpr/CurrentObject.cc'; then $(CYGPATH_W) 'ResolvExpr/CurrentObject.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CurrentObject.cc'; fi`
     1964
    19451965SymTab/driver_cfa_cpp-Indexer.o: SymTab/Indexer.cc
    19461966@am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Indexer.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Tpo -c -o SymTab/driver_cfa_cpp-Indexer.o `test -f 'SymTab/Indexer.cc' || echo '$(srcdir)/'`SymTab/Indexer.cc
  • src/Parser/InitializerNode.cc

    r2a7b3ca r579263a  
    7474
    7575        InitializerNode *moreInit;
    76         if  ( get_next() != 0 && ((moreInit = dynamic_cast< InitializerNode * >( get_next() ) ) != 0) )
     76        if ( (moreInit = dynamic_cast< InitializerNode * >( get_next() ) ) ) {
    7777                moreInit->printOneLine( os );
     78        }
    7879}
    7980
    8081Initializer *InitializerNode::build() const {
    8182        if ( aggregate ) {
     83                // steal designators from children
     84                std::list< Designation * > designlist;
     85                InitializerNode * child = next_init();
     86                for ( ; child != nullptr; child = dynamic_cast< InitializerNode * >( child->get_next() ) ) {
     87                        std::list< Expression * > desList;
     88                        buildList< Expression, ExpressionNode >( child->designator, desList );
     89                        designlist.push_back( new Designation( desList ) );
     90                } // for
    8291                std::list< Initializer * > initlist;
    8392                buildList< Initializer, InitializerNode >( next_init(), initlist );
    84 
    85                 std::list< Expression * > designlist;
    86 
    87                 if ( designator != 0 ) {
    88                         buildList< Expression, ExpressionNode >( designator, designlist );
    89                 } // if
    90 
    9193                return new ListInit( initlist, designlist, maybeConstructed );
    9294        } else {
    93                 std::list< Expression * > designators;
    94 
    95                 if ( designator != 0 )
    96                         buildList< Expression, ExpressionNode >( designator, designators );
    97 
    98                 if ( get_expression() != 0)
    99                         return new SingleInit( maybeBuild< Expression >( get_expression() ), designators, maybeConstructed );
     95                if ( get_expression() != 0) {
     96                        return new SingleInit( maybeBuild< Expression >( get_expression() ), maybeConstructed );
     97                }
    10098        } // if
    101 
    10299        return 0;
    103100}
  • src/Parser/TypeData.cc

    r2a7b3ca r579263a  
    760760                if ( cur->has_enumeratorValue() ) {
    761761                        ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members);
    762                         member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ), list< Expression * >() ) );
     762                        member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) ) );
    763763                } // if
    764764        } // for
  • src/ResolvExpr/AlternativeFinder.cc

    r2a7b3ca r579263a  
    604604//          )
    605605                SymTab::Indexer decls( indexer );
    606                 PRINT(
    607                         std::cerr << "============= original indexer" << std::endl;
    608                         indexer.print( std::cerr );
    609                         std::cerr << "============= new indexer" << std::endl;
    610                         decls.print( std::cerr );
    611                 )
     606                // PRINT(
     607                //      std::cerr << "============= original indexer" << std::endl;
     608                //      indexer.print( std::cerr );
     609                //      std::cerr << "============= new indexer" << std::endl;
     610                //      decls.print( std::cerr );
     611                // )
    612612                addToIndexer( have, decls );
    613613                AssertionSet newNeed;
     
    11821182        }
    11831183
     1184        void AlternativeFinder::visit( UntypedInitExpr *initExpr ) {
     1185                AlternativeFinder finder( indexer, env );
     1186                finder.findWithAdjustment( initExpr->get_expr() );
     1187                // handle each option like a cast -- should probably push this info into AltFinder as a kind of expression, both to keep common code close and to have less 'reach-in', but more 'push-in'
     1188                AltList candidates;
     1189                std::cerr << "untyped init expr: " << initExpr << std::endl;
     1190                // O(N^2) checks of d-types with e-types
     1191                for ( Alternative & alt : finder.get_alternatives() ) {
     1192                        for ( InitAlternative & initAlt : initExpr->get_initAlts() ) {
     1193                                AssertionSet needAssertions, haveAssertions;
     1194                                OpenVarSet openVars;
     1195                                std::cerr << "  " << initAlt.type << " " << initAlt.designation << std::endl;
     1196                                // It's possible that a cast can throw away some values in a multiply-valued expression.  (An example is a
     1197                                // cast-to-void, which casts from one value to zero.)  Figure out the prefix of the subexpression results
     1198                                // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
     1199                                // to.
     1200                                int discardedValues = alt.expr->get_result()->size() - initAlt.type->size();
     1201                                if ( discardedValues < 0 ) continue;
     1202                                // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not
     1203                                // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3]))
     1204                                // unification run for side-effects
     1205                                unify( initAlt.type, alt.expr->get_result(), alt.env, needAssertions, haveAssertions, openVars, indexer );
     1206
     1207                                Cost thisCost = castCost( alt.expr->get_result(), initAlt.type, indexer, alt.env );
     1208                                if ( thisCost != Cost::infinity ) {
     1209                                        // count one safe conversion for each value that is thrown away
     1210                                        thisCost += Cost( 0, 0, discardedValues );
     1211                                        candidates.push_back( Alternative( new InitExpr( alt.expr->clone(), initAlt.type->clone(), initAlt.designation->clone() ), alt.env, alt.cost, thisCost ) );
     1212                                }
     1213                        }
     1214                }
     1215
     1216                // findMinCost selects the alternatives with the lowest "cost" members, but has the side effect of copying the
     1217                // cvtCost member to the cost member (since the old cost is now irrelevant).  Thus, calling findMinCost twice
     1218                // selects first based on argument cost, then on conversion cost.
     1219                AltList minArgCost;
     1220                findMinCost( candidates.begin(), candidates.end(), std::back_inserter( minArgCost ) );
     1221                findMinCost( minArgCost.begin(), minArgCost.end(), std::back_inserter( alternatives ) );
     1222        }
    11841223} // namespace ResolvExpr
    11851224
  • src/ResolvExpr/AlternativeFinder.h

    r2a7b3ca r579263a  
    7373                virtual void visit( UniqueExpr *unqExpr );
    7474                virtual void visit( StmtExpr *stmtExpr );
     75                virtual void visit( UntypedInitExpr *initExpr );
    7576                /// Runs a new alternative finder on each element in [begin, end)
    7677                /// and writes each alternative finder to out.
  • src/ResolvExpr/Resolver.cc

    r2a7b3ca r579263a  
    1414//
    1515
     16#include <iostream>
     17
     18#include "Alternative.h"
     19#include "AlternativeFinder.h"
     20#include "CurrentObject.h"
     21#include "RenameVars.h"
    1622#include "Resolver.h"
    17 #include "AlternativeFinder.h"
    18 #include "Alternative.h"
    19 #include "RenameVars.h"
    2023#include "ResolveTypeof.h"
    2124#include "typeops.h"
     25
     26#include "SynTree/Expression.h"
     27#include "SynTree/Initializer.h"
    2228#include "SynTree/Statement.h"
    2329#include "SynTree/Type.h"
    24 #include "SynTree/Expression.h"
    25 #include "SynTree/Initializer.h"
     30
     31#include "SymTab/Autogen.h"
    2632#include "SymTab/Indexer.h"
    27 #include "SymTab/Autogen.h"
     33
    2834#include "Common/utility.h"
     35
    2936#include "InitTweak/InitTweak.h"
    3037
    31 #include <iostream>
    3238using namespace std;
    3339
     
    3945                        if ( const Resolver * res = dynamic_cast< const Resolver * >( &other ) ) {
    4046                                functionReturn = res->functionReturn;
    41                                 initContext = res->initContext;
     47                                currentObject = res->currentObject;
    4248                                inEnumDecl = res->inEnumDecl;
    4349                        }
     
    7985
    8086                Type * functionReturn = nullptr;
    81                 Type *initContext = nullptr;
     87                CurrentObject currentObject = nullptr;
    8288                bool inEnumDecl = false;
    8389        };
     
    186192                // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting
    187193                // the RHS.
    188                 Type *temp = initContext;
    189                 initContext = new_type;
    190                 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
     194                ValueGuard<CurrentObject> temp( currentObject );
     195                currentObject = CurrentObject( objectDecl->get_type() );
     196                if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
    191197                        // enumerator initializers should not use the enum type to initialize, since
    192198                        // the enum type is still incomplete at this point. Use signed int instead.
    193                         initContext = new BasicType( Type::Qualifiers(), BasicType::SignedInt );
     199                        currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
    194200                }
    195201                Parent::visit( objectDecl );
    196                 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
     202                if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
    197203                        // delete newly created signed int type
    198                         delete initContext;
    199                 }
    200                 initContext = temp;
     204                        // delete currentObject.getType();
     205                }
    201206        }
    202207
     
    315320
    316321        void Resolver::visit( SwitchStmt *switchStmt ) {
    317                 ValueGuard< Type * > oldInitContext( initContext );
     322                ValueGuard< CurrentObject > oldCurrentObject( currentObject );
    318323                Expression *newExpr;
    319324                newExpr = findIntegralExpression( switchStmt->get_condition(), *this );
     
    321326                switchStmt->set_condition( newExpr );
    322327
    323                 initContext = newExpr->get_result();
     328                currentObject = CurrentObject( newExpr->get_result() );
    324329                Parent::visit( switchStmt );
    325330        }
     
    327332        void Resolver::visit( CaseStmt *caseStmt ) {
    328333                if ( caseStmt->get_condition() ) {
    329                         assert( initContext );
    330                         CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initContext->clone() );
     334                        std::list< InitAlternative > initAlts = currentObject.getOptions();
     335                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." );
     336                        CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() );
    331337                        Expression * newExpr = findSingleExpression( castExpr, *this );
    332338                        castExpr = safe_dynamic_cast< CastExpr * >( newExpr );
     
    369375        }
    370376
     377        template< typename Aggr >
     378        void lookupDesignation( Aggr * aggr, const std::list< Expression > & designators ) {
     379
     380        }
     381
    371382        void Resolver::visit( SingleInit *singleInit ) {
    372                 if ( singleInit->get_value() ) {
    373                         // // find all the d's
    374                         // std::list<Expression *> &designators = singleInit->get_designators();
    375                         // std::list<Type *> types1{ initContext }, types2;
    376                         // for ( Expression * expr: designators ) {
    377                         //      cerr << expr << endl;
    378                         //      if ( NameExpr * nexpr = dynamic_cast<NameExpr *>( expr ) ) {
    379                         //              for ( Type * type: types1 ) {
    380                         //                      cerr << type << endl;
    381                         //                      ReferenceToType * fred = dynamic_cast<ReferenceToType *>(type);
    382                         //                      std::list<Declaration *> members;
    383                         //                      if ( fred ) {
    384                         //                              fred->lookup( nexpr->get_name(), members ); // concatenate identical field name
    385                         //                              for ( Declaration * mem: members ) {
    386                         //                                      if ( DeclarationWithType * dwt = dynamic_cast<DeclarationWithType *>(mem) ) {
    387                         //                                              types2.push_back( dwt->get_type() );
    388                         //                                      } // if
    389                         //                              } // for
    390                         //                      } // if
    391                         //              } // for
    392                         //              types1 = types2;
    393                         //              types2.clear();
    394                         //      } // if
    395                         // } // for
    396                         // // for ( Type * type: types1 ) {
    397                         // //   cerr << type << endl;
    398                         // // } // for
    399 
    400                         // // O(N^2) checks of d-types with f-types
    401                         // // find the minimum cost
    402                         CastExpr *castExpr = new CastExpr( singleInit->get_value(), initContext->clone() );
    403                         Expression *newExpr = findSingleExpression( castExpr, *this );
    404                         delete castExpr;
    405                         singleInit->set_value( newExpr );
    406 
    407                         // check if initializing type is char[]
    408                         if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
    409                                 if ( isCharType( at->get_base() ) ) {
    410                                         // check if the resolved type is char *
    411                                         if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
    412                                                 if ( isCharType( pt->get_base() ) ) {
    413                                                         // strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
    414                                                         CastExpr *ce = dynamic_cast< CastExpr * >( newExpr );
    415                                                         singleInit->set_value( ce->get_arg() );
    416                                                         ce->set_arg( NULL );
    417                                                         delete ce;
    418                                                 }
    419                                         }
    420                                 }
    421                         }
    422                 } // if
    423         }
    424 
    425         template< typename AggrInst >
    426         TypeSubstitution makeGenericSubstitutuion( AggrInst * inst ) {
    427                 assert( inst );
    428                 assert( inst->get_baseParameters() );
    429                 std::list< TypeDecl * > baseParams = *inst->get_baseParameters();
    430                 std::list< Expression * > typeSubs = inst->get_parameters();
    431                 TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
    432                 return subs;
    433         }
    434 
    435         ReferenceToType * isStructOrUnion( Type * type ) {
    436                 if ( StructInstType * sit = dynamic_cast< StructInstType * >( type ) ) {
    437                         return sit;
    438                 } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( type ) ) {
    439                         return uit;
    440                 }
    441                 return nullptr;
    442         }
    443 
    444         void Resolver::resolveSingleAggrInit( Declaration * dcl, InitIterator & init, InitIterator & initEnd, TypeSubstitution sub ) {
    445                 DeclarationWithType * dt = dynamic_cast< DeclarationWithType * >( dcl );
    446                 assert( dt );
    447                 // need to substitute for generic types, so that casts are to concrete types
    448                 initContext = dt->get_type()->clone();
    449                 sub.apply( initContext );
    450 
    451                 try {
    452                         if ( init == initEnd ) return; // stop when there are no more initializers
    453                         (*init)->accept( *this );
    454                         ++init; // made it past an initializer
    455                 } catch( SemanticError & ) {
    456                         // need to delve deeper, if you can
    457                         if ( ReferenceToType * type = isStructOrUnion( initContext ) ) {
    458                                 resolveAggrInit( type, init, initEnd );
    459                         } else {
    460                                 // member is not an aggregate type, so can't go any deeper
    461 
    462                                 // might need to rethink what is being thrown
    463                                 throw;
    464                         } // if
    465                 }
    466         }
    467 
    468         void Resolver::resolveAggrInit( ReferenceToType * inst, InitIterator & init, InitIterator & initEnd ) {
    469                 if ( StructInstType * sit = dynamic_cast< StructInstType * >( inst ) ) {
    470                         TypeSubstitution sub = makeGenericSubstitutuion( sit );
    471                         StructDecl * st = sit->get_baseStruct();
    472                         if(st->get_members().empty()) return;
    473                         // want to resolve each initializer to the members of the struct,
    474                         // but if there are more initializers than members we should stop
    475                         list< Declaration * >::iterator it = st->get_members().begin();
    476                         for ( ; it != st->get_members().end(); ++it) {
    477                                 resolveSingleAggrInit( *it, init, initEnd, sub );
    478                         }
    479                 } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( inst ) ) {
    480                         TypeSubstitution sub = makeGenericSubstitutuion( uit );
    481                         UnionDecl * un = uit->get_baseUnion();
    482                         if(un->get_members().empty()) return;
    483                         // only resolve to the first member of a union
    484                         resolveSingleAggrInit( *un->get_members().begin(), init, initEnd, sub );
    485                 } // if
    486         }
     383                UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );
     384                Expression * newExpr = findSingleExpression( untyped, *this );
     385                InitExpr * initExpr = safe_dynamic_cast< InitExpr * >( newExpr );
     386                singleInit->set_value( new CastExpr( initExpr->get_expr()->clone(), initExpr->get_result()->clone() ) );
     387                currentObject.setNext( initExpr->get_designation() );
     388                currentObject.increment();
     389                delete initExpr;
     390
     391                // // check if initializing type is char[]
     392                // if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
     393                //      if ( isCharType( at->get_base() ) ) {
     394                //              // check if the resolved type is char *
     395                //              if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
     396                //                      if ( isCharType( pt->get_base() ) ) {
     397                //                              // strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
     398                //                              CastExpr *ce = dynamic_cast< CastExpr * >( newExpr );
     399                //                              singleInit->set_value( ce->get_arg() );
     400                //                              ce->set_arg( NULL );
     401                //                              delete ce;
     402                //                      }
     403                //              }
     404                //      }
     405                // }
     406        }
     407
     408        // template< typename AggrInst >
     409        // TypeSubstitution makeGenericSubstitution( AggrInst * inst ) {
     410        //      assert( inst );
     411        //      assert( inst->get_baseParameters() );
     412        //      std::list< TypeDecl * > baseParams = *inst->get_baseParameters();
     413        //      std::list< Expression * > typeSubs = inst->get_parameters();
     414        //      TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
     415        //      return subs;
     416        // }
     417
     418        // ReferenceToType * isStructOrUnion( Type * type ) {
     419        //      if ( StructInstType * sit = dynamic_cast< StructInstType * >( type ) ) {
     420        //              return sit;
     421        //      } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( type ) ) {
     422        //              return uit;
     423        //      }
     424        //      return nullptr;
     425        // }
     426
     427        // void Resolver::resolveSingleAggrInit( Declaration * dcl, InitIterator & init, InitIterator & initEnd, TypeSubstitution sub ) {
     428        //      ObjectDecl * obj = dynamic_cast< ObjectDecl * >( dcl );
     429        //      assert( obj );
     430        //      // need to substitute for generic types, so that casts are to concrete types
     431        //      currentObject = obj->clone();  // xxx - delete this
     432        //      sub.apply( currentObject );
     433
     434        //      try {
     435        //              if ( init == initEnd ) return; // stop when there are no more initializers
     436        //              (*init)->accept( *this );
     437        //              ++init; // made it past an initializer
     438        //      } catch( SemanticError & ) {
     439        //              // need to delve deeper, if you can
     440        //              if ( ReferenceToType * type = isStructOrUnion( currentObject->get_type() ) ) {
     441        //                      resolveAggrInit( type, init, initEnd );
     442        //              } else {
     443        //                      // member is not an aggregate type, so can't go any deeper
     444
     445        //                      // might need to rethink what is being thrown
     446        //                      throw;
     447        //              } // if
     448        //      }
     449        // }
     450
     451        // void Resolver::resolveAggrInit( ReferenceToType * inst, InitIterator & init, InitIterator & initEnd ) {
     452        //      if ( StructInstType * sit = dynamic_cast< StructInstType * >( inst ) ) {
     453        //              TypeSubstitution sub = makeGenericSubstitution( sit );
     454        //              StructDecl * st = sit->get_baseStruct();
     455        //              if(st->get_members().empty()) return;
     456        //              // want to resolve each initializer to the members of the struct,
     457        //              // but if there are more initializers than members we should stop
     458        //              list< Declaration * >::iterator it = st->get_members().begin();
     459        //              for ( ; it != st->get_members().end(); ++it) {
     460        //                      resolveSingleAggrInit( *it, init, initEnd, sub );
     461        //              }
     462        //      } else if ( UnionInstType * uit = dynamic_cast< UnionInstType * >( inst ) ) {
     463        //              TypeSubstitution sub = makeGenericSubstitution( uit );
     464        //              UnionDecl * un = uit->get_baseUnion();
     465        //              if(un->get_members().empty()) return;
     466        //              // only resolve to the first member of a union
     467        //              resolveSingleAggrInit( *un->get_members().begin(), init, initEnd, sub );
     468        //      } // if
     469        // }
    487470
    488471        void Resolver::visit( ListInit * listInit ) {
    489                 InitIterator iter = listInit->begin();
    490                 InitIterator end = listInit->end();
    491 
    492                 if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
    493                         // resolve each member to the base type of the array
    494                         for ( ; iter != end; ++iter ) {
    495                                 initContext = at->get_base();
    496                                 (*iter)->accept( *this );
    497                         } // for
    498                 } else if ( TupleType * tt = dynamic_cast< TupleType * > ( initContext ) ) {
    499                         for ( Type * t : *tt ) {
    500                                 if ( iter == end ) break;
    501                                 initContext = t;
    502                                 (*iter++)->accept( *this );
    503                         }
    504                 } else if ( ReferenceToType * type = isStructOrUnion( initContext ) ) {
    505                         resolveAggrInit( type, iter, end );
    506                 } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {
    507                         Type * base = tt->get_baseType()->get_base();
    508                         if ( base ) {
    509                                 // know the implementation type, so try using that as the initContext
    510                                 initContext = base;
    511                                 visit( listInit );
    512                         } else {
    513                                 // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context
    514                                 Parent::visit( listInit );
    515                         }
    516                 } else {
    517                         assert( dynamic_cast< BasicType * >( initContext ) || dynamic_cast< PointerType * >( initContext )
    518                                 || dynamic_cast< ZeroType * >( initContext ) || dynamic_cast< OneType * >( initContext ) || dynamic_cast < EnumInstType * > ( initContext ) );
    519                         // basic types are handled here
    520                         Parent::visit( listInit );
    521                 }
    522 
    523 #if 0
    524                 if ( ArrayType *at = dynamic_cast<ArrayType*>(initContext) ) {
    525                         std::list<Initializer *>::iterator iter( listInit->begin_initializers() );
    526                         for ( ; iter != listInit->end_initializers(); ++iter ) {
    527                                 initContext = at->get_base();
    528                                 (*iter)->accept( *this );
    529                         } // for
    530                 } else if ( StructInstType *st = dynamic_cast<StructInstType*>(initContext) ) {
    531                         StructDecl *baseStruct = st->get_baseStruct();
    532                         std::list<Declaration *>::iterator iter1( baseStruct->get_members().begin() );
    533                         std::list<Initializer *>::iterator iter2( listInit->begin_initializers() );
    534                         for ( ; iter1 != baseStruct->get_members().end() && iter2 != listInit->end_initializers(); ++iter2 ) {
    535                                 if ( (*iter2)->get_designators().empty() ) {
    536                                         DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *iter1 );
    537                                         initContext = dt->get_type();
    538                                         (*iter2)->accept( *this );
    539                                         ++iter1;
    540                                 } else {
    541                                         StructDecl *st = baseStruct;
    542                                         iter1 = st->get_members().begin();
    543                                         std::list<Expression *>::iterator iter3( (*iter2)->get_designators().begin() );
    544                                         for ( ; iter3 != (*iter2)->get_designators().end(); ++iter3 ) {
    545                                                 NameExpr *key = dynamic_cast<NameExpr *>( *iter3 );
    546                                                 assert( key );
    547                                                 for ( ; iter1 != st->get_members().end(); ++iter1 ) {
    548                                                         if ( key->get_name() == (*iter1)->get_name() ) {
    549                                                                 (*iter1)->print( cout );
    550                                                                 cout << key->get_name() << endl;
    551                                                                 ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 );
    552                                                                 assert( fred );
    553                                                                 StructInstType *mary = dynamic_cast<StructInstType*>( fred->get_type() );
    554                                                                 assert( mary );
    555                                                                 st = mary->get_baseStruct();
    556                                                                 iter1 = st->get_members().begin();
    557                                                                 break;
    558                                                         } // if
    559                                                 }  // for
    560                                         } // for
    561                                         ObjectDecl *fred = dynamic_cast<ObjectDecl *>( *iter1 );
    562                                         assert( fred );
    563                                         initContext = fred->get_type();
    564                                         (*listInit->begin_initializers())->accept( *this );
    565                                 } // if
    566                         } // for
    567                 } else if ( UnionInstType *st = dynamic_cast<UnionInstType*>(initContext) ) {
    568                         DeclarationWithType *dt = dynamic_cast<DeclarationWithType *>( *st->get_baseUnion()->get_members().begin() );
    569                         initContext = dt->get_type();
    570                         (*listInit->begin_initializers())->accept( *this );
    571                 } // if
    572 #endif
     472                currentObject.enterListInit();
     473                // xxx - fix this so that the list isn't copied, iterator should be used to change current element
     474                std::list<Designation *> newDesignations;
     475                for ( auto p : group_iterate(listInit->get_designations(), listInit->get_initializers()) ) {
     476                        Designation * des = std::get<0>(p);
     477                        Initializer * init = std::get<1>(p);
     478                        newDesignations.push_back( currentObject.findNext( des ) );
     479                        init->accept( *this );
     480                }
     481                listInit->get_designations() = newDesignations; // xxx - memory management
     482                currentObject.exitListInit();
     483
     484                // } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {
     485                //      Type * base = tt->get_baseType()->get_base();
     486                //      if ( base ) {
     487                //              // know the implementation type, so try using that as the initContext
     488                //              ObjectDecl tmpObj( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, base->clone(), nullptr );
     489                //              currentObject = &tmpObj;
     490                //              visit( listInit );
     491                //      } else {
     492                //              // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context
     493                //              Parent::visit( listInit );
     494                //      }
     495                // } else {
    573496        }
    574497
  • src/ResolvExpr/module.mk

    r2a7b3ca r579263a  
    66## file "LICENCE" distributed with Cforall.
    77##
    8 ## module.mk -- 
     8## module.mk --
    99##
    1010## Author           : Richard C. Bilson
     
    3131       ResolvExpr/PolyCost.cc \
    3232       ResolvExpr/Occurs.cc \
    33        ResolvExpr/TypeEnvironment.cc
     33       ResolvExpr/TypeEnvironment.cc \
     34       ResolvExpr/CurrentObject.cc
  • src/SymTab/Autogen.h

    r2a7b3ca r579263a  
    2525
    2626namespace SymTab {
    27     /// Generates assignment operators, constructors, and destructor for aggregate types as required
    28     void autogenerateRoutines( std::list< Declaration * > &translationUnit );
     27        /// Generates assignment operators, constructors, and destructor for aggregate types as required
     28        void autogenerateRoutines( std::list< Declaration * > &translationUnit );
    2929
    30     /// returns true if obj's name is the empty string and it has a bitfield width
    31     bool isUnnamedBitfield( ObjectDecl * obj );
     30        /// returns true if obj's name is the empty string and it has a bitfield width
     31        bool isUnnamedBitfield( ObjectDecl * obj );
    3232
    33     /// size_t type - set when size_t typedef is seen. Useful in a few places,
    34     /// such as in determining array dimension type
    35     extern Type * SizeType;
     33        /// size_t type - set when size_t typedef is seen. Useful in a few places,
     34        /// such as in determining array dimension type
     35        extern Type * SizeType;
    3636
    37     /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
    38     template< typename OutputIterator >
     37        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
     38        template< typename OutputIterator >
    3939        Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false, bool forward = true );
    4040
    41     /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
    42     /// optionally returns a statement which must be inserted prior to the containing loop, if there is one
    43     template< typename OutputIterator >
     41        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
     42        /// optionally returns a statement which must be inserted prior to the containing loop, if there is one
     43        template< typename OutputIterator >
    4444        Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) {
    4545        // want to be able to generate assignment, ctor, and dtor generically,
     
    5050        dstParam = new AddressExpr( dstParam );
    5151        if ( addCast ) {
    52             // cast to T* with qualifiers removed, so that qualified objects can be constructed
    53             // and destructed with the same functions as non-qualified objects.
    54             // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
    55             // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
    56             // remove lvalue as a qualifier, this can change to
    57             //   type->get_qualifiers() = Type::Qualifiers();
    58             assert( type );
    59             Type * castType = type->clone();
    60 //                      castType->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, false);
    61             castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
    62             castType->set_lvalue( true ); // xxx - might not need this
    63             dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
     52                // cast to T* with qualifiers removed, so that qualified objects can be constructed
     53                // and destructed with the same functions as non-qualified objects.
     54                // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
     55                // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
     56                // remove lvalue as a qualifier, this can change to
     57                //   type->get_qualifiers() = Type::Qualifiers();
     58                assert( type );
     59                Type * castType = type->clone();
     60                castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
     61                castType->set_lvalue( true ); // xxx - might not need this
     62                dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
    6463        }
    6564        fExpr->get_args().push_back( dstParam );
     
    7574
    7675        return listInit;
    77     }
    78 
    79     /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
    80     /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
    81     template< typename OutputIterator >
    82         void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {
    83         static UniqueName indexName( "_index" );
    84 
    85         // for a flexible array member nothing is done -- user must define own assignment
    86         if ( ! array->get_dimension() ) return ;
    87 
    88         Expression * begin, * end, * update, * cmp;
    89         if ( forward ) {
    90             // generate: for ( int i = 0; i < N; ++i )
    91             begin = new ConstantExpr( Constant::from_int( 0 ) );
    92             end = array->get_dimension()->clone();
    93             cmp = new NameExpr( "?<?" );
    94             update = new NameExpr( "++?" );
    95         } else {
    96             // generate: for ( int i = N-1; i >= 0; --i )
    97             begin = new UntypedExpr( new NameExpr( "?-?" ) );
    98             ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
    99             ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) );
    100             end = new ConstantExpr( Constant::from_int( 0 ) );
    101             cmp = new NameExpr( "?>=?" );
    102             update = new NameExpr( "--?" );
    10376        }
    10477
    105         ObjectDecl *index = new ObjectDecl( indexName.newName(), Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), new SingleInit( begin, std::list<Expression*>() ) );
     78        /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
     79        /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
     80        template< typename OutputIterator >
     81        void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {
     82                static UniqueName indexName( "_index" );
    10683
    107         UntypedExpr *cond = new UntypedExpr( cmp );
    108         cond->get_args().push_back( new VariableExpr( index ) );
    109         cond->get_args().push_back( end );
     84                // for a flexible array member nothing is done -- user must define own assignment
     85                if ( ! array->get_dimension() ) return ;
    11086
    111         UntypedExpr *inc = new UntypedExpr( update );
    112         inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     87                Expression * begin, * end, * update, * cmp;
     88                if ( forward ) {
     89                        // generate: for ( int i = 0; i < N; ++i )
     90                        begin = new ConstantExpr( Constant::from_int( 0 ) );
     91                        end = array->get_dimension()->clone();
     92                        cmp = new NameExpr( "?<?" );
     93                        update = new NameExpr( "++?" );
     94                } else {
     95                        // generate: for ( int i = N-1; i >= 0; --i )
     96                        begin = new UntypedExpr( new NameExpr( "?-?" ) );
     97                        ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );
     98                        ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) );
     99                        end = new ConstantExpr( Constant::from_int( 0 ) );
     100                        cmp = new NameExpr( "?>=?" );
     101                        update = new NameExpr( "--?" );
     102                }
    113103
    114         UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
    115         dstIndex->get_args().push_back( dstParam );
    116         dstIndex->get_args().push_back( new VariableExpr( index ) );
    117         dstParam = dstIndex;
     104                ObjectDecl *index = new ObjectDecl( indexName.newName(), Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), new SingleInit( begin ) );
    118105
    119         // srcParam must keep track of the array indices to build the
    120         // source parameter and/or array list initializer
    121         srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() );
     106                UntypedExpr *cond = new UntypedExpr( cmp );
     107                cond->get_args().push_back( new VariableExpr( index ) );
     108                cond->get_args().push_back( end );
    122109
    123         // for stmt's body, eventually containing call
    124         CompoundStmt * body = new CompoundStmt( noLabels );
    125         Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward );
     110                UntypedExpr *inc = new UntypedExpr( update );
     111                inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    126112
    127         // block containing for stmt and index variable
    128         std::list<Statement *> initList;
    129         CompoundStmt * block = new CompoundStmt( noLabels );
    130         block->get_kids().push_back( new DeclStmt( noLabels, index ) );
    131         if ( listInit ) block->get_kids().push_back( listInit );
    132         block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
     113                UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
     114                dstIndex->get_args().push_back( dstParam );
     115                dstIndex->get_args().push_back( new VariableExpr( index ) );
     116                dstParam = dstIndex;
    133117
    134         *out++ = block;
    135     }
     118                // srcParam must keep track of the array indices to build the
     119                // source parameter and/or array list initializer
     120                srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() );
    136121
    137     template< typename OutputIterator >
     122                // for stmt's body, eventually containing call
     123                CompoundStmt * body = new CompoundStmt( noLabels );
     124                Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward );
     125
     126                // block containing for stmt and index variable
     127                std::list<Statement *> initList;
     128                CompoundStmt * block = new CompoundStmt( noLabels );
     129                block->get_kids().push_back( new DeclStmt( noLabels, index ) );
     130                if ( listInit ) block->get_kids().push_back( listInit );
     131                block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) );
     132
     133                *out++ = block;
     134        }
     135
     136        template< typename OutputIterator >
    138137        Statement * genCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) {
    139         if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    140             genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
    141             return 0;
    142         } else {
    143             return genScalarCall( srcParam, dstParam, fname, out, type, addCast );
     138                if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
     139                        genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
     140                        return 0;
     141                } else {
     142                        return genScalarCall( srcParam, dstParam, fname, out, type, addCast );
     143                }
    144144        }
    145     }
    146145
    147     /// inserts into out a generated call expression to function fname with arguments dstParam
    148     /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
    149     /// object being constructed. The function wraps constructor and destructor calls in an
    150     /// ImplicitCtorDtorStmt node.
    151     template< typename OutputIterator >
     146        /// inserts into out a generated call expression to function fname with arguments dstParam
     147        /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
     148        /// object being constructed. The function wraps constructor and destructor calls in an
     149        /// ImplicitCtorDtorStmt node.
     150        template< typename OutputIterator >
    152151        void genImplicitCall( InitTweak::InitExpander &  srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
    153         ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
    154         assert( obj );
    155         // unnamed bit fields are not copied as they cannot be accessed
    156         if ( isUnnamedBitfield( obj ) ) return;
     152                ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
     153                assert( obj );
     154                // unnamed bit fields are not copied as they cannot be accessed
     155                if ( isUnnamedBitfield( obj ) ) return;
    157156
    158         bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) );
    159         std::list< Statement * > stmts;
    160         genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward );
     157                bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) );
     158                std::list< Statement * > stmts;
     159                genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward );
    161160
    162         // currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call
    163         assert( stmts.size() <= 1 );
    164         if ( stmts.size() == 1 ) {
    165             Statement * callStmt = stmts.front();
    166             if ( addCast ) {
    167                 // implicitly generated ctor/dtor calls should be wrapped
    168                 // so that later passes are aware they were generated.
    169                 // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
    170                 // because this causes the address to be taken at codegen, which is illegal in C.
    171                 callStmt = new ImplicitCtorDtorStmt( callStmt );
    172             }
    173             *out++ = callStmt;
     161                // currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call
     162                assert( stmts.size() <= 1 );
     163                if ( stmts.size() == 1 ) {
     164                        Statement * callStmt = stmts.front();
     165                        if ( addCast ) {
     166                                // implicitly generated ctor/dtor calls should be wrapped
     167                                // so that later passes are aware they were generated.
     168                                // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
     169                                // because this causes the address to be taken at codegen, which is illegal in C.
     170                                callStmt = new ImplicitCtorDtorStmt( callStmt );
     171                        }
     172                        *out++ = callStmt;
     173                }
    174174        }
    175     }
    176175} // namespace SymTab
    177176#endif // AUTOGEN_H
  • src/SynTree/Expression.cc

    r2a7b3ca r579263a  
    9292
    9393        Declaration *decl = get_var();
    94         // if ( decl != 0) decl->print(os, indent + 2);
    9594        if ( decl != 0) decl->printShort(os, indent + 2);
    9695        os << std::endl;
     
    657656}
    658657
     658InitAlternative::InitAlternative( Type * type, Designation * designation ) : type( type ), designation( designation ) {}
     659InitAlternative::InitAlternative( const InitAlternative & other ) : type( maybeClone( other.type ) ), designation( maybeClone( other.designation ) ) {}
     660InitAlternative::~InitAlternative() {
     661        delete type;
     662        delete designation;
     663}
     664
     665UntypedInitExpr::UntypedInitExpr( Expression * expr, const std::list<InitAlternative> & initAlts ) : expr( expr ), initAlts( initAlts ) {}
     666UntypedInitExpr::UntypedInitExpr( const UntypedInitExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ), initAlts( other.initAlts ) {}
     667UntypedInitExpr::~UntypedInitExpr() {
     668        delete expr;
     669}
     670
     671void UntypedInitExpr::print( std::ostream & os, int indent ) const {
     672        os << "Untyped Init Expression" << std::endl << std::string( indent+2, ' ' );
     673        expr->print( os, indent+2 );
     674        if ( ! initAlts.empty() ) {
     675                for ( const InitAlternative & alt : initAlts ) {
     676                        os << std::string( indent+2, ' ' ) <<  "InitAlternative: ";
     677                        alt.type->print( os, indent+2 );
     678                        alt.designation->print( os, indent+2 );
     679                }
     680        }
     681}
     682
     683InitExpr::InitExpr( Expression * expr, Type * type, Designation * designation ) : expr( expr ), designation( designation ) {
     684        set_result( type );
     685}
     686InitExpr::InitExpr( const InitExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ), designation( maybeClone( other.designation) ) {}
     687InitExpr::~InitExpr() {
     688        delete expr;
     689        delete designation;
     690}
     691
     692void InitExpr::print( std::ostream & os, int indent ) const {
     693        os << "Init Expression" << std::endl << std::string( indent+2, ' ' );
     694        expr->print( os, indent+2 );
     695        os << std::string( indent+2, ' ' ) << "with designation: ";
     696        designation->print( os, indent+2 );
     697}
     698
     699
    659700std::ostream & operator<<( std::ostream & out, const Expression * expr ) {
    660701        if ( expr ) {
  • src/SynTree/Expression.h

    r2a7b3ca r579263a  
    744744};
    745745
     746struct InitAlternative {
     747public:
     748        Type * type = nullptr;
     749        Designation * designation = nullptr;
     750        InitAlternative( Type * type, Designation * designation );
     751        InitAlternative( const InitAlternative & other );
     752        InitAlternative & operator=( const Initializer & other ) = delete; // at the moment this isn't used, and I don't want to implement it
     753        ~InitAlternative();
     754};
     755
     756class UntypedInitExpr : public Expression {
     757public:
     758        UntypedInitExpr( Expression * expr, const std::list<InitAlternative> & initAlts );
     759        UntypedInitExpr( const UntypedInitExpr & other );
     760        ~UntypedInitExpr();
     761
     762        Expression * get_expr() const { return expr; }
     763        UntypedInitExpr * set_expr( Expression * newValue ) { expr = newValue; return this; }
     764
     765        std::list<InitAlternative> & get_initAlts() { return initAlts; }
     766
     767        virtual UntypedInitExpr * clone() const { return new UntypedInitExpr( * this ); }
     768        virtual void accept( Visitor & v ) { v.visit( this ); }
     769        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     770        virtual void print( std::ostream & os, int indent = 0 ) const;
     771private:
     772        Expression * expr;
     773        std::list<InitAlternative> initAlts;
     774};
     775
     776class InitExpr : public Expression {
     777public:
     778        InitExpr( Expression * expr, Type * type, Designation * designation );
     779        InitExpr( const InitExpr & other );
     780        ~InitExpr();
     781
     782        Expression * get_expr() const { return expr; }
     783        InitExpr * set_expr( Expression * newValue ) { expr = newValue; return this; }
     784
     785        Designation * get_designation() const { return designation; }
     786        InitExpr * set_designation( Designation * newValue ) { designation = newValue; return this; }
     787
     788        virtual InitExpr * clone() const { return new InitExpr( * this ); }
     789        virtual void accept( Visitor & v ) { v.visit( this ); }
     790        virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
     791        virtual void print( std::ostream & os, int indent = 0 ) const;
     792private:
     793        Expression * expr;
     794        Designation * designation;
     795};
     796
     797
    746798std::ostream & operator<<( std::ostream & out, const Expression * expr );
    747799
  • src/SynTree/Initializer.cc

    r2a7b3ca r579263a  
    1919#include "Common/utility.h"
    2020
     21Designation::Designation( const std::list< Expression * > & designators ) : designators( designators ) {}
     22Designation::Designation( const Designation & other ) : BaseSyntaxNode( other ) {
     23        // std::cerr << "cloning designation" << std::endl;
     24        cloneAll( other.designators, designators );
     25        // std::cerr << "finished cloning designation" << std::endl;
     26}
     27
     28Designation::~Designation() {
     29        // std::cerr << "destroying designation" << std::endl;
     30        deleteAll( designators );
     31        // std::cerr << "finished destroying designation" << std::endl;
     32}
     33
     34void Designation::print( std::ostream &os, int indent ) const {
     35        if ( ! designators.empty() ) {
     36                os << std::string(indent + 2, ' ' ) << "designated by: " << std::endl;
     37                for ( std::list < Expression * >::const_iterator i = designators.begin(); i != designators.end(); i++ ) {
     38                        os << std::string(indent + 4, ' ' );
     39                        ( *i )->print(os, indent + 4 );
     40                }
     41                os << std::endl;
     42        } // if
     43}
     44
    2145Initializer::Initializer( bool maybeConstructed ) : maybeConstructed( maybeConstructed ) {}
    2246Initializer::Initializer( const Initializer & other ) : BaseSyntaxNode( other ), maybeConstructed( other.maybeConstructed ) {
    2347}
    24 
    25 
    2648Initializer::~Initializer() {}
    2749
    28 std::string Initializer::designator_name( Expression *des ) {
    29         if ( NameExpr *n = dynamic_cast<NameExpr *>(des) )
    30                 return n->get_name();
    31         else
    32                 throw 0;
    33 }
    34 
    35 // void Initializer::print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent ) {}
    36 
    37 SingleInit::SingleInit( Expression *v, const std::list< Expression *> &_designators, bool maybeConstructed ) : Initializer( maybeConstructed ), value ( v ), designators( _designators ) {
     50SingleInit::SingleInit( Expression *v, bool maybeConstructed ) : Initializer( maybeConstructed ), value ( v ) {
    3851}
    3952
    4053SingleInit::SingleInit( const SingleInit &other ) : Initializer(other), value ( maybeClone( other.value ) ) {
    41         cloneAll(other.designators, designators );
    4254}
    4355
    4456SingleInit::~SingleInit() {
    4557        delete value;
    46         deleteAll(designators);
    4758}
    4859
    49 void SingleInit::print( std::ostream &os, int indent ) {
    50         os << std::endl << std::string(indent, ' ' ) << "Simple Initializer: " << std::endl;
     60void SingleInit::print( std::ostream &os, int indent ) const {
     61        os << std::string(indent, ' ' ) << "Simple Initializer: " << std::endl;
    5162        os << std::string(indent+4, ' ' );
    5263        value->print( os, indent+4 );
    53 
    54         if ( ! designators.empty() ) {
    55                 os << std::endl << std::string(indent + 2, ' ' ) << "designated by: " << std::endl;
    56                 for ( std::list < Expression * >::iterator i = designators.begin(); i != designators.end(); i++ ) {
    57                         os << std::string(indent + 4, ' ' );
    58                         ( *i )->print(os, indent + 4 );
    59                 }
    60         } // if
    6164}
    6265
    63 ListInit::ListInit( const std::list<Initializer*> &_initializers, const std::list<Expression *> &_designators, bool maybeConstructed )
    64         : Initializer( maybeConstructed ), initializers( _initializers ), designators( _designators ) {
     66
     67ListInit::ListInit( const std::list<Initializer*> &initializers, const std::list<Designation *> &designations, bool maybeConstructed )
     68        : Initializer( maybeConstructed ), initializers( initializers ), designations( designations ) {
    6569}
    6670
    6771ListInit::ListInit( const ListInit & other ) : Initializer( other ) {
    6872        cloneAll( other.initializers, initializers );
    69         cloneAll( other.designators, designators );
     73        cloneAll( other.designations, designations );
    7074}
    71 
    7275
    7376ListInit::~ListInit() {
    7477        deleteAll( initializers );
    75         deleteAll( designators );
     78        deleteAll( designations );
    7679}
    7780
    78 void ListInit::print( std::ostream &os, int indent ) {
    79         os << std::endl << std::string(indent, ' ') << "Compound initializer:  ";
    80         if ( ! designators.empty() ) {
    81                 os << std::string(indent + 2, ' ' ) << "designated by: [";
    82                 for ( std::list < Expression * >::iterator i = designators.begin();
    83                           i != designators.end(); i++ ) {
    84                         ( *i )->print(os, indent + 4 );
    85                 } // for
     81void ListInit::print( std::ostream &os, int indent ) const {
     82        os << std::string(indent, ' ') << "Compound initializer:  " << std::endl;
     83        for ( Designation * d : designations ) {
     84                d->print( os, indent + 2 );
     85        }
    8686
    87                 os << std::string(indent + 2, ' ' ) << "]";
    88         } // if
    89 
    90         for ( std::list<Initializer *>::iterator i = initializers.begin(); i != initializers.end(); i++ )
    91                 (*i)->print( os, indent + 2 );
     87        for ( const Initializer * init : initializers ) {
     88                init->print( os, indent + 2 );
     89                os << std::endl;
     90        }
    9291}
    9392
     
    103102}
    104103
    105 void ConstructorInit::print( std::ostream &os, int indent ) {
     104void ConstructorInit::print( std::ostream &os, int indent ) const {
    106105        os << std::endl << std::string(indent, ' ') << "Constructor initializer: " << std::endl;
    107106        if ( ctor ) {
     
    124123}
    125124
    126 std::ostream & operator<<( std::ostream & out, Initializer * init ) {
    127         init->print( out );
     125std::ostream & operator<<( std::ostream & out, const Initializer * init ) {
     126        if ( init ) {
     127                init->print( out );
     128        } else {
     129                out << "nullptr";
     130        }
     131        return out;
     132}
     133
     134std::ostream & operator<<( std::ostream & out, const Designation * des ) {
     135        if ( des ) {
     136                des->print( out );
     137        } else {
     138                out << "nullptr";
     139        }
    128140        return out;
    129141}
  • src/SynTree/Initializer.h

    r2a7b3ca r579263a  
    2525#include "Visitor.h"
    2626
    27 const std::list<Expression*> noDesignators;
     27// Designation: list of designator (NameExpr, VariableExpr, and ConstantExpr) expressions that specify an object being initialized.
     28class Designation : public BaseSyntaxNode {
     29public:
     30        Designation( const std::list< Expression * > & designators );
     31        Designation( const Designation & other );
     32        virtual ~Designation();
     33
     34        std::list< Expression * > & get_designators() { return designators; }
     35
     36        virtual Designation * clone() const { return new Designation( *this ); };
     37        virtual void accept( Visitor &v ) { v.visit( this ); }
     38        virtual Designation * acceptMutator( Mutator &m ) { return m.mutate( this ); }
     39        virtual void print( std::ostream &os, int indent = 0 ) const;
     40private:
     41        std::list< Expression * > designators;
     42};
     43
     44const std::list<Designation *> noDesignators;
    2845
    2946// Initializer: base class for object initializers (provide default values)
    3047class Initializer : public BaseSyntaxNode {
    3148  public:
    32         //      Initializer( std::string _name = std::string(""), int _pos = 0 );
    3349        Initializer( bool maybeConstructed );
    3450        Initializer( const Initializer & other );
    3551        virtual ~Initializer();
    36 
    37         static std::string designator_name( Expression *designator );
    38 
    39         //      void set_name( std::string newValue ) { name = newValue; }
    40         //      std::string get_name() const { return name; }
    41 
    42         //      void set_pos( int newValue ) { pos = newValue; }
    43         //      int get_pos() const { return pos; }
    44         virtual void set_designators( std::list<Expression *> & ) { assert(false); }
    45         virtual std::list<Expression *> &get_designators() {
    46                 assert(false);
    47                 std::list<Expression *> *ret = 0; return *ret;  // never reached
    48         }
    4952
    5053        bool get_maybeConstructed() { return maybeConstructed; }
     
    5356        virtual void accept( Visitor &v ) = 0;
    5457        virtual Initializer *acceptMutator( Mutator &m ) = 0;
    55         virtual void print( std::ostream &os, int indent = 0 ) = 0;
     58        virtual void print( std::ostream &os, int indent = 0 ) const = 0;
    5659  private:
    57         //      std::string name;
    58         //      int pos;
    5960        bool maybeConstructed;
    6061};
     
    6364class SingleInit : public Initializer {
    6465  public:
    65         SingleInit( Expression *value, const std::list< Expression *> &designators = std::list< Expression * >(), bool maybeConstructed = false );
     66        SingleInit( Expression *value, bool maybeConstructed = false );
    6667        SingleInit( const SingleInit &other );
    6768        virtual ~SingleInit();
     
    7071        void set_value( Expression *newValue ) { value = newValue; }
    7172
    72         std::list<Expression *> &get_designators() { return designators; }
    73         void set_designators( std::list<Expression *> &newValue ) { designators = newValue; }
    74 
    7573        virtual SingleInit *clone() const { return new SingleInit( *this); }
    7674        virtual void accept( Visitor &v ) { v.visit( this ); }
    7775        virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    78         virtual void print( std::ostream &os, int indent = 0 );
     76        virtual void print( std::ostream &os, int indent = 0 ) const;
    7977  private:
    8078        //Constant *value;
    8179        Expression *value;      // has to be a compile-time constant
    82         std::list< Expression * > designators;
    8380};
    8481
     
    8885  public:
    8986        ListInit( const std::list<Initializer*> &initializers,
    90                           const std::list<Expression *> &designators = std::list< Expression * >(), bool maybeConstructed = false );
     87                          const std::list<Designation *> &designators = {}, bool maybeConstructed = false );
    9188        ListInit( const ListInit & other );
    9289        virtual ~ListInit();
    9390
    94         void set_designators( std::list<Expression *> &newValue ) { designators = newValue; }
    95         std::list<Expression *> &get_designators() { return designators; }
    96         void set_initializers( std::list<Initializer*> &newValue ) { initializers = newValue; }
    97         std::list<Initializer*> &get_initializers() { return initializers; }
     91        std::list<Designation *> & get_designations() { return designations; }
     92        std::list<Initializer *> & get_initializers() { return initializers; }
    9893
    9994        typedef std::list<Initializer*>::iterator iterator;
     95        typedef std::list<Initializer*>::const_iterator const_iterator;
    10096        iterator begin() { return initializers.begin(); }
    10197        iterator end() { return initializers.end(); }
     98        const_iterator begin() const { return initializers.begin(); }
     99        const_iterator end() const { return initializers.end(); }
    102100
    103101        virtual ListInit *clone() const { return new ListInit( *this ); }
    104102        virtual void accept( Visitor &v ) { v.visit( this ); }
    105103        virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    106         virtual void print( std::ostream &os, int indent = 0 );
     104        virtual void print( std::ostream &os, int indent = 0 ) const;
    107105  private:
    108         std::list<Initializer*> initializers;  // order *is* important
    109         std::list<Expression *> designators;
     106        std::list<Initializer *> initializers;  // order *is* important
     107        std::list<Designation *> designations;  // order/length is consistent with initializers
    110108};
    111109
     
    130128        virtual void accept( Visitor &v ) { v.visit( this ); }
    131129        virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
    132         virtual void print( std::ostream &os, int indent = 0 );
     130        virtual void print( std::ostream &os, int indent = 0 ) const;
    133131
    134132  private:
     
    140138};
    141139
    142 std::ostream & operator<<( std::ostream & out, Initializer * init );
     140std::ostream & operator<<( std::ostream & out, const Initializer * init );
     141std::ostream & operator<<( std::ostream & out, const Designation * des );
    143142
    144143#endif // INITIALIZER_H
  • src/SynTree/Mutator.cc

    r2a7b3ca r579263a  
    433433}
    434434
     435Expression *Mutator::mutate( UntypedInitExpr * initExpr ) {
     436        initExpr->set_env( maybeMutate( initExpr->get_env(), *this ) );
     437        initExpr->set_result( maybeMutate( initExpr->get_result(), *this ) );
     438        initExpr->set_expr( maybeMutate( initExpr->get_expr(), *this ) );
     439        // not currently mutating initAlts, but this doesn't matter since this node is only used in the resolver.
     440        return initExpr;
     441}
     442
     443Expression *Mutator::mutate( InitExpr * initExpr ) {
     444        initExpr->set_env( maybeMutate( initExpr->get_env(), *this ) );
     445        initExpr->set_result( maybeMutate( initExpr->get_result(), *this ) );
     446        initExpr->set_expr( maybeMutate( initExpr->get_expr(), *this ) );
     447        initExpr->set_designation( maybeMutate( initExpr->get_designation(), *this ) );
     448        return initExpr;
     449}
     450
    435451
    436452Type *Mutator::mutate( VoidType *voidType ) {
     
    535551
    536552
     553Designation *Mutator::mutate( Designation * designation ) {
     554        mutateAll( designation->get_designators(), *this );
     555        return designation;
     556}
     557
    537558Initializer *Mutator::mutate( SingleInit *singleInit ) {
    538559        singleInit->set_value( singleInit->get_value()->acceptMutator( *this ) );
     
    541562
    542563Initializer *Mutator::mutate( ListInit *listInit ) {
    543         mutateAll( listInit->get_designators(), *this );
     564        mutateAll( listInit->get_designations(), *this );
    544565        mutateAll( listInit->get_initializers(), *this );
    545566        return listInit;
  • src/SynTree/Mutator.h

    r2a7b3ca r579263a  
    8585        virtual Expression* mutate( StmtExpr * stmtExpr );
    8686        virtual Expression* mutate( UniqueExpr * uniqueExpr );
     87        virtual Expression* mutate( UntypedInitExpr * initExpr );
     88        virtual Expression* mutate( InitExpr * initExpr );
    8789
    8890        virtual Type* mutate( VoidType *basicType );
     
    103105        virtual Type* mutate( OneType *oneType );
    104106
     107        virtual Designation* mutate( Designation *designation );
    105108        virtual Initializer* mutate( SingleInit *singleInit );
    106109        virtual Initializer* mutate( ListInit *listInit );
  • src/SynTree/SynTree.h

    r2a7b3ca r579263a  
    9393class StmtExpr;
    9494class UniqueExpr;
     95class UntypedInitExpr;
     96class InitExpr;
    9597
    9698class Type;
     
    113115class OneType;
    114116
     117class Designation;
    115118class Initializer;
    116119class SingleInit;
  • src/SynTree/Visitor.cc

    r2a7b3ca r579263a  
    340340}
    341341
     342void Visitor::visit( UntypedInitExpr * initExpr ) {
     343        maybeAccept( initExpr->get_result(), *this );
     344        maybeAccept( initExpr->get_expr(), *this );
     345        // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
     346}
     347
     348void Visitor::visit( InitExpr * initExpr ) {
     349        maybeAccept( initExpr->get_result(), *this );
     350        maybeAccept( initExpr->get_expr(), *this );
     351        maybeAccept( initExpr->get_designation(), *this );
     352}
     353
    342354
    343355void Visitor::visit( VoidType *voidType ) {
     
    424436}
    425437
     438void Visitor::visit( Designation * designation ) {
     439        acceptAll( designation->get_designators(), *this );
     440}
    426441
    427442void Visitor::visit( SingleInit *singleInit ) {
     
    430445
    431446void Visitor::visit( ListInit *listInit ) {
    432         acceptAll( listInit->get_designators(), *this );
     447        acceptAll( listInit->get_designations(), *this );
    433448        acceptAll( listInit->get_initializers(), *this );
    434449}
  • src/SynTree/Visitor.h

    r2a7b3ca r579263a  
    8888        virtual void visit( StmtExpr * stmtExpr );
    8989        virtual void visit( UniqueExpr * uniqueExpr );
     90        virtual void visit( UntypedInitExpr * initExpr );
     91        virtual void visit( InitExpr * initExpr );
    9092
    9193        virtual void visit( VoidType *basicType );
     
    106108        virtual void visit( OneType *oneType );
    107109
     110        virtual void visit( Designation *designation );
    108111        virtual void visit( SingleInit *singleInit );
    109112        virtual void visit( ListInit *listInit );
  • src/Tuples/TupleExpansion.cc

    r2a7b3ca r579263a  
    192192                        }
    193193                        ObjectDecl * finished = new ObjectDecl( toString( "_unq", id, "_finished_" ), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new BasicType( Type::Qualifiers(), BasicType::Bool ),
    194                                                                                                         new SingleInit( new ConstantExpr( Constant::from_int( 0 ) ), noDesignators ) );
     194                                                                                                        new SingleInit( new ConstantExpr( Constant::from_int( 0 ) ) ) );
    195195                        addDeclaration( finished );
    196196                        // (finished ? _unq_expr_N : (_unq_expr_N = <unqExpr->get_expr()>, finished = 1, _unq_expr_N))
Note: See TracChangeset for help on using the changeset viewer.