Ignore:
Timestamp:
Aug 22, 2017, 7:07:22 PM (9 years ago)
Author:
Rob Schluntz <rschlunt@…>
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, stuck-waitfor-destruct, with_gc
Children:
5fb6830
Parents:
5ccb10d
Message:

Update explode for references

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/Explode.h

    r5ccb10d r0b5d871  
    2626
    2727namespace Tuples {
     28        Expression * distributeReference( Expression * );
     29
    2830        /// helper function used by explode
    2931        template< typename OutputIterator >
    3032        void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign ) {
     33                if ( isTupleAssign ) {
     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 ) ) {
     36                                ResolvExpr::AltList alts;
     37                                explodeUnique( castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
     38                                for ( ResolvExpr::Alternative & alt : alts ) {
     39                                        // distribute reference cast over all components
     40                                        alt.expr = distributeReference( alt.expr );
     41                                        *out++ = alt;
     42                                }
     43                                // 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)
     44                                return;
     45                        }
     46                }
    3147                Type * res = expr->get_result()->stripReferences();
    3248                if ( TupleType * tupleType = dynamic_cast< TupleType * > ( res ) ) {
     
    4056                                // if expr type is reference, convert to value type
    4157                                Expression * arg = expr->clone();
    42 
    43                                 if ( dynamic_cast<ReferenceType *>( arg->get_result() ) ) {
    44                                         // TODO: does this go here (inside uniqueexpr) or outside uniqueexpr? I'm guessing probably should go after...
    45                                         arg = new CastExpr( arg, tupleType->clone() );
    46                                 }
    47                                 if ( Tuples::maybeImpure( arg ) && ! dynamic_cast< UniqueExpr * >( arg ) ) {
     58                                if ( Tuples::maybeImpureIgnoreUnique( arg ) ) {
    4859                                        // expressions which may contain side effects require a single unique instance of the expression.
    4960                                        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() );
    5065                                }
    5166                                for ( unsigned int i = 0; i < tupleType->size(); i++ ) {
Note: See TracChangeset for help on using the changeset viewer.