Changes in src/Tuples/Explode.h [7870799:490ff5c3]
- File:
-
- 1 edited
-
src/Tuples/Explode.h (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Tuples/Explode.h
r7870799 r490ff5c3 9 9 // Author : Rob Schluntz 10 10 // Created On : Wed Nov 9 13:12:24 2016 11 // Last Modified By : Andrew Beach12 // Last Modified On : Mon Jun 17 14:36:00 201913 // Update Count : 411 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:55:16 2017 13 // Update Count : 3 14 14 // 15 15 … … 19 19 #include <utility> // for forward 20 20 21 #include "AST/Expr.hpp"22 21 #include "ResolvExpr/Alternative.h" // for Alternative, AltList 23 #include "ResolvExpr/Candidate.hpp" // for Candidate, CandidateList24 22 #include "ResolvExpr/ExplodedActual.h" // for ExplodedActual 25 #include "ResolvExpr/ExplodedArg.hpp" // for ExplodedArg26 23 #include "SynTree/Expression.h" // for Expression, UniqueExpr, AddressExpr 27 24 #include "SynTree/Type.h" // for TupleType, Type 28 25 #include "Tuples.h" // for maybeImpure 29 30 namespace ast {31 class SymbolTable;32 }33 26 34 27 namespace SymTab { … … 51 44 template<typename OutputIterator> 52 45 void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env, 53 const ResolvExpr::OpenVarSet& openVars, const ResolvExpr::AssertionList& need,54 46 const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) { 55 *out++ = ResolvExpr::Alternative{ expr, env, openVars, need,cost, cvtCost };47 *out++ = ResolvExpr::Alternative{ expr, env, cost, cvtCost }; 56 48 } 57 49 58 50 /// Append alternative to an ExplodedActual 59 51 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& ) { 52 const ResolvExpr::TypeEnvironment&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) { 62 53 ea.exprs.emplace_back( expr ); 63 /// xxx -- merge environment, openVars, need,cost?54 /// xxx -- merge environment, cost? 64 55 } 65 56 … … 77 68 // distribute reference cast over all components 78 69 append( std::forward<Output>(out), distributeReference( alt.release_expr() ), 79 alt.env, alt. openVars, alt.need, alt.cost, alt.cvtCost );70 alt.env, alt.cost, alt.cvtCost ); 80 71 } 81 72 // 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) … … 111 102 } else { 112 103 // 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 ); 104 append( std::forward<Output>(out), expr->clone(), alt.env, alt.cost, alt.cvtCost ); 115 105 } 116 106 } … … 137 127 explode( alts.begin(), alts.end(), indexer, std::forward<Output>(out), isTupleAssign ); 138 128 } 139 140 const ast::Expr * distributeReference( const ast::Expr * );141 142 /// Append candidate to an OutputIterator of Candidates.143 template<typename OutputIterator>144 void append( OutputIterator out, const ast::Expr * expr, const ast::TypeEnvironment & env,145 const ast::OpenVarSet & open, const ast::AssertionList & need,146 const ResolvExpr::Cost & cost, const ResolvExpr::Cost & cvtCost ) {147 ast::TypeEnvironment copyEnv = env;148 ast::OpenVarSet copyOpen = open;149 ast::AssertionSet set;150 mergeAssertionSet( set, need );151 *out++ = std::make_shared<ResolvExpr::Candidate>( expr, std::move( copyEnv ),152 std::move( copyOpen ), std::move( set ), cost, cvtCost );153 }154 155 /// Append candidate to an ExplodedArg.156 static inline void append( ResolvExpr::ExplodedArg& ea, const ast::Expr * expr,157 const ast::TypeEnvironment&, const ast::OpenVarSet&,158 const ast::AssertionList&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) {159 // I'm not sure why most of the arguments are unused. But they were in the old version.160 ea.exprs.emplace_back( expr );161 }162 163 /// Check if the expression is a cast to a reference type, return it if it is.164 static inline const ast::CastExpr * isReferenceCast( const ast::Expr * expr ) {165 if ( const ast::CastExpr * cast = dynamic_cast< const ast::CastExpr * >( expr ) ) {166 if ( dynamic_cast< const ast::ReferenceType * >( cast->result.get() ) ) {167 return cast;168 }169 }170 return nullptr;171 }172 173 /// helper function (indirectely) used by explode174 template< typename Output >175 void explodeRecursive(176 const ast::CastExpr *, const ResolvExpr::Candidate &,177 const ast::SymbolTable &, Output &&178 ) {179 }180 181 /// helper function used by explode182 template< typename Output >183 void explodeUnique(184 const ast::ptr< ast::Expr > & expr, const ResolvExpr::Candidate & arg,185 const ast::SymbolTable & symtab, Output && out, bool isTupleAssign186 ) {187 // Tuple assignment can use a faster method if it is cast. Uses recursive exploding.188 if ( isTupleAssign ) if ( const ast::CastExpr * castExpr = isReferenceCast( expr ) ) {189 ResolvExpr::CandidateList candidates;190 explodeUnique( castExpr->arg, arg, symtab, back_inserter( candidates ), true );191 for ( ResolvExpr::CandidateRef & cand : candidates ) {192 // Distribute the reference cast over all components of the candidate.193 append( std::forward<Output>(out), distributeReference( cand->expr ), cand->env,194 cand->open, cand->need, cand->cost, cand->cvtCost );195 }196 return;197 }198 const ast::Type * res = expr->result->stripReferences();199 if ( const ast::TupleType * tupleType = dynamic_cast< const ast::TupleType * >( res ) ) {200 if ( const ast::ptr< ast::TupleExpr > & tupleExpr = expr.as< ast::TupleExpr >() ) {201 // Open the tuple expr and continue on its components.202 for ( const ast::Expr * expr : tupleExpr->exprs ) {203 explodeUnique( expr, arg, symtab, std::forward<Output>(out), isTupleAssign );204 }205 } else {206 ast::ptr< ast::Expr > local = expr;207 // Expressions which may have side effects require a single unique instance.208 if ( Tuples::maybeImpureIgnoreUnique( local ) ) {209 local = new ast::UniqueExpr( local->location, local );210 }211 // Cast a reference away to a value-type to allow further explosion.212 if ( dynamic_cast< const ast::ReferenceType *>( local->result.get() ) ) {213 local = new ast::CastExpr{ local, tupleType };214 }215 // Now we have to go across the tuple via indexing.216 for ( unsigned int i = 0 ; i < tupleType->size() ; ++i ) {217 ast::TupleIndexExpr * idx = new ast::TupleIndexExpr( local->location, local, i );218 explodeUnique( idx, arg, symtab, std::forward<Output>(out), isTupleAssign );219 // TODO: We need more input to figure out the exact lifetimes of these types.220 // delete idx;221 }222 // delete local;223 }224 } else {225 // For atomic/non-tuple types, no explosion is used.226 append( std::forward<Output>(out), expr, arg.env, arg.open, arg.need, arg.cost,227 arg.cvtCost );228 }229 }230 231 /// expands a tuple-valued candidate into multiple candidates, each with a non-tuple type232 template< typename Output >233 void explode(234 const ResolvExpr::Candidate & arg, const ast::SymbolTable & symtab, Output && out,235 bool isTupleAssign = false236 ) {237 explodeUnique( arg.expr, arg, symtab, std::forward< Output >( out ), isTupleAssign );238 }239 240 /// explode list of candidates into flattened list of candidates241 template< typename Output >242 void explode(243 const ResolvExpr::CandidateList & cands, const ast::SymbolTable & symtab, Output && out,244 bool isTupleAssign = false245 ) {246 for ( const ResolvExpr::CandidateRef & cand : cands ) {247 explode( *cand, symtab, std::forward< Output >( out ), isTupleAssign );248 }249 }250 251 129 } // namespace Tuples 252 130
Note:
See TracChangeset
for help on using the changeset viewer.