Changeset 90152a4 for src/GenPoly/Lvalue.cc
- Timestamp:
- Aug 27, 2018, 4:40:34 PM (7 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- b7c89aa
- Parents:
- f9feab8 (diff), 305581d (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
-
src/GenPoly/Lvalue.cc (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Lvalue.cc
rf9feab8 r90152a4 18 18 19 19 #include "Common/PassVisitor.h" 20 #include "Common/SemanticError.h" // for SemanticError21 20 #include "GenPoly.h" // for isPolyType 22 21 #include "Lvalue.h" … … 46 45 Expression * mkDeref( Expression * arg ) { 47 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 48 48 VariableExpr * deref = new VariableExpr( SymTab::dereferenceOperator ); 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() );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() ); 52 52 ApplicationExpr * ret = new ApplicationExpr( deref, { arg } ); 53 delete ret-> get_result();54 ret-> set_result( base->clone());55 ret-> get_result()->set_lvalue( true );53 delete ret->result; 54 ret->result = base->clone(); 55 ret->result->set_lvalue( true ); 56 56 return ret; 57 57 } else { … … 60 60 } 61 61 62 struct ReferenceConversions final {62 struct ReferenceConversions final : public WithStmtsToAdd { 63 63 Expression * postmutate( CastExpr * castExpr ); 64 64 Expression * postmutate( AddressExpr * addrExpr ); … … 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 … … 115 120 } 116 121 117 void convertLvalue( std::list< Declaration* > & translationUnit ) {122 void convertLvalue( std::list< Declaration* > & translationUnit ) { 118 123 PassVisitor<ReferenceConversions> refCvt; 119 124 PassVisitor<ReferenceTypeElimination> elim; … … 141 146 142 147 namespace { 143 // true for intrinsic function calls that return a reference148 // true for intrinsic function calls that return an lvalue in C 144 149 bool isIntrinsicReference( Expression * expr ) { 150 // known intrinsic-reference prelude functions 151 static std::set<std::string> lvalueFunctions = { "*?", "?[?]" }; 145 152 if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * >( expr ) ) { 146 153 std::string fname = InitTweak::getFunctionName( untyped ); 147 // known intrinsic-reference prelude functions 148 return fname == "*?" || fname == "?[?]"; 154 return lvalueFunctions.count(fname); 149 155 } else if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * > ( expr ) ) { 150 156 if ( DeclarationWithType * func = InitTweak::getFunction( appExpr ) ) { 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 ); 157 return func->linkage == LinkageSpec::Intrinsic && lvalueFunctions.count(func->name); 155 158 } 156 159 } … … 161 164 if ( isIntrinsicReference( appExpr ) ) { 162 165 // eliminate reference types from intrinsic applications - now they return lvalues 163 Type * result = appExpr->get_result();164 appExpr-> set_result( result->stripReferences()->clone());165 appExpr-> get_result()->set_lvalue( true );166 ReferenceType * result = strict_dynamic_cast< ReferenceType * >( appExpr->result ); 167 appExpr->result = result->base->clone(); 168 appExpr->result->set_lvalue( true ); 166 169 if ( ! inIntrinsic ) { 167 170 // when not in an intrinsic function, add a cast to 168 171 // don't add cast when in an intrinsic function, since they already have the cast 169 172 Expression * ret = new CastExpr( appExpr, result ); 170 ret->set_env( appExpr->get_env() ); 171 appExpr->set_env( nullptr ); 173 std::swap( ret->env, appExpr->env ); 172 174 return ret; 173 175 } … … 179 181 void FixIntrinsicResult::premutate( FunctionDecl * funcDecl ) { 180 182 GuardValue( inIntrinsic ); 181 inIntrinsic = funcDecl->linkage == LinkageSpec::Intrinsic;183 inIntrinsic = funcDecl->linkage == LinkageSpec::Intrinsic; 182 184 } 183 185 … … 188 190 assertf( ftype, "Function declaration does not have function type." ); 189 191 // can be of differing lengths only when function is variadic 190 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." ); 191 193 192 194 193 195 unsigned int i = 0; 194 const unsigned int end = ftype-> get_parameters().size();195 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 ) ) { 196 198 if (i == end) break; 197 199 Expression *& arg = std::get<0>( p ); … … 199 201 PRINT( 200 202 std::cerr << "pair<0>: " << arg << std::endl; 203 std::cerr << " -- " << arg->result << std::endl; 201 204 std::cerr << "pair<1>: " << formal << std::endl; 202 205 ) 203 206 if ( dynamic_cast<ReferenceType*>( formal ) ) { 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() ); 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() ); 217 235 PointerType * ptrType = new PointerType( Type::Qualifiers(), baseType->clone() ); 218 delete arg-> get_result();219 arg-> set_result( ptrType );236 delete arg->result; 237 arg->result = ptrType; 220 238 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 ) ); 221 240 } 222 241 } … … 228 247 229 248 // idea: &&&E: get outer &, inner & 230 // at inner &, record depth D of reference type 249 // at inner &, record depth D of reference type of argument of & 231 250 // at outer &, add D derefs. 232 void AddrRef::premutate( Expression * ) { 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. 233 255 GuardValue( current ); 234 256 GuardValue( first ); … … 237 259 } 238 260 261 void AddrRef::premutate( Expression * expr ) { 262 handleNonAddr( expr ); 263 GuardValue( addCast ); 264 addCast = false; 265 } 266 239 267 void AddrRef::premutate( AddressExpr * ) { 240 268 GuardValue( current ); 241 269 GuardValue( first ); 242 current = first; 243 first = false; 244 if ( current ) { 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 chain 272 if ( current ) { // this is the outermost address-of in a chain 245 273 GuardValue( refDepth ); 246 refDepth = 0; 274 refDepth = 0; // set depth to 0 so that postmutate can find the innermost address-of easily 247 275 } 248 276 } 249 277 250 278 Expression * AddrRef::postmutate( AddressExpr * addrExpr ) { 279 PRINT( std::cerr << "addr ref at " << addrExpr << std::endl; ) 251 280 if ( refDepth == 0 ) { 252 if ( ! isIntrinsicReference( addrExpr->get_arg() ) ) { 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 ) ) { 253 284 // try to avoid ?[?] 254 refDepth = addrExpr->get_arg()->get_result()->referenceDepth(); 255 } 256 } 257 if ( current ) { 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; ) 258 294 Expression * ret = addrExpr; 259 295 while ( refDepth ) { 296 // add one dereference for each 260 297 ret = mkDeref( ret ); 261 298 refDepth--; 262 299 } 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 than 303 // 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 single 305 // 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 } 263 311 return ret; 264 312 } 313 PRINT( std::cerr << "not current..." << std::endl; ) 265 314 return addrExpr; 266 315 } 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 cast 323 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 cast 331 addCast = true; 332 } 333 267 334 268 335 Expression * ReferenceConversions::postmutate( AddressExpr * addrExpr ) { … … 281 348 // pointer casts in the right places. 282 349 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; ) 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; 343 406 return castExpr; 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 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 348 443 PRINT( 349 std::cerr << "convert lvalue to reference -- &" << std::endl; 350 std::cerr << castExpr->get_arg() << std::endl; 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; 351 447 ) 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 ); 448 Expression * ret = castExpr->arg; 449 castExpr->arg = nullptr; 450 std::swap( castExpr->env, ret->env ); 364 451 delete castExpr; 365 452 return ret; 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; 453 } 454 return castExpr; 455 } 399 456 } 400 457 401 458 Type * ReferenceTypeElimination::postmutate( ReferenceType * refType ) { 402 Type * base = refType-> get_base();459 Type * base = refType->base; 403 460 Type::Qualifiers qualifiers = refType->get_qualifiers(); 404 refType-> set_base( nullptr );461 refType->base = nullptr; 405 462 delete refType; 406 463 return new PointerType( qualifiers, base ); … … 410 467 Expression * GeneralizedLvalue::applyTransformation( Expression * expr, Expression * arg, Func mkExpr ) { 411 468 if ( CommaExpr * commaExpr = dynamic_cast< CommaExpr * >( arg ) ) { 412 Expression * arg1 = commaExpr-> get_arg1()->clone();413 Expression * arg2 = commaExpr-> get_arg2()->clone();469 Expression * arg1 = commaExpr->arg1->clone(); 470 Expression * arg2 = commaExpr->arg2->clone(); 414 471 Expression * ret = new CommaExpr( arg1, mkExpr( arg2 )->acceptMutator( *visitor ) ); 415 ret-> set_env( expr->get_env() );416 expr-> set_env( nullptr );472 ret->env = expr->env; 473 expr->env = nullptr; 417 474 delete expr; 418 475 return ret; 419 476 } else if ( ConditionalExpr * condExpr = dynamic_cast< ConditionalExpr * >( arg ) ) { 420 Expression * arg1 = condExpr-> get_arg1()->clone();421 Expression * arg2 = condExpr-> get_arg2()->clone();422 Expression * arg3 = condExpr-> get_arg3()->clone();477 Expression * arg1 = condExpr->arg1->clone(); 478 Expression * arg2 = condExpr->arg2->clone(); 479 Expression * arg3 = condExpr->arg3->clone(); 423 480 ConditionalExpr * ret = new ConditionalExpr( arg1, mkExpr( arg2 )->acceptMutator( *visitor ), mkExpr( arg3 )->acceptMutator( *visitor ) ); 424 ret-> set_env( expr->get_env() );425 expr-> set_env( nullptr );481 ret->env = expr->env; 482 expr->env = nullptr; 426 483 delete expr; 427 484 … … 432 489 AssertionSet needAssertions, haveAssertions; 433 490 OpenVarSet openVars; 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());491 unify( ret->arg2->result, ret->arg3->result, newEnv, needAssertions, haveAssertions, openVars, SymTab::Indexer(), commonType ); 492 ret->result = commonType ? commonType : ret->arg2->result->clone(); 436 493 return ret; 437 494 } … … 440 497 441 498 Expression * GeneralizedLvalue::postmutate( MemberExpr * memExpr ) { 442 return applyTransformation( memExpr, memExpr-> get_aggregate(), [=]( Expression * aggr ) { return new MemberExpr( memExpr->get_member(), aggr ); } );499 return applyTransformation( memExpr, memExpr->aggregate, [=]( Expression * aggr ) { return new MemberExpr( memExpr->member, aggr ); } ); 443 500 } 444 501 445 502 Expression * GeneralizedLvalue::postmutate( AddressExpr * addrExpr ) { 446 return applyTransformation( addrExpr, addrExpr-> get_arg(), []( Expression * arg ) { return new AddressExpr( arg ); } );503 return applyTransformation( addrExpr, addrExpr->arg, []( Expression * arg ) { return new AddressExpr( arg ); } ); 447 504 } 448 505 449 506 Expression * CollapseAddrDeref::postmutate( AddressExpr * addrExpr ) { 450 Expression * arg = addrExpr-> get_arg();507 Expression * arg = addrExpr->arg; 451 508 if ( isIntrinsicReference( arg ) ) { 452 509 std::string fname = InitTweak::getFunctionName( arg ); … … 454 511 Expression *& arg0 = InitTweak::getCallArg( arg, 0 ); 455 512 Expression * ret = arg0; 456 ret->set_env( addrExpr-> get_env());513 ret->set_env( addrExpr->env ); 457 514 arg0 = nullptr; 458 addrExpr-> set_env( nullptr );515 addrExpr->env = nullptr; 459 516 delete addrExpr; 460 517 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 pointer 521 // 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; 461 527 } 462 528 } … … 474 540 // } 475 541 if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( arg ) ) { 476 Expression * ret = addrExpr-> get_arg();477 ret-> set_env( appExpr->get_env() );478 addrExpr-> set_arg( nullptr );479 appExpr-> set_env( nullptr );542 Expression * ret = addrExpr->arg; 543 ret->env = appExpr->env; 544 addrExpr->arg = nullptr; 545 appExpr->env = nullptr; 480 546 delete appExpr; 481 547 return ret;
Note:
See TracChangeset
for help on using the changeset viewer.