Changeset 67fa9f9 for src/ResolvExpr


Ignore:
Timestamp:
Jul 5, 2017, 10:50:22 AM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
0614d14
Parents:
11dbfe1 (diff), 307a732 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/ResolvExpr
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r11dbfe1 r67fa9f9  
    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;
     
    809809        }
    810810
     811        Expression * restructureCast( Expression * argExpr, Type * toType ) {
     812                if ( argExpr->get_result()->size() > 1 && ! toType->isVoid() ) {
     813                        // Argument expression is a tuple and the target type is not void. Cast each member of the tuple
     814                        // to its corresponding target type, producing the tuple of those cast expressions. If there are
     815                        // more components of the tuple than components in the target type, then excess components do not
     816                        // come out in the result expression (but UniqueExprs ensure that side effects will still be done).
     817                        if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) {
     818                                // expressions which may contain side effects require a single unique instance of the expression.
     819                                argExpr = new UniqueExpr( argExpr );
     820                        }
     821                        std::list< Expression * > componentExprs;
     822                        for ( unsigned int i = 0; i < toType->size(); i++ ) {
     823                                // cast each component
     824                                TupleIndexExpr * idx = new TupleIndexExpr( argExpr->clone(), i );
     825                                componentExprs.push_back( restructureCast( idx, toType->getComponent( i ) ) );
     826                        }
     827                        delete argExpr;
     828                        assert( componentExprs.size() > 0 );
     829                        // produce the tuple of casts
     830                        return new TupleExpr( componentExprs );
     831                } else {
     832                        // handle normally
     833                        return new CastExpr( argExpr, toType->clone() );
     834                }
     835        }
     836
    811837        void AlternativeFinder::visit( CastExpr *castExpr ) {
    812838                Type *& toType = castExpr->get_result();
     
    840866                                thisCost += Cost( 0, 0, discardedValues );
    841867
    842                                 Expression * argExpr = i->expr->clone();
    843                                 if ( argExpr->get_result()->size() > 1 && ! castExpr->get_result()->isVoid() ) {
    844                                         // Argument expression is a tuple and the target type is not void. Cast each member of the tuple
    845                                         // to its corresponding target type, producing the tuple of those cast expressions. If there are
    846                                         // more components of the tuple than components in the target type, then excess components do not
    847                                         // come out in the result expression (but UniqueExprs ensure that side effects will still be done).
    848                                         if ( Tuples::maybeImpure( argExpr ) && ! dynamic_cast< UniqueExpr * >( argExpr ) ) {
    849                                                 // expressions which may contain side effects require a single unique instance of the expression.
    850                                                 argExpr = new UniqueExpr( argExpr );
    851                                         }
    852                                         std::list< Expression * > componentExprs;
    853                                         for ( unsigned int i = 0; i < castExpr->get_result()->size(); i++ ) {
    854                                                 // cast each component
    855                                                 TupleIndexExpr * idx = new TupleIndexExpr( argExpr->clone(), i );
    856                                                 componentExprs.push_back( new CastExpr( idx, castExpr->get_result()->getComponent( i )->clone() ) );
    857                                         }
    858                                         delete argExpr;
    859                                         assert( componentExprs.size() > 0 );
    860                                         // produce the tuple of casts
    861                                         candidates.push_back( Alternative( new TupleExpr( componentExprs ), i->env, i->cost, thisCost ) );
    862                                 } else {
    863                                         // handle normally
    864                                         candidates.push_back( Alternative( new CastExpr( argExpr->clone(), toType->clone() ), i->env, i->cost, thisCost ) );
    865                                 }
     868                                candidates.push_back( Alternative( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ) );
    866869                        } // if
    867870                } // for
     
    11821185        }
    11831186
     1187        void AlternativeFinder::visit( UntypedInitExpr *initExpr ) {
     1188                // handle each option like a cast
     1189                AltList candidates;
     1190                PRINT( std::cerr << "untyped init expr: " << initExpr << std::endl; )
     1191                // O(N^2) checks of d-types with e-types
     1192                for ( InitAlternative & initAlt : initExpr->get_initAlts() ) {
     1193                        Type * toType = resolveTypeof( initAlt.type, indexer );
     1194                        SymTab::validateType( toType, &indexer );
     1195                        adjustExprType( toType, env, indexer );
     1196                        // Ideally the call to findWithAdjustment could be moved out of the loop, but unfortunately it currently has to occur inside or else
     1197                        // polymorphic return types are not properly bound to the initialization type, since return type variables are only open for the duration of resolving
     1198                        // the UntypedExpr. This is only actually an issue in initialization contexts that allow more than one possible initialization type, but it is still suboptimal.
     1199                        AlternativeFinder finder( indexer, env );
     1200                        finder.targetType = toType;
     1201                        finder.findWithAdjustment( initExpr->get_expr() );
     1202                        for ( Alternative & alt : finder.get_alternatives() ) {
     1203                                TypeEnvironment newEnv( alt.env );
     1204                                AssertionSet needAssertions, haveAssertions;
     1205                                OpenVarSet openVars;  // find things in env that don't have a "representative type" and claim those are open vars?
     1206                                PRINT( std::cerr << "  @ " << toType << " " << initAlt.designation << std::endl; )
     1207                                // It's possible that a cast can throw away some values in a multiply-valued expression.  (An example is a
     1208                                // cast-to-void, which casts from one value to zero.)  Figure out the prefix of the subexpression results
     1209                                // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
     1210                                // to.
     1211                                int discardedValues = alt.expr->get_result()->size() - toType->size();
     1212                                if ( discardedValues < 0 ) continue;
     1213                                // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not
     1214                                // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3]))
     1215                                // unification run for side-effects
     1216                                unify( toType, alt.expr->get_result(), newEnv, needAssertions, haveAssertions, openVars, indexer ); // xxx - do some inspecting on this line... why isn't result bound to initAlt.type??
     1217
     1218                                Cost thisCost = castCost( alt.expr->get_result(), toType, indexer, newEnv );
     1219                                if ( thisCost != Cost::infinity ) {
     1220                                        // count one safe conversion for each value that is thrown away
     1221                                        thisCost += Cost( 0, 0, discardedValues );
     1222                                        candidates.push_back( Alternative( new InitExpr( restructureCast( alt.expr->clone(), toType ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ) );
     1223                                }
     1224                        }
     1225                }
     1226
     1227                // findMinCost selects the alternatives with the lowest "cost" members, but has the side effect of copying the
     1228                // cvtCost member to the cost member (since the old cost is now irrelevant).  Thus, calling findMinCost twice
     1229                // selects first based on argument cost, then on conversion cost.
     1230                AltList minArgCost;
     1231                findMinCost( candidates.begin(), candidates.end(), std::back_inserter( minArgCost ) );
     1232                findMinCost( minArgCost.begin(), minArgCost.end(), std::back_inserter( alternatives ) );
     1233        }
    11841234} // namespace ResolvExpr
    11851235
  • src/ResolvExpr/AlternativeFinder.h

    r11dbfe1 r67fa9f9  
    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

    r11dbfe1 r67fa9f9  
    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                        }
     
    6470                virtual void visit( BranchStmt *branchStmt ) override;
    6571                virtual void visit( ReturnStmt *returnStmt ) override;
     72                virtual void visit( ThrowStmt *throwStmt ) override;
    6673
    6774                virtual void visit( SingleInit *singleInit ) override;
     
    7986
    8087                Type * functionReturn = nullptr;
    81                 Type *initContext = nullptr;
     88                CurrentObject currentObject = nullptr;
    8289                bool inEnumDecl = false;
    8390        };
     
    186193                // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting
    187194                // the RHS.
    188                 Type *temp = initContext;
    189                 initContext = new_type;
    190                 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
     195                ValueGuard<CurrentObject> temp( currentObject );
     196                currentObject = CurrentObject( objectDecl->get_type() );
     197                if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
    191198                        // enumerator initializers should not use the enum type to initialize, since
    192199                        // the enum type is still incomplete at this point. Use signed int instead.
    193                         initContext = new BasicType( Type::Qualifiers(), BasicType::SignedInt );
     200                        currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
    194201                }
    195202                Parent::visit( objectDecl );
    196                 if ( inEnumDecl && dynamic_cast< EnumInstType * >( initContext ) ) {
     203                if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
    197204                        // delete newly created signed int type
    198                         delete initContext;
    199                 }
    200                 initContext = temp;
     205                        // delete currentObject.getType();
     206                }
    201207        }
    202208
     
    315321
    316322        void Resolver::visit( SwitchStmt *switchStmt ) {
    317                 ValueGuard< Type * > oldInitContext( initContext );
     323                ValueGuard< CurrentObject > oldCurrentObject( currentObject );
    318324                Expression *newExpr;
    319325                newExpr = findIntegralExpression( switchStmt->get_condition(), *this );
     
    321327                switchStmt->set_condition( newExpr );
    322328
    323                 initContext = newExpr->get_result();
     329                currentObject = CurrentObject( newExpr->get_result() );
    324330                Parent::visit( switchStmt );
    325331        }
     
    327333        void Resolver::visit( CaseStmt *caseStmt ) {
    328334                if ( caseStmt->get_condition() ) {
    329                         assert( initContext );
    330                         CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initContext->clone() );
     335                        std::list< InitAlternative > initAlts = currentObject.getOptions();
     336                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral expression." );
     337                        CastExpr * castExpr = new CastExpr( caseStmt->get_condition(), initAlts.front().type->clone() );
    331338                        Expression * newExpr = findSingleExpression( castExpr, *this );
    332339                        castExpr = safe_dynamic_cast< CastExpr * >( newExpr );
     
    360367        }
    361368
     369        void Resolver::visit( ThrowStmt *throwStmt ) {
     370                if ( throwStmt->get_expr() ) {
     371                        Expression * wrapped = new CastExpr( throwStmt->get_expr(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
     372                        Expression * newExpr = findSingleExpression( wrapped, *this );
     373                        throwStmt->set_expr( newExpr );
     374                }
     375        }
     376
    362377        template< typename T >
    363378        bool isCharType( T t ) {
     
    370385
    371386        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                                                 }
     387                // resolve initialization using the possibilities as determined by the currentObject cursor
     388                UntypedInitExpr * untyped = new UntypedInitExpr( singleInit->get_value(), currentObject.getOptions() );
     389                Expression * newExpr = findSingleExpression( untyped, *this );
     390                InitExpr * initExpr = safe_dynamic_cast< InitExpr * >( newExpr );
     391
     392                // move cursor to the object that is actually initialized
     393                currentObject.setNext( initExpr->get_designation() );
     394
     395                // discard InitExpr wrapper and retain relevant pieces
     396                newExpr = initExpr->get_expr();
     397                newExpr->set_env( initExpr->get_env() );
     398                initExpr->set_expr( nullptr );
     399                initExpr->set_env( nullptr );
     400                delete initExpr;
     401
     402                // get the actual object's type (may not exactly match what comes back from the resolver due to conversions)
     403                Type * initContext = currentObject.getCurrentType();
     404
     405                // check if actual object's type is char[]
     406                if ( ArrayType * at = dynamic_cast< ArrayType * >( initContext ) ) {
     407                        if ( isCharType( at->get_base() ) ) {
     408                                // check if the resolved type is char *
     409                                if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
     410                                        if ( isCharType( pt->get_base() ) ) {
     411                                                // strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
     412                                                CastExpr *ce = safe_dynamic_cast< CastExpr * >( newExpr );
     413                                                newExpr = ce->get_arg();
     414                                                ce->set_arg( nullptr );
     415                                                delete ce;
    419416                                        }
    420417                                }
    421418                        }
    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
     419                }
     420
     421                // set initializer expr to resolved express
     422                singleInit->set_value( newExpr );
     423
     424                // move cursor to next object in preparation for next initializer
     425                currentObject.increment();
    486426        }
    487427
    488428        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
     429                // move cursor into brace-enclosed initializer-list
     430                currentObject.enterListInit();
     431                // xxx - fix this so that the list isn't copied, iterator should be used to change current element
     432                std::list<Designation *> newDesignations;
     433                for ( auto p : group_iterate(listInit->get_designations(), listInit->get_initializers()) ) {
     434                        // iterate designations and initializers in pairs, moving the cursor to the current designated object and resolving
     435                        // the initializer against that object.
     436                        Designation * des = std::get<0>(p);
     437                        Initializer * init = std::get<1>(p);
     438                        newDesignations.push_back( currentObject.findNext( des ) );
     439                        init->accept( *this );
     440                }
     441                // set the set of 'resolved' designations and leave the brace-enclosed initializer-list
     442                listInit->get_designations() = newDesignations; // xxx - memory management
     443                currentObject.exitListInit();
     444
     445                // xxx - this part has not be folded into CurrentObject yet
     446                // } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {
     447                //      Type * base = tt->get_baseType()->get_base();
     448                //      if ( base ) {
     449                //              // know the implementation type, so try using that as the initContext
     450                //              ObjectDecl tmpObj( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, base->clone(), nullptr );
     451                //              currentObject = &tmpObj;
     452                //              visit( listInit );
     453                //      } else {
     454                //              // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context
     455                //              Parent::visit( listInit );
     456                //      }
     457                // } else {
    573458        }
    574459
  • src/ResolvExpr/Unify.cc

    r11dbfe1 r67fa9f9  
    606606                        } else if ( tupleParam ) {
    607607                                // bundle other parameters into tuple to match
    608                                 TupleType* binder = new TupleType{ paramTy->get_qualifiers() };
     608                                std::list< Type * > binderTypes;
    609609
    610610                                do {
    611                                         binder->get_types().push_back( otherParam->get_type()->clone() );
     611                                        binderTypes.push_back( otherParam->get_type()->clone() );
    612612                                        ++jt;
    613613
     
    618618                                } while (true);
    619619
    620                                 otherParamTy = binder;
     620                                otherParamTy = new TupleType{ paramTy->get_qualifiers(), binderTypes };
    621621                                ++it;  // skip ttype parameter for break
    622622                        } else if ( otherTupleParam ) {
    623623                                // bundle parameters into tuple to match other
    624                                 TupleType* binder = new TupleType{ otherParamTy->get_qualifiers() };
     624                                std::list< Type * > binderTypes;
    625625
    626626                                do {
    627                                         binder->get_types().push_back( param->get_type()->clone() );
     627                                        binderTypes.push_back( param->get_type()->clone() );
    628628                                        ++it;
    629629
     
    634634                                } while (true);
    635635
    636                                 paramTy = binder;
     636                                paramTy = new TupleType{ otherParamTy->get_qualifiers(), binderTypes };
    637637                                ++jt;  // skip ttype parameter for break
    638638                        }
     
    756756                        return function->get_returnVals().front()->get_type()->clone();
    757757                } else {
    758                         TupleType * tupleType = new TupleType( Type::Qualifiers() );
     758                        std::list< Type * > types;
    759759                        for ( DeclarationWithType * decl : function->get_returnVals() ) {
    760                                 tupleType->get_types().push_back( decl->get_type()->clone() );
     760                                types.push_back( decl->get_type()->clone() );
    761761                        } // for
    762                         return tupleType;
     762                        return new TupleType( Type::Qualifiers(), types );
    763763                }
    764764        }
  • src/ResolvExpr/module.mk

    r11dbfe1 r67fa9f9  
    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
Note: See TracChangeset for help on using the changeset viewer.