Skip to content

Commit c7b35b9

Browse files
committed
update PR after merge from main that introduced explicit copy constructor for resource classes
1 parent dfa4144 commit c7b35b9

File tree

6 files changed

+40
-7
lines changed

6 files changed

+40
-7
lines changed

clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "clang/AST/Decl.h"
1818
#include "clang/AST/DeclCXX.h"
1919
#include "clang/AST/Expr.h"
20+
#include "clang/AST/Stmt.h"
2021
#include "clang/AST/Type.h"
2122
#include "clang/Basic/SourceLocation.h"
2223
#include "clang/Basic/Specifiers.h"
@@ -48,6 +49,14 @@ static FunctionDecl *lookupBuiltinFunction(Sema &S, StringRef Name) {
4849
"Since this is a builtin it should always resolve!");
4950
return cast<FunctionDecl>(R.getFoundDecl());
5051
}
52+
53+
CXXConstructorDecl *lookupCopyConstructor(QualType ResTy) {
54+
assert(ResTy->isRecordType() && "not a CXXRecord type");
55+
for (auto *CD : ResTy->getAsCXXRecordDecl()->ctors())
56+
if (CD->isCopyConstructor())
57+
return CD;
58+
return nullptr;
59+
}
5160
} // namespace
5261

5362
// Builder for template arguments of builtin types. Used internally
@@ -601,6 +610,20 @@ BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::returnValue(T ReturnValue) {
601610

602611
Expr *ReturnValueExpr = convertPlaceholder(ReturnValue);
603612
ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
613+
614+
QualType Ty = ReturnValueExpr->getType();
615+
if (Ty->isRecordType()) {
616+
// For record types, create a call to copy constructor to ensure proper copy
617+
// semantics.
618+
auto *ICE =
619+
ImplicitCastExpr::Create(AST, Ty.withConst(), CK_NoOp, ReturnValueExpr,
620+
nullptr, VK_XValue, FPOptionsOverride());
621+
CXXConstructorDecl *CD = lookupCopyConstructor(Ty);
622+
assert(CD && "no copy constructor found");
623+
ReturnValueExpr = CXXConstructExpr::Create(
624+
AST, Ty, SourceLocation(), CD, false, {ICE}, false, false, false, false,
625+
CXXConstructionKind::Complete, SourceRange());
626+
}
604627
StmtsList.push_back(
605628
ReturnStmt::Create(AST, SourceLocation(), ReturnValueExpr, nullptr));
606629
return *this;

clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ RESOURCE Buffer;
107107
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int'
108108
// CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *'
109109
// CHECK-NEXT: ReturnStmt
110+
// CHECK-NEXT: CXXConstructExpr {{.*}} 'hlsl::[[RESOURCE]]' 'void (const hlsl::[[RESOURCE]] &)'
111+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'const hlsl::[[RESOURCE]]' xvalue <NoOp>
110112
// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]'
111113
// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
112114

@@ -135,6 +137,8 @@ RESOURCE Buffer;
135137
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int'
136138
// CHECK-NEXT: DeclRefExpr {{.*}} 'const char *' ParmVar {{.*}} 'name' 'const char *'
137139
// CHECK-NEXT: ReturnStmt
140+
// CHECK-NEXT: CXXConstructExpr {{.*}} 'hlsl::[[RESOURCE]]' 'void (const hlsl::[[RESOURCE]] &)'
141+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'const hlsl::[[RESOURCE]]' xvalue <NoOp>
138142
// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]'
139143
// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
140144

clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,17 @@ void SecondEntry() {}
3333

3434
// Verify the constructors are alwaysinline
3535
// NOINLINE: ; Function Attrs: {{.*}}alwaysinline
36-
// NOINLINE-NEXT: define linkonce_odr hidden void @hlsl::RWBuffer<float>::RWBuffer()(ptr noundef nonnull align 4 dereferenceable(4) %this){{.*}} [[CtorAttr:\#[0-9]+]]
36+
// NOINLINE-NEXT: define linkonce_odr hidden void @hlsl::RWBuffer<float>::RWBuffer()({{.*}}){{.*}} [[CtorAttr:\#[0-9]+]]
37+
38+
// NOINLINE: ; Function Attrs: {{.*}}alwaysinline
39+
// NOINLINE-NEXT: define linkonce_odr hidden void @hlsl::RWBuffer<float>::RWBuffer(hlsl::RWBuffer<float> const&)({{.*}}){{.*}} [[CtorAttr]]
3740

3841
// NOINLINE: ; Function Attrs: {{.*}}alwaysinline
3942
// NOINLINE-NEXT: define linkonce_odr hidden void @hlsl::RWBuffer<float>::RWBuffer()(ptr noundef nonnull align 4 dereferenceable(4) %this){{.*}} [[CtorAttr:\#[0-9]+]]
4043

44+
// NOINLINE: ; Function Attrs: {{.*}}alwaysinline
45+
// NOINLINE-NEXT: define linkonce_odr hidden void @hlsl::RWBuffer<float>::RWBuffer(hlsl::RWBuffer<float> const&)({{.*}}){{.*}} [[CtorAttr]]
46+
4147
// NOINLINE: ; Function Attrs: {{.*}}alwaysinline
4248
// NOINLINE-NEXT: define internal void @_GLOBAL__sub_I_GlobalConstructorLib.hlsl() [[InitAttr:\#[0-9]+]]
4349

clang/test/CodeGenHLSL/resources/ByteAddressBuffers-constructors.hlsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export void foo() {
4545
// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0t(
4646
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::ByteAddressBuffer", ptr %[[Tmp1]], i32 0, i32 0
4747
// CHECK-DXIL: store target("dx.RawBuffer", i8, 0, 0) %[[Handle1]], ptr %__handle, align 4
48-
// CHECK-DXIL: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[RetValue1]], ptr align 4 %[[Tmp1]], i32 4, i1 false)
48+
// CHECK: call void @hlsl::ByteAddressBuffer::ByteAddressBuffer(hlsl::ByteAddressBuffer const&)(ptr {{.*}} %[[RetValue1]], ptr {{.*}} %[[Tmp1]])
4949

5050
// Buf2 initialization part 1 - global init function that calls RWByteAddressBuffer::__createFromImplicitBinding
5151
// CHECK: define internal void @__cxx_global_var_init.1()
@@ -62,7 +62,7 @@ export void foo() {
6262
// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.RawBuffer_i8_1_0t(
6363
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWByteAddressBuffer", ptr %[[Tmp2]], i32 0, i32 0
6464
// CHECK-DXIL: store target("dx.RawBuffer", i8, 1, 0) %[[Handle2]], ptr %__handle, align 4
65-
// CHECK-DXIL: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[RetValue2]], ptr align 4 %[[Tmp2]], i32 4, i1 false)
65+
// CHECK: call void @hlsl::RWByteAddressBuffer::RWByteAddressBuffer(hlsl::RWByteAddressBuffer const&)(ptr {{.*}} %[[RetValue2]], ptr {{.*}} %[[Tmp2]])
6666

6767
// Buf3 initialization part 1 - local variable declared in function foo() is initialized by
6868
// RasterizerOrderedByteAddressBuffer C1 default constructor

clang/test/CodeGenHLSL/resources/RWBuffer-constructor.hlsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export void foo() {
4545
// CHECK-SAME: @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(
4646
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer", ptr %[[Tmp1]], i32 0, i32 0
4747
// CHECK-DXIL: store target("dx.TypedBuffer", float, 1, 0, 0) %[[Handle1]], ptr %__handle, align 4
48-
// CHECK-DXIL: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[RetValue1]], ptr align 4 %[[Tmp1]], i32 4, i1 false)
48+
// CHECK: call void @hlsl::RWBuffer<float>::RWBuffer(hlsl::RWBuffer<float> const&)(ptr {{.*}} %[[RetValue1]], ptr {{.*}} %[[Tmp1]])
4949

5050
// Buf2 initialization part 1 - global init function that RWBuffer<float>::__createFromImplicitBinding
5151
// CHECK: define internal void @__cxx_global_var_init.1()
@@ -62,7 +62,7 @@ export void foo() {
6262
// CHECK-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.TypedBuffer_f64_1_0_0t(
6363
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer.0", ptr %[[Tmp2]], i32 0, i32 0
6464
// CHECK-DXIL: store target("dx.TypedBuffer", double, 1, 0, 0) %[[Handle2]], ptr %__handle, align 4
65-
// CHECK-DXIL: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[RetValue2]], ptr align 4 %[[Tmp2]], i32 4, i1 false)
65+
// CHECK: call void @hlsl::RWBuffer<double>::RWBuffer(hlsl::RWBuffer<double> const&)(ptr {{.*}} %[[RetValue2]], ptr {{.*}} %[[Tmp2]])
6666

6767
// Buf3 initialization part 1 - local variable declared in function foo() is initialized by RWBuffer<int> C1 default constructor
6868
// CHECK: define void @foo()

clang/test/CodeGenHLSL/resources/StructuredBuffers-constructors.hlsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export void foo() {
4646
// CHECK-DXIL-SAME: @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_0_0t(
4747
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::StructuredBuffer", ptr %[[Tmp1]], i32 0, i32 0
4848
// CHECK-DXIL: store target("dx.RawBuffer", float, 0, 0) %[[Handle1]], ptr %__handle, align 4
49-
// CHECK-DXIL: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[RetValue1]], ptr align 4 %[[Tmp1]], i32 4, i1 false)
49+
// CHECK: call void @hlsl::StructuredBuffer<float>::StructuredBuffer(hlsl::StructuredBuffer<float> const&)(ptr {{.*}} %[[RetValue1]], ptr {{.*}} %[[Tmp1]])
5050

5151
// Buf2 initialization part 1 - global init function that calls RWStructuredBuffer<float>::__createFromImplicitBinding
5252
// CHECK: define internal void @__cxx_global_var_init.1()
@@ -63,7 +63,7 @@ export void foo() {
6363
// CHECK-DXIL-SAME: @llvm.dx.resource.handlefromimplicitbinding.tdx.RawBuffer_f32_1_0t(
6464
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer", ptr %[[Tmp2]], i32 0, i32 0
6565
// CHECK-DXIL: store target("dx.RawBuffer", float, 1, 0) %[[Handle2]], ptr %__handle, align 4
66-
// CHECK-DXIL: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[RetValue2]], ptr align 4 %[[Tmp2]], i32 4, i1 false)
66+
// CHECK: call void @hlsl::RWStructuredBuffer<float>::RWStructuredBuffer(hlsl::RWStructuredBuffer<float> const&)(ptr {{.*}} %[[RetValue2]], ptr {{.*}} %[[Tmp2]])
6767

6868
// Buf3 initialization part 1 - local variable declared in function foo() is initialized by
6969
// AppendStructuredBuffer<float> C1 default constructor

0 commit comments

Comments
 (0)