Changeset da7fe39 for src/GenPoly/Lvalue.cc
- Timestamp:
- Apr 23, 2018, 12:57:46 PM (5 years ago)
- Branches:
- aaron-thesis, arm-eh, 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, with_gc
- Children:
- 57acae0
- Parents:
- ba89e9b7 (diff), c8ad5d9 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Lvalue.cc
rba89e9b7 rda7fe39 99 99 }; 100 100 101 struct AddrRef final : public WithGuards {101 struct AddrRef final : public WithGuards, public WithVisitorRef<AddrRef>, public WithShortCircuiting { 102 102 void premutate( AddressExpr * addrExpr ); 103 103 Expression * postmutate( AddressExpr * addrExpr ); 104 104 void premutate( Expression * expr ); 105 void premutate( ApplicationExpr * appExpr ); 106 void premutate( SingleInit * init ); 107 108 void handleNonAddr( Expression * ); 105 109 106 110 bool first = true; 107 111 bool current = false; 108 112 int refDepth = 0; 113 bool addCast = false; 109 114 }; 110 115 } // namespace … … 215 220 ) 216 221 // TODO: it's likely that the second condition should be ... && ! isIntrinsicReference( arg ), but this requires investigation. 217 // if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) { 218 // // if argument is dereference or array subscript, the result isn't REALLY a reference, but non-intrinsic functions expect a reference: take address 219 // // PRINT( 220 // std::cerr << "===is intrinsic arg in non-intrinsic call - adding address" << std::endl; 221 // // ) 222 // arg = new AddressExpr( arg ); 223 // } else 224 // if ( function->get_linkage() == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) { 225 if ( function->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getPointerBase( arg->result ) ) { 226 222 223 if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) { 227 224 // needed for definition of prelude functions, etc. 228 225 // if argument is dereference or array subscript, the result isn't REALLY a reference, but non-intrinsic functions expect a reference: take address 226 227 // NOTE: previously, this condition fixed 228 // void f(int *&); 229 // int & x = ...; 230 // f(&x); 231 // But now this is taken care of by a reference cast added by AddrRef. Need to find a new 232 // example or remove this branch. 233 234 PRINT( 235 std::cerr << "===is intrinsic arg in non-intrinsic call - adding address" << std::endl; 236 ) 237 arg = new AddressExpr( arg ); 238 // } else if ( function->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getPointerBase( arg->result ) ) { 239 } else if ( function->get_linkage() == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) { 229 240 // argument is a 'real' reference, but function expects a C lvalue: add a dereference to the reference-typed argument 230 241 PRINT( … … 247 258 248 259 // idea: &&&E: get outer &, inner & 249 // at inner &, record depth D of reference type 260 // at inner &, record depth D of reference type of argument of & 250 261 // at outer &, add D derefs. 251 void AddrRef::premutate( Expression * ) { 262 void AddrRef::handleNonAddr( Expression * ) { 263 // non-address-of: reset status variables: 264 // * current expr is NOT the first address-of expr in an address-of chain 265 // * next seen address-of expr IS the first in the chain. 252 266 GuardValue( current ); 253 267 GuardValue( first ); … … 256 270 } 257 271 272 void AddrRef::premutate( Expression * expr ) { 273 handleNonAddr( expr ); 274 GuardValue( addCast ); 275 addCast = false; 276 } 277 258 278 void AddrRef::premutate( AddressExpr * ) { 259 279 GuardValue( current ); 260 280 GuardValue( first ); 261 current = first; 262 first = false; 263 if ( current ) { 281 current = first; // is this the first address-of in the chain? 282 first = false; // from here out, no longer possible for next address-of to be first in chain 283 if ( current ) { // this is the outermost address-of in a chain 264 284 GuardValue( refDepth ); 265 refDepth = 0; 285 refDepth = 0; // set depth to 0 so that postmutate can find the innermost address-of easily 266 286 } 267 287 } 268 288 269 289 Expression * AddrRef::postmutate( AddressExpr * addrExpr ) { 290 PRINT( std::cerr << "addr ref at " << addrExpr << std::endl; ) 270 291 if ( refDepth == 0 ) { 292 PRINT( std::cerr << "depth 0, get new depth..." << std::endl; ) 293 // this is the innermost address-of in a chain, record depth D 271 294 if ( ! isIntrinsicReference( addrExpr->arg ) ) { 272 295 // try to avoid ?[?] 296 // xxx - is this condition still necessary? intrinsicReferences should have a cast around them at this point, so I don't think this condition ever fires. 273 297 refDepth = addrExpr->arg->result->referenceDepth(); 274 } 275 } 276 if ( current ) { 298 PRINT( std::cerr << "arg not intrinsic reference, new depth is: " << refDepth << std::endl; ) 299 } else { 300 assertf( false, "AddrRef : address-of should not have intrinsic reference argument: %s", toCString( addrExpr->arg ) ); 301 } 302 } 303 if ( current ) { // this is the outermost address-of in a chain 304 PRINT( std::cerr << "current, depth is: " << refDepth << std::endl; ) 277 305 Expression * ret = addrExpr; 278 306 while ( refDepth ) { 307 // add one dereference for each 279 308 ret = mkDeref( ret ); 280 309 refDepth--; 281 310 } 311 312 if ( addCast ) { 313 PRINT( std::cerr << "adding cast..." << std::endl; ) 314 return new CastExpr( ret, addrExpr->result->clone() ); 315 } 282 316 return ret; 283 317 } 318 PRINT( std::cerr << "not current..." << std::endl; ) 284 319 return addrExpr; 285 320 } 321 322 void AddrRef::premutate( ApplicationExpr * appExpr ) { 323 visit_children = false; 324 GuardValue( addCast ); 325 handleNonAddr( appExpr ); 326 for ( Expression *& arg : appExpr->args ) { 327 // each argument with address-of requires a cast 328 addCast = true; 329 arg = arg->acceptMutator( *visitor ); 330 } 331 } 332 333 void AddrRef::premutate( SingleInit * ) { 334 GuardValue( addCast ); 335 // each initialization context with address-of requires a cast 336 addCast = true; 337 } 338 286 339 287 340 Expression * ReferenceConversions::postmutate( AddressExpr * addrExpr ) { … … 391 444 assert( diff == 0 ); 392 445 // conversion between references of the same depth 446 if ( ResolvExpr::typesCompatible( castExpr->result, castExpr->arg->result, SymTab::Indexer() ) && castExpr->isGenerated ) { 447 // Remove useless generated casts 448 PRINT( 449 std::cerr << "types are compatible, removing cast: " << castExpr << std::endl; 450 std::cerr << "-- " << castExpr->result << std::endl; 451 std::cerr << "-- " << castExpr->arg->result << std::endl; 452 ) 453 Expression * ret = castExpr->arg; 454 castExpr->arg = nullptr; 455 std::swap( castExpr->env, ret->env ); 456 delete castExpr; 457 return ret; 458 } 393 459 return castExpr; 394 460 }
Note: See TracChangeset
for help on using the changeset viewer.