Changeset 1cdfa82 for src/GenPoly/Lvalue.cc
- Timestamp:
- Apr 25, 2018, 4:55:53 PM (6 years ago)
- Branches:
- new-env, with_gc
- Children:
- 42107b4
- Parents:
- 2efe4b8 (diff), 9d5fb67 (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
r2efe4b8 r1cdfa82 45 45 Expression * mkDeref( Expression * arg ) { 46 46 if ( SymTab::dereferenceOperator ) { 47 // note: reference depth can be arbitrarily deep here, so peel off the outermost pointer/reference, not just pointer because they are effecitvely equivalent in this pass 47 48 VariableExpr * deref = new VariableExpr( SymTab::dereferenceOperator ); 48 49 deref->result = new PointerType( Type::Qualifiers(), deref->result ); … … 58 59 } 59 60 60 struct ReferenceConversions final {61 struct ReferenceConversions final : public WithStmtsToAdd { 61 62 Expression * postmutate( CastExpr * castExpr ); 62 63 Expression * postmutate( AddressExpr * addrExpr ); … … 96 97 }; 97 98 98 struct AddrRef final : public WithGuards {99 struct AddrRef final : public WithGuards, public WithVisitorRef<AddrRef>, public WithShortCircuiting { 99 100 void premutate( AddressExpr * addrExpr ); 100 101 Expression * postmutate( AddressExpr * addrExpr ); 101 102 void premutate( Expression * expr ); 103 void premutate( ApplicationExpr * appExpr ); 104 void premutate( SingleInit * init ); 105 106 void handleNonAddr( Expression * ); 102 107 103 108 bool first = true; 104 109 bool current = false; 105 110 int refDepth = 0; 111 bool addCast = false; 106 112 }; 107 113 } // namespace … … 113 119 } 114 120 115 void convertLvalue( std::list< Declaration* > & translationUnit ) {121 void convertLvalue( std::list< Declaration* > & translationUnit ) { 116 122 PassVisitor<ReferenceConversions> refCvt; 117 123 PassVisitor<ReferenceTypeElimination> elim; … … 149 155 // use type of return variable rather than expr result type, since it may have been changed to a pointer type 150 156 FunctionType * ftype = GenPoly::getFunctionType( func->get_type() ); 151 Type * ret = ftype-> get_returnVals().empty() ? nullptr : ftype->get_returnVals().front()->get_type();152 return func-> get_linkage()== LinkageSpec::Intrinsic && dynamic_cast<ReferenceType *>( ret );157 Type * ret = ftype->returnVals.empty() ? nullptr : ftype->returnVals.front()->get_type(); 158 return func->linkage == LinkageSpec::Intrinsic && dynamic_cast<ReferenceType *>( ret ); 153 159 } 154 160 } … … 159 165 if ( isIntrinsicReference( appExpr ) ) { 160 166 // eliminate reference types from intrinsic applications - now they return lvalues 161 Type * result = appExpr-> get_result();162 appExpr-> set_result( result->stripReferences()->clone());163 appExpr-> get_result()->set_lvalue( true );167 Type * result = appExpr->result; 168 appExpr->result = result->stripReferences()->clone(); 169 appExpr->result->set_lvalue( true ); 164 170 if ( ! inIntrinsic ) { 165 171 // when not in an intrinsic function, add a cast to 166 172 // don't add cast when in an intrinsic function, since they already have the cast 167 173 Expression * ret = new CastExpr( appExpr, result ); 168 ret->set_env( appExpr->get_env() ); 169 appExpr->set_env( nullptr ); 174 std::swap( ret->env, appExpr->env ); 170 175 return ret; 171 176 } … … 185 190 assertf( ftype, "Function declaration does not have function type." ); 186 191 // can be of differing lengths only when function is variadic 187 assertf( ftype-> get_parameters().size() == appExpr->get_args().size() || ftype->get_isVarArgs(), "ApplicationExpr args do not match formal parameter type." );192 assertf( ftype->parameters.size() == appExpr->args.size() || ftype->isVarArgs, "ApplicationExpr args do not match formal parameter type." ); 188 193 189 194 190 195 unsigned int i = 0; 191 const unsigned int end = ftype-> get_parameters().size();192 for ( auto p : unsafe_group_iterate( appExpr-> get_args(), ftype->get_parameters()) ) {196 const unsigned int end = ftype->parameters.size(); 197 for ( auto p : unsafe_group_iterate( appExpr->args, ftype->parameters ) ) { 193 198 if (i == end) break; 194 199 Expression *& arg = std::get<0>( p ); … … 196 201 PRINT( 197 202 std::cerr << "pair<0>: " << arg << std::endl; 203 std::cerr << " -- " << arg->result << std::endl; 198 204 std::cerr << "pair<1>: " << formal << std::endl; 199 205 ) 200 206 if ( dynamic_cast<ReferenceType*>( formal ) ) { 201 if ( isIntrinsicReference( arg ) ) { // do not combine conditions, because that changes the meaning of the else if 202 if ( function->get_linkage() != LinkageSpec::Intrinsic ) { // intrinsic functions that turn pointers into references 203 // if argument is dereference or array subscript, the result isn't REALLY a reference, so it's not necessary to fix the argument 204 PRINT( 205 std::cerr << "===is intrinsic arg in non-intrinsic call - adding address" << std::endl; 206 ) 207 arg = new AddressExpr( arg ); 208 } 209 } else if ( function->get_linkage() == LinkageSpec::Intrinsic ) { 210 // std::cerr << "===adding deref to arg" << std::endl; 211 // if the parameter is a reference, add a dereference to the reference-typed argument. 212 Type * baseType = InitTweak::getPointerBase( arg->get_result() ); 213 assertf( baseType, "parameter is reference, arg must be pointer or reference: %s", toString( arg->get_result() ).c_str() ); 214 arg->set_result( new PointerType{ Type::Qualifiers(), baseType->clone() } ); 207 PRINT( 208 std::cerr << "===formal is reference" << std::endl; 209 ) 210 // TODO: it's likely that the second condition should be ... && ! isIntrinsicReference( arg ), but this requires investigation. 211 212 if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) { 213 // needed for definition of prelude functions, etc. 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 223 PRINT( 224 std::cerr << "===is intrinsic arg in non-intrinsic call - adding address" << std::endl; 225 ) 226 arg = new AddressExpr( arg ); 227 // } else if ( function->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getPointerBase( arg->result ) ) { 228 } else if ( function->get_linkage() == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) { 229 // argument is a 'real' reference, but function expects a C lvalue: add a dereference to the reference-typed argument 230 PRINT( 231 std::cerr << "===is non-intrinsic arg in intrinsic call - adding deref to arg" << std::endl; 232 ) 233 Type * baseType = InitTweak::getPointerBase( arg->result ); 234 assertf( baseType, "parameter is reference, arg must be pointer or reference: %s", toString( arg->result ).c_str() ); 235 arg->set_result( new PointerType( Type::Qualifiers(), baseType->clone() ) ); 215 236 arg = mkDeref( arg ); 237 // assertf( arg->result->referenceDepth() == 0, "Reference types should have been eliminated from intrinsic function calls, but weren't: %s", toCString( arg->result ) ); 216 238 } 217 239 } … … 223 245 224 246 // idea: &&&E: get outer &, inner & 225 // at inner &, record depth D of reference type 247 // at inner &, record depth D of reference type of argument of & 226 248 // at outer &, add D derefs. 227 void AddrRef::premutate( Expression * ) { 249 void AddrRef::handleNonAddr( Expression * ) { 250 // non-address-of: reset status variables: 251 // * current expr is NOT the first address-of expr in an address-of chain 252 // * next seen address-of expr IS the first in the chain. 228 253 GuardValue( current ); 229 254 GuardValue( first ); … … 232 257 } 233 258 259 void AddrRef::premutate( Expression * expr ) { 260 handleNonAddr( expr ); 261 GuardValue( addCast ); 262 addCast = false; 263 } 264 234 265 void AddrRef::premutate( AddressExpr * ) { 235 266 GuardValue( current ); 236 267 GuardValue( first ); 237 current = first; 238 first = false; 239 if ( current ) { 268 current = first; // is this the first address-of in the chain? 269 first = false; // from here out, no longer possible for next address-of to be first in chain 270 if ( current ) { // this is the outermost address-of in a chain 240 271 GuardValue( refDepth ); 241 refDepth = 0; 272 refDepth = 0; // set depth to 0 so that postmutate can find the innermost address-of easily 242 273 } 243 274 } 244 275 245 276 Expression * AddrRef::postmutate( AddressExpr * addrExpr ) { 277 PRINT( std::cerr << "addr ref at " << addrExpr << std::endl; ) 246 278 if ( refDepth == 0 ) { 247 if ( ! isIntrinsicReference( addrExpr->get_arg() ) ) { 279 PRINT( std::cerr << "depth 0, get new depth..." << std::endl; ) 280 // this is the innermost address-of in a chain, record depth D 281 if ( ! isIntrinsicReference( addrExpr->arg ) ) { 248 282 // try to avoid ?[?] 249 refDepth = addrExpr->get_arg()->get_result()->referenceDepth(); 250 } 251 } 252 if ( current ) { 283 // 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. 284 refDepth = addrExpr->arg->result->referenceDepth(); 285 PRINT( std::cerr << "arg not intrinsic reference, new depth is: " << refDepth << std::endl; ) 286 } else { 287 assertf( false, "AddrRef : address-of should not have intrinsic reference argument: %s", toCString( addrExpr->arg ) ); 288 } 289 } 290 if ( current ) { // this is the outermost address-of in a chain 291 PRINT( std::cerr << "current, depth is: " << refDepth << std::endl; ) 253 292 Expression * ret = addrExpr; 254 293 while ( refDepth ) { 294 // add one dereference for each 255 295 ret = mkDeref( ret ); 256 296 refDepth--; 257 297 } 298 299 // if addrExpr depth is 0, then the result is a pointer because the arg was depth 1 and not lvalue. 300 // This means the dereference result is not a reference, is lvalue, and one less pointer depth than 301 // the addrExpr. Thus the cast is meaningless. 302 // TODO: One thing to double check is whether it is possible for the types to differ outside of the single 303 // pointer level (i.e. can the base type of addrExpr differ from the type of addrExpr-arg?). 304 // If so then the cast might need to be added, conditional on a more sophisticated check. 305 if ( addCast && addrExpr->result->referenceDepth() != 0 ) { 306 PRINT( std::cerr << "adding cast to " << addrExpr->result << std::endl; ) 307 return new CastExpr( ret, addrExpr->result->clone() ); 308 } 258 309 return ret; 259 310 } 311 PRINT( std::cerr << "not current..." << std::endl; ) 260 312 return addrExpr; 261 313 } 314 315 void AddrRef::premutate( ApplicationExpr * appExpr ) { 316 visit_children = false; 317 GuardValue( addCast ); 318 handleNonAddr( appExpr ); 319 for ( Expression *& arg : appExpr->args ) { 320 // each argument with address-of requires a cast 321 addCast = true; 322 arg = arg->acceptMutator( *visitor ); 323 } 324 } 325 326 void AddrRef::premutate( SingleInit * ) { 327 GuardValue( addCast ); 328 // each initialization context with address-of requires a cast 329 addCast = true; 330 } 331 262 332 263 333 Expression * ReferenceConversions::postmutate( AddressExpr * addrExpr ) { … … 276 346 // pointer casts in the right places. 277 347 278 // conversion to reference type 279 if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( castExpr->get_result() ) ) { 280 (void)refType; 281 if ( ReferenceType * otherRef = dynamic_cast< ReferenceType * >( castExpr->get_arg()->get_result() ) ) { 282 // nothing to do if casting from reference to reference. 283 (void)otherRef; 284 PRINT( std::cerr << "convert reference to reference -- nop" << std::endl; ) 285 if ( isIntrinsicReference( castExpr->get_arg() ) ) { 286 Expression * callExpr = castExpr->get_arg(); 287 PRINT( 288 std::cerr << "but arg is deref -- &" << std::endl; 289 std::cerr << callExpr << std::endl; 290 ) 291 callExpr = new AddressExpr( callExpr ); // this doesn't work properly for multiple casts 292 callExpr->set_result( refType->clone() ); 293 // move environment out to new top-level 294 callExpr->set_env( castExpr->get_env() ); 295 castExpr->set_arg( nullptr ); 296 castExpr->set_env( nullptr ); 297 return callExpr; 298 } 299 int depth1 = refType->referenceDepth(); 300 int depth2 = otherRef->referenceDepth(); 301 int diff = depth1-depth2; 302 if ( diff == 0 ) { 303 // conversion between references of the same depth 304 assertf( depth1 == depth2, "non-intrinsic reference with cast of reference to reference not yet supported: %d %d %s", depth1, depth2, toString( castExpr ).c_str() ); 305 PRINT( std::cerr << castExpr << std::endl; ) 306 return castExpr; 307 } else if ( diff < 0 ) { 308 // conversion from reference to reference with less depth (e.g. int && -> int &): add dereferences 309 Expression * ret = castExpr->arg; 310 for ( int i = 0; i < diff; ++i ) { 311 ret = mkDeref( ret ); 312 } 313 ret->env = castExpr->env; 314 ret->result = castExpr->result; 315 ret->result->set_lvalue( true ); // ensure result is lvalue 316 castExpr->env = nullptr; 317 castExpr->arg = nullptr; 318 castExpr->result = nullptr; 319 return ret; 320 } else if ( diff > 0 ) { 321 // conversion from reference to reference with more depth (e.g. int & -> int &&): add address-of 322 Expression * ret = castExpr->arg; 323 for ( int i = 0; i < diff; ++i ) { 324 ret = new AddressExpr( ret ); 325 } 326 ret->env = castExpr->env; 327 ret->result = castExpr->result; 328 castExpr->env = nullptr; 329 castExpr->arg = nullptr; 330 castExpr->result = nullptr; 331 return ret; 332 } 333 334 assertf( depth1 == depth2, "non-intrinsic reference with cast of reference to reference not yet supported: %d %d %s", depth1, depth2, toString( castExpr ).c_str() ); 335 PRINT( std::cerr << castExpr << std::endl; ) 348 // Note: reference depth difference is the determining factor in what code is run, rather than whether something is 349 // reference type or not, since conversion still needs to occur when both types are references that differ in depth. 350 351 Type * destType = castExpr->result; 352 Type * srcType = castExpr->arg->result; 353 int depth1 = destType->referenceDepth(); 354 int depth2 = srcType->referenceDepth(); 355 int diff = depth1 - depth2; 356 357 if ( diff > 0 && ! srcType->get_lvalue() ) { 358 // rvalue to reference conversion -- introduce temporary 359 // know that reference depth of cast argument is 0, need to introduce n temporaries for reference depth of n, e.g. 360 // (int &&&)3; 361 // becomes 362 // int __ref_tmp_0 = 3; 363 // int & __ref_tmp_1 = _&_ref_tmp_0; 364 // int && __ref_tmp_2 = &__ref_tmp_1; 365 // &__ref_tmp_2; 366 // the last & comes from the remaining reference conversion code 367 SemanticWarning( castExpr->arg->location, Warning::RvalueToReferenceConversion, toCString( castExpr->arg ) ); 368 369 static UniqueName tempNamer( "__ref_tmp_" ); 370 ObjectDecl * temp = ObjectDecl::newObject( tempNamer.newName(), castExpr->arg->result->clone(), new SingleInit( castExpr->arg ) ); 371 PRINT( std::cerr << "made temp: " << temp << std::endl; ) 372 stmtsToAddBefore.push_back( new DeclStmt( temp ) ); 373 for ( int i = 0; i < depth1-1; i++ ) { // xxx - maybe this should be diff-1? check how this works with reference type for srcType 374 ObjectDecl * newTemp = ObjectDecl::newObject( tempNamer.newName(), new ReferenceType( Type::Qualifiers(), temp->type->clone() ), new SingleInit( new AddressExpr( new VariableExpr( temp ) ) ) ); 375 PRINT( std::cerr << "made temp" << i << ": " << newTemp << std::endl; ) 376 stmtsToAddBefore.push_back( new DeclStmt( newTemp ) ); 377 temp = newTemp; 378 } 379 // update diff so that remaining code works out correctly 380 castExpr->arg = new VariableExpr( temp ); 381 PRINT( std::cerr << "update cast to: " << castExpr << std::endl; ) 382 srcType = castExpr->arg->result; 383 depth2 = srcType->referenceDepth(); 384 diff = depth1 - depth2; 385 assert( diff == 1 ); 386 } 387 388 // handle conversion between different depths 389 PRINT ( 390 if ( depth1 || depth2 ) { 391 std::cerr << "destType: " << destType << " / srcType: " << srcType << std::endl; 392 std::cerr << "depth: " << depth1 << " / " << depth2 << std::endl; 393 } 394 ) 395 if ( diff > 0 ) { 396 // conversion to type with more depth (e.g. int & -> int &&): add address-of for each level of difference 397 Expression * ret = castExpr->arg; 398 for ( int i = 0; i < diff; ++i ) { 399 ret = new AddressExpr( ret ); 400 } 401 if ( srcType->get_lvalue() && srcType->get_qualifiers() != strict_dynamic_cast<ReferenceType *>( destType )->base->get_qualifiers() ) { 402 // must keep cast if cast-to type is different from the actual type 403 castExpr->arg = ret; 336 404 return castExpr; 337 } else if ( castExpr->arg->result->get_lvalue() ) { 338 // conversion from lvalue to reference 339 // xxx - keep cast, but turn into pointer cast?? 340 // xxx - memory 341 PRINT( 342 std::cerr << "convert lvalue to reference -- &" << std::endl; 343 std::cerr << castExpr->arg << std::endl; 344 ) 345 AddressExpr * ret = new AddressExpr( castExpr->arg ); 346 if ( refType->base->get_qualifiers() != castExpr->arg->result->get_qualifiers() ) { 347 // must keep cast if cast-to type is different from the actual type 348 castExpr->arg = ret; 349 return castExpr; 350 } 351 ret->env = castExpr->env; 352 ret->result = castExpr->result; 353 castExpr->env = nullptr; 354 castExpr->arg = nullptr; 355 castExpr->result = nullptr; 356 return ret; 357 } else { 358 // rvalue to reference conversion -- introduce temporary 359 } 360 assertf( false, "Only conversions to reference from lvalue are currently supported: %s", toString( castExpr ).c_str() ); 361 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( castExpr->arg->result ) ) { 362 (void)refType; 363 // conversion from reference to rvalue 364 PRINT( 365 std::cerr << "convert reference to rvalue -- *" << std::endl; 366 std::cerr << "was = " << castExpr << std::endl; 367 ) 405 } 406 ret->env = castExpr->env; 407 ret->result = castExpr->result; 408 castExpr->env = nullptr; 409 castExpr->arg = nullptr; 410 castExpr->result = nullptr; 411 return ret; 412 } else if ( diff < 0 ) { 413 // conversion to type with less depth (e.g. int && -> int &): add dereferences for each level of difference 414 diff = -diff; // care only about magnitude now 368 415 Expression * ret = castExpr->arg; 369 TypeSubstitution * env = castExpr->env; 370 castExpr->set_env( nullptr ); 371 if ( ! isIntrinsicReference( ret ) ) { 372 // dereference if not already dereferenced 416 for ( int i = 0; i < diff; ++i ) { 373 417 ret = mkDeref( ret ); 374 } 375 if ( ResolvExpr::typesCompatibleIgnoreQualifiers( castExpr->result, castExpr->arg->result->stripReferences(), SymTab::Indexer() ) ) { 376 // can remove cast if types are compatible, changing expression type to value type 377 ret->result = castExpr->result->clone(); 378 ret->result->set_lvalue( true ); // ensure result is lvalue 379 castExpr->arg = nullptr; 380 } else { 418 // xxx - try removing one reference here? actually, looks like mkDeref already does this, so more closely look at the types generated. 419 } 420 if ( ! ResolvExpr::typesCompatibleIgnoreQualifiers( destType->stripReferences(), srcType->stripReferences(), SymTab::Indexer() ) ) { 381 421 // must keep cast if types are different 382 422 castExpr->arg = ret; 383 ret = castExpr; 384 } 385 ret->set_env( env ); 386 PRINT( std::cerr << "now: " << ret << std::endl; ) 423 return castExpr; 424 } 425 ret->env = castExpr->env; 426 ret->result = castExpr->result; 427 ret->result->set_lvalue( true ); // ensure result is lvalue 428 castExpr->env = nullptr; 429 castExpr->arg = nullptr; 430 castExpr->result = nullptr; 387 431 return ret; 388 } 389 return castExpr; 432 } else { 433 assert( diff == 0 ); 434 // conversion between references of the same depth 435 if ( ResolvExpr::typesCompatible( castExpr->result, castExpr->arg->result, SymTab::Indexer() ) && castExpr->isGenerated ) { 436 // Remove useless generated casts 437 PRINT( 438 std::cerr << "types are compatible, removing cast: " << castExpr << std::endl; 439 std::cerr << "-- " << castExpr->result << std::endl; 440 std::cerr << "-- " << castExpr->arg->result << std::endl; 441 ) 442 Expression * ret = castExpr->arg; 443 castExpr->arg = nullptr; 444 std::swap( castExpr->env, ret->env ); 445 return ret; 446 } 447 return castExpr; 448 } 390 449 } 391 450 392 451 Type * ReferenceTypeElimination::postmutate( ReferenceType * refType ) { 393 Type * base = refType-> get_base();452 Type * base = refType->base; 394 453 Type::Qualifiers qualifiers = refType->get_qualifiers(); 395 refType-> set_base( nullptr );454 refType->base = nullptr; 396 455 return new PointerType( qualifiers, base ); 397 456 } … … 400 459 Expression * GeneralizedLvalue::applyTransformation( Expression * expr, Expression * arg, Func mkExpr ) { 401 460 if ( CommaExpr * commaExpr = dynamic_cast< CommaExpr * >( arg ) ) { 402 Expression * arg1 = commaExpr-> get_arg1()->clone();403 Expression * arg2 = commaExpr-> get_arg2()->clone();461 Expression * arg1 = commaExpr->arg1->clone(); 462 Expression * arg2 = commaExpr->arg2->clone(); 404 463 Expression * ret = new CommaExpr( arg1, mkExpr( arg2 )->acceptMutator( *visitor ) ); 405 ret-> set_env( expr->get_env() );406 expr-> set_env( nullptr );464 ret->env = expr->env; 465 expr->env = nullptr; 407 466 return ret; 408 467 } else if ( ConditionalExpr * condExpr = dynamic_cast< ConditionalExpr * >( arg ) ) { 409 Expression * arg1 = condExpr-> get_arg1()->clone();410 Expression * arg2 = condExpr-> get_arg2()->clone();411 Expression * arg3 = condExpr-> get_arg3()->clone();468 Expression * arg1 = condExpr->arg1->clone(); 469 Expression * arg2 = condExpr->arg2->clone(); 470 Expression * arg3 = condExpr->arg3->clone(); 412 471 ConditionalExpr * ret = new ConditionalExpr( arg1, mkExpr( arg2 )->acceptMutator( *visitor ), mkExpr( arg3 )->acceptMutator( *visitor ) ); 413 ret-> set_env( expr->get_env() );414 expr-> set_env( nullptr );472 ret->env = expr->env; 473 expr->env = nullptr; 415 474 416 475 // conditional expr type may not be either of the argument types, need to unify … … 420 479 AssertionSet needAssertions, haveAssertions; 421 480 OpenVarSet openVars; 422 unify( ret-> get_arg2()->get_result(), ret->get_arg3()->get_result(), newEnv, needAssertions, haveAssertions, openVars, SymTab::Indexer(), commonType );423 ret-> set_result( commonType ? commonType : ret->get_arg2()->get_result()->clone());481 unify( ret->arg2->result, ret->arg3->result, newEnv, needAssertions, haveAssertions, openVars, SymTab::Indexer(), commonType ); 482 ret->result = commonType ? commonType : ret->arg2->result->clone(); 424 483 return ret; 425 484 } … … 428 487 429 488 Expression * GeneralizedLvalue::postmutate( MemberExpr * memExpr ) { 430 return applyTransformation( memExpr, memExpr-> get_aggregate(), [=]( Expression * aggr ) { return new MemberExpr( memExpr->get_member(), aggr ); } );489 return applyTransformation( memExpr, memExpr->aggregate, [=]( Expression * aggr ) { return new MemberExpr( memExpr->member, aggr ); } ); 431 490 } 432 491 433 492 Expression * GeneralizedLvalue::postmutate( AddressExpr * addrExpr ) { 434 return applyTransformation( addrExpr, addrExpr-> get_arg(), []( Expression * arg ) { return new AddressExpr( arg ); } );493 return applyTransformation( addrExpr, addrExpr->arg, []( Expression * arg ) { return new AddressExpr( arg ); } ); 435 494 } 436 495 437 496 Expression * CollapseAddrDeref::postmutate( AddressExpr * addrExpr ) { 438 Expression * arg = addrExpr-> get_arg();497 Expression * arg = addrExpr->arg; 439 498 if ( isIntrinsicReference( arg ) ) { 440 499 std::string fname = InitTweak::getFunctionName( arg ); … … 442 501 Expression *& arg0 = InitTweak::getCallArg( arg, 0 ); 443 502 Expression * ret = arg0; 444 ret->set_env( addrExpr-> get_env());503 ret->set_env( addrExpr->env ); 445 504 arg0 = nullptr; 446 addrExpr-> set_env( nullptr );505 addrExpr->env = nullptr; 447 506 return ret; 448 507 } … … 470 529 // } 471 530 if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( arg ) ) { 472 Expression * ret = addrExpr-> get_arg();473 ret-> set_env( appExpr->get_env() );474 addrExpr-> set_arg( nullptr );475 appExpr-> set_env( nullptr );531 Expression * ret = addrExpr->arg; 532 ret->env = appExpr->env; 533 addrExpr->arg = nullptr; 534 appExpr->env = nullptr; 476 535 return ret; 477 536 }
Note: See TracChangeset
for help on using the changeset viewer.