Ignore:
Timestamp:
Nov 14, 2023, 12:19:09 PM (23 months ago)
Author:
caparson <caparson@…>
Branches:
master
Children:
1ccae59, 89a8bab
Parents:
df8ba61a (diff), 5625427 (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 plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Tuples/Explode.h

    rdf8ba61a r8d182b1  
    2020
    2121#include "AST/Expr.hpp"
    22 #include "ResolvExpr/Alternative.h"     // for Alternative, AltList
    2322#include "ResolvExpr/Candidate.hpp"     // for Candidate, CandidateList
    24 #include "ResolvExpr/ExplodedActual.h"  // for ExplodedActual
    2523#include "ResolvExpr/ExplodedArg.hpp"   // for ExplodedArg
    26 #include "SynTree/Expression.h"         // for Expression, UniqueExpr, AddressExpr
    27 #include "SynTree/Type.h"               // for TupleType, Type
    2824#include "Tuples.h"                     // for maybeImpure
    2925
     
    3228}
    3329
    34 namespace SymTab {
    35 class Indexer;
    36 }  // namespace SymTab
    37 
    3830namespace Tuples {
    39         Expression * distributeReference( Expression * );
    40 
    41         static inline CastExpr * isReferenceCast( Expression * expr ) {
    42                 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
    43                         if ( dynamic_cast< ReferenceType * >( castExpr->result ) ) {
    44                                 return castExpr;
    45                         }
    46                 }
    47                 return nullptr;
    48         }
    49 
    50         /// Append alternative to an OutputIterator of Alternatives
    51         template<typename OutputIterator>
    52         void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env,
    53                         const ResolvExpr::OpenVarSet& openVars, const ResolvExpr::AssertionList& need,
    54                         const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) {
    55                 *out++ = ResolvExpr::Alternative{ expr, env, openVars, need, cost, cvtCost };
    56         }
    57 
    58         /// Append alternative to an ExplodedActual
    59         static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr,
    60                         const ResolvExpr::TypeEnvironment&, const ResolvExpr::OpenVarSet&,
    61                         const ResolvExpr::AssertionList&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) {
    62                 ea.exprs.emplace_back( expr );
    63                 /// xxx -- merge environment, openVars, need, cost?
    64         }
    65 
    66         /// helper function used by explode
    67         template< typename Output >
    68         void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt,
    69                         const SymTab::Indexer & indexer, Output&& out, bool isTupleAssign ) {
    70                 if ( isTupleAssign ) {
    71                         // tuple assignment needs CastExprs to be recursively exploded to easily get at all of the components
    72                         if ( CastExpr * castExpr = isReferenceCast( expr ) ) {
    73                                 ResolvExpr::AltList alts;
    74                                 explodeUnique(
    75                                         castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign );
    76                                 for ( ResolvExpr::Alternative & alt : alts ) {
    77                                         // distribute reference cast over all components
    78                                         append( std::forward<Output>(out), distributeReference( alt.release_expr() ),
    79                                                 alt.env, alt.openVars, alt.need, alt.cost, alt.cvtCost );
    80                                 }
    81                                 // 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)
    82                                 return;
    83                         }
    84                 }
    85                 Type * res = expr->get_result()->stripReferences();
    86                 if ( TupleType * tupleType = dynamic_cast< TupleType * > ( res ) ) {
    87                         if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( expr ) ) {
    88                                 // can open tuple expr and dump its exploded components
    89                                 for ( Expression * expr : tupleExpr->get_exprs() ) {
    90                                         explodeUnique( expr, alt, indexer, std::forward<Output>(out), isTupleAssign );
    91                                 }
    92                         } else {
    93                                 // tuple type, but not tuple expr - recursively index into its components.
    94                                 // if expr type is reference, convert to value type
    95                                 Expression * arg = expr->clone();
    96                                 if ( Tuples::maybeImpureIgnoreUnique( arg ) ) {
    97                                         // expressions which may contain side effects require a single unique instance of the expression.
    98                                         arg = new UniqueExpr( arg );
    99                                 }
    100                                 // cast reference to value type to facilitate further explosion
    101                                 if ( dynamic_cast<ReferenceType *>( arg->get_result() ) ) {
    102                                         arg = new CastExpr( arg, tupleType->clone() );
    103                                 }
    104                                 for ( unsigned int i = 0; i < tupleType->size(); i++ ) {
    105                                         TupleIndexExpr * idx = new TupleIndexExpr( arg->clone(), i );
    106                                         explodeUnique( idx, alt, indexer, std::forward<Output>(out), isTupleAssign );
    107                                         delete idx;
    108                                 }
    109                                 delete arg;
    110                         }
    111                 } else {
    112                         // atomic (non-tuple) type - output a clone of the expression in a new alternative
    113                         append( std::forward<Output>(out), expr->clone(), alt.env, alt.openVars, alt.need,
    114                                 alt.cost, alt.cvtCost );
    115                 }
    116         }
    117 
    118         /// expands a tuple-valued alternative into multiple alternatives, each with a non-tuple-type
    119         template< typename Output >
    120         void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer,
    121                         Output&& out, bool isTupleAssign = false ) {
    122                 explodeUnique( alt.expr, alt, indexer, std::forward<Output>(out), isTupleAssign );
    123         }
    124 
    125         // explode list of alternatives
    126         template< typename AltIterator, typename Output >
    127         void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer,
    128                         Output&& out, bool isTupleAssign = false ) {
    129                 for ( ; altBegin != altEnd; ++altBegin ) {
    130                         explode( *altBegin, indexer, std::forward<Output>(out), isTupleAssign );
    131                 }
    132         }
    133 
    134         template< typename Output >
    135         void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, Output&& out,
    136                         bool isTupleAssign = false ) {
    137                 explode( alts.begin(), alts.end(), indexer, std::forward<Output>(out), isTupleAssign );
    138         }
    13931
    14032const ast::Expr * distributeReference( const ast::Expr * );
Note: See TracChangeset for help on using the changeset viewer.