Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/Explode.h

    r6d267ca r6b0b624  
    99// Author           : Rob Schluntz
    1010// Created On       : Wed Nov 9 13:12:24 2016
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Nov 9 13:20:24 2016
    13 // Update Count     : 2
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sat Jul 22 09:55:16 2017
     13// Update Count     : 3
    1414//
    1515
    16 #ifndef _EXPLODE_H_
    17 #define _EXPLODE_H_
     16#pragma once
    1817
    1918#include "ResolvExpr/AlternativeFinder.h"
     
    2726
    2827namespace Tuples {
     28        /// helper function used by explode to properly distribute
     29        /// '&' across a tuple expression
     30        Expression * distributeAddr( Expression * expr );
     31
    2932        /// helper function used by explode
    3033        template< typename OutputIterator >
    3134        void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign ) {
    32                 Type * res = expr->get_result()->stripReferences();
     35                if ( isTupleAssign ) {
     36                        // tuple assignment needs AddressExprs to be recursively exploded to easily get at all of the components
     37                        if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( expr ) ) {
     38                                ResolvExpr::AltList alts;
     39                                explodeUnique( addrExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
     40                                for ( ResolvExpr::Alternative & alt : alts ) {
     41                                        // distribute '&' over all components
     42                                        alt.expr = distributeAddr( alt.expr );
     43                                        *out++ = alt;
     44                                }
     45                                // in tuple assignment, still need to handle the other cases, but only if not already handled here (don't want to output too many alternatives)
     46                                return;
     47                        }
     48                }
     49                Type * res = expr->get_result();
    3350                if ( TupleType * tupleType = dynamic_cast< TupleType * > ( res ) ) {
    3451                        if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( expr ) ) {
     
    3855                                }
    3956                        } else {
    40                                 // tuple type, but not tuple expr - recursively index into its components.
    41                                 // if expr type is reference, convert to value type
     57                                // tuple type, but not tuple expr - recursively index into its components
    4258                                Expression * arg = expr->clone();
    43 
    44                                 if ( dynamic_cast<ReferenceType *>( arg->get_result() ) ) {
    45                                         // TODO: does this go here (inside uniqueexpr) or outside uniqueexpr? I'm guessing probably should go after...
    46                                         arg = new CastExpr( arg, tupleType->clone() );
    47                                 }
    4859                                if ( Tuples::maybeImpure( arg ) && ! dynamic_cast< UniqueExpr * >( arg ) ) {
    4960                                        // expressions which may contain side effects require a single unique instance of the expression.
     
    8394} // namespace Tuples
    8495
    85 #endif // _TUPLE_ASSIGNMENT_H_
    86 
    8796// Local Variables: //
    8897// tab-width: 4 //
Note: See TracChangeset for help on using the changeset viewer.