Changeset cb43451
- Timestamp:
- Jul 21, 2017, 9:51:17 AM (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:
- 53a8e68
- Parents:
- 17f22e78
- Location:
- src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Lvalue.cc
r17f22e78 rcb43451 39 39 // need to be careful about polymorphic references... e.g. in *? (___operator_deref__A0_1_0_0__Fd0_Pd0_intrinsic___1) 40 40 // the variable is automatically dereferenced and this causes errors dereferencing void*. 41 42 #if 0 43 #define PRINT(x) x 44 #else 45 #define PRINT(x) 46 #endif 41 47 42 48 namespace GenPoly { … … 79 85 Expression * postmutate( AddressExpr * addressExpr ); 80 86 }; 87 88 /// Removes redundant &*/*& pattern that this pass can generate 89 struct CollapseAddrDeref final { 90 Expression * postmutate( AddressExpr * addressExpr ); 91 Expression * postmutate( ApplicationExpr * appExpr ); 92 }; 81 93 } // namespace 82 94 … … 87 99 PassVisitor<GeneralizedLvalue> genLval; 88 100 PassVisitor<FixIntrinsicArgs> fixer; 101 PassVisitor<CollapseAddrDeref> collapser; 89 102 mutateAll( translationUnit, refCvt ); 90 103 mutateAll( translationUnit, fixer ); 91 104 mutateAll( translationUnit, elim ); 92 105 mutateAll( translationUnit, genLval ); 106 mutateAll( translationUnit, collapser ); 93 107 } 94 108 … … 139 153 delete arg->get_result(); 140 154 arg->set_result( ptrType ); 141 arg = mkDeref( new CastExpr( arg, arg->get_result()->clone() ) ); 142 } 143 } 144 155 arg = mkDeref( arg ); 156 } 157 } 158 159 // xxx - might need to & every * (or every * that is an arg to non-intrinsic function??) 145 160 Expression * FixIntrinsicArgs::postmutate( ApplicationExpr * appExpr ) { 146 161 // intrinsic functions don't really take reference-typed parameters, so they require an implicit dereference on their arguments. … … 152 167 Expression *& arg = std::get<0>( p ); 153 168 DeclarationWithType * formal = std::get<1>( p ); 154 std::cerr << "pair<0>: " << arg << std::endl; 155 std::cerr << "pair<1>: " << formal->get_type() << std::endl; 169 PRINT( 170 std::cerr << "pair<0>: " << arg << std::endl; 171 std::cerr << "pair<1>: " << formal->get_type() << std::endl; 172 ) 156 173 if ( isIntrinsicReference( arg ) ) { // intrinsic functions that turn pointers into references 157 174 // if argument is dereference or array subscript, the result isn't REALLY a reference, so it's not necessary to fix the argument 158 std::cerr << "skipping intrinsic reference" << std::endl;175 PRINT( std::cerr << "skipping intrinsic reference" << std::endl; ) 159 176 continue; 160 177 } else { … … 181 198 // nothing to do if casting from reference to reference. 182 199 (void)otherRef; 183 std::cerr << "convert reference to reference -- nop" << std::endl;200 PRINT( std::cerr << "convert reference to reference -- nop" << std::endl; ) 184 201 if ( isIntrinsicReference( castExpr->get_arg() ) ) { 185 202 Expression * callExpr = castExpr->get_arg(); 186 std::cerr << "but arg is deref -- &" << std::endl; 187 std::cerr << callExpr << std::endl; 203 PRINT( 204 std::cerr << "but arg is deref -- &" << std::endl; 205 std::cerr << callExpr << std::endl; 206 ) 188 207 // move environment out to new top-level 189 208 callExpr->set_env( castExpr->get_env() ); … … 194 213 } 195 214 assertf( false, "non-intrinsic reference with cast of reference to reference not yet supported: ", toString( castExpr ) ); 196 std::cerr << castExpr << std::endl;215 PRINT( std::cerr << castExpr << std::endl; ) 197 216 return castExpr; 198 217 } else if ( castExpr->get_arg()->get_result()->get_lvalue() ) { … … 200 219 // xxx - keep cast, but turn into pointer cast?? 201 220 // xxx - memory 202 std::cerr << "convert lvalue to reference -- &" << std::endl; 203 std::cerr << castExpr->get_arg() << std::endl; 204 Expression * ret = new AddressExpr( castExpr->get_arg() ); 221 PRINT( 222 std::cerr << "convert lvalue to reference -- &" << std::endl; 223 std::cerr << castExpr->get_arg() << std::endl; 224 ) 225 AddressExpr * ret = new AddressExpr( castExpr->get_arg() ); 226 if ( refType->get_base()->get_qualifiers() != castExpr->get_arg()->get_result()->get_qualifiers() ) { 227 // must keep cast if cast-to type is different from the actual type 228 castExpr->set_arg( ret ); 229 230 return castExpr; 231 } 205 232 ret->set_env( castExpr->get_env() ); 206 233 castExpr->set_env( nullptr ); … … 215 242 // conversion from reference to rvalue 216 243 // should be easy, just need to move deref code up here? 217 std::cerr << "convert reference to rvalue -- *" << std::endl;244 PRINT( std::cerr << "convert reference to rvalue -- *" << std::endl; ) 218 245 if ( isIntrinsicReference( castExpr->get_arg() ) ) { 219 std::cerr << "but arg is intrinsic reference -- nop" << std::endl;246 PRINT( std::cerr << "but arg is intrinsic reference -- nop" << std::endl; ) 220 247 return castExpr; 221 248 } 222 std::cerr << "was = " << castExpr << std::endl;249 PRINT( std::cerr << "was = " << castExpr << std::endl; ) 223 250 224 251 Expression * deref = mkDeref( castExpr->get_arg() ); … … 227 254 castExpr->set_env( nullptr ); 228 255 delete castExpr; 229 std::cerr << "now: " << deref << std::endl;256 PRINT( std::cerr << "now: " << deref << std::endl; ) 230 257 return deref; 231 258 } … … 255 282 return addrExpr; 256 283 } 284 285 Expression * CollapseAddrDeref::postmutate( AddressExpr * addressExpr ) { 286 Expression * arg = addressExpr->get_arg(); 287 if ( isIntrinsicReference( arg ) ) { 288 std::string fname = InitTweak::getFunctionName( arg ); 289 if ( fname == "*?" ) { 290 Expression *& arg0 = InitTweak::getCallArg( arg, 0 ); 291 Expression * ret = arg0; 292 ret->set_env( addressExpr->get_env() ); 293 arg0 = nullptr; 294 addressExpr->set_env( nullptr ); 295 delete addressExpr; 296 return ret; 297 } 298 } 299 return addressExpr; 300 } 301 302 Expression * CollapseAddrDeref::postmutate( ApplicationExpr * appExpr ) { 303 if ( isIntrinsicReference( appExpr ) ) { 304 std::string fname = InitTweak::getFunctionName( appExpr ); 305 if ( fname == "*?" ) { 306 Expression * arg = InitTweak::getCallArg( appExpr, 0 ); 307 // xxx - this isn't right, because it can remove casts that should be there... 308 // while ( CastExpr * castExpr = dynamic_cast< CastExpr * >( arg ) ) { 309 // arg = castExpr->get_arg(); 310 // } 311 if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( arg ) ) { 312 Expression * ret = addrExpr->get_arg(); 313 ret->set_env( appExpr->get_env() ); 314 addrExpr->set_arg( nullptr ); 315 appExpr->set_env( nullptr ); 316 delete appExpr; 317 return ret; 318 } 319 } 320 } 321 return appExpr; 322 } 257 323 } // namespace 258 324 } // namespace GenPoly -
src/ResolvExpr/ConversionCost.cc
r17f22e78 rcb43451 248 248 void ConversionCost::visit(PointerType *pointerType) { 249 249 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) { 250 if ( pointerType->get_base()->get_qualifiers() <= destAsPtr->get_base()->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) { 251 cost = Cost::safe; 252 } else { // xxx - this discards pointer qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right? 250 // std::cerr << pointerType << " ===> " << destAsPtr; 251 Type::Qualifiers tq1 = pointerType->get_base()->get_qualifiers(); 252 Type::Qualifiers tq2 = destAsPtr->get_base()->get_qualifiers(); 253 if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) { 254 if ( tq1 == tq2 ) { 255 // types are the same 256 cost = Cost::zero; 257 } else { 258 // types are the same, except otherPointer has more qualifiers 259 // std::cerr << " :: compatible and good qualifiers" << std::endl; 260 cost = Cost::safe; 261 } 262 } else { // xxx - this discards qualifiers from consideration -- reducing qualifiers is a safe conversion; is this right? 253 263 int assignResult = ptrsAssignable( pointerType->get_base(), destAsPtr->get_base(), env ); 254 if ( assignResult < 0 ) { 264 // std::cerr << " :: " << assignResult << std::endl; 265 if ( assignResult < 0 && pointerType->get_base()->get_qualifiers() <= destAsPtr->get_qualifiers() ) { 255 266 cost = Cost::safe; 256 267 } else if ( assignResult > 0 ) { 257 268 cost = Cost::unsafe; 258 269 } // if 270 // assignResult == 0 means Cost::Infinity 259 271 } // if 260 272 } else if ( dynamic_cast< ZeroType* >( dest ) != nullptr || dynamic_cast< OneType* >( dest ) != nullptr ) { … … 272 284 // cv can be safely dropped because of 'implicit dereference' behavior. 273 285 refType->get_base()->accept( *this ); 274 cost.incReference(); 286 if ( refType->get_base()->get_qualifiers() == dest->get_qualifiers() ) { 287 cost.incReference(); // prefer exact qualifiers 288 } else if ( refType->get_base()->get_qualifiers() < dest->get_qualifiers() ) { 289 cost.incSafe(); // then gaining qualifiers 290 } else { 291 cost.incUnsafe(); // lose qualifiers as last resort 292 } 293 // std::cerr << refType << " ==> " << dest << " " << cost << std::endl; 275 294 } 276 295
Note: See TracChangeset
for help on using the changeset viewer.