Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/TupleAssignment.cc

    r938dd75 r753bf60  
    154154                                                lhsAlt.expr = new CastExpr( lhsAlt.expr,
    155155                                                                new ReferenceType( Type::Qualifiers(),
    156                                                                         lhsAlt.expr->get_result()->clone() ) );
     156                                                                        lhsAlt.expr->result->clone() ) );
    157157                                        }
    158158
     
    231231
    232232                        ResolvExpr::AlternativeFinder finder{ currentFinder.get_indexer(),
    233                                 currentFinder.get_environ() };
     233                                matcher->compositeEnv };
     234
    234235                        try {
    235236                                finder.findWithAdjustment(*i);
     
    298299        ObjectDecl * TupleAssignSpotter::Matcher::newObject( UniqueName & namer, Expression * expr ) {
    299300                assert( expr->result && ! expr->get_result()->isVoid() );
    300                 ObjectDecl * ret = new ObjectDecl( namer.newName(), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, expr->get_result()->clone(), new SingleInit( expr->clone() ) );
     301                ObjectDecl * ret = new ObjectDecl( namer.newName(), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, expr->result->clone(), new SingleInit( expr->clone() ) );
    301302                // if expression type is a reference, don't need to construct anything, a simple initializer is sufficient.
    302                 if ( ! dynamic_cast< ReferenceType * >( expr->get_result() ) ) {
     303                if ( ! dynamic_cast< ReferenceType * >( expr->result ) ) {
    303304                        ConstructorInit * ctorInit = InitTweak::genCtorInit( ret );
    304305                        ret->init = ctorInit;
     
    318319                assert( (! lhs.empty() && rhs.size() <= 1) || (lhs.empty() && rhs.empty()) );
    319320
     321                // xxx - may need to split this up into multiple declarations, because potential conversion to references
     322                //  probably should not reference local variable - see MultipleAssignMatcher::match
    320323                ObjectDecl * rtmp = rhs.size() == 1 ? newObject( rhsNamer, rhs.front().expr ) : nullptr;
    321324                for ( ResolvExpr::Alternative & lhsAlt : lhs ) {
     
    336339                        std::list< ObjectDecl * > ltmp;
    337340                        std::list< ObjectDecl * > rtmp;
    338                         std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), [&]( ResolvExpr::Alternative & alt ){
    339                                 return newObject( lhsNamer, alt.expr );
    340                         });
    341                         std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), [&]( ResolvExpr::Alternative & alt ){
    342                                 return newObject( rhsNamer, alt.expr );
    343                         });
    344                         zipWith( ltmp.begin(), ltmp.end(), rtmp.begin(), rtmp.end(), back_inserter(out), [&](ObjectDecl * obj1, ObjectDecl * obj2 ) { return createFunc(spotter.fname, obj1, obj2); } );
     341                        for ( auto p : group_iterate( lhs, rhs ) ) {
     342                                ResolvExpr::Alternative & lhsAlt = std::get<0>(p);
     343                                ResolvExpr::Alternative & rhsAlt = std::get<1>(p);
     344                                // convert RHS to LHS type minus one reference -- important for the case where LHS is && and RHS is lvalue, etc.
     345                                ReferenceType * lhsType = strict_dynamic_cast<ReferenceType *>( lhsAlt.expr->result );
     346                                rhsAlt.expr = new CastExpr( rhsAlt.expr, lhsType->base->clone() );
     347                                ObjectDecl * lobj = newObject( lhsNamer, lhsAlt.expr );
     348                                ObjectDecl * robj = newObject( rhsNamer, rhsAlt.expr );
     349                                out.push_back( createFunc(spotter.fname, lobj, robj) );
     350                                ltmp.push_back( lobj );
     351                                rtmp.push_back( robj );
     352
     353                                // resolve the cast expression so that rhsAlt return type is bound by the cast type as needed, and transfer the resulting environment
     354                                ResolvExpr::AlternativeFinder finder{ spotter.currentFinder.get_indexer(), compositeEnv };
     355                                finder.findWithAdjustment( rhsAlt.expr );
     356                                assert( finder.get_alternatives().size() == 1 );
     357                                compositeEnv = std::move( finder.get_alternatives().front().env );
     358                        }
    345359                        tmpDecls.splice( tmpDecls.end(), ltmp );
    346360                        tmpDecls.splice( tmpDecls.end(), rtmp );
Note: See TracChangeset for help on using the changeset viewer.