Changes in / [383e159:9d48a17]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/InstantiateGeneric.cc
r383e159 r9d48a17 21 21 #include <vector> // for vector 22 22 23 #include "CodeGen/OperatorTable.h" 23 24 #include "Common/PassVisitor.h" // for PassVisitor, WithDeclsToAdd 24 25 #include "Common/ScopedMap.h" // for ScopedMap … … 27 28 #include "Common/utility.h" // for deleteAll, cloneAll 28 29 #include "GenPoly.h" // for isPolyType, typesPolyCompatible 30 #include "InitTweak/InitTweak.h" 29 31 #include "ResolvExpr/typeops.h" 30 32 #include "ScopedSet.h" // for ScopedSet, ScopedSet<>::iterator … … 154 156 155 157 /// Add cast to dtype-static member expressions so that type information is not lost in GenericInstantiator 156 struct FixDtypeStatic final {158 struct FixDtypeStatic final : public WithGuards, public WithVisitorRef<FixDtypeStatic>, public WithShortCircuiting, public WithStmtsToAdd { 157 159 Expression * postmutate( MemberExpr * memberExpr ); 160 161 void premutate( ApplicationExpr * appExpr ); 162 void premutate( AddressExpr * addrExpr ); 158 163 159 164 template<typename AggrInst> 160 165 Expression * fixMemberExpr( AggrInst * inst, MemberExpr * memberExpr ); 166 167 bool isLvalueArg = false; 161 168 }; 162 169 … … 210 217 PassVisitor<GenericInstantiator> instantiator; 211 218 212 //mutateAll( translationUnit, fixer );219 mutateAll( translationUnit, fixer ); 213 220 mutateAll( translationUnit, instantiator ); 214 221 } … … 501 508 if ( isDtypeStatic( baseParams ) ) { 502 509 if ( ! ResolvExpr::typesCompatible( memberExpr->result, memberExpr->member->get_type(), SymTab::Indexer() ) ) { 503 // type of member and type of expression differ, so add cast to actual type 504 return new CastExpr( memberExpr, memberExpr->result->clone() ); 510 // type of member and type of expression differ 511 Type * concType = memberExpr->result->clone(); 512 if ( isLvalueArg ) { 513 // result must be C lvalue, so make a new reference variable with the correct actual type to replace the member expression 514 // forall(dtype T) 515 // struct Ptr { 516 // T * x 517 // }; 518 // Ptr(int) p; 519 // int i; 520 // p.x = &i; 521 // becomes 522 // int *& _dtype_static_member_0 = (int **)&p.x; 523 // _dtype_static_member_0 = &i; 524 // Note: this currently creates more temporaries than is strictly necessary, since it does not check for duplicate uses of the same member expression. 525 static UniqueName tmpNamer( "_dtype_static_member_" ); 526 Expression * init = new CastExpr( new AddressExpr( memberExpr ), new PointerType( Type::Qualifiers(), concType->clone() ) ); 527 ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), new ReferenceType( Type::Qualifiers(), concType ), new SingleInit( init ) ); 528 stmtsToAddBefore.push_back( new DeclStmt( noLabels, tmp ) ); 529 return new VariableExpr( tmp ); 530 } else { 531 // can simply add a cast to actual type 532 return new CastExpr( memberExpr, concType ); 533 } 505 534 } 506 535 } … … 520 549 } 521 550 551 void FixDtypeStatic::premutate( ApplicationExpr * appExpr ) { 552 GuardValue( isLvalueArg ); 553 isLvalueArg = false; 554 DeclarationWithType * function = InitTweak::getFunction( appExpr ); 555 if ( function->linkage == LinkageSpec::Intrinsic && CodeGen::isAssignment( function->name ) ) { 556 // explicitly visit children because only the first argument must be a C lvalue. 557 visit_children = false; 558 appExpr->env = maybeMutate( appExpr->env, *visitor ); 559 appExpr->result = maybeMutate( appExpr->result, *visitor ); 560 appExpr->function = maybeMutate( appExpr->function, *visitor ); 561 isLvalueArg = true; 562 for ( Expression * arg : appExpr->args ) { 563 arg = maybeMutate( arg, *visitor ); 564 isLvalueArg = false; 565 } 566 } 567 } 568 569 void FixDtypeStatic::premutate( AddressExpr * ) { 570 // argument of & must be C lvalue 571 GuardValue( isLvalueArg ); 572 isLvalueArg = true; 573 } 522 574 } // namespace GenPoly 523 575
Note: See TracChangeset
for help on using the changeset viewer.