Changeset d3e4d6c for src/Tuples/Explode.cc
- Timestamp:
- Aug 23, 2017, 6:22:07 PM (8 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:
- 87e08e24, cb811ac
- Parents:
- 9f07232 (diff), bd37119 (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Tuples/Explode.cc
r9f07232 rd3e4d6c 15 15 16 16 #include "Explode.h" 17 #include <list> // for list 17 18 18 #include <list> // for list 19 20 #include "SynTree/Mutator.h" // for Mutator 19 #include "SynTree/Mutator.h" // for Mutator 20 #include "Common/PassVisitor.h" // for PassVisitor 21 21 22 22 namespace Tuples { 23 23 namespace { 24 struct AddrExploder : public Mutator { 24 // remove one level of reference from a reference type -- may be useful elsewhere. 25 Type * getReferenceBase( Type * t ) { 26 if ( ReferenceType * refType = dynamic_cast<ReferenceType *>( t ) ) { 27 return refType->get_base(); 28 } else { 29 // for the moment, I want to know immediately if a non-reference type is ever passed in here. 30 assertf( false, "getReferenceBase for non-ref: %s", toString( refType ).c_str() ); 31 return nullptr; 32 } 33 } 34 35 struct CastExploder { 36 bool castAdded = false; 25 37 bool foundUniqueExpr = false; 26 Expression * apply Addr( Expression * expr, bool first = true ) {38 Expression * applyCast( Expression * expr, bool first = true ) { 27 39 if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( expr ) ){ 28 40 foundUniqueExpr = true; 29 41 std::list< Expression * > exprs; 30 42 for ( Expression *& expr : tupleExpr->get_exprs() ) { 31 // move &into tuple exprs32 exprs.push_back( apply Addr( expr, false ) );43 // move cast into tuple exprs 44 exprs.push_back( applyCast( expr, false ) ); 33 45 } 34 // want the top-level expression to be address-taken, but not nested46 // want the top-level expression to be cast to reference type, but not nested 35 47 // tuple expressions 36 48 if ( first ) { 37 return new AddressExpr( new TupleExpr( exprs ) ); 49 castAdded = true; 50 Expression * tupleExpr = new TupleExpr( exprs ); 51 return new CastExpr( tupleExpr, new ReferenceType( Type::Qualifiers(), tupleExpr->result->clone() ) ); 38 52 } else { 39 53 return new TupleExpr( exprs ); 40 54 } 41 55 } 42 // anything else should be address-taken as normal 43 return new AddressExpr( expr->clone() ); 56 if ( dynamic_cast<ReferenceType*>( expr->result ) ) { 57 // don't need to cast reference type to another reference type 58 return expr->clone(); 59 } else { 60 // anything else should be cast to reference as normal 61 castAdded = true; 62 return new CastExpr( expr->clone(), new ReferenceType( Type::Qualifiers(), expr->result->clone() ) ); 63 } 44 64 } 45 65 46 virtual Expression *mutate( UniqueExpr * uniqueExpr ) {47 // move & into unique expr so that the unique expr has type T*rather than66 Expression * postmutate( UniqueExpr * uniqueExpr ) { 67 // move cast into unique expr so that the unique expr has type T& rather than 48 68 // type T. In particular, this transformation helps with generating the 49 // correct code for address-takenmember tuple expressions, since the result50 // should now be a tuple of addresses rather than the address ofa tuple.69 // correct code for reference-cast member tuple expressions, since the result 70 // should now be a tuple of references rather than a reference to a tuple. 51 71 // Still, this code is a bit awkward, and could use some improvement. 52 if ( dynamic_cast< AddressExpr * > ( uniqueExpr->get_expr() ) ) { 53 // this unique expression has already been mutated or otherwise shouldn't be (can't take the address-of an address-of expression) 54 return uniqueExpr; 72 UniqueExpr * newUniqueExpr = new UniqueExpr( applyCast( uniqueExpr->get_expr() ), uniqueExpr->get_id() ); 73 delete uniqueExpr; 74 if ( castAdded ) { 75 // if a cast was added by applyCast, then unique expr now has one more layer of reference 76 // than it had coming into this function. To ensure types still match correctly, need to cast 77 // to reference base so that outer expressions are still correct. 78 castAdded = false; 79 Type * toType = getReferenceBase( newUniqueExpr->result ); 80 return new CastExpr( newUniqueExpr, toType->clone() ); 55 81 } 56 UniqueExpr * newUniqueExpr = new UniqueExpr( applyAddr( uniqueExpr->get_expr() ), uniqueExpr->get_id() ); 57 delete uniqueExpr; 58 UntypedExpr * deref = UntypedExpr::createDeref( Mutator::mutate( newUniqueExpr ) ); 59 return deref; 82 return newUniqueExpr; 60 83 } 61 84 62 virtual Expression * mutate( TupleIndexExpr * tupleExpr ) { 85 86 Expression * postmutate( TupleIndexExpr * tupleExpr ) { 63 87 // tuple index expr needs to be rebuilt to ensure that the type of the 64 88 // field is consistent with the type of the tuple expr, since the field 65 // may have changed from type T to T *.66 Expression * expr = tupleExpr->get_tuple() ->acceptMutator( *this );89 // may have changed from type T to T&. 90 Expression * expr = tupleExpr->get_tuple(); 67 91 tupleExpr->set_tuple( nullptr ); 68 92 TupleIndexExpr * ret = new TupleIndexExpr( expr, tupleExpr->get_index() ); … … 73 97 } // namespace 74 98 75 Expression * distributeAddr( Expression * expr ) { 76 AddrExploder addrExploder; 77 expr = expr->acceptMutator( addrExploder ); 78 if ( ! addrExploder.foundUniqueExpr ) { 79 expr = new AddressExpr( expr ); 99 Expression * distributeReference( Expression * expr ) { 100 PassVisitor<CastExploder> exploder; 101 expr = expr->acceptMutator( exploder ); 102 if ( ! exploder.pass.foundUniqueExpr ) { 103 // if a UniqueExpr was found, then the cast has already been added inside the UniqueExpr as appropriate 104 expr = new CastExpr( expr, new ReferenceType( Type::Qualifiers(), expr->result->clone() ) ); 80 105 } 81 106 return expr;
Note:
See TracChangeset
for help on using the changeset viewer.