Changes in src/Tuples/Explode.cc [b910d15:0b5d871]
- File:
-
- 1 edited
-
src/Tuples/Explode.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Tuples/Explode.cc
rb910d15 r0b5d871 9 9 // Author : Rob Schluntz 10 10 // Created On : Wed Nov 9 13:12:24 2016 11 // Last Modified By : Andrew Beach12 // Last Modified On : Wed Jun 12 16:40:00201613 // Update Count : 311 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Nov 9 13:20:24 2016 13 // Update Count : 2 14 14 // 15 15 16 16 #include "Explode.h" 17 #include <list> // for list 18 19 #include "SynTree/Mutator.h" // for Mutator 20 #include "Common/PassVisitor.h" // for PassVisitor 17 #include "SynTree/Mutator.h" 18 #include "Common/PassVisitor.h" 21 19 22 20 namespace Tuples { … … 106 104 return expr; 107 105 } 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->location,138 tuple, new ast::ReferenceType( tuple->result.get(), ast::CV::Qualifiers() ) );139 } else {140 return new ast::TupleExpr( tupleExpr->location, std::move( exprs ) );141 }142 }143 if ( dynamic_cast< const ast::ReferenceType * >( expr->result.get() ) ) {144 return expr;145 } else {146 castAdded = true;147 return new ast::CastExpr( expr->location, expr,148 new ast::ReferenceType( expr->result, ast::CV::Qualifiers() ) );149 }150 }151 152 const ast::Expr * postmutate( const ast::UniqueExpr * node ) {153 // move cast into unique expr so that the unique expr has type T& rather than154 // type T. In particular, this transformation helps with generating the155 // correct code for reference-cast member tuple expressions, since the result156 // should now be a tuple of references rather than a reference to a tuple.157 // Still, this code is a bit awkward, and could use some improvement.158 const ast::UniqueExpr * newNode = new ast::UniqueExpr( node->location,159 applyCast( node->expr ), node->id );160 if ( castAdded ) {161 // if a cast was added by applyCast, then unique expr now has one more layer of reference162 // than it had coming into this function. To ensure types still match correctly, need to cast163 // to reference base so that outer expressions are still correct.164 castAdded = false;165 const ast::Type * newType = getReferenceBase( newNode->result );166 return new ast::CastExpr( newNode->location, node, newType );167 }168 return newNode;169 }170 171 const ast::Expr * postmutate( const ast::TupleIndexExpr * tupleExpr ) {172 // tuple index expr needs to be rebuilt to ensure that the type of the173 // field is consistent with the type of the tuple expr, since the field174 // may have changed from type T to T&.175 return new ast::TupleIndexExpr( tupleExpr->location, tupleExpr->tuple, tupleExpr->index );176 }177 };178 179 } // namespace180 181 const ast::Expr * distributeReference( const ast::Expr * expr ) {182 ast::Pass<CastExploderCore> exploder;183 expr = expr->accept( exploder );184 if ( ! exploder.pass.foundUniqueExpr ) {185 expr = new ast::CastExpr( expr->location, expr,186 new ast::ReferenceType( expr->result, ast::CV::Qualifiers() ) );187 }188 return expr;189 }190 191 106 } // namespace Tuples 192 107
Note:
See TracChangeset
for help on using the changeset viewer.