Ignore:
Timestamp:
Nov 8, 2023, 2:01:11 PM (8 months ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
master
Children:
3e4bf0d, f5ec35a
Parents:
790d835
Message:

Remove BaseSyntaxNode? and clean-up.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/Explode.cc

    r790d835 rc6b4432  
    1515
    1616#include "Explode.h"
    17 #include <list>                  // for list
    1817
    1918#include "AST/Pass.hpp"          // for Pass
    20 #include "SynTree/Mutator.h"     // for Mutator
    21 #include "Common/PassVisitor.h"  // for PassVisitor
    2219
    2320namespace Tuples {
    24         namespace {
    25                 // remove one level of reference from a reference type -- may be useful elsewhere.
    26                 Type * getReferenceBase( Type * t ) {
    27                         if ( ReferenceType * refType = dynamic_cast<ReferenceType *>( t ) ) {
    28                                 return refType->get_base();
    29                         } else {
    30                                 // for the moment, I want to know immediately if a non-reference type is ever passed in here.
    31                                 assertf( false, "getReferenceBase for non-ref: %s", toString( refType ).c_str() );
    32                                 return nullptr;
    33                         }
    34                 }
    35 
    36                 struct CastExploder {
    37                         bool castAdded = false;
    38                         bool foundUniqueExpr = false;
    39                         Expression * applyCast( Expression * expr, bool first = true ) {
    40                                 if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( expr ) ){
    41                                         foundUniqueExpr = true;
    42                                         std::list< Expression * > exprs;
    43                                         for ( Expression *& expr : tupleExpr->get_exprs() ) {
    44                                                 // move cast into tuple exprs
    45                                                 exprs.push_back( applyCast( expr, false ) );
    46                                         }
    47                                         // want the top-level expression to be cast to reference type, but not nested
    48                                         // tuple expressions
    49                                         if ( first ) {
    50                                                 castAdded = true;
    51                                                 Expression * tupleExpr = new TupleExpr( exprs );
    52                                                 return new CastExpr( tupleExpr, new ReferenceType( Type::Qualifiers(), tupleExpr->result->clone() ) );
    53                                         } else {
    54                                                 return new TupleExpr( exprs );
    55                                         }
    56                                 }
    57                                 if ( dynamic_cast<ReferenceType*>( expr->result ) ) {
    58                                         // don't need to cast reference type to another reference type
    59                                         return expr->clone();
    60                                 } else {
    61                                         // anything else should be cast to reference as normal
    62                                         castAdded = true;
    63                                         return new CastExpr( expr->clone(), new ReferenceType( Type::Qualifiers(), expr->result->clone() ) );
    64                                 }
    65                         }
    66 
    67                         Expression * postmutate( UniqueExpr * uniqueExpr ) {
    68                                 // move cast into unique expr so that the unique expr has type T& rather than
    69                                 // type T. In particular, this transformation helps with generating the
    70                                 // correct code for reference-cast member tuple expressions, since the result
    71                                 // should now be a tuple of references rather than a reference to a tuple.
    72                                 // Still, this code is a bit awkward, and could use some improvement.
    73                                 UniqueExpr * newUniqueExpr = new UniqueExpr( applyCast( uniqueExpr->get_expr() ), uniqueExpr->get_id() );
    74                                 delete uniqueExpr;
    75                                 if ( castAdded ) {
    76                                         // if a cast was added by applyCast, then unique expr now has one more layer of reference
    77                                         // than it had coming into this function. To ensure types still match correctly, need to cast
    78                                         //  to reference base so that outer expressions are still correct.
    79                                         castAdded = false;
    80                                         Type * toType = getReferenceBase( newUniqueExpr->result );
    81                                         return new CastExpr( newUniqueExpr, toType->clone() );
    82                                 }
    83                                 return newUniqueExpr;
    84                         }
    85 
    86 
    87                         Expression * postmutate( TupleIndexExpr * tupleExpr ) {
    88                                 // tuple index expr needs to be rebuilt to ensure that the type of the
    89                                 // field is consistent with the type of the tuple expr, since the field
    90                                 // may have changed from type T to T&.
    91                                 Expression * expr = tupleExpr->get_tuple();
    92                                 tupleExpr->set_tuple( nullptr );
    93                                 TupleIndexExpr * ret = new TupleIndexExpr( expr, tupleExpr->get_index() );
    94                                 delete tupleExpr;
    95                                 return ret;
    96                         }
    97                 };
    98         } // namespace
    99 
    100         Expression * distributeReference( Expression * expr ) {
    101                 PassVisitor<CastExploder> exploder;
    102                 expr = expr->acceptMutator( exploder );
    103                 if ( ! exploder.pass.foundUniqueExpr ) {
    104                         // if a UniqueExpr was found, then the cast has already been added inside the UniqueExpr as appropriate
    105                         expr = new CastExpr( expr, new ReferenceType( Type::Qualifiers(), expr->result->clone() ) );
    106                 }
    107                 return expr;
    108         }
    10921
    11022namespace {
Note: See TracChangeset for help on using the changeset viewer.