Ignore:
Timestamp:
Aug 23, 2017, 6:22:07 PM (8 years ago)
Author:
Peter A. Buhr <pabuhr@…>
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:
87e08e24, cb811ac
Parents:
9f07232 (diff), bd37119 (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 plg2:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/TupleAssignment.cc

    r9f07232 rd3e4d6c  
    2121#include <string>                          // for string
    2222
     23#include "CodeGen/OperatorTable.h"
    2324#include "Common/UniqueName.h"             // for UniqueName
    2425#include "Common/utility.h"                // for zipWith
     
    8485                if ( ! expr ) return false;
    8586                assert( expr->has_result() );
    86                 return dynamic_cast< TupleType * >( expr->get_result() );
     87                return dynamic_cast< TupleType * >( expr->get_result()->stripReferences() );
    8788        }
    8889
     
    9697        }
    9798
    98         bool pointsToTuple( Expression *expr ) {
     99        bool refToTuple( Expression *expr ) {
     100                assert( expr->get_result() );
    99101                // also check for function returning tuple of reference types
    100102                if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
    101                         return pointsToTuple( castExpr->get_arg() );
    102                 } else if ( AddressExpr *addr = dynamic_cast< AddressExpr * >( expr) ) {
    103                         return isTuple( addr->get_arg() );
     103                        return refToTuple( castExpr->get_arg() );
     104                } else {
     105                        return isTuple( expr );
    104106                }
    105107                return false;
     
    116118        void TupleAssignSpotter::spot( UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities ) {
    117119                if (  NameExpr *op = dynamic_cast< NameExpr * >(expr->get_function()) ) {
    118                         if ( InitTweak::isCtorDtorAssign( op->get_name() ) ) {
     120                        if ( CodeGen::isCtorDtorAssign( op->get_name() ) ) {
    119121                                fname = op->get_name();
    120122                                for ( std::list<ResolvExpr::AltList>::const_iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) {
    121123                                        if ( ali->size() == 0 ) continue; // AlternativeFinder will natrually handle this case, if it's legal
    122                                         if ( ali->size() <= 1 && InitTweak::isAssignment( op->get_name() ) ) {
     124                                        if ( ali->size() <= 1 && CodeGen::isAssignment( op->get_name() ) ) {
    123125                                                // what does it mean if an assignment takes 1 argument? maybe someone defined such a function, in which case AlternativeFinder will naturally handle it
    124126                                                continue;
     
    129131                                        const ResolvExpr::Alternative & alt1 = ali->front();
    130132                                        auto begin = std::next(ali->begin(), 1), end = ali->end();
    131                                         if ( pointsToTuple(alt1.expr) ) {
     133                                        if ( refToTuple(alt1.expr) ) {
    132134                                                if ( isMultAssign( begin, end ) ) {
    133135                                                        matcher.reset( new MultipleAssignMatcher( *this, *ali ) );
     
    187189
    188190                ResolvExpr::Alternative lhsAlt = alts.front();
    189                 // peel off the cast that exists on ctor/dtor expressions
    190                 bool isCast = false;
    191                 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( lhsAlt.expr ) ) {
    192                         lhsAlt.expr = castExpr->get_arg();
    193                         castExpr->set_arg( nullptr );
    194                         delete castExpr;
    195                         isCast = true;
     191                // explode is aware of casts - ensure every LHS expression is sent into explode with a reference cast
     192                if ( ! dynamic_cast< CastExpr * >( lhsAlt.expr ) ) {
     193                        lhsAlt.expr = new CastExpr( lhsAlt.expr, new ReferenceType( Type::Qualifiers(), lhsAlt.expr->get_result()->clone() ) );
    196194                }
    197195
     
    199197                explode( lhsAlt, spotter.currentFinder.get_indexer(), back_inserter(lhs), true );
    200198
    201                 // and finally, re-add the cast to each lhs expr, so that qualified tuple fields can be constructed
    202                 if ( isCast ) {
    203                         for ( ResolvExpr::Alternative & alt : lhs ) {
    204                                 Expression *& expr = alt.expr;
    205                                 Type * castType = expr->get_result()->clone();
    206                                 Type * type = InitTweak::getPointerBase( castType );
    207                                 assert( type );
    208                                 type->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
    209                                 type->set_lvalue( true ); // xxx - might not need this
    210                                 expr = new CastExpr( expr, castType );
     199                for ( ResolvExpr::Alternative & alt : lhs ) {
     200                        // every LHS value must be a reference - some come in with a cast expression, if it doesn't just cast to reference here.
     201                        if ( ! dynamic_cast< ReferenceType * >( alt.expr->get_result() ) ) {
     202                                alt.expr = new CastExpr( alt.expr, new ReferenceType( Type::Qualifiers(), alt.expr->get_result()->clone() ) );
    211203                        }
    212204                }
     
    228220                assert( left );
    229221                std::list< Expression * > args;
    230                 args.push_back( new AddressExpr( UntypedExpr::createDeref( new VariableExpr( left ) ) ) );
     222                args.push_back( new VariableExpr( left ) );
    231223                // args.push_back( new AddressExpr( new VariableExpr( left ) ) );
    232224                if ( right ) args.push_back( new VariableExpr( right ) );
     
    248240                assert( expr->has_result() && ! expr->get_result()->isVoid() );
    249241                ObjectDecl * ret = new ObjectDecl( namer.newName(), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, expr->get_result()->clone(), new SingleInit( expr->clone() ) );
    250                 ConstructorInit * ctorInit = InitTweak::genCtorInit( ret );
    251                 ret->set_init( ctorInit );
    252                 ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object
    253                 EnvRemover rm; // remove environments from subexpressions of StmtExprs
    254                 ctorInit->accept( rm );
     242                // if expression type is a reference, don't need to construct anything, a simple initializer is sufficient.
     243                if ( ! dynamic_cast< ReferenceType * >( expr->get_result() ) ) {
     244                        ConstructorInit * ctorInit = InitTweak::genCtorInit( ret );
     245                        ret->set_init( ctorInit );
     246                        ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object
     247                        EnvRemover rm; // remove environments from subexpressions of StmtExprs
     248                        ctorInit->accept( rm );
     249                }
    255250                return ret;
    256251        }
Note: See TracChangeset for help on using the changeset viewer.