Skip to content

Commit e509189

Browse files
committed
[HLSL] GetDimensions methods for buffer resources
Adds GetDimensions methods on all supported buffer resources.
1 parent 3750123 commit e509189

14 files changed

+406
-4
lines changed

clang/include/clang/Basic/Builtins.td

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4951,6 +4951,18 @@ def HLSLResourceNonUniformIndex : LangBuiltin<"HLSL_LANG"> {
49514951
let Prototype = "uint32_t(uint32_t)";
49524952
}
49534953

4954+
def HLSLResourceGetDimensions : LangBuiltin<"HLSL_LANG"> {
4955+
let Spellings = ["__builtin_hlsl_buffer_getdimensions"];
4956+
let Attributes = [NoThrow];
4957+
let Prototype = "void(...)";
4958+
}
4959+
4960+
def HLSLResourceGetStride : LangBuiltin<"HLSL_LANG"> {
4961+
let Spellings = ["__builtin_hlsl_buffer_getstride"];
4962+
let Attributes = [NoThrow];
4963+
let Prototype = "void(...)";
4964+
}
4965+
49544966
def HLSLAll : LangBuiltin<"HLSL_LANG"> {
49554967
let Spellings = ["__builtin_hlsl_all"];
49564968
let Attributes = [NoThrow, Const];

clang/lib/CodeGen/CGHLSLBuiltins.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,58 @@ static Value *handleHlslSplitdouble(const CallExpr *E, CodeGenFunction *CGF) {
160160
return LastInst;
161161
}
162162

163+
static Value *emitDXILGetDimensions(CodeGenFunction *CGF, Value *Handle,
164+
Value *MipLevel, LValue *OutArg0,
165+
LValue *OutArg1 = nullptr,
166+
LValue *OutArg2 = nullptr,
167+
LValue *OutArg3 = nullptr) {
168+
assert(OutArg0 && "first output argument is required");
169+
170+
llvm::Type *I32 = CGF->Int32Ty;
171+
StructType *RetTy = llvm::StructType::get(I32, I32, I32, I32);
172+
173+
CallInst *CI = CGF->Builder.CreateIntrinsic(
174+
RetTy, llvm::Intrinsic::dx_resource_getdimensions,
175+
ArrayRef<Value *>{Handle, MipLevel});
176+
177+
Value *LastInst = nullptr;
178+
unsigned OutArgIndex = 0;
179+
for (LValue *OutArg : {OutArg0, OutArg1, OutArg2, OutArg3}) {
180+
if (OutArg) {
181+
Value *OutArgVal = CGF->Builder.CreateExtractValue(CI, OutArgIndex);
182+
LastInst = CGF->Builder.CreateStore(OutArgVal, OutArg->getAddress());
183+
}
184+
++OutArgIndex;
185+
}
186+
assert(LastInst && "no output argument stored?");
187+
return LastInst;
188+
}
189+
190+
static Value *emitBufferGetDimensions(CodeGenFunction *CGF, Value *Handle,
191+
LValue &Dim) {
192+
// Generate the call to get the buffer dimension.
193+
switch (CGF->CGM.getTarget().getTriple().getArch()) {
194+
case llvm::Triple::dxil:
195+
return emitDXILGetDimensions(CGF, Handle, PoisonValue::get(CGF->Int32Ty),
196+
&Dim);
197+
break;
198+
case llvm::Triple::spirv:
199+
llvm_unreachable("SPIR-V GetDimensions codegen not implemented yet.");
200+
default:
201+
llvm_unreachable("GetDimensions not supported by target architecture");
202+
}
203+
}
204+
205+
static Value *emitBufferStride(CodeGenFunction *CGF, const Expr *HandleExpr,
206+
LValue &Stride) {
207+
// Figure out the stride of the buffer elements from the handle type.
208+
auto *HandleTy =
209+
cast<HLSLAttributedResourceType>(HandleExpr->getType().getTypePtr());
210+
QualType ElementTy = HandleTy->getContainedType();
211+
Value *StrideValue = CGF->getTypeSize(ElementTy);
212+
return CGF->Builder.CreateStore(StrideValue, Stride.getAddress());
213+
}
214+
163215
// Return dot product intrinsic that corresponds to the QT scalar type
164216
static Intrinsic::ID getDotProductIntrinsic(CGHLSLRuntime &RT, QualType QT) {
165217
if (QT->isFloatingType())
@@ -359,6 +411,15 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
359411
RetTy, CGM.getHLSLRuntime().getNonUniformResourceIndexIntrinsic(),
360412
ArrayRef<Value *>{IndexOp});
361413
}
414+
case Builtin::BI__builtin_hlsl_buffer_getdimensions: {
415+
Value *Handle = EmitScalarExpr(E->getArg(0));
416+
LValue Dim = EmitLValue(E->getArg(1));
417+
return emitBufferGetDimensions(this, Handle, Dim);
418+
}
419+
case Builtin::BI__builtin_hlsl_buffer_getstride: {
420+
LValue Stride = EmitLValue(E->getArg(1));
421+
return emitBufferStride(this, E->getArg(0), Stride);
422+
}
362423
case Builtin::BI__builtin_hlsl_all: {
363424
Value *Op0 = EmitScalarExpr(E->getArg(0));
364425
return Builder.CreateIntrinsic(

clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,29 @@ CXXConstructorDecl *lookupCopyConstructor(QualType ResTy) {
5757
return CD;
5858
return nullptr;
5959
}
60+
61+
ParameterABI
62+
convertParamModifierToParamABI(HLSLParamModifierAttr::Spelling Modifier) {
63+
assert(Modifier != HLSLParamModifierAttr::Spelling::Keyword_in &&
64+
"HLSL 'in' parameters modifier cannot be converted to ParameterABI");
65+
switch (Modifier) {
66+
case HLSLParamModifierAttr::Spelling::Keyword_out:
67+
return ParameterABI::HLSLOut;
68+
case HLSLParamModifierAttr::Spelling::Keyword_inout:
69+
return ParameterABI::HLSLInOut;
70+
default:
71+
llvm_unreachable("Invalid HLSL parameter modifier");
72+
}
73+
}
74+
75+
QualType getInoutParameterType(ASTContext &AST, QualType Ty) {
76+
assert(!Ty->isReferenceType() &&
77+
"Pointer and reference types cannot be inout or out parameters");
78+
Ty = AST.getLValueReferenceType(Ty);
79+
Ty.addRestrict();
80+
return Ty;
81+
}
82+
6083
} // namespace
6184

6285
// Builder for template arguments of builtin types. Used internally
@@ -421,13 +444,32 @@ BuiltinTypeMethodBuilder::addParam(StringRef Name, QualType Ty,
421444
void BuiltinTypeMethodBuilder::createDecl() {
422445
assert(Method == nullptr && "Method or constructor is already created");
423446

424-
// create method or constructor type
447+
// create function prototype
425448
ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
426449
SmallVector<QualType> ParamTypes;
427-
for (Param &MP : Params)
428-
ParamTypes.emplace_back(MP.Ty);
450+
SmallVector<FunctionType::ExtParameterInfo> ParamExtInfos(Params.size());
451+
uint32_t ArgIndex = 0;
452+
bool IsTemplate = DeclBuilder.Template != nullptr;
453+
bool UseParamExtInfo = false;
454+
for (Param &MP : Params) {
455+
QualType Ty = MP.Ty;
456+
if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
457+
UseParamExtInfo = true;
458+
ParamExtInfos[ArgIndex].withABI(
459+
convertParamModifierToParamABI(MP.Modifier));
460+
// Only update types on inout and out parameters for non-templated
461+
// methods. Templated types will have their inout/out parameters
462+
// converted to references during template instantiation.
463+
if (!IsTemplate)
464+
Ty = getInoutParameterType(AST, Ty);
465+
}
466+
ParamTypes.emplace_back(Ty);
467+
++ArgIndex;
468+
}
429469

430470
FunctionProtoType::ExtProtoInfo ExtInfo;
471+
if (UseParamExtInfo)
472+
ExtInfo.ExtParameterInfos = ParamExtInfos.data();
431473
if (IsConst)
432474
ExtInfo.TypeQuals.addConst();
433475

@@ -459,6 +501,7 @@ void BuiltinTypeMethodBuilder::createDecl() {
459501
AST.getTrivialTypeSourceInfo(MP.Ty, SourceLocation()), SC_None,
460502
nullptr);
461503
if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
504+
Parm->setType(getInoutParameterType(AST, Parm->getType()));
462505
auto *Mod =
463506
HLSLParamModifierAttr::Create(AST, SourceRange(), MP.Modifier);
464507
Parm->addAttr(Mod);
@@ -1127,5 +1170,37 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addConsumeMethod() {
11271170
.finalize();
11281171
}
11291172

1173+
BuiltinTypeDeclBuilder &
1174+
BuiltinTypeDeclBuilder::addGetDimensionsMethodForBuffer() {
1175+
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1176+
ASTContext &AST = SemaRef.getASTContext();
1177+
QualType UIntTy = AST.UnsignedIntTy;
1178+
1179+
QualType HandleTy = getResourceHandleField()->getType();
1180+
auto *AttrResTy = cast<HLSLAttributedResourceType>(HandleTy.getTypePtr());
1181+
1182+
// Structured buffers except {RW}ByteAddressBuffer have overload
1183+
// GetDimensions(out uint numStructs, out uint stride).
1184+
if (AttrResTy->getAttrs().RawBuffer &&
1185+
AttrResTy->getContainedType() != AST.Char8Ty) {
1186+
return BuiltinTypeMethodBuilder(*this, "GetDimensions", AST.VoidTy)
1187+
.addParam("numStructs", UIntTy, HLSLParamModifierAttr::Keyword_out)
1188+
.addParam("stride", UIntTy, HLSLParamModifierAttr::Keyword_out)
1189+
.callBuiltin("__builtin_hlsl_buffer_getdimensions", QualType(),
1190+
PH::Handle, PH::_0)
1191+
.callBuiltin("__builtin_hlsl_buffer_getstride", QualType(), PH::Handle,
1192+
PH::_1)
1193+
.finalize();
1194+
}
1195+
1196+
// Typed buffers and {RW}ByteAddressBuffer have overload
1197+
// GetDimensions(out uint dim).
1198+
return BuiltinTypeMethodBuilder(*this, "GetDimensions", AST.VoidTy)
1199+
.addParam("dim", UIntTy, HLSLParamModifierAttr::Keyword_out)
1200+
.callBuiltin("__builtin_hlsl_buffer_getdimensions", QualType(),
1201+
PH::Handle, PH::_0)
1202+
.finalize();
1203+
}
1204+
11301205
} // namespace hlsl
11311206
} // namespace clang

clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ class BuiltinTypeDeclBuilder {
9595
BuiltinTypeDeclBuilder &addAppendMethod();
9696
BuiltinTypeDeclBuilder &addConsumeMethod();
9797

98+
BuiltinTypeDeclBuilder &addGetDimensionsMethodForBuffer();
99+
98100
private:
99101
BuiltinTypeDeclBuilder &addResourceMember(StringRef MemberName,
100102
ResourceClass RC, bool IsROV,

clang/lib/Sema/HLSLExternalSemaSource.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
380380
/*RawBuffer=*/false, /*HasCounter=*/false)
381381
.addArraySubscriptOperators()
382382
.addLoadMethods()
383+
.addGetDimensionsMethodForBuffer()
383384
.completeDefinition();
384385
});
385386

@@ -392,6 +393,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
392393
/*RawBuffer=*/false, /*HasCounter=*/false)
393394
.addArraySubscriptOperators()
394395
.addLoadMethods()
396+
.addGetDimensionsMethodForBuffer()
395397
.completeDefinition();
396398
});
397399

@@ -404,6 +406,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
404406
/*RawBuffer=*/false, /*HasCounter=*/false)
405407
.addArraySubscriptOperators()
406408
.addLoadMethods()
409+
.addGetDimensionsMethodForBuffer()
407410
.completeDefinition();
408411
});
409412

@@ -415,6 +418,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
415418
/*RawBuffer=*/true, /*HasCounter=*/false)
416419
.addArraySubscriptOperators()
417420
.addLoadMethods()
421+
.addGetDimensionsMethodForBuffer()
418422
.completeDefinition();
419423
});
420424

@@ -428,6 +432,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
428432
.addLoadMethods()
429433
.addIncrementCounterMethod()
430434
.addDecrementCounterMethod()
435+
.addGetDimensionsMethodForBuffer()
431436
.completeDefinition();
432437
});
433438

@@ -439,6 +444,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
439444
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
440445
/*RawBuffer=*/true, /*HasCounter=*/true)
441446
.addAppendMethod()
447+
.addGetDimensionsMethodForBuffer()
442448
.completeDefinition();
443449
});
444450

@@ -450,6 +456,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
450456
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
451457
/*RawBuffer=*/true, /*HasCounter=*/true)
452458
.addConsumeMethod()
459+
.addGetDimensionsMethodForBuffer()
453460
.completeDefinition();
454461
});
455462

@@ -464,6 +471,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
464471
.addLoadMethods()
465472
.addIncrementCounterMethod()
466473
.addDecrementCounterMethod()
474+
.addGetDimensionsMethodForBuffer()
467475
.completeDefinition();
468476
});
469477

@@ -472,13 +480,15 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
472480
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
473481
setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
474482
/*RawBuffer=*/true, /*HasCounter=*/false)
483+
.addGetDimensionsMethodForBuffer()
475484
.completeDefinition();
476485
});
477486
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWByteAddressBuffer")
478487
.finalizeForwardDeclaration();
479488
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
480489
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
481490
/*RawBuffer=*/true, /*HasCounter=*/false)
491+
.addGetDimensionsMethodForBuffer()
482492
.completeDefinition();
483493
});
484494
Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
@@ -487,6 +497,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
487497
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
488498
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/true,
489499
/*RawBuffer=*/true, /*HasCounter=*/false)
500+
.addGetDimensionsMethodForBuffer()
490501
.completeDefinition();
491502
});
492503
}

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2978,6 +2978,24 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
29782978
TheCall->setType(ResourceTy);
29792979
break;
29802980
}
2981+
case Builtin::BI__builtin_hlsl_buffer_getdimensions: {
2982+
ASTContext &AST = SemaRef.getASTContext();
2983+
if (SemaRef.checkArgCount(TheCall, 2) ||
2984+
CheckResourceHandle(&SemaRef, TheCall, 0) ||
2985+
CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
2986+
CheckModifiableLValue(&SemaRef, TheCall, 1))
2987+
return true;
2988+
break;
2989+
}
2990+
case Builtin::BI__builtin_hlsl_buffer_getstride: {
2991+
ASTContext &AST = SemaRef.getASTContext();
2992+
if (SemaRef.checkArgCount(TheCall, 2) ||
2993+
CheckResourceHandle(&SemaRef, TheCall, 0) ||
2994+
CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
2995+
CheckModifiableLValue(&SemaRef, TheCall, 1))
2996+
return true;
2997+
break;
2998+
}
29812999
case Builtin::BI__builtin_hlsl_and:
29823000
case Builtin::BI__builtin_hlsl_or: {
29833001
if (SemaRef.checkArgCount(TheCall, 2))

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,5 +142,19 @@ RESOURCE Buffer;
142142
// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]'
143143
// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
144144

145+
// GetDimensions method
146+
147+
// CHECK-NEXT: CXXMethodDecl {{.*}} GetDimensions 'void (unsigned int &__restrict)'
148+
// CHECK-NEXT: ParmVarDecl {{.*}} dim 'unsigned int &__restrict'
149+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
150+
// CHECK-NEXT: CompoundStmt
151+
// CHECK-NEXT: CallExpr {{.*}} 'void'
152+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr>
153+
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_buffer_getdimensions' 'void (...) noexcept'
154+
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle {{.*}}
155+
// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
156+
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'dim' 'unsigned int &__restrict'
157+
// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
158+
145159
// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl {{.*}} operator[] 'const char8_t &(unsigned int) const'
146160
// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl {{.*}} operator[] 'char8_t &(unsigned int)'

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,28 @@ RESOURCE<float> Buffer;
334334
// CHECK-CONSUME-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
335335
// CHECK-CONSUME-NEXT: IntegerLiteral {{.*}} 'int' -1
336336

337+
// GetDimensions method
338+
339+
// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (unsigned int, unsigned int)'
340+
// CHECK-NEXT: ParmVarDecl {{.*}} numStructs 'unsigned int &__restrict'
341+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
342+
// CHECK-NEXT: ParmVarDecl {{.*}} stride 'unsigned int &__restrict'
343+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
344+
// CHECK-NEXT: CompoundStmt
345+
// CHECK-NEXT: CallExpr {{.*}} 'void'
346+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr>
347+
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_buffer_getdimensions' 'void (...) noexcept'
348+
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle {{.*}}
349+
// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
350+
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'numStructs' 'unsigned int &__restrict'
351+
// CHECK-NEXT: CallExpr {{.*}} 'void'
352+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr>
353+
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_buffer_getstride' 'void (...) noexcept'
354+
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle {{.*}}
355+
// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
356+
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'stride' 'unsigned int &__restrict'
357+
// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
358+
337359
// CHECK: ClassTemplateSpecializationDecl {{.*}} class [[RESOURCE]] definition
338360
// CHECK: TemplateArgument type 'float'
339361
// CHECK-NEXT: BuiltinType {{.*}} 'float'

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,20 @@ RESOURCE<float> Buffer;
214214
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
215215
// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
216216

217+
// GetDimensions method
218+
219+
// CHECK-NEXT: CXXMethodDecl {{.*}} GetDimensions 'void (unsigned int)'
220+
// CHECK-NEXT: ParmVarDecl {{.*}} dim 'unsigned int &__restrict'
221+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
222+
// CHECK-NEXT: CompoundStmt
223+
// CHECK-NEXT: CallExpr {{.*}} 'void'
224+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr>
225+
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_buffer_getdimensions' 'void (...) noexcept'
226+
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle {{.*}}
227+
// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
228+
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'dim' 'unsigned int &__restrict'
229+
// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
230+
217231
// CHECK: ClassTemplateSpecializationDecl {{.*}} class [[RESOURCE]] definition
218232

219233
// CHECK: TemplateArgument type 'float'

0 commit comments

Comments
 (0)