Changeset 0b5d871
- Timestamp:
- Aug 22, 2017, 7:07:22 PM (7 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:
- 5fb6830
- Parents:
- 5ccb10d
- Location:
- src/Tuples
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Tuples/Explode.cc
r5ccb10d r0b5d871 16 16 #include "Explode.h" 17 17 #include "SynTree/Mutator.h" 18 #include "Common/PassVisitor.h" 18 19 19 20 namespace Tuples { 20 21 namespace { 21 struct AddrExploder : public Mutator { 22 // remove one level of reference from a reference type -- may be useful elsewhere. 23 Type * getReferenceBase( Type * t ) { 24 if ( ReferenceType * refType = dynamic_cast<ReferenceType *>( t ) ) { 25 return refType->get_base(); 26 } else { 27 // for the moment, I want to know immediately if a non-reference type is ever passed in here. 28 assertf( false, "getReferenceBase for non-ref: %s", toString( refType ).c_str() ); 29 return nullptr; 30 } 31 } 32 33 struct CastExploder { 34 bool castAdded = false; 22 35 bool foundUniqueExpr = false; 23 Expression * apply Addr( Expression * expr, bool first = true ) {36 Expression * applyCast( Expression * expr, bool first = true ) { 24 37 if ( TupleExpr * tupleExpr = dynamic_cast< TupleExpr * >( expr ) ){ 25 38 foundUniqueExpr = true; 26 39 std::list< Expression * > exprs; 27 40 for ( Expression *& expr : tupleExpr->get_exprs() ) { 28 // move &into tuple exprs29 exprs.push_back( apply Addr( expr, false ) );41 // move cast into tuple exprs 42 exprs.push_back( applyCast( expr, false ) ); 30 43 } 31 // want the top-level expression to be address-taken, but not nested44 // want the top-level expression to be cast to reference type, but not nested 32 45 // tuple expressions 33 46 if ( first ) { 34 return new AddressExpr( new TupleExpr( exprs ) ); 47 castAdded = true; 48 Expression * tupleExpr = new TupleExpr( exprs ); 49 return new CastExpr( tupleExpr, new ReferenceType( Type::Qualifiers(), tupleExpr->result->clone() ) ); 35 50 } else { 36 51 return new TupleExpr( exprs ); 37 52 } 38 53 } 39 // anything else should be address-taken as normal 40 return new AddressExpr( expr->clone() ); 54 if ( dynamic_cast<ReferenceType*>( expr->result ) ) { 55 // don't need to cast reference type to another reference type 56 return expr->clone(); 57 } else { 58 // anything else should be cast to reference as normal 59 castAdded = true; 60 return new CastExpr( expr->clone(), new ReferenceType( Type::Qualifiers(), expr->result->clone() ) ); 61 } 41 62 } 42 63 43 virtual Expression *mutate( UniqueExpr * uniqueExpr ) {44 // move & into unique expr so that the unique expr has type T*rather than64 Expression * postmutate( UniqueExpr * uniqueExpr ) { 65 // move cast into unique expr so that the unique expr has type T& rather than 45 66 // type T. In particular, this transformation helps with generating the 46 // correct code for address-takenmember tuple expressions, since the result47 // should now be a tuple of addresses rather than the address ofa tuple.67 // correct code for reference-cast member tuple expressions, since the result 68 // should now be a tuple of references rather than a reference to a tuple. 48 69 // Still, this code is a bit awkward, and could use some improvement. 49 if ( dynamic_cast< AddressExpr * > ( uniqueExpr->get_expr() ) ) { 50 // this unique expression has already been mutated or otherwise shouldn't be (can't take the address-of an address-of expression) 51 return uniqueExpr; 70 UniqueExpr * newUniqueExpr = new UniqueExpr( applyCast( uniqueExpr->get_expr() ), uniqueExpr->get_id() ); 71 delete uniqueExpr; 72 if ( castAdded ) { 73 // if a cast was added by applyCast, then unique expr now has one more layer of reference 74 // than it had coming into this function. To ensure types still match correctly, need to cast 75 // to reference base so that outer expressions are still correct. 76 castAdded = false; 77 Type * toType = getReferenceBase( newUniqueExpr->result ); 78 return new CastExpr( newUniqueExpr, toType->clone() ); 52 79 } 53 UniqueExpr * newUniqueExpr = new UniqueExpr( applyAddr( uniqueExpr->get_expr() ), uniqueExpr->get_id() ); 54 delete uniqueExpr; 55 UntypedExpr * deref = UntypedExpr::createDeref( Mutator::mutate( newUniqueExpr ) ); 56 return deref; 80 return newUniqueExpr; 57 81 } 58 82 59 virtual Expression * mutate( TupleIndexExpr * tupleExpr ) { 83 84 Expression * postmutate( TupleIndexExpr * tupleExpr ) { 60 85 // tuple index expr needs to be rebuilt to ensure that the type of the 61 86 // field is consistent with the type of the tuple expr, since the field 62 // may have changed from type T to T *.63 Expression * expr = tupleExpr->get_tuple() ->acceptMutator( *this );87 // may have changed from type T to T&. 88 Expression * expr = tupleExpr->get_tuple(); 64 89 tupleExpr->set_tuple( nullptr ); 65 90 TupleIndexExpr * ret = new TupleIndexExpr( expr, tupleExpr->get_index() ); … … 70 95 } // namespace 71 96 72 Expression * distributeAddr( Expression * expr ) { 73 AddrExploder addrExploder; 74 expr = expr->acceptMutator( addrExploder ); 75 if ( ! addrExploder.foundUniqueExpr ) { 76 expr = new AddressExpr( expr ); 97 Expression * distributeReference( Expression * expr ) { 98 PassVisitor<CastExploder> exploder; 99 expr = expr->acceptMutator( exploder ); 100 if ( ! exploder.pass.foundUniqueExpr ) { 101 // if a UniqueExpr was found, then the cast has already been added inside the UniqueExpr as appropriate 102 expr = new CastExpr( expr, new ReferenceType( Type::Qualifiers(), expr->result->clone() ) ); 77 103 } 78 104 return expr; -
src/Tuples/Explode.h
r5ccb10d r0b5d871 26 26 27 27 namespace Tuples { 28 Expression * distributeReference( Expression * ); 29 28 30 /// helper function used by explode 29 31 template< typename OutputIterator > 30 32 void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign ) { 33 if ( isTupleAssign ) { 34 // tuple assignment needs CastExprs to be recursively exploded to easily get at all of the components 35 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) { 36 ResolvExpr::AltList alts; 37 explodeUnique( castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign ); 38 for ( ResolvExpr::Alternative & alt : alts ) { 39 // distribute reference cast over all components 40 alt.expr = distributeReference( alt.expr ); 41 *out++ = alt; 42 } 43 // 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) 44 return; 45 } 46 } 31 47 Type * res = expr->get_result()->stripReferences(); 32 48 if ( TupleType * tupleType = dynamic_cast< TupleType * > ( res ) ) { … … 40 56 // if expr type is reference, convert to value type 41 57 Expression * arg = expr->clone(); 42 43 if ( dynamic_cast<ReferenceType *>( arg->get_result() ) ) { 44 // TODO: does this go here (inside uniqueexpr) or outside uniqueexpr? I'm guessing probably should go after... 45 arg = new CastExpr( arg, tupleType->clone() ); 46 } 47 if ( Tuples::maybeImpure( arg ) && ! dynamic_cast< UniqueExpr * >( arg ) ) { 58 if ( Tuples::maybeImpureIgnoreUnique( arg ) ) { 48 59 // expressions which may contain side effects require a single unique instance of the expression. 49 60 arg = new UniqueExpr( arg ); 61 } 62 // cast reference to value type to facilitate further explosion 63 if ( dynamic_cast<ReferenceType *>( arg->get_result() ) ) { 64 arg = new CastExpr( arg, tupleType->clone() ); 50 65 } 51 66 for ( unsigned int i = 0; i < tupleType->size(); i++ ) {
Note: See TracChangeset
for help on using the changeset viewer.