Changeset d335627
- Timestamp:
- Jul 25, 2017, 10:48:07 AM (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:
- 8a6cf7e
- Parents:
- 6d267ca
- Location:
- src/GenPoly
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
r6d267ca rd335627 1027 1027 } // if 1028 1028 if ( baseType1 || baseType2 ) { 1029 ret->set_result( appExpr->get_result()->clone() ); 1029 Type * baseType = InitTweak::getPointerBase( appExpr->get_result() ); 1030 assert( baseType ); 1031 ret->set_result( baseType->clone() ); 1030 1032 if ( appExpr->get_env() ) { 1031 1033 ret->set_env( appExpr->get_env() ); … … 1222 1224 // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward 1223 1225 // out of the if condition. 1226 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 1227 // ... but must happen after mutate, since argument might change (e.g. intrinsic *?, ?[?]) - re-evaluate above comment 1224 1228 bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env ); 1225 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );1226 1229 if ( polytype || needs ) { 1227 1230 Expression *ret = addrExpr->get_arg(); -
src/GenPoly/Lvalue.cc
r6d267ca rd335627 82 82 /// https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Lvalues.html#Lvalues 83 83 /// Replaces &(a,b) with (a, &b), &(a ? b : c) with (a ? &b : &c) 84 struct GeneralizedLvalue final {84 struct GeneralizedLvalue final : public WithVisitorRef<GeneralizedLvalue> { 85 85 Expression * postmutate( AddressExpr * addressExpr ); 86 86 }; … … 145 145 } 146 146 147 void fixArg( Expression *& arg, Type * formal ) {148 if ( dynamic_cast<ReferenceType*>( formal ) ) {149 // if the parameter is a reference, add a dereference to the reference-typed argument.150 Type * baseType = InitTweak::getPointerBase( arg->get_result() );151 assertf( baseType, "parameter is reference, arg must be pointer or reference: %s", toString( arg->get_result() ) );152 PointerType * ptrType = new PointerType( Type::Qualifiers(), baseType->clone() );153 delete arg->get_result();154 arg->set_result( ptrType );155 arg = mkDeref( arg );156 }157 }158 159 147 // xxx - might need to & every * (or every * that is an arg to non-intrinsic function??) 160 148 Expression * FixIntrinsicArgs::postmutate( ApplicationExpr * appExpr ) { 161 149 // intrinsic functions don't really take reference-typed parameters, so they require an implicit dereference on their arguments. 162 150 if ( DeclarationWithType * function = InitTweak::getFunction( appExpr ) ) { 163 if ( function->get_linkage() == LinkageSpec::Intrinsic ) { 164 FunctionType * ftype = GenPoly::getFunctionType( function->get_type() ); 165 assertf( ftype, "Function declaration does not have function type." ); 166 for ( auto p : group_iterate( appExpr->get_args(), ftype->get_parameters() ) ) { 167 Expression *& arg = std::get<0>( p ); 168 DeclarationWithType * formal = std::get<1>( p ); 169 PRINT( 170 std::cerr << "pair<0>: " << arg << std::endl; 171 std::cerr << "pair<1>: " << formal->get_type() << std::endl; 172 ) 173 if ( isIntrinsicReference( arg ) ) { // intrinsic functions that turn pointers into references 174 // if argument is dereference or array subscript, the result isn't REALLY a reference, so it's not necessary to fix the argument 175 PRINT( std::cerr << "skipping intrinsic reference" << std::endl; ) 176 continue; 177 } else { 178 fixArg( arg, formal->get_type() ); 151 FunctionType * ftype = GenPoly::getFunctionType( function->get_type() ); 152 assertf( ftype, "Function declaration does not have function type." ); 153 // can be of differing lengths only when function is variadic 154 assertf( ftype->get_parameters().size() == appExpr->get_args().size() || ftype->get_isVarArgs(), "ApplicationExpr args do not match formal parameter type." ); 155 unsigned int i = 0; 156 const unsigned int end = ftype->get_parameters().size(); 157 for ( auto p : unsafe_group_iterate( appExpr->get_args(), ftype->get_parameters() ) ) { 158 if (i == end) break; 159 Expression *& arg = std::get<0>( p ); 160 Type * formal = std::get<1>( p )->get_type(); 161 PRINT( 162 std::cerr << "pair<0>: " << arg << std::endl; 163 std::cerr << "pair<1>: " << formal << std::endl; 164 ) 165 if ( dynamic_cast<ReferenceType*>( formal ) ) { 166 if ( isIntrinsicReference( arg ) ) { 167 if ( function->get_linkage() != LinkageSpec::Intrinsic ) { // intrinsic functions that turn pointers into references 168 // if argument is dereference or array subscript, the result isn't REALLY a reference, so it's not necessary to fix the argument 169 PRINT( std::cerr << "is intrinsic arg in non-intrinsic call - adding address" << std::endl; ) 170 arg = new AddressExpr( arg ); 171 } 172 } else if ( function->get_linkage() == LinkageSpec::Intrinsic ) { 173 // if the parameter is a reference, add a dereference to the reference-typed argument. 174 Type * baseType = InitTweak::getPointerBase( arg->get_result() ); 175 assertf( baseType, "parameter is reference, arg must be pointer or reference: %s", toString( arg->get_result() ) ); 176 PointerType * ptrType = new PointerType( Type::Qualifiers(), baseType->clone() ); 177 delete arg->get_result(); 178 arg->set_result( ptrType ); 179 arg = mkDeref( arg ); 179 180 } 180 181 } 182 ++i; 181 183 } 182 184 } … … 240 242 assertf( false, "Only conversions to reference from lvalue are currently supported: %s", toString( castExpr ).c_str() ); 241 243 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( castExpr->get_arg()->get_result() ) ) { 244 (void)refType; 242 245 // conversion from reference to rvalue 243 246 PRINT( std::cerr << "convert reference to rvalue -- *" << std::endl; ) … … 270 273 Expression * arg2 = commaExpr->get_arg2()->clone(); 271 274 delete addrExpr; 272 return new CommaExpr( arg1, new AddressExpr( arg2) );275 return new CommaExpr( arg1, (new AddressExpr( arg2 ))->acceptMutator( *visitor ) ); 273 276 } else if ( ConditionalExpr * condExpr = dynamic_cast< ConditionalExpr * >( addrExpr->get_arg() ) ) { 274 277 Expression * arg1 = condExpr->get_arg1()->clone(); … … 276 279 Expression * arg3 = condExpr->get_arg3()->clone(); 277 280 delete addrExpr; 278 return new ConditionalExpr( arg1, new AddressExpr( arg2 ), new AddressExpr( arg3) );281 return new ConditionalExpr( arg1, (new AddressExpr( arg2 ))->acceptMutator( *visitor ), (new AddressExpr( arg3 ))->acceptMutator( *visitor ) ); 279 282 } 280 283 return addrExpr;
Note: See TracChangeset
for help on using the changeset viewer.