Changes in src/Tuples/Explode.cc [0b5d871:b8524ca]
- File:
-
- 1 edited
-
src/Tuples/Explode.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Tuples/Explode.cc
r0b5d871 rb8524ca 9 9 // Author : Rob Schluntz 10 10 // Created On : Wed Nov 9 13:12:24 2016 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Wed Nov 9 13:20:24201613 // Update Count : 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jun 12 16:40:00 2016 13 // Update Count : 3 14 14 // 15 15 16 16 #include "Explode.h" 17 #include "SynTree/Mutator.h" 18 #include "Common/PassVisitor.h" 17 #include <list> // for list 18 19 #include "SynTree/Mutator.h" // for Mutator 20 #include "Common/PassVisitor.h" // for PassVisitor 19 21 20 22 namespace Tuples { … … 104 106 return expr; 105 107 } 108 109 namespace { 110 111 // Remove one level of reference from a reference type. 112 const ast::Type * getReferenceBase( const ast::Type * t ) { 113 if ( const ast::ReferenceType * ref = dynamic_cast< const ast::ReferenceType * >( t ) ) { 114 return ref->base; 115 } else { 116 assertf( false, "getReferenceBase for non-ref: %s", toString( t ).c_str() ); 117 return nullptr; 118 } 119 } 120 121 struct CastExploderCore { 122 bool castAdded = false; 123 bool foundUniqueExpr = false; 124 const ast::Expr * applyCast( const ast::Expr * expr, bool first = true ) { 125 // On tuple push the cast down. 126 if ( const ast::TupleExpr * tupleExpr = dynamic_cast< const ast::TupleExpr * >( expr ) ) { 127 foundUniqueExpr = true; 128 std::vector< ast::ptr< ast::Expr > > exprs; 129 for ( const ast::Expr * expr : tupleExpr->exprs ) { 130 exprs.emplace_back( applyCast( expr, false ) ); 131 //exprs.emplace_back( ast::ptr< ast::Expr >( applyCast( expr, false ) ) ); 132 } 133 if ( first ) { 134 castAdded = true; 135 const ast::Expr * tuple = new ast::TupleExpr{ 136 tupleExpr->location, std::move( exprs ) }; 137 return new ast::CastExpr{ tuple, new ast::ReferenceType{ tuple->result } }; 138 } else { 139 return new ast::TupleExpr( tupleExpr->location, std::move( exprs ) ); 140 } 141 } 142 if ( dynamic_cast< const ast::ReferenceType * >( expr->result.get() ) ) { 143 return expr; 144 } else { 145 castAdded = true; 146 return new ast::CastExpr{ expr, new ast::ReferenceType{ expr->result } }; 147 } 148 } 149 150 const ast::Expr * postmutate( const ast::UniqueExpr * node ) { 151 // move cast into unique expr so that the unique expr has type T& rather than 152 // type T. In particular, this transformation helps with generating the 153 // correct code for reference-cast member tuple expressions, since the result 154 // should now be a tuple of references rather than a reference to a tuple. 155 // Still, this code is a bit awkward, and could use some improvement. 156 const ast::UniqueExpr * newNode = new ast::UniqueExpr( node->location, 157 applyCast( node->expr ), node->id ); 158 if ( castAdded ) { 159 // if a cast was added by applyCast, then unique expr now has one more layer of reference 160 // than it had coming into this function. To ensure types still match correctly, need to cast 161 // to reference base so that outer expressions are still correct. 162 castAdded = false; 163 const ast::Type * newType = getReferenceBase( newNode->result ); 164 return new ast::CastExpr{ newNode->location, node, newType }; 165 } 166 return newNode; 167 } 168 169 const ast::Expr * postmutate( const ast::TupleIndexExpr * tupleExpr ) { 170 // tuple index expr needs to be rebuilt to ensure that the type of the 171 // field is consistent with the type of the tuple expr, since the field 172 // may have changed from type T to T&. 173 return new ast::TupleIndexExpr( tupleExpr->location, tupleExpr->tuple, tupleExpr->index ); 174 } 175 }; 176 177 } // namespace 178 179 const ast::Expr * distributeReference( const ast::Expr * expr ) { 180 ast::Pass<CastExploderCore> exploder; 181 expr = expr->accept( exploder ); 182 if ( ! exploder.pass.foundUniqueExpr ) { 183 expr = new ast::CastExpr{ expr, new ast::ReferenceType{ expr->result } }; 184 } 185 return expr; 186 } 187 106 188 } // namespace Tuples 107 189
Note:
See TracChangeset
for help on using the changeset viewer.