Changes in src/GenPoly/Lvalue.cc [85b2300:e3e16bc]
- File:
-
- 1 edited
-
src/GenPoly/Lvalue.cc (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Lvalue.cc
r85b2300 re3e16bc 18 18 19 19 #include "Common/PassVisitor.h" 20 #include "Common/SemanticError.h" // for SemanticError 20 21 #include "GenPoly.h" // for isPolyType 21 22 #include "Lvalue.h" … … 45 46 Expression * mkDeref( Expression * arg ) { 46 47 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 pass48 48 VariableExpr * deref = new VariableExpr( SymTab::dereferenceOperator ); 49 deref-> result = new PointerType( Type::Qualifiers(), deref->result);50 Type * base = InitTweak::getPointerBase( arg-> result);51 assertf( base, "expected pointer type in dereference (type was %s)", toString( arg-> result).c_str() );49 deref->set_result( new PointerType( Type::Qualifiers(), deref->get_result() ) ); 50 Type * base = InitTweak::getPointerBase( arg->get_result() ); 51 assertf( base, "expected pointer type in dereference (type was %s)", toString( arg->get_result() ).c_str() ); 52 52 ApplicationExpr * ret = new ApplicationExpr( deref, { arg } ); 53 delete ret-> result;54 ret-> result = base->clone();55 ret-> result->set_lvalue( true );53 delete ret->get_result(); 54 ret->set_result( base->clone() ); 55 ret->get_result()->set_lvalue( true ); 56 56 return ret; 57 57 } else { … … 60 60 } 61 61 62 struct ReferenceConversions final : public WithStmtsToAdd{62 struct ReferenceConversions final { 63 63 Expression * postmutate( CastExpr * castExpr ); 64 64 Expression * postmutate( AddressExpr * addrExpr ); … … 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 … … 120 115 } 121 116 122 void convertLvalue( std::list< Declaration* > & translationUnit ) {117 void convertLvalue( std::list< Declaration* >& translationUnit ) { 123 118 PassVisitor<ReferenceConversions> refCvt; 124 119 PassVisitor<ReferenceTypeElimination> elim; … … 146 141 147 142 namespace { 148 // true for intrinsic function calls that return a n lvalue in C143 // true for intrinsic function calls that return a reference 149 144 bool isIntrinsicReference( Expression * expr ) { 150 // known intrinsic-reference prelude functions151 static std::set<std::string> lvalueFunctions = { "*?", "?[?]" };152 145 if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * >( expr ) ) { 153 146 std::string fname = InitTweak::getFunctionName( untyped ); 154 return lvalueFunctions.count(fname); 147 // known intrinsic-reference prelude functions 148 return fname == "*?" || fname == "?[?]"; 155 149 } else if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * > ( expr ) ) { 156 150 if ( DeclarationWithType * func = InitTweak::getFunction( appExpr ) ) { 157 return func->linkage == LinkageSpec::Intrinsic && lvalueFunctions.count(func->name); 151 // use type of return variable rather than expr result type, since it may have been changed to a pointer type 152 FunctionType * ftype = GenPoly::getFunctionType( func->get_type() ); 153 Type * ret = ftype->get_returnVals().empty() ? nullptr : ftype->get_returnVals().front()->get_type(); 154 return func->get_linkage() == LinkageSpec::Intrinsic && dynamic_cast<ReferenceType *>( ret ); 158 155 } 159 156 } … … 164 161 if ( isIntrinsicReference( appExpr ) ) { 165 162 // eliminate reference types from intrinsic applications - now they return lvalues 166 ReferenceType * result = strict_dynamic_cast< ReferenceType * >( appExpr->result);167 appExpr-> result = result->base->clone();168 appExpr-> result->set_lvalue( true );163 Type * result = appExpr->get_result(); 164 appExpr->set_result( result->stripReferences()->clone() ); 165 appExpr->get_result()->set_lvalue( true ); 169 166 if ( ! inIntrinsic ) { 170 167 // when not in an intrinsic function, add a cast to 171 168 // don't add cast when in an intrinsic function, since they already have the cast 172 169 Expression * ret = new CastExpr( appExpr, result ); 173 std::swap( ret->env, appExpr->env ); 170 ret->set_env( appExpr->get_env() ); 171 appExpr->set_env( nullptr ); 174 172 return ret; 175 173 } … … 181 179 void FixIntrinsicResult::premutate( FunctionDecl * funcDecl ) { 182 180 GuardValue( inIntrinsic ); 183 inIntrinsic = funcDecl->linkage == LinkageSpec::Intrinsic;181 inIntrinsic = funcDecl->linkage == LinkageSpec::Intrinsic; 184 182 } 185 183 … … 190 188 assertf( ftype, "Function declaration does not have function type." ); 191 189 // can be of differing lengths only when function is variadic 192 assertf( ftype-> parameters.size() == appExpr->args.size() || ftype->isVarArgs, "ApplicationExpr args do not match formal parameter type." );190 assertf( ftype->get_parameters().size() == appExpr->get_args().size() || ftype->get_isVarArgs(), "ApplicationExpr args do not match formal parameter type." ); 193 191 194 192 195 193 unsigned int i = 0; 196 const unsigned int end = ftype-> parameters.size();197 for ( auto p : unsafe_group_iterate( appExpr-> args, ftype->parameters) ) {194 const unsigned int end = ftype->get_parameters().size(); 195 for ( auto p : unsafe_group_iterate( appExpr->get_args(), ftype->get_parameters() ) ) { 198 196 if (i == end) break; 199 197 Expression *& arg = std::get<0>( p ); … … 201 199 PRINT( 202 200 std::cerr << "pair<0>: " << arg << std::endl; 203 std::cerr << " -- " << arg->result << std::endl;204 201 std::cerr << "pair<1>: " << formal << std::endl; 205 202 ) 206 203 if ( dynamic_cast<ReferenceType*>( formal ) ) { 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->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->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() ); 204 if ( isIntrinsicReference( arg ) ) { // do not combine conditions, because that changes the meaning of the else if 205 if ( function->get_linkage() != LinkageSpec::Intrinsic ) { // intrinsic functions that turn pointers into references 206 // if argument is dereference or array subscript, the result isn't REALLY a reference, so it's not necessary to fix the argument 207 PRINT( 208 std::cerr << "===is intrinsic arg in non-intrinsic call - adding address" << std::endl; 209 ) 210 arg = new AddressExpr( arg ); 211 } 212 } else if ( function->get_linkage() == LinkageSpec::Intrinsic ) { 213 // std::cerr << "===adding deref to arg" << std::endl; 214 // if the parameter is a reference, add a dereference to the reference-typed argument. 215 Type * baseType = InitTweak::getPointerBase( arg->get_result() ); 216 assertf( baseType, "parameter is reference, arg must be pointer or reference: %s", toString( arg->get_result() ).c_str() ); 235 217 PointerType * ptrType = new PointerType( Type::Qualifiers(), baseType->clone() ); 236 delete arg-> result;237 arg-> result = ptrType;218 delete arg->get_result(); 219 arg->set_result( ptrType ); 238 220 arg = mkDeref( arg ); 239 // assertf( arg->result->referenceDepth() == 0, "Reference types should have been eliminated from intrinsic function calls, but weren't: %s", toCString( arg->result ) );240 221 } 241 222 } … … 247 228 248 229 // idea: &&&E: get outer &, inner & 249 // at inner &, record depth D of reference type of argument of &230 // at inner &, record depth D of reference type 250 231 // at outer &, add D derefs. 251 void AddrRef::handleNonAddr( Expression * ) { 252 // non-address-of: reset status variables: 253 // * current expr is NOT the first address-of expr in an address-of chain 254 // * next seen address-of expr IS the first in the chain. 232 void AddrRef::premutate( Expression * ) { 255 233 GuardValue( current ); 256 234 GuardValue( first ); … … 259 237 } 260 238 261 void AddrRef::premutate( Expression * expr ) {262 handleNonAddr( expr );263 GuardValue( addCast );264 addCast = false;265 }266 267 239 void AddrRef::premutate( AddressExpr * ) { 268 240 GuardValue( current ); 269 241 GuardValue( first ); 270 current = first; // is this the first address-of in the chain?271 first = false; // from here out, no longer possible for next address-of to be first in chain272 if ( current ) { // this is the outermost address-of in a chain242 current = first; 243 first = false; 244 if ( current ) { 273 245 GuardValue( refDepth ); 274 refDepth = 0; // set depth to 0 so that postmutate can find the innermost address-of easily246 refDepth = 0; 275 247 } 276 248 } 277 249 278 250 Expression * AddrRef::postmutate( AddressExpr * addrExpr ) { 279 PRINT( std::cerr << "addr ref at " << addrExpr << std::endl; )280 251 if ( refDepth == 0 ) { 281 PRINT( std::cerr << "depth 0, get new depth..." << std::endl; ) 282 // this is the innermost address-of in a chain, record depth D 283 if ( ! isIntrinsicReference( addrExpr->arg ) ) { 252 if ( ! isIntrinsicReference( addrExpr->get_arg() ) ) { 284 253 // try to avoid ?[?] 285 // 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. 286 refDepth = addrExpr->arg->result->referenceDepth(); 287 PRINT( std::cerr << "arg not intrinsic reference, new depth is: " << refDepth << std::endl; ) 288 } else { 289 assertf( false, "AddrRef : address-of should not have intrinsic reference argument: %s", toCString( addrExpr->arg ) ); 290 } 291 } 292 if ( current ) { // this is the outermost address-of in a chain 293 PRINT( std::cerr << "current, depth is: " << refDepth << std::endl; ) 254 refDepth = addrExpr->get_arg()->get_result()->referenceDepth(); 255 } 256 } 257 if ( current ) { 294 258 Expression * ret = addrExpr; 295 259 while ( refDepth ) { 296 // add one dereference for each297 260 ret = mkDeref( ret ); 298 261 refDepth--; 299 262 } 300 301 // if addrExpr depth is 0, then the result is a pointer because the arg was depth 1 and not lvalue.302 // This means the dereference result is not a reference, is lvalue, and one less pointer depth than303 // the addrExpr. Thus the cast is meaningless.304 // TODO: One thing to double check is whether it is possible for the types to differ outside of the single305 // pointer level (i.e. can the base type of addrExpr differ from the type of addrExpr-arg?).306 // If so then the cast might need to be added, conditional on a more sophisticated check.307 if ( addCast && addrExpr->result->referenceDepth() != 0 ) {308 PRINT( std::cerr << "adding cast to " << addrExpr->result << std::endl; )309 return new CastExpr( ret, addrExpr->result->clone() );310 }311 263 return ret; 312 264 } 313 PRINT( std::cerr << "not current..." << std::endl; )314 265 return addrExpr; 315 266 } 316 317 void AddrRef::premutate( ApplicationExpr * appExpr ) {318 visit_children = false;319 GuardValue( addCast );320 handleNonAddr( appExpr );321 for ( Expression *& arg : appExpr->args ) {322 // each argument with address-of requires a cast323 addCast = true;324 arg = arg->acceptMutator( *visitor );325 }326 }327 328 void AddrRef::premutate( SingleInit * ) {329 GuardValue( addCast );330 // each initialization context with address-of requires a cast331 addCast = true;332 }333 334 267 335 268 Expression * ReferenceConversions::postmutate( AddressExpr * addrExpr ) { … … 348 281 // pointer casts in the right places. 349 282 350 // Note: reference depth difference is the determining factor in what code is run, rather than whether something is 351 // reference type or not, since conversion still needs to occur when both types are references that differ in depth. 352 353 Type * destType = castExpr->result; 354 Type * srcType = castExpr->arg->result; 355 int depth1 = destType->referenceDepth(); 356 int depth2 = srcType->referenceDepth(); 357 int diff = depth1 - depth2; 358 359 if ( diff > 0 && ! srcType->get_lvalue() ) { 360 // rvalue to reference conversion -- introduce temporary 361 // know that reference depth of cast argument is 0, need to introduce n temporaries for reference depth of n, e.g. 362 // (int &&&)3; 363 // becomes 364 // int __ref_tmp_0 = 3; 365 // int & __ref_tmp_1 = _&_ref_tmp_0; 366 // int && __ref_tmp_2 = &__ref_tmp_1; 367 // &__ref_tmp_2; 368 // the last & comes from the remaining reference conversion code 369 SemanticWarning( castExpr->arg->location, Warning::RvalueToReferenceConversion, toCString( castExpr->arg ) ); 370 371 static UniqueName tempNamer( "__ref_tmp_" ); 372 ObjectDecl * temp = ObjectDecl::newObject( tempNamer.newName(), castExpr->arg->result->clone(), new SingleInit( castExpr->arg ) ); 373 PRINT( std::cerr << "made temp: " << temp << std::endl; ) 374 stmtsToAddBefore.push_back( new DeclStmt( temp ) ); 375 for ( int i = 0; i < depth1-1; i++ ) { // xxx - maybe this should be diff-1? check how this works with reference type for srcType 376 ObjectDecl * newTemp = ObjectDecl::newObject( tempNamer.newName(), new ReferenceType( Type::Qualifiers(), temp->type->clone() ), new SingleInit( new AddressExpr( new VariableExpr( temp ) ) ) ); 377 PRINT( std::cerr << "made temp" << i << ": " << newTemp << std::endl; ) 378 stmtsToAddBefore.push_back( new DeclStmt( newTemp ) ); 379 temp = newTemp; 380 } 381 // update diff so that remaining code works out correctly 382 castExpr->arg = new VariableExpr( temp ); 383 PRINT( std::cerr << "update cast to: " << castExpr << std::endl; ) 384 srcType = castExpr->arg->result; 385 depth2 = srcType->referenceDepth(); 386 diff = depth1 - depth2; 387 assert( diff == 1 ); 388 } 389 390 // handle conversion between different depths 391 PRINT ( 392 if ( depth1 || depth2 ) { 393 std::cerr << "destType: " << destType << " / srcType: " << srcType << std::endl; 394 std::cerr << "depth: " << depth1 << " / " << depth2 << std::endl; 395 } 396 ) 397 if ( diff > 0 ) { 398 // conversion to type with more depth (e.g. int & -> int &&): add address-of for each level of difference 399 Expression * ret = castExpr->arg; 400 for ( int i = 0; i < diff; ++i ) { 401 ret = new AddressExpr( ret ); 402 } 403 if ( srcType->get_lvalue() && ! ResolvExpr::typesCompatible( srcType, strict_dynamic_cast<ReferenceType *>( destType )->base, SymTab::Indexer() ) ) { 404 // must keep cast if cast-to type is different from the actual type 405 castExpr->arg = ret; 283 // conversion to reference type 284 if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( castExpr->get_result() ) ) { 285 (void)refType; 286 if ( ReferenceType * otherRef = dynamic_cast< ReferenceType * >( castExpr->get_arg()->get_result() ) ) { 287 // nothing to do if casting from reference to reference. 288 (void)otherRef; 289 PRINT( std::cerr << "convert reference to reference -- nop" << std::endl; ) 290 if ( isIntrinsicReference( castExpr->get_arg() ) ) { 291 Expression * callExpr = castExpr->get_arg(); 292 PRINT( 293 std::cerr << "but arg is deref -- &" << std::endl; 294 std::cerr << callExpr << std::endl; 295 ) 296 callExpr = new AddressExpr( callExpr ); // this doesn't work properly for multiple casts 297 delete callExpr->get_result(); 298 callExpr->set_result( refType->clone() ); 299 // move environment out to new top-level 300 callExpr->set_env( castExpr->get_env() ); 301 castExpr->set_arg( nullptr ); 302 castExpr->set_env( nullptr ); 303 delete castExpr; 304 return callExpr; 305 } 306 int depth1 = refType->referenceDepth(); 307 int depth2 = otherRef->referenceDepth(); 308 int diff = depth1-depth2; 309 if ( diff == 0 ) { 310 assertf( depth1 == depth2, "non-intrinsic reference with cast of reference to reference not yet supported: %d %d %s", depth1, depth2, toString( castExpr ).c_str() ); 311 PRINT( std::cerr << castExpr << std::endl; ) 312 return castExpr; 313 } else if ( diff < 0 ) { 314 Expression * ret = castExpr->get_arg(); 315 for ( int i = 0; i < diff; ++i ) { 316 ret = mkDeref( ret ); 317 } 318 ret->set_env( castExpr->get_env() ); 319 delete ret->get_result(); 320 ret->set_result( castExpr->get_result() ); 321 castExpr->set_env( nullptr ); 322 castExpr->set_arg( nullptr ); 323 castExpr->set_result( nullptr ); 324 delete castExpr; 325 return ret; 326 } else if ( diff > 0 ) { 327 Expression * ret = castExpr->get_arg(); 328 for ( int i = 0; i < diff; ++i ) { 329 ret = new AddressExpr( ret ); 330 } 331 ret->set_env( castExpr->get_env() ); 332 delete ret->get_result(); 333 ret->set_result( castExpr->get_result() ); 334 castExpr->set_env( nullptr ); 335 castExpr->set_arg( nullptr ); 336 castExpr->set_result( nullptr ); 337 delete castExpr; 338 return ret; 339 } 340 341 assertf( depth1 == depth2, "non-intrinsic reference with cast of reference to reference not yet supported: %d %d %s", depth1, depth2, toString( castExpr ).c_str() ); 342 PRINT( std::cerr << castExpr << std::endl; ) 406 343 return castExpr; 407 } 408 ret->env = castExpr->env; 409 delete ret->result; 410 ret->result = castExpr->result; 411 castExpr->env = nullptr; 412 castExpr->arg = nullptr; 413 castExpr->result = nullptr; 414 delete castExpr; 415 return ret; 416 } else if ( diff < 0 ) { 417 // conversion to type with less depth (e.g. int && -> int &): add dereferences for each level of difference 418 diff = -diff; // care only about magnitude now 419 Expression * ret = castExpr->arg; 420 for ( int i = 0; i < diff; ++i ) { 421 ret = mkDeref( ret ); 422 // xxx - try removing one reference here? actually, looks like mkDeref already does this, so more closely look at the types generated. 423 } 424 if ( ! ResolvExpr::typesCompatibleIgnoreQualifiers( destType->stripReferences(), srcType->stripReferences(), SymTab::Indexer() ) ) { 425 // must keep cast if types are different 426 castExpr->arg = ret; 427 return castExpr; 428 } 429 ret->env = castExpr->env; 430 delete ret->result; 431 ret->result = castExpr->result; 432 ret->result->set_lvalue( true ); // ensure result is lvalue 433 castExpr->env = nullptr; 434 castExpr->arg = nullptr; 435 castExpr->result = nullptr; 436 delete castExpr; 437 return ret; 438 } else { 439 assert( diff == 0 ); 440 // conversion between references of the same depth 441 if ( ResolvExpr::typesCompatible( castExpr->result, castExpr->arg->result, SymTab::Indexer() ) && castExpr->isGenerated ) { 442 // Remove useless generated casts 344 } else if ( castExpr->get_arg()->get_result()->get_lvalue() ) { 345 // conversion from lvalue to reference 346 // xxx - keep cast, but turn into pointer cast?? 347 // xxx - memory 443 348 PRINT( 444 std::cerr << "types are compatible, removing cast: " << castExpr << std::endl; 445 std::cerr << "-- " << castExpr->result << std::endl; 446 std::cerr << "-- " << castExpr->arg->result << std::endl; 349 std::cerr << "convert lvalue to reference -- &" << std::endl; 350 std::cerr << castExpr->get_arg() << std::endl; 447 351 ) 448 Expression * ret = castExpr->arg; 449 castExpr->arg = nullptr; 450 std::swap( castExpr->env, ret->env ); 352 AddressExpr * ret = new AddressExpr( castExpr->get_arg() ); 353 if ( refType->get_base()->get_qualifiers() != castExpr->get_arg()->get_result()->get_qualifiers() ) { 354 // must keep cast if cast-to type is different from the actual type 355 castExpr->set_arg( ret ); 356 return castExpr; 357 } 358 ret->set_env( castExpr->get_env() ); 359 delete ret->get_result(); 360 ret->set_result( castExpr->get_result() ); 361 castExpr->set_env( nullptr ); 362 castExpr->set_arg( nullptr ); 363 castExpr->set_result( nullptr ); 451 364 delete castExpr; 452 365 return ret; 453 } 454 return castExpr; 455 } 366 } else { 367 // rvalue to reference conversion -- introduce temporary 368 } 369 assertf( false, "Only conversions to reference from lvalue are currently supported: %s", toString( castExpr ).c_str() ); 370 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( castExpr->get_arg()->get_result() ) ) { 371 (void)refType; 372 // conversion from reference to rvalue 373 PRINT( 374 std::cerr << "convert reference to rvalue -- *" << std::endl; 375 std::cerr << "was = " << castExpr << std::endl; 376 ) 377 Expression * ret = castExpr->get_arg(); 378 TypeSubstitution * env = castExpr->get_env(); 379 castExpr->set_env( nullptr ); 380 if ( ! isIntrinsicReference( ret ) ) { 381 // dereference if not already dereferenced 382 ret = mkDeref( ret ); 383 } 384 if ( ResolvExpr::typesCompatibleIgnoreQualifiers( castExpr->get_result(), castExpr->get_arg()->get_result()->stripReferences(), SymTab::Indexer() ) ) { 385 // can remove cast if types are compatible, changing expression type to value type 386 ret->set_result( castExpr->get_result()->clone() ); 387 castExpr->set_arg( nullptr ); 388 delete castExpr; 389 } else { 390 // must keep cast if types are different 391 castExpr->set_arg( ret ); 392 ret = castExpr; 393 } 394 ret->set_env( env ); 395 PRINT( std::cerr << "now: " << ret << std::endl; ) 396 return ret; 397 } 398 return castExpr; 456 399 } 457 400 458 401 Type * ReferenceTypeElimination::postmutate( ReferenceType * refType ) { 459 Type * base = refType-> base;402 Type * base = refType->get_base(); 460 403 Type::Qualifiers qualifiers = refType->get_qualifiers(); 461 refType-> base = nullptr;404 refType->set_base( nullptr ); 462 405 delete refType; 463 406 return new PointerType( qualifiers, base ); … … 467 410 Expression * GeneralizedLvalue::applyTransformation( Expression * expr, Expression * arg, Func mkExpr ) { 468 411 if ( CommaExpr * commaExpr = dynamic_cast< CommaExpr * >( arg ) ) { 469 Expression * arg1 = commaExpr-> arg1->clone();470 Expression * arg2 = commaExpr-> arg2->clone();412 Expression * arg1 = commaExpr->get_arg1()->clone(); 413 Expression * arg2 = commaExpr->get_arg2()->clone(); 471 414 Expression * ret = new CommaExpr( arg1, mkExpr( arg2 )->acceptMutator( *visitor ) ); 472 ret-> env = expr->env;473 expr-> env = nullptr;415 ret->set_env( expr->get_env() ); 416 expr->set_env( nullptr ); 474 417 delete expr; 475 418 return ret; 476 419 } else if ( ConditionalExpr * condExpr = dynamic_cast< ConditionalExpr * >( arg ) ) { 477 Expression * arg1 = condExpr-> arg1->clone();478 Expression * arg2 = condExpr-> arg2->clone();479 Expression * arg3 = condExpr-> arg3->clone();420 Expression * arg1 = condExpr->get_arg1()->clone(); 421 Expression * arg2 = condExpr->get_arg2()->clone(); 422 Expression * arg3 = condExpr->get_arg3()->clone(); 480 423 ConditionalExpr * ret = new ConditionalExpr( arg1, mkExpr( arg2 )->acceptMutator( *visitor ), mkExpr( arg3 )->acceptMutator( *visitor ) ); 481 ret-> env = expr->env;482 expr-> env = nullptr;424 ret->set_env( expr->get_env() ); 425 expr->set_env( nullptr ); 483 426 delete expr; 484 427 … … 489 432 AssertionSet needAssertions, haveAssertions; 490 433 OpenVarSet openVars; 491 unify( ret-> arg2->result, ret->arg3->result, newEnv, needAssertions, haveAssertions, openVars, SymTab::Indexer(), commonType );492 ret-> result = commonType ? commonType : ret->arg2->result->clone();434 unify( ret->get_arg2()->get_result(), ret->get_arg3()->get_result(), newEnv, needAssertions, haveAssertions, openVars, SymTab::Indexer(), commonType ); 435 ret->set_result( commonType ? commonType : ret->get_arg2()->get_result()->clone() ); 493 436 return ret; 494 437 } … … 497 440 498 441 Expression * GeneralizedLvalue::postmutate( MemberExpr * memExpr ) { 499 return applyTransformation( memExpr, memExpr-> aggregate, [=]( Expression * aggr ) { return new MemberExpr( memExpr->member, aggr ); } );442 return applyTransformation( memExpr, memExpr->get_aggregate(), [=]( Expression * aggr ) { return new MemberExpr( memExpr->get_member(), aggr ); } ); 500 443 } 501 444 502 445 Expression * GeneralizedLvalue::postmutate( AddressExpr * addrExpr ) { 503 return applyTransformation( addrExpr, addrExpr-> arg, []( Expression * arg ) { return new AddressExpr( arg ); } );446 return applyTransformation( addrExpr, addrExpr->get_arg(), []( Expression * arg ) { return new AddressExpr( arg ); } ); 504 447 } 505 448 506 449 Expression * CollapseAddrDeref::postmutate( AddressExpr * addrExpr ) { 507 Expression * arg = addrExpr-> arg;450 Expression * arg = addrExpr->get_arg(); 508 451 if ( isIntrinsicReference( arg ) ) { 509 452 std::string fname = InitTweak::getFunctionName( arg ); … … 511 454 Expression *& arg0 = InitTweak::getCallArg( arg, 0 ); 512 455 Expression * ret = arg0; 513 ret->set_env( addrExpr-> env);456 ret->set_env( addrExpr->get_env() ); 514 457 arg0 = nullptr; 515 addrExpr-> env = nullptr;458 addrExpr->set_env( nullptr ); 516 459 delete addrExpr; 517 460 return ret; 518 }519 } else if ( CastExpr * castExpr = dynamic_cast< CastExpr * > ( arg ) ) {520 // need to move cast to pointer type out a level since address of pointer521 // is not valid C code (can be introduced in prior passes, e.g., InstantiateGeneric)522 if ( InitTweak::getPointerBase( castExpr->result ) ) {523 addrExpr->arg = castExpr->arg;524 castExpr->arg = addrExpr;525 castExpr->result = new PointerType( Type::Qualifiers(), castExpr->result );526 return castExpr;527 461 } 528 462 } … … 540 474 // } 541 475 if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( arg ) ) { 542 Expression * ret = addrExpr-> arg;543 ret-> env = appExpr->env;544 addrExpr-> arg = nullptr;545 appExpr-> env = nullptr;476 Expression * ret = addrExpr->get_arg(); 477 ret->set_env( appExpr->get_env() ); 478 addrExpr->set_arg( nullptr ); 479 appExpr->set_env( nullptr ); 546 480 delete appExpr; 547 481 return ret;
Note:
See TracChangeset
for help on using the changeset viewer.