Handle implicit `this` methods (#4123)

This catches a case I missed in #4112, for handling implicit `this` in
member method lookups.
This commit is contained in:
Chris B 2021-12-02 21:15:35 -06:00 коммит произвёл GitHub
Родитель ccf845a744
Коммит 235c801d6e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 37 добавлений и 8 удалений

Просмотреть файл

@ -982,8 +982,10 @@ CXXThisExpr *Sema::genereateHLSLThis(SourceLocation Loc, QualType ThisType,
bool isImplicit) {
// Expressions cannot be of reference type - instead, they yield
// an lvalue on the underlying type.
CXXThisExpr *ResultExpr = new (Context)
CXXThisExpr(Loc, ThisType.getTypePtr()->getPointeeType(), isImplicit);
const Type *TypePtr = ThisType.getTypePtr();
CXXThisExpr *ResultExpr = new (Context) CXXThisExpr(
Loc, TypePtr->isPointerType() ? TypePtr->getPointeeType() : ThisType,
isImplicit);
ResultExpr->setValueKind(ExprValueKind::VK_LValue);
return ResultExpr;
}

Просмотреть файл

@ -11835,9 +11835,12 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
Qualifier = UnresExpr->getQualifier();
QualType ObjectType = UnresExpr->getBaseType();
Expr::Classification ObjectClassification
= UnresExpr->isArrow()? Expr::Classification::makeSimpleLValue()
: UnresExpr->getBase()->Classify(Context);
// HLSL Change Begin - This is a reference
Expr::Classification ObjectClassification =
(getLangOpts().HLSL || UnresExpr->isArrow())
? Expr::Classification::makeSimpleLValue()
: UnresExpr->getBase()->Classify(Context);
// HLSL Change End - This is a reference
// Add overload candidates
OverloadCandidateSet CandidateSet(UnresExpr->getMemberLoc(),
@ -12691,9 +12694,14 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
if (MemExpr->getQualifier())
Loc = MemExpr->getQualifierLoc().getBeginLoc();
CheckCXXThisCapture(Loc);
Base = new (Context) CXXThisExpr(Loc,
MemExpr->getBaseType(),
/*isImplicit=*/true);
// HLSL Change Begin - This is a reference
if (getLangOpts().HLSL)
Base = genereateHLSLThis(Loc, MemExpr->getBaseType(),
/*isImplicit=*/true);
else
Base = new (Context) CXXThisExpr(Loc, MemExpr->getBaseType(),
/*isImplicit=*/true);
// HLSL Change End - This is a reference
}
} else
Base = MemExpr->getBase();

Просмотреть файл

@ -0,0 +1,19 @@
// RUN: %dxc -T ps_6_0 -ast-dump %s | FileCheck %s
struct Foo {
float m;
float2 f(float2 v) { return 0; }
float3 f(float3 v) { return 1; }
float2 g(float2 v) { return f(v); }
};
// CHECK: CXXMemberCallExpr 0x{{[0-9a-zA-Z]+}} <col:31, col:34> 'float2':'vector<float, 2>'
// CHECK-NEXT: MemberExpr 0x{{[0-9a-zA-Z]+}} <col:31> '<bound member function type>' .f
// CHECK-NEXT: CXXThisExpr 0x{{[0-9a-zA-Z]+}} <col:31> 'Foo' lvalue this
// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-zA-Z]+}} <col:33> 'float2':'vector<float, 2>' <LValueToRValue>
// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-zA-Z]+}} <col:33> 'float2':'vector<float, 2>' lvalue ParmVar 0x{{[0-9a-zA-Z]+}} 'v' 'float2':'vector<float, 2>'
float4 main(float2 coord: TEXCOORD) : SV_TARGET {
Foo foo = { coord.x };
return float4(foo.g(coord.y), 0, 1);
}