Skip to content

Commit a4e932c

Browse files
committed
[HLSL] Implement RWBuffer::operator[] via __builtin_hlsl_resource_getpointer
This introduces `__builtin_hlsl_resource_getpointer`, which lowers to `llvm.dx.resource.getpointer` and is used to implement indexing into resources. This will only work through the backend for typed buffers at this point, but the changes to structured buffers should be correct as far as the frontend is concerned. Note: We probably want this to return a reference in the HLSL device address space, but for now we're just using address space 0. Creating a device address space and updating this code can be done later as necessary. Fixes #95956
1 parent 012dd8b commit a4e932c

21 files changed

+248
-138
lines changed

clang/include/clang/Basic/Builtins.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4738,6 +4738,12 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> {
47384738
}
47394739

47404740
// HLSL
4741+
def HLSLTypedBufferPointer : LangBuiltin<"HLSL_LANG"> {
4742+
let Spellings = ["__builtin_hlsl_resource_getpointer"];
4743+
let Attributes = [NoThrow];
4744+
let Prototype = "void(...)";
4745+
}
4746+
47414747
def HLSLAll : LangBuiltin<"HLSL_LANG"> {
47424748
let Spellings = ["__builtin_hlsl_all"];
47434749
let Attributes = [NoThrow, Const];

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12487,6 +12487,7 @@ def err_hlsl_pointers_unsupported : Error<
1248712487
"%select{pointers|references}0 are unsupported in HLSL">;
1248812488
def err_hlsl_missing_resource_class : Error<"HLSL resource needs to have [[hlsl::resource_class()]] attribute">;
1248912489
def err_hlsl_attribute_needs_intangible_type: Error<"attribute %0 can be used only on HLSL intangible type %1">;
12490+
def err_hlsl_builtin_requires_resource: Error<"operand must be of __hlsl_resource_t type">;
1249012491

1249112492
def err_hlsl_operator_unsupported : Error<
1249212493
"the '%select{&|*|->}0' operator is unsupported in HLSL">;

clang/lib/AST/Type.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4723,7 +4723,9 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
47234723
case Type::Pipe:
47244724
return computeTypeLinkageInfo(cast<PipeType>(T)->getElementType());
47254725
case Type::HLSLAttributedResource:
4726-
llvm_unreachable("not yet implemented");
4726+
return computeTypeLinkageInfo(cast<HLSLAttributedResourceType>(T)
4727+
->getContainedType()
4728+
->getCanonicalTypeInternal());
47274729
}
47284730

47294731
llvm_unreachable("unhandled type class");

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19008,6 +19008,16 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
1900819008
return nullptr;
1900919009

1901019010
switch (BuiltinID) {
19011+
case Builtin::BI__builtin_hlsl_resource_getpointer: {
19012+
Value *HandleOp = EmitScalarExpr(E->getArg(0));
19013+
Value *IndexOp = EmitScalarExpr(E->getArg(1));
19014+
19015+
// TODO: Map to an hlsl_device address space.
19016+
llvm::Type *RetTy = llvm::PointerType::getUnqual(getLLVMContext());
19017+
19018+
return Builder.CreateIntrinsic(RetTy, Intrinsic::dx_resource_getpointer,
19019+
ArrayRef<Value *>{HandleOp, IndexOp});
19020+
}
1901119021
case Builtin::BI__builtin_hlsl_all: {
1901219022
Value *Op0 = EmitScalarExpr(E->getArg(0));
1901319023
return Builder.CreateIntrinsic(

clang/lib/Sema/HLSLExternalSemaSource.cpp

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ struct BuiltinTypeDeclBuilder {
157157
assert(R.isSingleResult() &&
158158
"Since this is a builtin it should always resolve!");
159159
auto *VD = cast<ValueDecl>(R.getFoundDecl());
160-
QualType Ty = VD->getType();
161160
return DeclRefExpr::Create(AST, NestedNameSpecifierLoc(), SourceLocation(),
162-
VD, false, NameInfo, Ty, VK_PRValue);
161+
VD, false, NameInfo, AST.BuiltinFnTy,
162+
VK_PRValue);
163163
}
164164

165165
BuiltinTypeDeclBuilder &addDefaultHandleConstructor(Sema &S) {
@@ -186,15 +186,15 @@ struct BuiltinTypeDeclBuilder {
186186
return *this;
187187
}
188188

189-
BuiltinTypeDeclBuilder &addArraySubscriptOperators() {
189+
BuiltinTypeDeclBuilder &addArraySubscriptOperators(Sema &S) {
190190
if (Record->isCompleteDefinition())
191191
return *this;
192-
addArraySubscriptOperator(true);
193-
addArraySubscriptOperator(false);
192+
addArraySubscriptOperator(S, true);
193+
addArraySubscriptOperator(S, false);
194194
return *this;
195195
}
196196

197-
BuiltinTypeDeclBuilder &addArraySubscriptOperator(bool IsConst) {
197+
BuiltinTypeDeclBuilder &addArraySubscriptOperator(Sema &S, bool IsConst) {
198198
if (Record->isCompleteDefinition())
199199
return *this;
200200

@@ -241,23 +241,29 @@ struct BuiltinTypeDeclBuilder {
241241
auto FnProtoLoc = TSInfo->getTypeLoc().getAs<FunctionProtoTypeLoc>();
242242
FnProtoLoc.setParam(0, IdxParam);
243243

244-
// FIXME: Placeholder to make sure we return the correct type - create
245-
// field of element_type and return reference to it. This field will go
246-
// away once indexing into resources is properly implemented in
247-
// llvm/llvm-project#95956.
248-
if (Fields.count("e") == 0) {
249-
addMemberVariable("e", ElemTy, {});
250-
}
251-
FieldDecl *ElemFieldDecl = Fields["e"];
252-
253244
auto *This =
254245
CXXThisExpr::Create(AST, SourceLocation(),
255246
MethodDecl->getFunctionObjectParameterType(), true);
256-
Expr *ElemField = MemberExpr::CreateImplicit(
257-
AST, This, false, ElemFieldDecl, ElemFieldDecl->getType(), VK_LValue,
258-
OK_Ordinary);
259-
auto *Return =
260-
ReturnStmt::Create(AST, SourceLocation(), ElemField, nullptr);
247+
FieldDecl *Handle = Fields["__handle"];
248+
auto *HandleExpr = MemberExpr::CreateImplicit(
249+
AST, This, false, Handle, Handle->getType(), VK_LValue, OK_Ordinary);
250+
251+
auto *IndexExpr = DeclRefExpr::Create(
252+
AST, NestedNameSpecifierLoc(), SourceLocation(), IdxParam, false,
253+
DeclarationNameInfo(IdxParam->getDeclName(), SourceLocation()),
254+
AST.UnsignedIntTy, VK_PRValue);
255+
256+
DeclRefExpr *Builtin =
257+
lookupBuiltinFunction(AST, S, "__builtin_hlsl_resource_getpointer");
258+
// TODO: Map to an hlsl_device address space.
259+
QualType ElemPtrTy = AST.getPointerType(ElemTy);
260+
Expr *Call = CallExpr::Create(AST, Builtin, {HandleExpr, IndexExpr},
261+
ElemPtrTy, VK_PRValue,
262+
SourceLocation(), FPOptionsOverride());
263+
Expr *Deref = UnaryOperator::Create(
264+
AST, Call, UO_Deref, ElemTy, VK_PRValue, OK_Ordinary, SourceLocation(),
265+
/*CanOverflow=*/false, FPOptionsOverride());
266+
auto *Return = ReturnStmt::Create(AST, SourceLocation(), Deref, nullptr);
261267

262268
MethodDecl->setBody(CompoundStmt::Create(AST, {Return}, FPOptionsOverride(),
263269
SourceLocation(),
@@ -482,7 +488,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
482488
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
483489
ResourceKind::TypedBuffer, /*IsROV=*/false,
484490
/*RawBuffer=*/false)
485-
.addArraySubscriptOperators()
491+
.addArraySubscriptOperators(*SemaPtr)
486492
.completeDefinition();
487493
});
488494

@@ -494,7 +500,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
494500
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
495501
ResourceKind::TypedBuffer, /*IsROV=*/true,
496502
/*RawBuffer=*/false)
497-
.addArraySubscriptOperators()
503+
.addArraySubscriptOperators(*SemaPtr)
498504
.completeDefinition();
499505
});
500506

@@ -504,7 +510,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
504510
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
505511
setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, ResourceKind::RawBuffer,
506512
/*IsROV=*/false, /*RawBuffer=*/true)
507-
.addArraySubscriptOperators()
513+
.addArraySubscriptOperators(*SemaPtr)
508514
.completeDefinition();
509515
});
510516

@@ -514,7 +520,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
514520
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
515521
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
516522
/*IsROV=*/false, /*RawBuffer=*/true)
517-
.addArraySubscriptOperators()
523+
.addArraySubscriptOperators(*SemaPtr)
518524
.completeDefinition();
519525
});
520526

@@ -545,7 +551,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
545551
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
546552
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer,
547553
/*IsROV=*/true, /*RawBuffer=*/true)
548-
.addArraySubscriptOperators()
554+
.addArraySubscriptOperators(*SemaPtr)
549555
.completeDefinition();
550556
});
551557
}

clang/lib/Sema/SemaExpr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -980,6 +980,9 @@ Sema::VarArgKind Sema::isValidVarArgType(const QualType &Ty) {
980980
if (Ty->isObjCObjectType())
981981
return VAK_Invalid;
982982

983+
if (getLangOpts().HLSL && Ty->getAs<HLSLAttributedResourceType>())
984+
return VAK_Valid;
985+
983986
if (getLangOpts().MSVCCompat)
984987
return VAK_MSVCUndefined;
985988

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1882,6 +1882,25 @@ static bool CheckVectorSelect(Sema *S, CallExpr *TheCall) {
18821882
// returning an ExprError
18831883
bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
18841884
switch (BuiltinID) {
1885+
case Builtin::BI__builtin_hlsl_resource_getpointer: {
1886+
if (SemaRef.checkArgCount(TheCall, 2))
1887+
return true;
1888+
auto *ResourceTy =
1889+
TheCall->getArg(0)->getType()->getAs<HLSLAttributedResourceType>();
1890+
if (!ResourceTy) {
1891+
SemaRef.Diag(TheCall->getBeginLoc(),
1892+
diag::err_hlsl_builtin_requires_resource)
1893+
<< TheCall->getArg(0)->getSourceRange();
1894+
return true;
1895+
}
1896+
1897+
QualType ContainedTy = ResourceTy->getContainedType();
1898+
// TODO: Map to an hlsl_device address space.
1899+
TheCall->setType(getASTContext().getPointerType(ContainedTy));
1900+
TheCall->setValueKind(VK_LValue);
1901+
1902+
break;
1903+
}
18851904
case Builtin::BI__builtin_hlsl_all:
18861905
case Builtin::BI__builtin_hlsl_any: {
18871906
if (SemaRef.checkArgCount(TheCall, 1))

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

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,30 @@ RWBuffer<float> Buffer;
3838
// CHECK-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> Idx 'unsigned int'
3939
// CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
4040
// CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
41-
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' lvalue .e 0x{{[0-9A-Fa-f]+}}
41+
// CHECK-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' prefix '*' cannot overflow
42+
// CHECK-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type *'
43+
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '<builtin fn type>' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
44+
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '__hlsl_resource_t
45+
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
46+
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
47+
// CHECK-SAME: ' lvalue .__handle 0x{{[0-9A-Fa-f]+}}
4248
// CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'const RWBuffer<element_type>' lvalue implicit this
49+
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
4350
// CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
4451

4552
// CHECK-NEXT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> operator[] 'element_type &(unsigned int)'
4653
// CHECK-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> Idx 'unsigned int'
4754
// CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
4855
// CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
49-
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' lvalue .e 0x{{[0-9A-Fa-f]+}}
56+
// CHECK-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' prefix '*' cannot overflow
57+
// CHECK-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type *'
58+
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '<builtin fn type>' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
59+
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '__hlsl_resource_t
60+
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
61+
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
62+
// CHECK-SAME: ' lvalue .__handle 0x{{[0-9A-Fa-f]+}}
5063
// CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'RWBuffer<element_type>' lvalue implicit this
64+
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
5165
// CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
5266

5367
// CHECK: ClassTemplateSpecializationDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class RWBuffer definition

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,32 @@ RWStructuredBuffer<int> Buffer;
4040
// CHECK-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> Idx 'unsigned int'
4141
// CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
4242
// CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
43-
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' lvalue .e 0x{{[0-9A-Fa-f]+}}
43+
// CHECK-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' prefix '*' cannot overflow
44+
// CHECK-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type *'
45+
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '<builtin fn type>' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
46+
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '__hlsl_resource_t
47+
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
48+
// CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]]
49+
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
50+
// CHECK-SAME: ' lvalue .__handle 0x{{[0-9A-Fa-f]+}}
4451
// CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'const RWStructuredBuffer<element_type>' lvalue implicit this
52+
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
4553
// CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
4654

4755
// CHECK-NEXT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> operator[] 'element_type &(unsigned int)'
4856
// CHECK-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> Idx 'unsigned int'
4957
// CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
5058
// CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
51-
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' lvalue .e 0x{{[0-9A-Fa-f]+}}
59+
// CHECK-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' prefix '*' cannot overflow
60+
// CHECK-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type *'
61+
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '<builtin fn type>' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
62+
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '__hlsl_resource_t
63+
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
64+
// CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]]
65+
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
66+
// CHECK-SAME: ' lvalue .__handle 0x{{[0-9A-Fa-f]+}}
5267
// CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'RWStructuredBuffer<element_type>' lvalue implicit this
68+
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
5369
// CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
5470

5571
// CHECK: ClassTemplateSpecializationDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class RWStructuredBuffer definition

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

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,34 @@ RasterizerOrderedStructuredBuffer<int> Buffer;
4141
// CHECK-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> Idx 'unsigned int'
4242
// CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
4343
// CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
44-
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' lvalue .e 0x{{[0-9A-Fa-f]+}}
44+
// CHECK-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' prefix '*' cannot overflow
45+
// CHECK-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type *'
46+
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '<builtin fn type>' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
47+
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '__hlsl_resource_t
48+
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
49+
// CHECK-SAME{LITERAL}: [[hlsl::is_rov]]
50+
// CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]]
51+
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
52+
// CHECK-SAME: ' lvalue .__handle 0x{{[0-9A-Fa-f]+}}
4553
// CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'const RasterizerOrderedStructuredBuffer<element_type>' lvalue implicit this
54+
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
4655
// CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
4756

4857
// CHECK-NEXT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> operator[] 'element_type &(unsigned int)'
4958
// CHECK-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> Idx 'unsigned int'
5059
// CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
5160
// CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
52-
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' lvalue .e 0x{{[0-9A-Fa-f]+}}
61+
// CHECK-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' prefix '*' cannot overflow
62+
// CHECK-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type *'
63+
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '<builtin fn type>' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
64+
// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> '__hlsl_resource_t
65+
// CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
66+
// CHECK-SAME{LITERAL}: [[hlsl::is_rov]]
67+
// CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]]
68+
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
69+
// CHECK-SAME: ' lvalue .__handle 0x{{[0-9A-Fa-f]+}}
5370
// CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'RasterizerOrderedStructuredBuffer<element_type>' lvalue implicit this
71+
// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
5472
// CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
5573

5674
// CHECK: ClassTemplateSpecializationDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> class RasterizerOrderedStructuredBuffer definition

0 commit comments

Comments
 (0)