Changes in src/GenPoly/Lvalue.cc [f74eb47:a9b1b0c]
- File:
-
- 1 edited
-
src/GenPoly/Lvalue.cc (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Lvalue.cc
rf74eb47 ra9b1b0c 98 98 }; 99 99 100 struct AddrRef final : public WithGuards , public WithVisitorRef<AddrRef>, public WithShortCircuiting{100 struct AddrRef final : public WithGuards { 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 * );108 104 109 105 bool first = true; 110 106 bool current = false; 111 107 int refDepth = 0; 112 bool addCast = false;113 108 }; 114 109 } // namespace … … 213 208 if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) { 214 209 // 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 fixed217 // 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 new221 // example or remove this branch.222 223 210 PRINT( 224 211 std::cerr << "===is intrinsic arg in non-intrinsic call - adding address" << std::endl; … … 246 233 247 234 // idea: &&&E: get outer &, inner & 248 // at inner &, record depth D of reference type of argument of &235 // at inner &, record depth D of reference type 249 236 // at outer &, add D derefs. 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. 237 void AddrRef::premutate( Expression * ) { 254 238 GuardValue( current ); 255 239 GuardValue( first ); … … 258 242 } 259 243 260 void AddrRef::premutate( Expression * expr ) {261 handleNonAddr( expr );262 GuardValue( addCast );263 addCast = false;264 }265 266 244 void AddrRef::premutate( AddressExpr * ) { 267 245 GuardValue( current ); 268 246 GuardValue( first ); 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 chain271 if ( current ) { // this is the outermost address-of in a chain247 current = first; 248 first = false; 249 if ( current ) { 272 250 GuardValue( refDepth ); 273 refDepth = 0; // set depth to 0 so that postmutate can find the innermost address-of easily251 refDepth = 0; 274 252 } 275 253 } 276 254 277 255 Expression * AddrRef::postmutate( AddressExpr * addrExpr ) { 278 PRINT( std::cerr << "addr ref at " << addrExpr << std::endl; )279 256 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 D282 257 if ( ! isIntrinsicReference( addrExpr->arg ) ) { 283 258 // 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.285 259 refDepth = addrExpr->arg->result->referenceDepth(); 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; ) 260 } 261 } 262 if ( current ) { 293 263 Expression * ret = addrExpr; 294 264 while ( refDepth ) { 295 // add one dereference for each296 265 ret = mkDeref( ret ); 297 266 refDepth--; 298 267 } 299 300 if ( addCast ) { 301 PRINT( std::cerr << "adding cast..." << std::endl; ) 302 return new CastExpr( ret, addrExpr->result->clone() ); 303 } 304 return ret; 305 } 306 PRINT( std::cerr << "not current..." << std::endl; ) 268 return ret; 269 } 307 270 return addrExpr; 308 271 } 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 cast316 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 cast324 addCast = true;325 }326 327 272 328 273 Expression * ReferenceConversions::postmutate( AddressExpr * addrExpr ) { … … 431 376 assert( diff == 0 ); 432 377 // conversion between references of the same depth 433 if ( ResolvExpr::typesCompatible( castExpr->result, castExpr->arg->result, SymTab::Indexer() ) && castExpr->isGenerated ) {434 // Remove useless generated casts435 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 }446 378 return castExpr; 447 379 }
Note:
See TracChangeset
for help on using the changeset viewer.