Changes in src/Tuples/TupleAssignment.cc [615a096:7d49b72]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Tuples/TupleAssignment.cc
r615a096 r7d49b72 22 22 #include "Explode.h" 23 23 #include "Common/SemanticError.h" 24 #include "CodeGen/OperatorTable.h" 24 25 #include "InitTweak/InitTweak.h" 25 26 #include "InitTweak/GenInit.h" … … 77 78 if ( ! expr ) return false; 78 79 assert( expr->has_result() ); 79 return dynamic_cast< TupleType * >( expr->get_result() );80 return dynamic_cast< TupleType * >( expr->get_result()->stripReferences() ); 80 81 } 81 82 … … 89 90 } 90 91 91 bool pointsToTuple( Expression *expr ) { 92 bool refToTuple( Expression *expr ) { 93 assert( expr->get_result() ); 92 94 // also check for function returning tuple of reference types 93 95 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) { 94 return pointsToTuple( castExpr->get_arg() );95 } else if ( AddressExpr *addr = dynamic_cast< AddressExpr * >( expr) ){96 return isTuple( addr->get_arg());96 return refToTuple( castExpr->get_arg() ); 97 } else { 98 return isTuple( expr ); 97 99 } 98 100 return false; … … 109 111 void TupleAssignSpotter::spot( UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities ) { 110 112 if ( NameExpr *op = dynamic_cast< NameExpr * >(expr->get_function()) ) { 111 if ( InitTweak::isCtorDtorAssign( op->get_name() ) ) {113 if ( CodeGen::isCtorDtorAssign( op->get_name() ) ) { 112 114 fname = op->get_name(); 113 115 for ( std::list<ResolvExpr::AltList>::const_iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) { 114 116 if ( ali->size() == 0 ) continue; // AlternativeFinder will natrually handle this case, if it's legal 115 if ( ali->size() <= 1 && InitTweak::isAssignment( op->get_name() ) ) {117 if ( ali->size() <= 1 && CodeGen::isAssignment( op->get_name() ) ) { 116 118 // what does it mean if an assignment takes 1 argument? maybe someone defined such a function, in which case AlternativeFinder will naturally handle it 117 119 continue; … … 122 124 const ResolvExpr::Alternative & alt1 = ali->front(); 123 125 auto begin = std::next(ali->begin(), 1), end = ali->end(); 124 if ( pointsToTuple(alt1.expr) ) {126 if ( refToTuple(alt1.expr) ) { 125 127 if ( isMultAssign( begin, end ) ) { 126 128 matcher.reset( new MultipleAssignMatcher( *this, *ali ) ); … … 196 198 for ( ResolvExpr::Alternative & alt : lhs ) { 197 199 Expression *& expr = alt.expr; 198 Type * castType = expr->get_result()->clone(); 199 Type * type = InitTweak::getPointerBase( castType ); 200 assert( type ); 200 Type * type = expr->get_result()->clone(); 201 201 type->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic ); 202 type->set_lvalue( true ); // xxx - might not need this 203 expr = new CastExpr( expr, castType ); 202 expr = new CastExpr( expr, new ReferenceType( Type::Qualifiers(), type ) ); 203 } 204 } 205 206 for ( ResolvExpr::Alternative & alt : lhs ) { 207 // every LHS value must be a reference - some come in with a cast expression, if it doesn't just cast to reference here. 208 // TODO: can this somehow be merge with the cast code directly above? 209 if ( ! dynamic_cast< ReferenceType * >( alt.expr->get_result() ) ) { 210 alt.expr = new CastExpr( alt.expr, new ReferenceType( Type::Qualifiers(), alt.expr->get_result()->clone() ) ); 204 211 } 205 212 } … … 221 228 assert( left ); 222 229 std::list< Expression * > args; 223 args.push_back( new AddressExpr( UntypedExpr::createDeref( new VariableExpr( left ) )) );230 args.push_back( new VariableExpr( left ) ); 224 231 // args.push_back( new AddressExpr( new VariableExpr( left ) ) ); 225 232 if ( right ) args.push_back( new VariableExpr( right ) ); … … 241 248 assert( expr->has_result() && ! expr->get_result()->isVoid() ); 242 249 ObjectDecl * ret = new ObjectDecl( namer.newName(), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, expr->get_result()->clone(), new SingleInit( expr->clone() ) ); 243 ConstructorInit * ctorInit = InitTweak::genCtorInit( ret ); 244 ret->set_init( ctorInit ); 245 ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object 246 EnvRemover rm; // remove environments from subexpressions of StmtExprs 247 ctorInit->accept( rm ); 250 // if expression type is a reference, don't need to construct anything, a simple initializer is sufficient. 251 if ( ! dynamic_cast< ReferenceType * >( expr->get_result() ) ) { 252 ConstructorInit * ctorInit = InitTweak::genCtorInit( ret ); 253 ret->set_init( ctorInit ); 254 ResolvExpr::resolveCtorInit( ctorInit, spotter.currentFinder.get_indexer() ); // resolve ctor/dtors for the new object 255 EnvRemover rm; // remove environments from subexpressions of StmtExprs 256 ctorInit->accept( rm ); 257 } 248 258 return ret; 249 259 }
Note: See TracChangeset
for help on using the changeset viewer.