Ignore:
Timestamp:
Aug 27, 2018, 4:40:34 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
b7c89aa
Parents:
f9feab8 (diff), 305581d (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' into cleanup-dtors

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/TupleAssignment.cc

    rf9feab8 r90152a4  
    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);
     
    272273                // args.push_back( new AddressExpr( new VariableExpr( left ) ) );
    273274                if ( right ) args.push_back( new VariableExpr( right ) );
    274                 return new UntypedExpr( new NameExpr( fname ), args );
    275         }
    276 
    277         // removes environments from subexpressions within statement exprs, which could throw off later passes like those in Box which rely on PolyMutator.
     275                if ( left->type->referenceDepth() > 1 && CodeGen::isConstructor( fname ) ) {
     276                        args.front() = new AddressExpr( args.front() );
     277                        if ( right ) args.back() = new AddressExpr( args.back() );
     278                        return new UntypedExpr( new NameExpr( "?=?" ), args );
     279                } else {
     280                        return new UntypedExpr( new NameExpr( fname ), args );
     281                }
     282        }
     283
     284        // removes environments from subexpressions within statement exprs, which could throw off later passes like those in Box which rely on PolyMutator, and adds the bindings to the compositeEnv
    278285        // xxx - maybe this should happen in alternative finder for every StmtExpr?
    279         // xxx - it's possible that these environments could contain some useful information. Maybe the right thing to do is aggregate the environments and pass the aggregate back to be added into the compositeEnv
    280286        struct EnvRemover {
    281287                void previsit( ExprStmt * stmt ) {
    282                         delete stmt->expr->env;
    283                         stmt->expr->env = nullptr;
    284                 }
     288                        assert( compositeEnv );
     289                        if ( stmt->expr->env ) {
     290                                compositeEnv->add( *stmt->expr->env );
     291                                delete stmt->expr->env;
     292                                stmt->expr->env = nullptr;
     293                        }
     294                }
     295
     296                ResolvExpr::TypeEnvironment * compositeEnv = nullptr;
    285297        };
    286298
    287299        ObjectDecl * TupleAssignSpotter::Matcher::newObject( UniqueName & namer, Expression * expr ) {
    288300                assert( expr->result && ! expr->get_result()->isVoid() );
    289                 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() ) );
    290302                // if expression type is a reference, don't need to construct anything, a simple initializer is sufficient.
    291                 if ( ! dynamic_cast< ReferenceType * >( expr->get_result() ) ) {
     303                if ( ! dynamic_cast< ReferenceType * >( expr->result ) ) {
    292304                        ConstructorInit * ctorInit = InitTweak::genCtorInit( ret );
    293                         ret->set_init( ctorInit );
     305                        ret->init = ctorInit;
    294306                        ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object
    295307                        PassVisitor<EnvRemover> rm; // remove environments from subexpressions of StmtExprs
     308                        rm.pass.compositeEnv = &compositeEnv;
    296309                        ctorInit->accept( rm );
    297310                }
     
    306319                assert( (! lhs.empty() && rhs.size() <= 1) || (lhs.empty() && rhs.empty()) );
    307320
     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
    308323                ObjectDecl * rtmp = rhs.size() == 1 ? newObject( rhsNamer, rhs.front().expr ) : nullptr;
    309324                for ( ResolvExpr::Alternative & lhsAlt : lhs ) {
     
    324339                        std::list< ObjectDecl * > ltmp;
    325340                        std::list< ObjectDecl * > rtmp;
    326                         std::transform( lhs.begin(), lhs.end(), back_inserter( ltmp ), [&]( ResolvExpr::Alternative & alt ){
    327                                 return newObject( lhsNamer, alt.expr );
    328                         });
    329                         std::transform( rhs.begin(), rhs.end(), back_inserter( rtmp ), [&]( ResolvExpr::Alternative & alt ){
    330                                 return newObject( rhsNamer, alt.expr );
    331                         });
    332                         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                        }
    333359                        tmpDecls.splice( tmpDecls.end(), ltmp );
    334360                        tmpDecls.splice( tmpDecls.end(), rtmp );
Note: See TracChangeset for help on using the changeset viewer.