[clang] Implement `ByteAddressBuffer` Load/Store methods (PR #176058)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 14 15:23:30 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-hlsl
Author: Kaitlin Peng (kmpeng)
<details>
<summary>Changes</summary>
Closes #<!-- -->108058.
This PR adds the `uint` `Load` and `Store` methods (`Load`, `Load2`, `Load3`, `Load4`, `Store`, `Store2`, `Store3`, `Store4`) to the existing `ByteAddressBuffer` and `RWByteAddressBuffer` objects , as well as the new templated `Load` and `Store` methods, allowing types other than `uint` (e.g. aggregate types) to be used directly.
---
Patch is 48.74 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/176058.diff
10 Files Affected:
- (modified) clang/lib/CodeGen/CGHLSLBuiltins.cpp (+3)
- (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp (+124-3)
- (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h (+2)
- (modified) clang/lib/Sema/HLSLExternalSemaSource.cpp (+3)
- (modified) clang/lib/Sema/SemaHLSL.cpp (+20-2)
- (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+14-2)
- (modified) clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl (+216-3)
- (modified) clang/test/AST/HLSL/StructuredBuffers-AST.hlsl (+5-5)
- (modified) clang/test/AST/HLSL/TypedBuffers-AST.hlsl (+3-3)
- (modified) clang/test/CodeGenHLSL/resources/ByteAddressBuffers-methods.hlsl (+160)
``````````diff
diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index 1b6c3714f7821..98708f23a35e6 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -432,6 +432,9 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
if (RT->getAttrs().RawBuffer) {
Value *Offset = Builder.getInt32(0);
+ // Offset is poison for ByteAddressBuffer
+ if (RT->getContainedType()->isChar8Type())
+ Offset = llvm::PoisonValue::get(Builder.getInt32Ty());
Args.push_back(Offset);
}
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index 868f894a03c49..fea27d487526c 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -153,6 +153,8 @@ struct BuiltinTypeMethodBuilder {
StorageClass SC;
llvm::SmallVector<Param> Params;
llvm::SmallVector<Stmt *> StmtsList;
+ TemplateParameterList *TemplateParams;
+ llvm::SmallVector<NamedDecl *> TemplateParamDecls;
// Argument placeholders, inspired by std::placeholder. These are the indices
// of arguments to forward to `callBuiltin` and other method builder methods.
@@ -184,7 +186,7 @@ struct BuiltinTypeMethodBuilder {
QualType ReturnTy, bool IsConst = false,
bool IsCtor = false, StorageClass SC = SC_None)
: DeclBuilder(DB), Name(Name), ReturnTy(ReturnTy), Method(nullptr),
- IsConst(IsConst), IsCtor(IsCtor), SC(SC) {}
+ IsConst(IsConst), IsCtor(IsCtor), SC(SC), TemplateParams(nullptr) {}
BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB, StringRef NameStr,
QualType ReturnTy, bool IsConst = false,
@@ -199,6 +201,7 @@ struct BuiltinTypeMethodBuilder {
BuiltinTypeMethodBuilder &addParam(StringRef Name, QualType Ty,
HLSLParamModifierAttr::Spelling Modifier =
HLSLParamModifierAttr::Keyword_in);
+ QualType addTemplateTypeParam(StringRef Name);
BuiltinTypeMethodBuilder &declareLocalVar(LocalVar &Var);
template <typename... Ts>
BuiltinTypeMethodBuilder &callBuiltin(StringRef BuiltinName,
@@ -449,6 +452,22 @@ BuiltinTypeMethodBuilder::addParam(StringRef Name, QualType Ty,
Params.emplace_back(II, Ty, Modifier);
return *this;
}
+QualType BuiltinTypeMethodBuilder::addTemplateTypeParam(StringRef Name) {
+ assert(Method == nullptr &&
+ "Cannot add template param, method already created");
+ ASTContext &AST = DeclBuilder.SemaRef.getASTContext();
+ unsigned Position = static_cast<unsigned>(TemplateParamDecls.size());
+ auto *Decl = TemplateTypeParmDecl::Create(
+ AST, DeclBuilder.Record, SourceLocation(), SourceLocation(),
+ /* TemplateDepth */ 0, Position,
+ &AST.Idents.get(Name, tok::TokenKind::identifier),
+ /* Typename */ true,
+ /* ParameterPack */ false,
+ /* HasTypeConstraint*/ false);
+ TemplateParamDecls.emplace_back(Decl);
+
+ return QualType(Decl->getTypeForDecl(), 0);
+}
void BuiltinTypeMethodBuilder::createDecl() {
assert(Method == nullptr && "Method or constructor is already created");
@@ -615,7 +634,7 @@ BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::dereference(T Ptr) {
Expr *Deref =
UnaryOperator::Create(DeclBuilder.SemaRef.getASTContext(), PtrExpr,
UO_Deref, PtrExpr->getType()->getPointeeType(),
- VK_PRValue, OK_Ordinary, SourceLocation(),
+ VK_LValue, OK_Ordinary, SourceLocation(),
/*CanOverflow=*/false, FPOptionsOverride());
StmtsList.push_back(Deref);
return *this;
@@ -747,7 +766,22 @@ BuiltinTypeDeclBuilder &BuiltinTypeMethodBuilder::finalize() {
Method->setAccess(AS_public);
Method->addAttr(AlwaysInlineAttr::CreateImplicit(
AST, SourceRange(), AlwaysInlineAttr::CXX11_clang_always_inline));
- DeclBuilder.Record->addDecl(Method);
+ if (!TemplateParamDecls.empty()) {
+ TemplateParams = TemplateParameterList::Create(
+ AST, SourceLocation(), SourceLocation(), TemplateParamDecls,
+ SourceLocation(), nullptr);
+
+ auto *FuncTemplate = FunctionTemplateDecl::Create(AST, DeclBuilder.Record,
+ SourceLocation(), Name,
+ TemplateParams, Method);
+ FuncTemplate->setAccess(AS_public);
+ FuncTemplate->setLexicalDeclContext(DeclBuilder.Record);
+ FuncTemplate->setImplicit(true);
+ Method->setDescribedFunctionTemplate(FuncTemplate);
+ DeclBuilder.Record->addDecl(FuncTemplate);
+ } else {
+ DeclBuilder.Record->addDecl(Method);
+ }
}
return DeclBuilder;
}
@@ -1145,6 +1179,93 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addLoadMethods() {
return *this;
}
+BuiltinTypeDeclBuilder &
+BuiltinTypeDeclBuilder::addByteAddressBufferLoadMethods() {
+ assert(!Record->isCompleteDefinition() && "record is already complete");
+
+ using PH = BuiltinTypeMethodBuilder::PlaceHolder;
+ ASTContext &AST = SemaRef.getASTContext();
+
+ auto addLoadMethod = [&](StringRef MethodName, QualType ReturnType) {
+ IdentifierInfo &II = AST.Idents.get(MethodName, tok::TokenKind::identifier);
+ DeclarationName Load(&II);
+
+ // Load without status
+ BuiltinTypeMethodBuilder MMB(*this, Load, ReturnType);
+ if (ReturnType->isDependentType()) {
+ ReturnType = MMB.addTemplateTypeParam("element_type");
+ MMB.ReturnTy = ReturnType; // Update return type to template parameter
+ }
+ QualType AddrSpaceElemTy =
+ AST.getAddrSpaceQualType(ReturnType, LangAS::hlsl_device);
+
+ MMB.addParam("Index", AST.UnsignedIntTy)
+ .callBuiltin("__builtin_hlsl_resource_getpointer",
+ AST.getPointerType(AddrSpaceElemTy), PH::Handle, PH::_0)
+ .dereference(PH::LastStmt)
+ .finalize();
+
+ // Load with status
+ BuiltinTypeMethodBuilder MMB2(*this, Load, ReturnType);
+ if (ReturnType->isDependentType()) {
+ ReturnType = MMB2.addTemplateTypeParam("element_type");
+ MMB2.ReturnTy = ReturnType; // Update return type to template parameter
+ }
+
+ MMB2.addParam("Index", AST.UnsignedIntTy)
+ .addParam("Status", AST.UnsignedIntTy,
+ HLSLParamModifierAttr::Keyword_out)
+ .callBuiltin("__builtin_hlsl_resource_load_with_status", ReturnType,
+ PH::Handle, PH::_0, PH::_1)
+ .finalize();
+ };
+
+ addLoadMethod("Load", AST.UnsignedIntTy);
+ addLoadMethod("Load2", AST.getExtVectorType(AST.UnsignedIntTy, 2));
+ addLoadMethod("Load3", AST.getExtVectorType(AST.UnsignedIntTy, 3));
+ addLoadMethod("Load4", AST.getExtVectorType(AST.UnsignedIntTy, 4));
+ addLoadMethod("Load", AST.DependentTy); // Templated version
+
+ return *this;
+}
+
+BuiltinTypeDeclBuilder &
+BuiltinTypeDeclBuilder::addByteAddressBufferStoreMethods() {
+ assert(!Record->isCompleteDefinition() && "record is already complete");
+
+ using PH = BuiltinTypeMethodBuilder::PlaceHolder;
+ ASTContext &AST = SemaRef.getASTContext();
+
+ // Helper to add uint Store methods
+ auto addStoreMethod = [&](StringRef MethodName, QualType ValueType) {
+ IdentifierInfo &II = AST.Idents.get(MethodName, tok::TokenKind::identifier);
+ DeclarationName Store(&II);
+
+ BuiltinTypeMethodBuilder MMB(*this, Store, AST.VoidTy);
+ if (ValueType->isDependentType()) {
+ ValueType = MMB.addTemplateTypeParam("element_type");
+ }
+ QualType AddrSpaceElemTy =
+ AST.getAddrSpaceQualType(ValueType, LangAS::hlsl_device);
+
+ MMB.addParam("Index", AST.UnsignedIntTy)
+ .addParam("Value", ValueType)
+ .callBuiltin("__builtin_hlsl_resource_getpointer",
+ AST.getPointerType(AddrSpaceElemTy), PH::Handle, PH::_0)
+ .dereference(PH::LastStmt)
+ .assign(PH::LastStmt, PH::_1)
+ .finalize();
+ };
+
+ addStoreMethod("Store", AST.UnsignedIntTy);
+ addStoreMethod("Store2", AST.getExtVectorType(AST.UnsignedIntTy, 2));
+ addStoreMethod("Store3", AST.getExtVectorType(AST.UnsignedIntTy, 3));
+ addStoreMethod("Store4", AST.getExtVectorType(AST.UnsignedIntTy, 4));
+ addStoreMethod("Store", AST.DependentTy); // Templated version
+
+ return *this;
+}
+
FieldDecl *BuiltinTypeDeclBuilder::getResourceHandleField() const {
auto I = Fields.find("__handle");
assert(I != Fields.end() &&
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index 47c8b0e225612..8309ba990fda0 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -87,6 +87,8 @@ class BuiltinTypeDeclBuilder {
// Builtin types methods
BuiltinTypeDeclBuilder &addLoadMethods();
+ BuiltinTypeDeclBuilder &addByteAddressBufferLoadMethods();
+ BuiltinTypeDeclBuilder &addByteAddressBufferStoreMethods();
BuiltinTypeDeclBuilder &addIncrementCounterMethod();
BuiltinTypeDeclBuilder &addDecrementCounterMethod();
BuiltinTypeDeclBuilder &addHandleAccessFunction(DeclarationName &Name,
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index 6be84f19a8f08..948005312f4dd 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -480,6 +480,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
/*RawBuffer=*/true, /*HasCounter=*/false)
+ .addByteAddressBufferLoadMethods()
.addGetDimensionsMethodForBuffer()
.completeDefinition();
});
@@ -488,6 +489,8 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
onCompletion(Decl, [this](CXXRecordDecl *Decl) {
setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, /*IsROV=*/false,
/*RawBuffer=*/true, /*HasCounter=*/false)
+ .addByteAddressBufferLoadMethods()
+ .addByteAddressBufferStoreMethods()
.addGetDimensionsMethodForBuffer()
.completeDefinition();
});
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index f15b274a65a53..a705e5d9792f3 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -3308,9 +3308,22 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
auto *ResourceTy =
TheCall->getArg(0)->getType()->castAs<HLSLAttributedResourceType>();
- QualType ContainedTy = ResourceTy->getContainedType();
+ QualType ElementTy = ResourceTy->getContainedType();
+ // ByteAddressBuffer uses the FunctionDecl types instead of the contained
+ // type
+ if (ResourceTy->getAttrs().RawBuffer && ElementTy->isChar8Type()) {
+ // Load method uses return type
+ FunctionDecl *FD = dyn_cast<FunctionDecl>(SemaRef.CurContext);
+ ElementTy = FD->getReturnType();
+ // Store method uses 2nd parameter type
+ if (ElementTy->isVoidType()) {
+ assert(FD->getNumParams() == 2 &&
+ "expected 2 parameters for Store method");
+ ElementTy = FD->getParamDecl(1)->getType();
+ }
+ }
auto ReturnType =
- SemaRef.Context.getAddrSpaceQualType(ContainedTy, LangAS::hlsl_device);
+ SemaRef.Context.getAddrSpaceQualType(ElementTy, LangAS::hlsl_device);
ReturnType = SemaRef.Context.getPointerType(ReturnType);
TheCall->setType(ReturnType);
TheCall->setValueKind(VK_LValue);
@@ -3330,6 +3343,11 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
auto *ResourceTy =
TheCall->getArg(0)->getType()->castAs<HLSLAttributedResourceType>();
QualType ReturnType = ResourceTy->getContainedType();
+ // ByteAddressBuffer uses the FunctionDecl return type instead of the
+ // contained type
+ if (ResourceTy->getAttrs().RawBuffer && ReturnType->isChar8Type()) {
+ ReturnType = dyn_cast<FunctionDecl>(SemaRef.CurContext)->getReturnType();
+ }
TheCall->setType(ReturnType);
break;
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index e74c41517ecbf..348ac5e75af7c 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -6901,8 +6901,20 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
// whose type is not instantiation dependent, do nothing to the decl
// - otherwise find its instantiated decl.
if (isa<ParmVarDecl>(D) && !ParentDependsOnArgs &&
- !cast<ParmVarDecl>(D)->getType()->isInstantiationDependentType())
- return D;
+ !cast<ParmVarDecl>(D)->getType()->isInstantiationDependentType()) {
+ // Check if D belongs to a function template
+ auto *PVD = cast<ParmVarDecl>(D);
+ bool IsFromFunctionTemplate =
+ llvm::any_of(ParentDC->decls(), [PVD](Decl *D) {
+ if (auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
+ return llvm::is_contained(FTD->getTemplatedDecl()->parameters(),
+ PVD);
+ return false;
+ });
+
+ if (!IsFromFunctionTemplate)
+ return D;
+ }
if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) ||
isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) ||
(ParentDependsOnArgs && (ParentDC->isFunctionOrMethod() ||
diff --git a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
index 2713cc19ea2be..212c8b0cbbb39 100644
--- a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
@@ -4,7 +4,7 @@
//
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \
// RUN: -DRESOURCE=ByteAddressBuffer %s | FileCheck -DRESOURCE=ByteAddressBuffer \
-// RUN: -check-prefixes=CHECK,CHECK-SRV,CHECK-NOSUBSCRIPT %s
+// RUN: -check-prefixes=CHECK,CHECK-SRV,CHECK-NOSUBSCRIPT,CHECK-LOAD %s
//
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \
// RUN: -DRESOURCE=RWByteAddressBuffer %s | FileCheck -DRESOURCE=RWByteAddressBuffer \
@@ -12,7 +12,7 @@
//
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \
// RUN: -DRESOURCE=RWByteAddressBuffer %s | FileCheck -DRESOURCE=RWByteAddressBuffer \
-// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT %s
+// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT,CHECK-LOAD,CHECK-STORE %s
//
// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \
// RUN: -DRESOURCE=RasterizerOrderedByteAddressBuffer %s | FileCheck -DRESOURCE=RasterizerOrderedByteAddressBuffer \
@@ -142,9 +142,222 @@ RESOURCE Buffer;
// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue Var {{.*}} 'tmp' 'hlsl::[[RESOURCE]]'
// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
+// Load methods
+
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'unsigned int (unsigned int)'
+// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
+// CHECK-LOAD-NEXT: CompoundStmt
+// CHECK-LOAD-NEXT: ReturnStmt
+// CHECK-LOAD-NEXT: UnaryOperator {{.*}} 'hlsl_device unsigned int' lvalue prefix '*' cannot overflow
+// CHECK-LOAD-NEXT: CallExpr {{.*}} 'hlsl_device unsigned int *'
+// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr>
+// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
+// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
+// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
+// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load 'unsigned int (unsigned int, out unsigned int)
+// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
+// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Status 'unsigned int &__restrict'
+// CHECK-LOAD-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-LOAD-NEXT: CompoundStmt
+// CHECK-LOAD-NEXT: ReturnStmt
+// CHECK-LOAD-NEXT: CallExpr {{.*}} 'unsigned int'
+// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr>
+// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_load_with_status' 'void (...) noexcept'
+// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
+// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
+// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Status' 'unsigned int &__restrict'
+// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
+
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load2 'vector<unsigned int (unsigned int), 2>'
+// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
+// CHECK-LOAD-NEXT: CompoundStmt
+// CHECK-LOAD-NEXT: ReturnStmt
+// CHECK-LOAD-NEXT: UnaryOperator {{.*}} 'vector<unsigned int hlsl_device, 2>' lvalue prefix '*' cannot overflow
+// CHECK-LOAD-NEXT: CallExpr {{.*}} 'vector<unsigned int hlsl_device *, 2>'
+// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr>
+// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
+// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
+// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
+// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load2 'vector<unsigned int (unsigned int, out unsigned int), 2>'
+// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
+// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Status 'unsigned int &__restrict'
+// CHECK-LOAD-NEXT: HLSLParamModifierAttr {{.*}} out
+// CHECK-LOAD-NEXT: CompoundStmt
+// CHECK-LOAD-NEXT: ReturnStmt
+// CHECK-LOAD-NEXT: CallExpr {{.*}} 'vector<unsigned int, 2>'
+// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr>
+// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_load_with_status' 'void (...) noexcept'
+// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
+// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
+// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Status' 'unsigned int &__restrict'
+// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
+
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load3 'vector<unsigned int (unsigned int), 3>'
+// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
+// CHECK-LOAD-NEXT: CompoundStmt
+// CHECK-LOAD-NEXT: ReturnStmt
+// CHECK-LOAD-NEXT: UnaryOperator {{.*}} 'vector<unsigned int hlsl_device, 3>' lvalue prefix '*' cannot overflow
+// CHECK-LOAD-NEXT: CallExpr {{.*}} 'vector<unsigned int hlsl_device *, 3>'
+// CHECK-LOAD-NEXT: ImplicitCastExpr {{.*}} 'void (*)(...) noexcept' <BuiltinFnToFnPtr>
+// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept'
+// CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
+// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
+// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
+// CHECK-LOAD: CXXMethodDecl {{.*}} Load3 'vector<unsigned int (unsigned int, out unsigned int), 3>'
+// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int'
+// CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Status 'unsigned int &__restrict'
+// CHECK-LOAD-NEXT: HLSLPa...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/176058
More information about the cfe-commits
mailing list