This revision was automatically updated to reflect the committed changes.
Closed by commit rG86674f66cc78: [HLSL] Added HLSL this as a reference
(authored by gracejennings, committed by python3kgae).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D135721/new/
https://reviews.llvm.org/D135721
Files:
clang/lib/AST/ExprClassification.cpp
clang/lib/CodeGen/CGExpr.cpp
clang/lib/Sema/HLSLExternalSemaSource.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaExprMember.cpp
clang/test/AST/HLSL/RWBuffer-AST.hlsl
clang/test/AST/HLSL/this-reference-template.hlsl
clang/test/AST/HLSL/this-reference.hlsl
clang/test/CodeGenHLSL/this-assignment-overload.hlsl
clang/test/CodeGenHLSL/this-assignment.hlsl
clang/test/CodeGenHLSL/this-reference.hlsl
Index: clang/test/CodeGenHLSL/this-reference.hlsl
===================================================================
--- /dev/null
+++ clang/test/CodeGenHLSL/this-reference.hlsl
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -emit-llvm -disable-llvm-passes -o - -hlsl-entry main %s | FileCheck %s
+
+struct Pair {
+ int First;
+ float Second;
+
+ int getFirst() {
+ return this.First;
+ }
+
+ float getSecond() {
+ return Second;
+ }
+};
+
+[numthreads(1, 1, 1)]
+void main() {
+ Pair Vals = {1, 2.0};
+ Vals.First = Vals.getFirst();
+ Vals.Second = Vals.getSecond();
+}
+
+// This tests reference like `this` in HLSL
+ // CHECK: %call = call noundef i32 @"?getFirst@Pair@@QAAHXZ"(ptr noundef nonnull align 4 dereferenceable(8) %Vals)
+ // CHECK-NEXT: %First = getelementptr inbounds %struct.Pair, ptr %Vals, i32 0, i32 0
+ // CHECK-NEXT: store i32 %call, ptr %First, align 4
+ // CHECK-NEXT: %call1 = call noundef float @"?getSecond@Pair@@QAAMXZ"(ptr noundef nonnull align 4 dereferenceable(8) %Vals)
+ // CHECK-NEXT: %Second = getelementptr inbounds %struct.Pair, ptr %Vals, i32 0, i32 1
Index: clang/test/CodeGenHLSL/this-assignment.hlsl
===================================================================
--- /dev/null
+++ clang/test/CodeGenHLSL/this-assignment.hlsl
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -emit-llvm -disable-llvm-passes -o - -hlsl-entry main %s | FileCheck %s
+
+struct Pair {
+ int First;
+ int Second;
+
+ int getFirst() {
+ Pair Another = {5, 10};
+ this = Another;
+ return this.First;
+ }
+
+ int getSecond() {
+ this = Pair();
+ return Second;
+ }
+};
+
+[numthreads(1, 1, 1)]
+void main() {
+ Pair Vals = {1, 2.0};
+ Vals.First = Vals.getFirst();
+ Vals.Second = Vals.getSecond();
+}
+
+// This tests reference like implicit this in HLSL
+// CHECK: define linkonce_odr noundef i32 @"?getFirst@Pair@@QAAHXZ"(ptr noundef nonnull align 4 dereferenceable(8) %this) #3 align 2 {
+// CHECK-NEXT:entry:
+// CHECK-NEXT:%this.addr = alloca ptr, align 4
+// CHECK-NEXT:%Another = alloca %struct.Pair, align 4
+// CHECK-NEXT:store ptr %this, ptr %this.addr, align 4
+// CHECK-NEXT:%this1 = load ptr, ptr %this.addr, align 4
+// CHECK-NEXT:call void @llvm.memcpy.p0.p0.i32(ptr align 4 %Another, ptr align 4 @"__const.?getFirst@Pair@@QAAHXZ.Another", i32 8, i1 false)
+// CHECK-NEXT:call void @llvm.memcpy.p0.p0.i32(ptr align 4 %this1, ptr align 4 %Another, i32 8, i1 false)
+// CHECK-NEXT:%First = getelementptr inbounds %struct.Pair, ptr %this1, i32 0, i32 0
+
+// CHECK: define linkonce_odr noundef i32 @"?getSecond@Pair@@QAAHXZ"(ptr noundef nonnull align 4 dereferenceable(8) %this) #3 align 2 {
+// CHECK-NEXT:entry:
+// CHECK-NEXT:%this.addr = alloca ptr, align 4
+// CHECK-NEXT:%ref.tmp = alloca %struct.Pair, align 4
+// CHECK-NEXT:store ptr %this, ptr %this.addr, align 4
+// CHECK-NEXT:%this1 = load ptr, ptr %this.addr, align 4
+// CHECK-NEXT:call void @llvm.memset.p0.i32(ptr align 4 %ref.tmp, i8 0, i32 8, i1 false)
+// CHECK-NEXT:call void @llvm.memcpy.p0.p0.i32(ptr align 4 %this1, ptr align 4 %ref.tmp, i32 8, i1 false)
+// CHECK-NEXT:%Second = getelementptr inbounds %struct.Pair, ptr %this1, i32 0, i32 1
Index: clang/test/CodeGenHLSL/this-assignment-overload.hlsl
===================================================================
--- /dev/null
+++ clang/test/CodeGenHLSL/this-assignment-overload.hlsl
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -emit-llvm -disable-llvm-passes -o - -std=hlsl202x %s | FileCheck %s
+
+struct Pair {
+ int First;
+ int Second;
+ int getFirst() {
+ Pair Another = {5, 10};
+ this = Another;
+ return this.First;
+ }
+ int getSecond() {
+ this = Pair();
+ return Second;
+ }
+ void operator=(Pair P) {
+ First = P.First;
+ Second = 2;
+ }
+};
+[numthreads(1, 1, 1)]
+void main() {
+ Pair Vals = {1, 2};
+ Vals.First = Vals.getFirst();
+ Vals.Second = Vals.getSecond();
+}
+
+// This test makes a probably safe assumption that HLSL 202x includes operator overloading for assignment operators.
+// CHECK: define linkonce_odr noundef i32 @"?getFirst@Pair@@QAAHXZ"(ptr noundef nonnull align 4 dereferenceable(8) %this) #2 align 2 {
+// CHECK-NEXT:entry:
+// CHECK-NEXT:%this.addr = alloca ptr, align 4
+// CHECK-NEXT:%Another = alloca %struct.Pair, align 4
+// CHECK-NEXT:%agg.tmp = alloca %struct.Pair, align 4
+// CHECK-NEXT:store ptr %this, ptr %this.addr, align 4
+// CHECK-NEXT:%this1 = load ptr, ptr %this.addr, align 4
+// CHECK-NEXT:%First = getelementptr inbounds %struct.Pair, ptr %Another, i32 0, i32 0
+// CHECK-NEXT:store i32 5, ptr %First, align 4
+// CHECK-NEXT:%Second = getelementptr inbounds %struct.Pair, ptr %Another, i32 0, i32 1
+// CHECK-NEXT:store i32 10, ptr %Second, align 4
+// CHECK-NEXT:call void @llvm.memcpy.p0.p0.i32(ptr align 4 %agg.tmp, ptr align 4 %Another, i32 8, i1 false)
+// CHECK-NEXT:call void @"??4Pair@@QAAXU0@@Z"(ptr noundef nonnull align 4 dereferenceable(8) %this1, ptr noundef byval(%struct.Pair) align 4 %agg.tmp)
+// CHECK-NEXT:%First2 = getelementptr inbounds %struct.Pair, ptr %this1, i32 0, i32 0
+// CHECK-NEXT:%0 = load i32, ptr %First2, align 4
+// CHECK-NEXT:ret i32 %0
+
+// CHECK: define linkonce_odr noundef i32 @"?getSecond@Pair@@QAAHXZ"(ptr noundef nonnull align 4 dereferenceable(8) %this) #2 align 2 {
+// CHECK-NEXT:entry:
+// CHECK-NEXT:%this.addr = alloca ptr, align 4
+// CHECK-NEXT:%agg.tmp = alloca %struct.Pair, align 4
+// CHECK-NEXT:store ptr %this, ptr %this.addr, align 4
+// CHECK-NEXT:%this1 = load ptr, ptr %this.addr, align 4
+// CHECK-NEXT:call void @llvm.memset.p0.i32(ptr align 4 %agg.tmp, i8 0, i32 8, i1 false)
+// CHECK-NEXT:call void @"??4Pair@@QAAXU0@@Z"(ptr noundef nonnull align 4 dereferenceable(8) %this1, ptr noundef byval(%struct.Pair) align 4 %agg.tmp)
+// CHECK-NEXT:%Second = getelementptr inbounds %struct.Pair, ptr %this1, i32 0, i32 1
+// CHECK-NEXT:%0 = load i32, ptr %Second, align 4
+// CHECK-NEXT:ret i32 %0
Index: clang/test/AST/HLSL/this-reference.hlsl
===================================================================
--- /dev/null
+++ clang/test/AST/HLSL/this-reference.hlsl
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -ast-dump -disable-llvm-passes -o - -hlsl-entry main %s | FileCheck %s
+
+class Pair {
+ int First;
+ int Second;
+
+ int getFirst() {
+ return this.First;
+ }
+
+ int getSecond() {
+ return Second;
+ }
+};
+
+class PairInfo : Pair {
+ int Sum;
+
+ int getSum() {
+ return this.First + Second;
+ }
+};
+
+[numthreads(1, 1, 1)]
+void main() {
+ Pair Vals = {1, 2};
+ Vals.First = Vals.getFirst();
+ Vals.Second = Vals.getSecond();
+
+ PairInfo ValsInfo;
+ ValsInfo.First = Vals.First;
+ ValsInfo.Second = Vals.Second;
+ ValsInfo.Sum = ValsInfo.getSum();
+
+}
+
+// CHECK: -CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <line:7:3, line:9:3> line:7:7 used getFirst 'int ()' implicit-inline
+// CHECK-NEXT:`-CompoundStmt 0x{{[0-9A-Fa-f]+}} <col:18, line:9:3>
+// CHECK-NEXT:`-ReturnStmt 0x{{[0-9A-Fa-f]+}} <line:8:4, col:16>
+// CHECK-NEXT:`-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:11, col:16> 'int' <LValueToRValue>
+// CHECK-NEXT:`-MemberExpr 0x{{[0-9A-Fa-f]+}} <col:11, col:16> 'int' lvalue .First 0x{{[0-9A-Fa-f]+}}
+// CHECK-NEXT:`-CXXThisExpr 0x{{[0-9A-Fa-f]+}} <col:11> 'Pair' lvalue this
+// CHECK-NEXT:-CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <line:11:3, line:13:3> line:11:7 used getSecond 'int ()' implicit-inline
+// CHECK-NEXT:`-CompoundStmt 0x{{[0-9A-Fa-f]+}} <col:19, line:13:3>
+// CHECK-NEXT:`-ReturnStmt 0x{{[0-9A-Fa-f]+}} <line:12:5, col:12>
+// CHECK-NEXT:`-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:12> 'int' <LValueToRValue>
+// CHECK-NEXT:`-MemberExpr 0x{{[0-9A-Fa-f]+}} <col:12> 'int' lvalue .Second 0x{{[0-9A-Fa-f]+}}
+// CHECK-NEXT:`-CXXThisExpr 0x{{[0-9A-Fa-f]+}} <col:12> 'Pair' lvalue implicit this
+
+
+// CHECK: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <line:19:3, line:21:3> line:19:7 used getSum 'int ()' implicit-inline
+// CHECK-NEXT:`-CompoundStmt 0x{{[0-9A-Fa-f]+}} <col:16, line:21:3>
+// CHECK-NEXT:`-ReturnStmt 0x{{[0-9A-Fa-f]+}} <line:20:5, col:25>
+// CHECK-NEXT:`-BinaryOperator 0x{{[0-9A-Fa-f]+}} <col:12, col:25> 'int' '+'
+// CHECK-NEXT:-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:12, col:17> 'int' <LValueToRValue>
+// CHECK-NEXT:`-MemberExpr 0x{{[0-9A-Fa-f]+}} <col:12, col:17> 'int' lvalue .First 0x{{[0-9A-Fa-f]+}}
+// CHECK-NEXT:`-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:12> 'Pair' lvalue <UncheckedDerivedToBase (Pair)>
+// CHECK-NEXT:`-CXXThisExpr 0x{{[0-9A-Fa-f]+}} <col:12> 'PairInfo' lvalue this
+// CHECK-NEXT:`-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:25> 'int' <LValueToRValue>
+// CHECK-NEXT:`-MemberExpr 0x{{[0-9A-Fa-f]+}} <col:25> 'int' lvalue .Second 0x{{[0-9A-Fa-f]+}}
+// CHECK-NEXT:`-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:25> 'Pair' lvalue <UncheckedDerivedToBase (Pair)>
+// CHECK-NEXT:`-CXXThisExpr 0x{{[0-9A-Fa-f]+}} <col:25> 'PairInfo' lvalue implicit this
Index: clang/test/AST/HLSL/this-reference-template.hlsl
===================================================================
--- /dev/null
+++ clang/test/AST/HLSL/this-reference-template.hlsl
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -ast-dump -disable-llvm-passes -o - -hlsl-entry main %s | FileCheck %s
+
+template<typename K, typename V>
+struct Pair {
+ K First;
+ V Second;
+
+ K getFirst() {
+ return this.First;
+ }
+
+ V getSecond() {
+ return Second;
+ }
+};
+
+[numthreads(1, 1, 1)]
+void main() {
+ Pair<int, float> Vals = {1, 2.0};
+ Vals.First = Vals.getFirst();
+ Vals.Second = Vals.getSecond();
+}
+
+// CHECK: -CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <line:8:3, line:10:3> line:8:5 getFirst 'K ()' implicit-inline
+// CHECK-NEXT:-CompoundStmt 0x{{[0-9A-Fa-f]+}} <col:16, line:10:3>
+// CHECK-NEXT:-ReturnStmt 0x{{[0-9A-Fa-f]+}} <line:9:4, col:16>
+// CHECK-NEXT:-CXXDependentScopeMemberExpr 0x{{[0-9A-Fa-f]+}} <col:11, col:16> '<dependent type>' lvalue .First
+// CHECK-NEXT:-CXXThisExpr 0x{{[0-9A-Fa-f]+}} <col:11> 'Pair<K, V>' lvalue this
+// CHECK-NEXT:-CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <line:12:3, line:14:3> line:12:5 getSecond 'V ()' implicit-inline
+// CHECK-NEXT:-CompoundStmt 0x{{[0-9A-Fa-f]+}} <col:17, line:14:3>
+// CHECK-NEXT:-ReturnStmt 0x{{[0-9A-Fa-f]+}} <line:13:5, col:12>
+// CHECK-NEXT:-MemberExpr 0x{{[0-9A-Fa-f]+}} <col:12> 'V' lvalue .Second 0x{{[0-9A-Fa-f]+}}
+// CHECK-NEXT:-CXXThisExpr 0x{{[0-9A-Fa-f]+}} <col:12> 'Pair<K, V>' lvalue implicit this
+
+// CHECK: -CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <line:8:3, line:10:3> line:8:5 used getFirst 'int ()' implicit-inline
+// CHECK-NEXT:-CompoundStmt 0x{{[0-9A-Fa-f]+}} <col:16, line:10:3>
+// CHECK-NEXT:-ReturnStmt 0x{{[0-9A-Fa-f]+}} <line:9:4, col:16>
+// CHECK-NEXT:-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:11, col:16> 'int':'int' <LValueToRValue>
+// CHECK-NEXT:-MemberExpr 0x{{[0-9A-Fa-f]+}} <col:11, col:16> 'int':'int' lvalue .First 0x{{[0-9A-Fa-f]+}}
+// CHECK-NEXT:-CXXThisExpr 0x{{[0-9A-Fa-f]+}} <col:11> 'Pair<int, float>' lvalue this
+// CHECK-NEXT:-CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <line:12:3, line:14:3> line:12:5 used getSecond 'float ()' implicit-inline
+// CHECK-NEXT:-CompoundStmt 0x{{[0-9A-Fa-f]+}} <col:17, line:14:3>
+// CHECK-NEXT:-ReturnStmt 0x{{[0-9A-Fa-f]+}} <line:13:5, col:12>
+// CHECK-NEXT:-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:12> 'float':'float' <LValueToRValue>
+// CHECK-NEXT:-MemberExpr 0x{{[0-9A-Fa-f]+}} <col:12> 'float':'float' lvalue .Second 0x{{[0-9A-Fa-f]+}}
+// CHECK-NEXT:-CXXThisExpr 0x{{[0-9A-Fa-f]+}} <col:12> 'Pair<int, float>' lvalue implicit this
Index: clang/test/AST/HLSL/RWBuffer-AST.hlsl
===================================================================
--- clang/test/AST/HLSL/RWBuffer-AST.hlsl
+++ clang/test/AST/HLSL/RWBuffer-AST.hlsl
@@ -46,8 +46,8 @@
// CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
// CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
// CHECK-NEXT: ArraySubscriptExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' lvalue
-// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type *' lvalue ->h 0x{{[0-9A-Fa-f]+}}
-// CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'const RWBuffer<element_type> *' implicit this
+// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
+// CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'const RWBuffer<element_type>' lvalue implicit this
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
// CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
@@ -56,8 +56,8 @@
// CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
// CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
// CHECK-NEXT: ArraySubscriptExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' lvalue
-// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type *' lvalue ->h 0x{{[0-9A-Fa-f]+}}
-// CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'RWBuffer<element_type> *' implicit this
+// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
+// CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'RWBuffer<element_type>' lvalue implicit this
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
// CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
Index: clang/lib/Sema/SemaExprMember.cpp
===================================================================
--- clang/lib/Sema/SemaExprMember.cpp
+++ clang/lib/Sema/SemaExprMember.cpp
@@ -1903,6 +1903,14 @@
if (SS.getRange().isValid())
Loc = SS.getRange().getBegin();
baseExpr = BuildCXXThisExpr(loc, ThisTy, /*IsImplicit=*/true);
+ if (getLangOpts().HLSL && ThisTy.getTypePtr()->isPointerType()) {
+ ThisTy = ThisTy.getTypePtr()->getPointeeType();
+ return BuildMemberReferenceExpr(baseExpr, ThisTy,
+ /*OpLoc*/ SourceLocation(),
+ /*IsArrow*/ false, SS, TemplateKWLoc,
+ /*FirstQualifierInScope*/ nullptr, R,
+ TemplateArgs, S);
+ }
}
return BuildMemberReferenceExpr(baseExpr, ThisTy,
Index: clang/lib/Sema/SemaExprCXX.cpp
===================================================================
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -1390,6 +1390,13 @@
Expr *Sema::BuildCXXThisExpr(SourceLocation Loc, QualType Type,
bool IsImplicit) {
+ if (getLangOpts().HLSL && Type.getTypePtr()->isPointerType()) {
+ auto *This = new (Context)
+ CXXThisExpr(Loc, Type.getTypePtr()->getPointeeType(), IsImplicit);
+ This->setValueKind(ExprValueKind::VK_LValue);
+ MarkThisReferenced(This);
+ return This;
+ }
auto *This = new (Context) CXXThisExpr(Loc, Type, IsImplicit);
MarkThisReferenced(This);
return This;
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -15587,7 +15587,7 @@
}
}
- if (getLangOpts().HLSL) {
+ if (getLangOpts().HLSL && OpLoc.isValid()) {
if (Opc == UO_AddrOf)
return ExprError(Diag(OpLoc, diag::err_hlsl_operator_unsupported) << 0);
if (Opc == UO_Deref)
Index: clang/lib/Sema/SemaDeclCXX.cpp
===================================================================
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -14681,7 +14681,8 @@
MemberBuilder From(OtherRef, OtherRefType, /*IsArrow=*/false, MemberLookup);
- MemberBuilder To(This, getCurrentThisType(), /*IsArrow=*/true, MemberLookup);
+ MemberBuilder To(This, getCurrentThisType(), /*IsArrow=*/!LangOpts.HLSL,
+ MemberLookup);
// Build the copy of this field.
StmtResult Copy = buildSingleCopyAssign(*this, Loc, FieldType,
@@ -14699,9 +14700,16 @@
if (!Invalid) {
// Add a "return *this;"
- ExprResult ThisObj = CreateBuiltinUnaryOp(Loc, UO_Deref, This.build(*this, Loc));
+ Expr *ThisExpr = nullptr;
+ if (!LangOpts.HLSL) {
+ ExprResult ThisObj =
+ CreateBuiltinUnaryOp(Loc, UO_Deref, This.build(*this, Loc));
+ ThisExpr = ThisObj.get();
+ } else {
+ ThisExpr = This.build(*this, Loc);
+ }
- StmtResult Return = BuildReturnStmt(Loc, ThisObj.get());
+ StmtResult Return = BuildReturnStmt(Loc, ThisExpr);
if (Return.isInvalid())
Invalid = true;
else
Index: clang/lib/Sema/HLSLExternalSemaSource.cpp
===================================================================
--- clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -175,9 +175,11 @@
Expr *Call = CallExpr::Create(AST, Fn, {RCExpr}, AST.VoidPtrTy, VK_PRValue,
SourceLocation(), FPOptionsOverride());
- CXXThisExpr *This = new (AST)
- CXXThisExpr(SourceLocation(), Constructor->getThisType(), true);
- Expr *Handle = MemberExpr::CreateImplicit(AST, This, true, Fields["h"],
+ CXXThisExpr *This = new (AST) CXXThisExpr(
+ SourceLocation(),
+ Constructor->getThisType().getTypePtr()->getPointeeType(), true);
+ This->setValueKind(ExprValueKind::VK_LValue);
+ Expr *Handle = MemberExpr::CreateImplicit(AST, This, false, Fields["h"],
Fields["h"]->getType(), VK_LValue,
OK_Ordinary);
@@ -260,10 +262,12 @@
auto FnProtoLoc = TSInfo->getTypeLoc().getAs<FunctionProtoTypeLoc>();
FnProtoLoc.setParam(0, IdxParam);
- auto *This = new (AST)
- CXXThisExpr(SourceLocation(), MethodDecl->getThisType(), true);
+ auto *This = new (AST) CXXThisExpr(
+ SourceLocation(),
+ MethodDecl->getThisType().getTypePtr()->getPointeeType(), true);
+ This->setValueKind(ExprValueKind::VK_LValue);
auto *HandleAccess = MemberExpr::CreateImplicit(
- AST, This, true, Handle, Handle->getType(), VK_LValue, OK_Ordinary);
+ AST, This, false, Handle, Handle->getType(), VK_LValue, OK_Ordinary);
auto *IndexExpr = DeclRefExpr::Create(
AST, NestedNameSpecifierLoc(), SourceLocation(), IdxParam, false,
Index: clang/lib/CodeGen/CGExpr.cpp
===================================================================
--- clang/lib/CodeGen/CGExpr.cpp
+++ clang/lib/CodeGen/CGExpr.cpp
@@ -1383,6 +1383,8 @@
return EmitOMPArraySectionExpr(cast<OMPArraySectionExpr>(E));
case Expr::ExtVectorElementExprClass:
return EmitExtVectorElementExpr(cast<ExtVectorElementExpr>(E));
+ case Expr::CXXThisExprClass:
+ return MakeAddrLValue(LoadCXXThisAddress(), E->getType());
case Expr::MemberExprClass:
return EmitMemberExpr(cast<MemberExpr>(E));
case Expr::CompoundLiteralExprClass:
Index: clang/lib/AST/ExprClassification.cpp
===================================================================
--- clang/lib/AST/ExprClassification.cpp
+++ clang/lib/AST/ExprClassification.cpp
@@ -160,7 +160,6 @@
case Expr::CXXPseudoDestructorExprClass:
case Expr::UnaryExprOrTypeTraitExprClass:
case Expr::CXXNewExprClass:
- case Expr::CXXThisExprClass:
case Expr::CXXNullPtrLiteralExprClass:
case Expr::ImaginaryLiteralClass:
case Expr::GNUNullExprClass:
@@ -205,6 +204,10 @@
case Expr::RequiresExprClass:
return Cl::CL_PRValue;
+ // Make HLSL this reference-like
+ case Expr::CXXThisExprClass:
+ return Lang.HLSL ? Cl::CL_LValue : Cl::CL_PRValue;
+
case Expr::ConstantExprClass:
return ClassifyInternal(Ctx, cast<ConstantExpr>(E)->getSubExpr());
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits