Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/Explode.h

    r03321e4 r0b5d871  
    1616#pragma once
    1717
    18 #include <iterator>                  // for back_inserter, back_insert_iterator
     18#include "ResolvExpr/AlternativeFinder.h"
     19#include "ResolvExpr/Resolver.h"
    1920
    20 #include "ResolvExpr/Alternative.h"  // for Alternative, AltList
    21 #include "SynTree/Expression.h"      // for Expression, UniqueExpr, AddressExpr
    22 #include "SynTree/Type.h"            // for TupleType, Type
    23 #include "Tuples.h"                  // for maybeImpure
     21#include "SynTree/Expression.h"
     22#include "SynTree/Declaration.h"
     23#include "SynTree/Type.h"
    2424
    25 namespace SymTab {
    26 class Indexer;
    27 }  // namespace SymTab
     25#include "Tuples.h"
    2826
    2927namespace Tuples {
    30         /// helper function used by explode to properly distribute
    31         /// '&' across a tuple expression
    32         Expression * distributeAddr( Expression * expr );
     28        Expression * distributeReference( Expression * );
    3329
    3430        /// helper function used by explode
     
    3632        void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign ) {
    3733                if ( isTupleAssign ) {
    38                         // tuple assignment needs AddressExprs to be recursively exploded to easily get at all of the components
    39                         if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( expr ) ) {
     34                        // tuple assignment needs CastExprs to be recursively exploded to easily get at all of the components
     35                        if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
    4036                                ResolvExpr::AltList alts;
    41                                 explodeUnique( addrExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
     37                                explodeUnique( castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
    4238                                for ( ResolvExpr::Alternative & alt : alts ) {
    43                                         // distribute '&' over all components
    44                                         alt.expr = distributeAddr( alt.expr );
     39                                        // distribute reference cast over all components
     40                                        alt.expr = distributeReference( alt.expr );
    4541                                        *out++ = alt;
    4642                                }
     
    4945                        }
    5046                }
    51                 Type * res = expr->get_result();
     47                Type * res = expr->get_result()->stripReferences();
    5248                if ( TupleType * tupleType = dynamic_cast< TupleType * > ( res ) ) {
    5349                        if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( expr ) ) {
     
    5753                                }
    5854                        } else {
    59                                 // tuple type, but not tuple expr - recursively index into its components
     55                                // tuple type, but not tuple expr - recursively index into its components.
     56                                // if expr type is reference, convert to value type
    6057                                Expression * arg = expr->clone();
    61                                 if ( Tuples::maybeImpure( arg ) && ! dynamic_cast< UniqueExpr * >( arg ) ) {
     58                                if ( Tuples::maybeImpureIgnoreUnique( arg ) ) {
    6259                                        // expressions which may contain side effects require a single unique instance of the expression.
    6360                                        arg = new UniqueExpr( arg );
     61                                }
     62                                // cast reference to value type to facilitate further explosion
     63                                if ( dynamic_cast<ReferenceType *>( arg->get_result() ) ) {
     64                                        arg = new CastExpr( arg, tupleType->clone() );
    6465                                }
    6566                                for ( unsigned int i = 0; i < tupleType->size(); i++ ) {
Note: See TracChangeset for help on using the changeset viewer.