Skip to content

Commit f15fbd1

Browse files
authored
[HLSL] Use static create methods to initialize individual resources (#156544)
Use static methods `__createFromBinding` and `__createFromImplicitBinding` to initialize individual resources in Sema HLSL instead of calling resource constructor with binding information per proposal update llvm/wg-hlsl#336. Initialization of resources in arrays will be updated in a separate change because that happens in the codegen layer. Test updates include the use of the `llvm-cxxfilt` tool which takes care of demangling of function names for a more readable test baseline.
1 parent 06aaa0e commit f15fbd1

10 files changed

+329
-209
lines changed

clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp

Lines changed: 26 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
@@ -580,6 +589,23 @@ BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::returnValue(T ReturnValue) {
580589

581590
Expr *ReturnValueExpr = convertPlaceholder(ReturnValue);
582591
ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
592+
593+
QualType Ty = ReturnValueExpr->getType();
594+
if (Ty->isRecordType()) {
595+
// For record types, create a call to copy constructor to ensure proper copy
596+
// semantics.
597+
auto *ICE =
598+
ImplicitCastExpr::Create(AST, Ty.withConst(), CK_NoOp, ReturnValueExpr,
599+
nullptr, VK_XValue, FPOptionsOverride());
600+
CXXConstructorDecl *CD = lookupCopyConstructor(Ty);
601+
assert(CD && "no copy constructor found");
602+
ReturnValueExpr = CXXConstructExpr::Create(
603+
AST, Ty, SourceLocation(), CD, /*Elidable=*/false, {ICE},
604+
/*HadMultipleCandidates=*/false, /*ListInitialization=*/false,
605+
/*StdInitListInitialization=*/false,
606+
/*ZeroInitListInitialization=*/false, CXXConstructionKind::Complete,
607+
SourceRange());
608+
}
583609
StmtsList.push_back(
584610
ReturnStmt::Create(AST, SourceLocation(), ReturnValueExpr, nullptr));
585611
return *this;

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 109 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,15 @@ struct PerVisibilityBindingChecker {
12281228
}
12291229
};
12301230

1231+
static CXXMethodDecl *lookupMethod(Sema &S, CXXRecordDecl *RecordDecl,
1232+
StringRef Name, SourceLocation Loc) {
1233+
DeclarationName DeclName(&S.getASTContext().Idents.get(Name));
1234+
LookupResult Result(S, DeclName, Loc, Sema::LookupMemberName);
1235+
if (!S.LookupQualifiedName(Result, static_cast<DeclContext *>(RecordDecl)))
1236+
return nullptr;
1237+
return cast<CXXMethodDecl>(Result.getFoundDecl());
1238+
}
1239+
12311240
} // end anonymous namespace
12321241

12331242
bool SemaHLSL::handleRootSignatureElements(
@@ -3784,26 +3793,6 @@ void SemaHLSL::ActOnVariableDeclarator(VarDecl *VD) {
37843793
deduceAddressSpace(VD);
37853794
}
37863795

3787-
static bool initVarDeclWithCtor(Sema &S, VarDecl *VD,
3788-
MutableArrayRef<Expr *> Args) {
3789-
InitializedEntity Entity = InitializedEntity::InitializeVariable(VD);
3790-
InitializationKind Kind = InitializationKind::CreateDirect(
3791-
VD->getLocation(), SourceLocation(), SourceLocation());
3792-
3793-
InitializationSequence InitSeq(S, Entity, Kind, Args);
3794-
if (InitSeq.Failed())
3795-
return false;
3796-
3797-
ExprResult Init = InitSeq.Perform(S, Entity, Kind, Args);
3798-
if (!Init.get())
3799-
return false;
3800-
3801-
VD->setInit(S.MaybeCreateExprWithCleanups(Init.get()));
3802-
VD->setInitStyle(VarDecl::CallInit);
3803-
S.CheckCompleteVariableDeclaration(VD);
3804-
return true;
3805-
}
3806-
38073796
void SemaHLSL::createResourceRecordCtorArgs(
38083797
const Type *ResourceTy, StringRef VarName, HLSLResourceBindingAttr *RBA,
38093798
HLSLVkBindingAttr *VkBinding, uint32_t ArrayIndex,
@@ -3854,11 +3843,106 @@ void SemaHLSL::createResourceRecordCtorArgs(
38543843
}
38553844

38563845
bool SemaHLSL::initGlobalResourceDecl(VarDecl *VD) {
3857-
SmallVector<Expr *> Args;
3858-
createResourceRecordCtorArgs(VD->getType().getTypePtr(), VD->getName(),
3859-
VD->getAttr<HLSLResourceBindingAttr>(),
3860-
VD->getAttr<HLSLVkBindingAttr>(), 0, Args);
3861-
return initVarDeclWithCtor(SemaRef, VD, Args);
3846+
assert(VD->getType()->isHLSLResourceRecord() &&
3847+
"expected resource record type");
3848+
3849+
ASTContext &AST = SemaRef.getASTContext();
3850+
uint64_t UIntTySize = AST.getTypeSize(AST.UnsignedIntTy);
3851+
uint64_t IntTySize = AST.getTypeSize(AST.IntTy);
3852+
3853+
// Gather resource binding information from attributes.
3854+
HLSLResourceBindingAttr *RBA = VD->getAttr<HLSLResourceBindingAttr>();
3855+
HLSLVkBindingAttr *VkBinding = VD->getAttr<HLSLVkBindingAttr>();
3856+
std::optional<uint32_t> RegisterSlot;
3857+
uint32_t SpaceNo = 0;
3858+
if (VkBinding) {
3859+
RegisterSlot = VkBinding->getBinding();
3860+
SpaceNo = VkBinding->getSet();
3861+
} else if (RBA) {
3862+
if (RBA->hasRegisterSlot())
3863+
RegisterSlot = RBA->getSlotNumber();
3864+
SpaceNo = RBA->getSpaceNumber();
3865+
}
3866+
3867+
// Find correct initialization method and create its arguments.
3868+
QualType ResourceTy = VD->getType();
3869+
CXXRecordDecl *ResourceDecl = ResourceTy->getAsCXXRecordDecl();
3870+
CXXMethodDecl *CreateMethod = nullptr;
3871+
llvm::SmallVector<Expr *> Args;
3872+
3873+
if (RegisterSlot.has_value()) {
3874+
// The resource has explicit binding.
3875+
CreateMethod = lookupMethod(SemaRef, ResourceDecl, "__createFromBinding",
3876+
VD->getLocation());
3877+
IntegerLiteral *RegSlot = IntegerLiteral::Create(
3878+
AST, llvm::APInt(UIntTySize, RegisterSlot.value()), AST.UnsignedIntTy,
3879+
SourceLocation());
3880+
Args.push_back(RegSlot);
3881+
} else {
3882+
// The resource has implicit binding.
3883+
CreateMethod =
3884+
lookupMethod(SemaRef, ResourceDecl, "__createFromImplicitBinding",
3885+
VD->getLocation());
3886+
uint32_t OrderID = (RBA && RBA->hasImplicitBindingOrderID())
3887+
? RBA->getImplicitBindingOrderID()
3888+
: getNextImplicitBindingOrderID();
3889+
IntegerLiteral *OrderId =
3890+
IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, OrderID),
3891+
AST.UnsignedIntTy, SourceLocation());
3892+
Args.push_back(OrderId);
3893+
}
3894+
3895+
if (!CreateMethod)
3896+
// This can happen if someone creates a struct that looks like an HLSL
3897+
// resource record but does not have the required static create method.
3898+
// No binding will be generated for it.
3899+
return false;
3900+
3901+
IntegerLiteral *Space =
3902+
IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, SpaceNo),
3903+
AST.UnsignedIntTy, SourceLocation());
3904+
Args.push_back(Space);
3905+
3906+
IntegerLiteral *RangeSize = IntegerLiteral::Create(
3907+
AST, llvm::APInt(IntTySize, 1), AST.IntTy, SourceLocation());
3908+
Args.push_back(RangeSize);
3909+
3910+
IntegerLiteral *Index = IntegerLiteral::Create(
3911+
AST, llvm::APInt(UIntTySize, 0), AST.UnsignedIntTy, SourceLocation());
3912+
Args.push_back(Index);
3913+
3914+
StringRef VarName = VD->getName();
3915+
StringLiteral *Name = StringLiteral::Create(
3916+
AST, VarName, StringLiteralKind::Ordinary, false,
3917+
AST.getStringLiteralArrayType(AST.CharTy.withConst(), VarName.size()),
3918+
SourceLocation());
3919+
ImplicitCastExpr *NameCast = ImplicitCastExpr::Create(
3920+
AST, AST.getPointerType(AST.CharTy.withConst()), CK_ArrayToPointerDecay,
3921+
Name, nullptr, VK_PRValue, FPOptionsOverride());
3922+
Args.push_back(NameCast);
3923+
3924+
// Make sure the create method template is instantiated and emitted.
3925+
if (!CreateMethod->isDefined() && CreateMethod->isTemplateInstantiation())
3926+
SemaRef.InstantiateFunctionDefinition(VD->getLocation(), CreateMethod,
3927+
true);
3928+
3929+
// Create CallExpr with a call to the static method and set it as the decl
3930+
// initialization.
3931+
DeclRefExpr *DRE = DeclRefExpr::Create(
3932+
AST, NestedNameSpecifierLoc(), SourceLocation(), CreateMethod, false,
3933+
CreateMethod->getNameInfo(), CreateMethod->getType(), VK_PRValue);
3934+
3935+
auto *ImpCast = ImplicitCastExpr::Create(
3936+
AST, AST.getPointerType(CreateMethod->getType()),
3937+
CK_FunctionToPointerDecay, DRE, nullptr, VK_PRValue, FPOptionsOverride());
3938+
3939+
CallExpr *InitExpr =
3940+
CallExpr::Create(AST, ImpCast, Args, ResourceTy, VK_PRValue,
3941+
SourceLocation(), FPOptionsOverride());
3942+
VD->setInit(InitExpr);
3943+
VD->setInitStyle(VarDecl::CallInit);
3944+
SemaRef.CheckCompleteVariableDeclaration(VD);
3945+
return true;
38623946
}
38633947

38643948
bool SemaHLSL::initGlobalResourceArrayDecl(VarDecl *VD) {

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ RESOURCE Buffer;
3434

3535
#endif
3636

37-
// CHECK: CXXRecordDecl {{.*}} implicit referenced <undeserialized declarations> class [[RESOURCE]] definition
37+
// CHECK: CXXRecordDecl {{.*}} implicit referenced class [[RESOURCE]] definition
3838
// CHECK: FinalAttr {{.*}} Implicit final
3939
// CHECK-NEXT: FieldDecl {{.*}} implicit __handle '__hlsl_resource_t
4040
// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
@@ -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/AST/HLSL/vk_binding_attr.hlsl

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,23 @@
22
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.8-library -finclude-default-header -ast-dump -o - %s | FileCheck %s -check-prefixes=DXIL,CHECK
33

44
// CHECK: VarDecl {{.*}} Buf 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>'
5-
// SPV-NEXT: CXXConstructExpr {{.*}} 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>' 'void (unsigned int, unsigned int, int, unsigned int, const char *)'
5+
// CHECK-NEXT: CallExpr {{.*}} 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>'
6+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'hlsl::StructuredBuffer<float> (*)(unsigned int, unsigned int, int, unsigned int, const char *)' <FunctionToPointerDecay>
7+
// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::StructuredBuffer<float> (unsigned int, unsigned int, int, unsigned int, const char *)'
8+
// CHECK-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'hlsl::StructuredBuffer<float> (unsigned int, unsigned int, int, unsigned int, const char *)'
69
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 23
710
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 102
8-
// DXIL-NEXT: CXXConstructExpr {{.*}} 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>' 'void (unsigned int, int, unsigned int, unsigned int, const char *)'
911
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
10-
// DXIL-NEXT: IntegerLiteral {{.*}} 'int' 1
12+
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
1113
// SPV: HLSLVkBindingAttr {{.*}} 23 102
1214
// DXIL-NOT: HLSLVkBindingAttr
1315
[[vk::binding(23, 102)]] StructuredBuffer<float> Buf;
1416

1517
// CHECK: VarDecl {{.*}} Buf2 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>'
16-
// CHECK-NEXT: CXXConstructExpr {{.*}} 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>' 'void (unsigned int, unsigned int, int, unsigned int, const char *)'
18+
// CHECK-NEXT: CallExpr {{.*}} 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>'
19+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'hlsl::StructuredBuffer<float> (*)(unsigned int, unsigned int, int, unsigned int, const char *)' <FunctionToPointerDecay>
20+
// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::StructuredBuffer<float> (unsigned int, unsigned int, int, unsigned int, const char *)'
21+
// CHECK-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'hlsl::StructuredBuffer<float> (unsigned int, unsigned int, int, unsigned int, const char *)'
1722
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 14
1823
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 1
1924
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 23
@@ -24,7 +29,10 @@
2429
[[vk::binding(14, 1)]] StructuredBuffer<float> Buf2 : register(t23, space102);
2530

2631
// CHECK: VarDecl {{.*}} Buf3 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>'
27-
// CHECK-NEXT: CXXConstructExpr {{.*}} 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>' 'void (unsigned int, unsigned int, int, unsigned int, const char *)'
32+
// CHECK-NEXT: CallExpr {{.*}} 'StructuredBuffer<float>':'hlsl::StructuredBuffer<float>'
33+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'hlsl::StructuredBuffer<float> (*)(unsigned int, unsigned int, int, unsigned int, const char *)' <FunctionToPointerDecay>
34+
// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::StructuredBuffer<float> (unsigned int, unsigned int, int, unsigned int, const char *)'
35+
// CHECK-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'hlsl::StructuredBuffer<float> (unsigned int, unsigned int, int, unsigned int, const char *)'
2836
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 14
2937
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
3038
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 23
@@ -43,28 +51,46 @@
4351
}
4452

4553
// CHECK: VarDecl {{.*}} Buf4 'Buffer<int>':'hlsl::Buffer<int>'
46-
// SPV-NEXT: CXXConstructExpr {{.*}} 'Buffer<int>':'hlsl::Buffer<int>' 'void (unsigned int, unsigned int, int, unsigned int, const char *)'
54+
// CHECK-NEXT: CallExpr {{.*}} 'Buffer<int>':'hlsl::Buffer<int>'
55+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'hlsl::Buffer<int> (*)(unsigned int, unsigned int, int, unsigned int, const char *)' <FunctionToPointerDecay>
56+
// SPV-NEXT: DeclRefExpr {{.*}} 'hlsl::Buffer<int> (unsigned int, unsigned int, int, unsigned int, const char *)'
57+
// SPV-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'Buffer<int> (unsigned int, unsigned int, int, unsigned int, const char *)'
4758
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 24
4859
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 103
49-
// DXL-NEXT: CXXConstructExpr {{.*}} 'Buffer<int>':'hlsl::Buffer<int>' 'void (unsigned int, int, unsigned int, unsigned int, const char *)'
60+
// DXIL-NEXT: DeclRefExpr {{.*}} 'hlsl::Buffer<int> (unsigned int, unsigned int, int, unsigned int, const char *)'
61+
// DXIL-NEXT-SAME: CXXMethod {{.*}} '__createFromImplicitBinding' 'Buffer<int> (unsigned int, unsigned int, int, unsigned int, const char *)'
62+
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 2
63+
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
5064
// SPV: HLSLVkBindingAttr {{.*}} 24 103
5165
// DXIL-NOT: HLSLVkBindingAttr
5266
[[vk::binding(24, 103)]] Buffer<int> Buf4;
5367

5468
// CHECK: VarDecl {{.*}} Buf5 'RWBuffer<int2>':'hlsl::RWBuffer<vector<int, 2>>'
55-
// SPV-NEXT: CXXConstructExpr {{.*}} 'RWBuffer<int2>':'hlsl::RWBuffer<vector<int, 2>>' 'void (unsigned int, unsigned int, int, unsigned int, const char *)'
69+
// CHECK-NEXT: CallExpr {{.*}} 'RWBuffer<int2>':'hlsl::RWBuffer<vector<int, 2>>'
70+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'hlsl::RWBuffer<vector<int, 2>> (*)(unsigned int, unsigned int, int, unsigned int, const char *)' <FunctionToPointerDecay>
71+
// SPV-NEXT: DeclRefExpr {{.*}} 'hlsl::RWBuffer<vector<int, 2>> (unsigned int, unsigned int, int, unsigned int, const char *)'
72+
// SPV-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'Buffer<int2> (unsigned int, unsigned int, int, unsigned int, const char *)'
5673
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 25
5774
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 104
58-
// DXL-NEXT: CXXConstructExpr {{.*}} 'Buffer<int>':'hlsl::Buffer<int>' 'void (unsigned int, int, unsigned int, unsigned int, const char *)'
75+
// DXIL-NEXT: DeclRefExpr {{.*}} 'hlsl::RWBuffer<vector<int, 2>> (unsigned int, unsigned int, int, unsigned int, const char *)'
76+
// DXIL-NEXT-SAME: CXXMethod {{.*}} '__createFromImplicitBinding' 'Buffer<int2> (unsigned int, unsigned int, int, unsigned int, const char *)'
77+
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 3
78+
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
5979
// SPV: HLSLVkBindingAttr {{.*}} 25 104
6080
// DXIL-NOT: HLSLVkBindingAttr
6181
[[vk::binding(25, 104)]] RWBuffer<int2> Buf5;
6282

6383
// CHECK: VarDecl {{.*}} Buf6 'RWStructuredBuffer<int>':'hlsl::RWStructuredBuffer<int>'
64-
// SPV-NEXT: CXXConstructExpr {{.*}} 'RWStructuredBuffer<int>':'hlsl::RWStructuredBuffer<int>' 'void (unsigned int, unsigned int, int, unsigned int, const char *)'
84+
// CHECK-NEXT: CallExpr {{.*}} 'RWStructuredBuffer<int>':'hlsl::RWStructuredBuffer<int>'
85+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'hlsl::RWStructuredBuffer<int> (*)(unsigned int, unsigned int, int, unsigned int, const char *)' <FunctionToPointerDecay>
86+
// SPV-NEXT: DeclRefExpr {{.*}} 'hlsl::RWStructuredBuffer<int> (unsigned int, unsigned int, int, unsigned int, const char *)'
87+
// SPV-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'hlsl::RWStructuredBuffer<int> (unsigned int, unsigned int, int, unsigned int, const char *)'
6588
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 26
6689
// SPV-NEXT: IntegerLiteral {{.*}} 'unsigned int' 105
67-
// DXL-NEXT: CXXConstructExpr {{.*}} 'Buffer<int>':'hlsl::Buffer<int>' 'void (unsigned int, int, unsigned int, unsigned int, const char *)'
90+
// DXIL-NEXT: DeclRefExpr {{.*}} 'hlsl::RWStructuredBuffer<int> (unsigned int, unsigned int, int, unsigned int, const char *)'
91+
// DXIL-NEXT-SAME: CXXMethod {{.*}} '__createFromBinding' 'hlsl::RWStructuredBuffer<int> (unsigned int, unsigned int, int, unsigned int, const char *)'
92+
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 4
93+
// DXIL-NEXT: IntegerLiteral {{.*}} 'unsigned int' 0
6894
// SPV: HLSLVkBindingAttr {{.*}} 26 105
6995
// DXIL-NOT: HLSLVkBindingAttr
7096
[[vk::binding(26, 105)]] RWStructuredBuffer<int> Buf6;

0 commit comments

Comments
 (0)