Skip to content

Commit 024dd56

Browse files
authored
[HLSL] GetDimensions methods for buffer resources (#161929)
Adds `GetDimensions` methods to all supported buffer resource classes (`{RW}Buffer`, `*StructuredBuffer`, `{RW}ByteAddressBuffer`). The method is implemented by calling one of both built-in functions `__builtin_hlsl_resource_getdimensions_x` and `__builtin_hlsl_resource_getstride` as described in proposal llvm/wg-hlsl#350. The `__builtin_hlsl_resource_getstride` is implemented directly by Clang codegen by setting the buffer stride to the output variable. The `__building_hlsl_buffer_getdimensions` built-in function gets translated to LLVM intrinsic `@llvm.dx.resource.getdimensions.x`. Closes #112984
1 parent db2a75d commit 024dd56

14 files changed

+353
-4
lines changed

clang/include/clang/Basic/Builtins.td

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

4960+
def HLSLResourceGetDimensionsX : LangBuiltin<"HLSL_LANG"> {
4961+
let Spellings = ["__builtin_hlsl_resource_getdimensions_x"];
4962+
let Attributes = [NoThrow];
4963+
let Prototype = "void(...)";
4964+
}
4965+
4966+
def HLSLResourceGetStride : LangBuiltin<"HLSL_LANG"> {
4967+
let Spellings = ["__builtin_hlsl_resource_getstride"];
4968+
let Attributes = [NoThrow];
4969+
let Prototype = "void(...)";
4970+
}
4971+
49604972
def HLSLAll : LangBuiltin<"HLSL_LANG"> {
49614973
let Spellings = ["__builtin_hlsl_all"];
49624974
let Attributes = [NoThrow, Const];

clang/lib/CodeGen/CGHLSLBuiltins.cpp

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

163+
static Value *emitBufferStride(CodeGenFunction *CGF, const Expr *HandleExpr,
164+
LValue &Stride) {
165+
// Figure out the stride of the buffer elements from the handle type.
166+
auto *HandleTy =
167+
cast<HLSLAttributedResourceType>(HandleExpr->getType().getTypePtr());
168+
QualType ElementTy = HandleTy->getContainedType();
169+
Value *StrideValue = CGF->getTypeSize(ElementTy);
170+
return CGF->Builder.CreateStore(StrideValue, Stride.getAddress());
171+
}
172+
163173
// Return dot product intrinsic that corresponds to the QT scalar type
164174
static Intrinsic::ID getDotProductIntrinsic(CGHLSLRuntime &RT, QualType QT) {
165175
if (QT->isFloatingType())
@@ -372,6 +382,19 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
372382
RetTy, CGM.getHLSLRuntime().getNonUniformResourceIndexIntrinsic(),
373383
ArrayRef<Value *>{IndexOp});
374384
}
385+
case Builtin::BI__builtin_hlsl_resource_getdimensions_x: {
386+
Value *Handle = EmitScalarExpr(E->getArg(0));
387+
LValue Dim = EmitLValue(E->getArg(1));
388+
llvm::Type *RetTy = llvm::Type::getInt32Ty(getLLVMContext());
389+
Value *DimValue = Builder.CreateIntrinsic(
390+
RetTy, CGM.getHLSLRuntime().getGetDimensionsXIntrinsic(),
391+
ArrayRef<Value *>{Handle});
392+
return Builder.CreateStore(DimValue, Dim.getAddress());
393+
}
394+
case Builtin::BI__builtin_hlsl_resource_getstride: {
395+
LValue Stride = EmitLValue(E->getArg(1));
396+
return emitBufferStride(this, E->getArg(0), Stride);
397+
}
375398
case Builtin::BI__builtin_hlsl_all: {
376399
Value *Op0 = EmitScalarExpr(E->getArg(0));
377400
return Builder.CreateIntrinsic(

clang/lib/CodeGen/CGHLSLRuntime.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ class CGHLSLRuntime {
135135
GENERATE_HLSL_INTRINSIC_FUNCTION(BufferUpdateCounter, resource_updatecounter)
136136
GENERATE_HLSL_INTRINSIC_FUNCTION(GroupMemoryBarrierWithGroupSync,
137137
group_memory_barrier_with_group_sync)
138+
GENERATE_HLSL_INTRINSIC_FUNCTION(GetDimensionsX, resource_getdimensions_x)
138139

139140
//===----------------------------------------------------------------------===//
140141
// End of reserved area for HLSL intrinsic getters.

clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp

Lines changed: 76 additions & 4 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
@@ -430,19 +453,36 @@ BuiltinTypeMethodBuilder::addParam(StringRef Name, QualType Ty,
430453
void BuiltinTypeMethodBuilder::createDecl() {
431454
assert(Method == nullptr && "Method or constructor is already created");
432455

433-
// create method or constructor type
456+
// create function prototype
434457
ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
435458
SmallVector<QualType> ParamTypes;
436-
for (Param &MP : Params)
459+
SmallVector<FunctionType::ExtParameterInfo> ParamExtInfos(Params.size());
460+
uint32_t ArgIndex = 0;
461+
462+
// Create function prototype.
463+
bool UseParamExtInfo = false;
464+
for (Param &MP : Params) {
465+
if (MP.Modifier != HLSLParamModifierAttr::Keyword_in) {
466+
UseParamExtInfo = true;
467+
FunctionType::ExtParameterInfo &PI = ParamExtInfos[ArgIndex];
468+
ParamExtInfos[ArgIndex] =
469+
PI.withABI(convertParamModifierToParamABI(MP.Modifier));
470+
if (!MP.Ty->isDependentType())
471+
MP.Ty = getInoutParameterType(AST, MP.Ty);
472+
}
437473
ParamTypes.emplace_back(MP.Ty);
474+
++ArgIndex;
475+
}
438476

439477
FunctionProtoType::ExtProtoInfo ExtInfo;
478+
if (UseParamExtInfo)
479+
ExtInfo.ExtParameterInfos = ParamExtInfos.data();
440480
if (IsConst)
441481
ExtInfo.TypeQuals.addConst();
442482

443483
QualType FuncTy = AST.getFunctionType(ReturnTy, ParamTypes, ExtInfo);
444484

445-
// create method or constructor decl
485+
// Create method or constructor declaration.
446486
auto *TSInfo = AST.getTrivialTypeSourceInfo(FuncTy, SourceLocation());
447487
DeclarationNameInfo NameInfo = DeclarationNameInfo(Name, SourceLocation());
448488
if (IsCtor)
@@ -455,7 +495,7 @@ void BuiltinTypeMethodBuilder::createDecl() {
455495
AST, DeclBuilder.Record, SourceLocation(), NameInfo, FuncTy, TSInfo, SC,
456496
false, false, ConstexprSpecKind::Unspecified, SourceLocation());
457497

458-
// create params & set them to the function prototype
498+
// Create params & set them to the method/constructor and function prototype.
459499
SmallVector<ParmVarDecl *> ParmDecls;
460500
unsigned CurScopeDepth = DeclBuilder.SemaRef.getCurScope()->getDepth();
461501
auto FnProtoLoc =
@@ -1258,5 +1298,37 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addConsumeMethod() {
12581298
.finalize();
12591299
}
12601300

1301+
BuiltinTypeDeclBuilder &
1302+
BuiltinTypeDeclBuilder::addGetDimensionsMethodForBuffer() {
1303+
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1304+
ASTContext &AST = SemaRef.getASTContext();
1305+
QualType UIntTy = AST.UnsignedIntTy;
1306+
1307+
QualType HandleTy = getResourceHandleField()->getType();
1308+
auto *AttrResTy = cast<HLSLAttributedResourceType>(HandleTy.getTypePtr());
1309+
1310+
// Structured buffers except {RW}ByteAddressBuffer have overload
1311+
// GetDimensions(out uint numStructs, out uint stride).
1312+
if (AttrResTy->getAttrs().RawBuffer &&
1313+
AttrResTy->getContainedType() != AST.Char8Ty) {
1314+
return BuiltinTypeMethodBuilder(*this, "GetDimensions", AST.VoidTy)
1315+
.addParam("numStructs", UIntTy, HLSLParamModifierAttr::Keyword_out)
1316+
.addParam("stride", UIntTy, HLSLParamModifierAttr::Keyword_out)
1317+
.callBuiltin("__builtin_hlsl_resource_getdimensions_x", QualType(),
1318+
PH::Handle, PH::_0)
1319+
.callBuiltin("__builtin_hlsl_resource_getstride", QualType(),
1320+
PH::Handle, PH::_1)
1321+
.finalize();
1322+
}
1323+
1324+
// Typed buffers and {RW}ByteAddressBuffer have overload
1325+
// GetDimensions(out uint dim).
1326+
return BuiltinTypeMethodBuilder(*this, "GetDimensions", AST.VoidTy)
1327+
.addParam("dim", UIntTy, HLSLParamModifierAttr::Keyword_out)
1328+
.callBuiltin("__builtin_hlsl_resource_getdimensions_x", QualType(),
1329+
PH::Handle, PH::_0)
1330+
.finalize();
1331+
}
1332+
12611333
} // namespace hlsl
12621334
} // namespace clang

clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h

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

97+
BuiltinTypeDeclBuilder &addGetDimensionsMethodForBuffer();
98+
9799
private:
98100
BuiltinTypeDeclBuilder &addCreateFromBinding();
99101
BuiltinTypeDeclBuilder &addCreateFromImplicitBinding();

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
@@ -3006,6 +3006,24 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
30063006
TheCall->setType(CounterHandleTy);
30073007
break;
30083008
}
3009+
case Builtin::BI__builtin_hlsl_resource_getdimensions_x: {
3010+
ASTContext &AST = SemaRef.getASTContext();
3011+
if (SemaRef.checkArgCount(TheCall, 2) ||
3012+
CheckResourceHandle(&SemaRef, TheCall, 0) ||
3013+
CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
3014+
CheckModifiableLValue(&SemaRef, TheCall, 1))
3015+
return true;
3016+
break;
3017+
}
3018+
case Builtin::BI__builtin_hlsl_resource_getstride: {
3019+
ASTContext &AST = SemaRef.getASTContext();
3020+
if (SemaRef.checkArgCount(TheCall, 2) ||
3021+
CheckResourceHandle(&SemaRef, TheCall, 0) ||
3022+
CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) ||
3023+
CheckModifiableLValue(&SemaRef, TheCall, 1))
3024+
return true;
3025+
break;
3026+
}
30093027
case Builtin::BI__builtin_hlsl_and:
30103028
case Builtin::BI__builtin_hlsl_or: {
30113029
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 (out unsigned int)'
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_resource_getdimensions_x' '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
@@ -408,6 +408,28 @@ RESOURCE<float> Buffer;
408408
// CHECK-CONSUME-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
409409
// CHECK-CONSUME-NEXT: IntegerLiteral {{.*}} 'int' -1
410410

411+
// GetDimensions method
412+
413+
// CHECK: CXXMethodDecl {{.*}} GetDimensions 'void (out unsigned int, out unsigned int)'
414+
// CHECK-NEXT: ParmVarDecl {{.*}} numStructs 'unsigned int &__restrict'
415+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
416+
// CHECK-NEXT: ParmVarDecl {{.*}} stride 'unsigned int &__restrict'
417+
// CHECK-NEXT: HLSLParamModifierAttr {{.*}} out
418+
// CHECK-NEXT: CompoundStmt
419+
// CHECK-NEXT: CallExpr {{.*}} 'void'
420+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr>
421+
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getdimensions_x' 'void (...) noexcept'
422+
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle {{.*}}
423+
// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
424+
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'numStructs' 'unsigned int &__restrict'
425+
// CHECK-NEXT: CallExpr {{.*}} 'void'
426+
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr>
427+
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getstride' 'void (...) noexcept'
428+
// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle {{.*}}
429+
// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
430+
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'stride' 'unsigned int &__restrict'
431+
// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
432+
411433
// CHECK: ClassTemplateSpecializationDecl {{.*}} class [[RESOURCE]] definition
412434
// CHECK: TemplateArgument type 'float'
413435
// 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 (out 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_resource_getdimensions_x' '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)