Changeset 2162c2c for src/Tuples
- Timestamp:
- Jan 11, 2017, 4:11:02 PM (9 years ago)
- 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, with_gc
- Children:
- 075734f
- Parents:
- bb82c03 (diff), d3a85240 (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. - Location:
- src/Tuples
- Files:
-
- 4 edited
-
Explode.h (modified) (3 diffs)
-
TupleAssignment.cc (modified) (6 diffs)
-
TupleExpansion.cc (modified) (3 diffs)
-
Tuples.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/Tuples/Explode.h
rbb82c03 r2162c2c 33 33 /// helper function used by explode 34 34 template< typename OutputIterator > 35 void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, const SymTab::Indexer & indexer, OutputIterator out ) { 35 void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign ) { 36 if ( isTupleAssign ) { 37 // tuple assignment needs AddressExprs to be recursively exploded to easily get at all of the components 38 if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( expr ) ) { 39 ResolvExpr::AltList alts; 40 explodeUnique( addrExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign ); 41 for ( ResolvExpr::Alternative & alt : alts ) { 42 // distribute '&' over all components 43 alt.expr = distributeAddr( alt.expr ); 44 *out++ = alt; 45 } 46 // 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) 47 return; 48 } 49 } 36 50 Type * res = expr->get_result(); 37 if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( expr ) ) { 38 ResolvExpr::AltList alts; 39 explodeUnique( addrExpr->get_arg(), alt, indexer, back_inserter( alts ) ); 40 for ( ResolvExpr::Alternative & alt : alts ) { 41 // distribute '&' over all components 42 alt.expr = distributeAddr( alt.expr ); 43 *out++ = alt; 44 } 45 } else if ( TupleType * tupleType = dynamic_cast< TupleType * > ( res ) ) { 51 if ( TupleType * tupleType = dynamic_cast< TupleType * > ( res ) ) { 46 52 if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( expr ) ) { 47 53 // can open tuple expr and dump its exploded components 48 54 for ( Expression * expr : tupleExpr->get_exprs() ) { 49 explodeUnique( expr, alt, indexer, out );55 explodeUnique( expr, alt, indexer, out, isTupleAssign ); 50 56 } 51 57 } else { … … 58 64 for ( unsigned int i = 0; i < tupleType->size(); i++ ) { 59 65 TupleIndexExpr * idx = new TupleIndexExpr( arg->clone(), i ); 60 explodeUnique( idx, alt, indexer, out );66 explodeUnique( idx, alt, indexer, out, isTupleAssign ); 61 67 delete idx; 62 68 } … … 71 77 /// expands a tuple-valued alternative into multiple alternatives, each with a non-tuple-type 72 78 template< typename OutputIterator > 73 void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer, OutputIterator out ) {74 explodeUnique( alt.expr, alt, indexer, out );79 void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) { 80 explodeUnique( alt.expr, alt, indexer, out, isTupleAssign ); 75 81 } 76 82 77 83 // explode list of alternatives 78 84 template< typename AltIterator, typename OutputIterator > 79 void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer, OutputIterator out ) {85 void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) { 80 86 for ( ; altBegin != altEnd; ++altBegin ) { 81 explode( *altBegin, indexer, out );87 explode( *altBegin, indexer, out, isTupleAssign ); 82 88 } 83 89 } 84 90 85 91 template< typename OutputIterator > 86 void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, OutputIterator out ) {87 explode( alts.begin(), alts.end(), indexer, out );92 void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) { 93 explode( alts.begin(), alts.end(), indexer, out, isTupleAssign ); 88 94 } 89 95 } // namespace Tuples -
src/Tuples/TupleAssignment.cc
rbb82c03 r2162c2c 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; -
src/Tuples/TupleExpansion.cc
rbb82c03 r2162c2c 144 144 145 145 Expression * MemberTupleExpander::mutate( UntypedMemberExpr * memberExpr ) { 146 if ( TupleExpr * tupleExpr = dynamic_cast<TupleExpr * > ( memberExpr->get_member() ) ) {146 if ( UntypedTupleExpr * tupleExpr = dynamic_cast< UntypedTupleExpr * > ( memberExpr->get_member() ) ) { 147 147 Expression * aggr = memberExpr->get_aggregate()->clone()->acceptMutator( *this ); 148 148 // aggregate expressions which might be impure must be wrapped in unique expressions … … 225 225 decl->get_parameters().push_back( tyParam ); 226 226 } 227 if ( tupleType->size() == 0 ) { 228 // empty structs are not standard C. Add a dummy field to empty tuples to silence warnings when a compound literal Tuple0 is created. 229 decl->get_members().push_back( new ObjectDecl( "dummy", DeclarationNode::NoStorageClass, LinkageSpec::C, nullptr, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) ); 230 } 227 231 typeMap[mangleName] = decl; 228 232 addDeclaration( decl ); … … 315 319 qualifiers &= type->get_qualifiers(); 316 320 } // for 321 if ( exprs.empty() ) qualifiers = Type::Qualifiers(); 317 322 return tupleType; 323 } 324 325 TypeInstType * isTtype( Type * type ) { 326 if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( type ) ) { 327 if ( inst->get_baseType()->get_kind() == TypeDecl::Ttype ) { 328 return inst; 329 } 330 } 331 return nullptr; 318 332 } 319 333 -
src/Tuples/Tuples.h
rbb82c03 r2162c2c 42 42 Type * makeTupleType( const std::list< Expression * > & exprs ); 43 43 44 /// returns a TypeInstType if `type` is a ttype, nullptr otherwise 45 TypeInstType * isTtype( Type * type ); 46 44 47 /// returns true if the expression may contain side-effects. 45 48 bool maybeImpure( Expression * expr );
Note:
See TracChangeset
for help on using the changeset viewer.