Changes in src/Tuples/TupleAssignment.cc [1d2b64f:f831177]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Tuples/TupleAssignment.cc
r1d2b64f rf831177 73 73 }; 74 74 75 /// true if expr is an expression of tuple type , i.e. a tuple expression, tuple variable, or MRV (multiple-return-value) function75 /// true if expr is an expression of tuple type 76 76 bool isTuple( Expression *expr ) { 77 77 if ( ! expr ) return false; 78 78 assert( expr->has_result() ); 79 return dynamic_cast< TupleExpr *>(expr) || expr->get_result()->size() > 1;79 return dynamic_cast< TupleType * >( expr->get_result() ); 80 80 } 81 81 … … 142 142 matcher->match( new_assigns ); 143 143 144 if ( new_assigns.empty() ) return; 144 if ( ! matcher->lhs.empty() || ! matcher->rhs.empty() ) { 145 // if both lhs and rhs are empty then this is the empty tuple case, wherein it's okay for new_assigns to be empty. 146 // if not the empty tuple case, return early so that no new alternatives are generated. 147 if ( new_assigns.empty() ) return; 148 } 145 149 ResolvExpr::AltList current; 146 150 // now resolve new assignments … … 186 190 187 191 // explode the lhs so that each field of the tuple-valued-expr is assigned. 188 explode( lhsAlt, spotter.currentFinder.get_indexer(), back_inserter(lhs) );192 explode( lhsAlt, spotter.currentFinder.get_indexer(), back_inserter(lhs), true ); 189 193 190 194 // and finally, re-add the cast to each lhs expr, so that qualified tuple fields can be constructed … … 211 215 TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ) : Matcher( spotter, alts ) { 212 216 // explode the rhs so that each field of the tuple-valued-expr is assigned. 213 explode( std::next(alts.begin(), 1), alts.end(), spotter.currentFinder.get_indexer(), back_inserter(rhs) );217 explode( std::next(alts.begin(), 1), alts.end(), spotter.currentFinder.get_indexer(), back_inserter(rhs), true ); 214 218 } 215 219 … … 248 252 static UniqueName lhsNamer( "__massassign_L" ); 249 253 static UniqueName rhsNamer( "__massassign_R" ); 250 assert ( ! lhs.empty() && rhs.size() <= 1); 254 // empty tuple case falls into this matcher, hence the second part of the assert 255 assert( (! lhs.empty() && rhs.size() <= 1) || (lhs.empty() && rhs.empty()) ); 251 256 252 257 ObjectDecl * rtmp = rhs.size() == 1 ? newObject( rhsNamer, rhs.front().expr ) : nullptr; 253 258 for ( ResolvExpr::Alternative & lhsAlt : lhs ) { 259 // create a temporary object for each value in the lhs and create a call involving the rhs 254 260 ObjectDecl * ltmp = newObject( lhsNamer, lhsAlt.expr ); 255 261 out.push_back( createFunc( spotter.fname, ltmp, rtmp ) ); … … 263 269 static UniqueName rhsNamer( "__multassign_R" ); 264 270 265 // xxx - need more complicated matching?266 271 if ( lhs.size() == rhs.size() ) { 272 // produce a new temporary object for each value in the lhs and rhs and pairwise create the calls 267 273 std::list< ObjectDecl * > ltmp; 268 274 std::list< ObjectDecl * > rtmp;
Note:
See TracChangeset
for help on using the changeset viewer.