Changeset c28afead for src/GenPoly/Lvalue.cc
- Timestamp:
- Apr 19, 2018, 6:11:07 PM (6 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, with_gc
- Children:
- 8633f060
- Parents:
- 9dc31c10 (diff), 60ba456 (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
r9dc31c10 rc28afead 98 98 }; 99 99 100 struct AddrRef final : public WithGuards {100 struct AddrRef final : public WithGuards, public WithVisitorRef<AddrRef>, public WithShortCircuiting { 101 101 void premutate( AddressExpr * addrExpr ); 102 102 Expression * postmutate( AddressExpr * addrExpr ); 103 103 void premutate( Expression * expr ); 104 void premutate( ApplicationExpr * appExpr ); 105 void premutate( SingleInit * init ); 106 107 void handleNonAddr( Expression * ); 104 108 105 109 bool first = true; 106 110 bool current = false; 107 111 int refDepth = 0; 112 bool addCast = false; 108 113 }; 109 114 } // namespace … … 208 213 if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) { 209 214 // if argument is dereference or array subscript, the result isn't REALLY a reference, but non-intrinsic functions expect a reference: take address 215 216 // NOTE: previously, this condition fixed 217 // void f(int *&); 218 // int & x = ...; 219 // f(&x); 220 // But now this is taken care of by a reference cast added by AddrRef. Need to find a new 221 // example or remove this branch. 222 210 223 PRINT( 211 224 std::cerr << "===is intrinsic arg in non-intrinsic call - adding address" << std::endl; … … 233 246 234 247 // idea: &&&E: get outer &, inner & 235 // at inner &, record depth D of reference type 248 // at inner &, record depth D of reference type of argument of & 236 249 // at outer &, add D derefs. 237 void AddrRef::premutate( Expression * ) { 250 void AddrRef::handleNonAddr( Expression * ) { 251 // non-address-of: reset status variables: 252 // * current expr is NOT the first address-of expr in an address-of chain 253 // * next seen address-of expr IS the first in the chain. 238 254 GuardValue( current ); 239 255 GuardValue( first ); … … 242 258 } 243 259 260 void AddrRef::premutate( Expression * expr ) { 261 handleNonAddr( expr ); 262 GuardValue( addCast ); 263 addCast = false; 264 } 265 244 266 void AddrRef::premutate( AddressExpr * ) { 245 267 GuardValue( current ); 246 268 GuardValue( first ); 247 current = first; 248 first = false; 249 if ( current ) { 269 current = first; // is this the first address-of in the chain? 270 first = false; // from here out, no longer possible for next address-of to be first in chain 271 if ( current ) { // this is the outermost address-of in a chain 250 272 GuardValue( refDepth ); 251 refDepth = 0; 273 refDepth = 0; // set depth to 0 so that postmutate can find the innermost address-of easily 252 274 } 253 275 } 254 276 255 277 Expression * AddrRef::postmutate( AddressExpr * addrExpr ) { 278 PRINT( std::cerr << "addr ref at " << addrExpr << std::endl; ) 256 279 if ( refDepth == 0 ) { 280 PRINT( std::cerr << "depth 0, get new depth..." << std::endl; ) 281 // this is the innermost address-of in a chain, record depth D 257 282 if ( ! isIntrinsicReference( addrExpr->arg ) ) { 258 283 // try to avoid ?[?] 284 // 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. 259 285 refDepth = addrExpr->arg->result->referenceDepth(); 260 } 261 } 262 if ( current ) { 286 PRINT( std::cerr << "arg not intrinsic reference, new depth is: " << refDepth << std::endl; ) 287 } else { 288 assertf( false, "AddrRef : address-of should not have intrinsic reference argument: %s", toCString( addrExpr->arg ) ); 289 } 290 } 291 if ( current ) { // this is the outermost address-of in a chain 292 PRINT( std::cerr << "current, depth is: " << refDepth << std::endl; ) 263 293 Expression * ret = addrExpr; 264 294 while ( refDepth ) { 295 // add one dereference for each 265 296 ret = mkDeref( ret ); 266 297 refDepth--; 267 298 } 299 300 if ( addCast ) { 301 PRINT( std::cerr << "adding cast..." << std::endl; ) 302 return new CastExpr( ret, addrExpr->result->clone() ); 303 } 268 304 return ret; 269 305 } 306 PRINT( std::cerr << "not current..." << std::endl; ) 270 307 return addrExpr; 271 308 } 309 310 void AddrRef::premutate( ApplicationExpr * appExpr ) { 311 visit_children = false; 312 GuardValue( addCast ); 313 handleNonAddr( appExpr ); 314 for ( Expression *& arg : appExpr->args ) { 315 // each argument with address-of requires a cast 316 addCast = true; 317 arg = arg->acceptMutator( *visitor ); 318 } 319 } 320 321 void AddrRef::premutate( SingleInit * ) { 322 GuardValue( addCast ); 323 // each initialization context with address-of requires a cast 324 addCast = true; 325 } 326 272 327 273 328 Expression * ReferenceConversions::postmutate( AddressExpr * addrExpr ) { … … 376 431 assert( diff == 0 ); 377 432 // conversion between references of the same depth 433 if ( ResolvExpr::typesCompatible( castExpr->result, castExpr->arg->result, SymTab::Indexer() ) && castExpr->isGenerated ) { 434 // Remove useless generated casts 435 PRINT( 436 std::cerr << "types are compatible, removing cast: " << castExpr << std::endl; 437 std::cerr << "-- " << castExpr->result << std::endl; 438 std::cerr << "-- " << castExpr->arg->result << std::endl; 439 ) 440 Expression * ret = castExpr->arg; 441 castExpr->arg = nullptr; 442 std::swap( castExpr->env, ret->env ); 443 delete castExpr; 444 return ret; 445 } 378 446 return castExpr; 379 447 }
Note: See TracChangeset
for help on using the changeset viewer.