Changeset a3323db1
- Timestamp:
- Apr 17, 2018, 11:06:04 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, with_gc
- Children:
- c0bf94e
- Parents:
- 5f08961d
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Lvalue.cc
r5f08961d ra3323db1 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 } … … 255 277 Expression * AddrRef::postmutate( AddressExpr * addrExpr ) { 256 278 if ( refDepth == 0 ) { 279 // this is the innermost address-of in a chain, record depth D 257 280 if ( ! isIntrinsicReference( addrExpr->arg ) ) { 258 281 // try to avoid ?[?] 282 // 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 283 refDepth = addrExpr->arg->result->referenceDepth(); 260 } 261 } 262 if ( current ) { 284 } else { 285 assertf( false, "AddrRef : address-of should not have intrinsic reference argument: %s", toCString( addrExpr->arg ) ); 286 } 287 } 288 if ( current ) { // this is the outermost address-of in a chain 263 289 Expression * ret = addrExpr; 264 290 while ( refDepth ) { 291 // add one dereference for each 265 292 ret = mkDeref( ret ); 266 293 refDepth--; 267 294 } 295 296 if ( addCast ) { 297 return new CastExpr( ret, addrExpr->result->clone() ); 298 } 268 299 return ret; 269 300 } 270 301 return addrExpr; 271 302 } 303 304 void AddrRef::premutate( ApplicationExpr * appExpr ) { 305 visit_children = false; 306 GuardValue( addCast ); 307 handleNonAddr( appExpr ); 308 for ( Expression *& arg : appExpr->args ) { 309 // each argument with address-of requires a cast 310 addCast = true; 311 arg = arg->acceptMutator( *visitor ); 312 } 313 } 314 315 void AddrRef::premutate( SingleInit * ) { 316 GuardValue( addCast ); 317 // each initialization context with address-of requires a cast 318 addCast = true; 319 } 320 272 321 273 322 Expression * ReferenceConversions::postmutate( AddressExpr * addrExpr ) {
Note: See TracChangeset
for help on using the changeset viewer.