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/Explode.cc

    r9f07232 rd3e4d6c  
    1515
    1616#include "Explode.h"
     17#include <list>                  // for list
    1718
    18 #include <list>               // for list
    19 
    20 #include "SynTree/Mutator.h"  // for Mutator
     19#include "SynTree/Mutator.h"     // for Mutator
     20#include "Common/PassVisitor.h"  // for PassVisitor
    2121
    2222namespace Tuples {
    2323        namespace {
    24                 struct AddrExploder : public Mutator {
     24                // remove one level of reference from a reference type -- may be useful elsewhere.
     25                Type * getReferenceBase( Type * t ) {
     26                        if ( ReferenceType * refType = dynamic_cast<ReferenceType *>( t ) ) {
     27                                return refType->get_base();
     28                        } else {
     29                                // for the moment, I want to know immediately if a non-reference type is ever passed in here.
     30                                assertf( false, "getReferenceBase for non-ref: %s", toString( refType ).c_str() );
     31                                return nullptr;
     32                        }
     33                }
     34
     35                struct CastExploder {
     36                        bool castAdded = false;
    2537                        bool foundUniqueExpr = false;
    26                         Expression * applyAddr( Expression * expr, bool first = true ) {
     38                        Expression * applyCast( Expression * expr, bool first = true ) {
    2739                                if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( expr ) ){
    2840                                        foundUniqueExpr = true;
    2941                                        std::list< Expression * > exprs;
    3042                                        for ( Expression *& expr : tupleExpr->get_exprs() ) {
    31                                                 // move & into tuple exprs
    32                                                 exprs.push_back( applyAddr( expr, false ) );
     43                                                // move cast into tuple exprs
     44                                                exprs.push_back( applyCast( expr, false ) );
    3345                                        }
    34                                         // want the top-level expression to be address-taken, but not nested
     46                                        // want the top-level expression to be cast to reference type, but not nested
    3547                                        // tuple expressions
    3648                                        if ( first ) {
    37                                                 return new AddressExpr( new TupleExpr( exprs ) );
     49                                                castAdded = true;
     50                                                Expression * tupleExpr = new TupleExpr( exprs );
     51                                                return new CastExpr( tupleExpr, new ReferenceType( Type::Qualifiers(), tupleExpr->result->clone() ) );
    3852                                        } else {
    3953                                                return new TupleExpr( exprs );
    4054                                        }
    4155                                }
    42                                 // anything else should be address-taken as normal
    43                                 return new AddressExpr( expr->clone() );
     56                                if ( dynamic_cast<ReferenceType*>( expr->result ) ) {
     57                                        // don't need to cast reference type to another reference type
     58                                        return expr->clone();
     59                                } else {
     60                                        // anything else should be cast to reference as normal
     61                                        castAdded = true;
     62                                        return new CastExpr( expr->clone(), new ReferenceType( Type::Qualifiers(), expr->result->clone() ) );
     63                                }
    4464                        }
    4565
    46                         virtual Expression * mutate( UniqueExpr * uniqueExpr ) {
    47                                 // move & into unique expr so that the unique expr has type T* rather than
     66                        Expression * postmutate( UniqueExpr * uniqueExpr ) {
     67                                // move cast into unique expr so that the unique expr has type T& rather than
    4868                                // type T. In particular, this transformation helps with generating the
    49                                 // correct code for address-taken member tuple expressions, since the result
    50                                 // should now be a tuple of addresses rather than the address of a tuple.
     69                                // correct code for reference-cast member tuple expressions, since the result
     70                                // should now be a tuple of references rather than a reference to a tuple.
    5171                                // Still, this code is a bit awkward, and could use some improvement.
    52                                 if ( dynamic_cast< AddressExpr * > ( uniqueExpr->get_expr() ) ) {
    53                                         // this unique expression has already been mutated or otherwise shouldn't be (can't take the address-of an address-of expression)
    54                                         return uniqueExpr;
     72                                UniqueExpr * newUniqueExpr = new UniqueExpr( applyCast( uniqueExpr->get_expr() ), uniqueExpr->get_id() );
     73                                delete uniqueExpr;
     74                                if ( castAdded ) {
     75                                        // if a cast was added by applyCast, then unique expr now has one more layer of reference
     76                                        // than it had coming into this function. To ensure types still match correctly, need to cast
     77                                        //  to reference base so that outer expressions are still correct.
     78                                        castAdded = false;
     79                                        Type * toType = getReferenceBase( newUniqueExpr->result );
     80                                        return new CastExpr( newUniqueExpr, toType->clone() );
    5581                                }
    56                                 UniqueExpr * newUniqueExpr = new UniqueExpr( applyAddr( uniqueExpr->get_expr() ), uniqueExpr->get_id() );
    57                                 delete uniqueExpr;
    58                                 UntypedExpr * deref = UntypedExpr::createDeref( Mutator::mutate( newUniqueExpr ) );
    59                                 return deref;
     82                                return newUniqueExpr;
    6083                        }
    6184
    62                         virtual Expression * mutate( TupleIndexExpr * tupleExpr ) {
     85
     86                        Expression * postmutate( TupleIndexExpr * tupleExpr ) {
    6387                                // tuple index expr needs to be rebuilt to ensure that the type of the
    6488                                // field is consistent with the type of the tuple expr, since the field
    65                                 // may have changed from type T to T*.
    66                                 Expression * expr = tupleExpr->get_tuple()->acceptMutator( *this );
     89                                // may have changed from type T to T&.
     90                                Expression * expr = tupleExpr->get_tuple();
    6791                                tupleExpr->set_tuple( nullptr );
    6892                                TupleIndexExpr * ret = new TupleIndexExpr( expr, tupleExpr->get_index() );
     
    7397        } // namespace
    7498
    75         Expression * distributeAddr( Expression * expr ) {
    76                 AddrExploder addrExploder;
    77                 expr = expr->acceptMutator( addrExploder );
    78                 if ( ! addrExploder.foundUniqueExpr ) {
    79                         expr = new AddressExpr( expr );
     99        Expression * distributeReference( Expression * expr ) {
     100                PassVisitor<CastExploder> exploder;
     101                expr = expr->acceptMutator( exploder );
     102                if ( ! exploder.pass.foundUniqueExpr ) {
     103                        // if a UniqueExpr was found, then the cast has already been added inside the UniqueExpr as appropriate
     104                        expr = new CastExpr( expr, new ReferenceType( Type::Qualifiers(), expr->result->clone() ) );
    80105                }
    81106                return expr;
Note: See TracChangeset for help on using the changeset viewer.