llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: Helena Kotas (hekota)

<details>
<summary>Changes</summary>

Adds support for dynamic resources, also known as bindless or directly indexed 
resources. The design is described in 
https://github.com/llvm/wg-hlsl/issues/204.

The change adds:
- The `ResourceDescriptorHeap` and `SamplerDescriptorHeap` global symbols, 
which expose the Shader Model 6.6 descriptor heaps.
- Internal `__hlsl_heap_resource_info` and `__hlsl_heap_sampler_info` types, 
which are produced by indexing the corresponding descriptor heap. HLSL resource 
and sampler types can be implicitly constructed from these values.
- Constructors that accept the corresponding internal heap info type for all 
currently implemented resource classes.
- Clang builtins `__builtin_hlsl_resource_handlefromheap` and 
`__builtin_hlsl_resource_counterhandlefromheap` for creating resource and 
counter handles from descriptor heap indices.
- Sema validation and return-type handling for the new builtins.

For DXIL, the built-in function is lowered to 
`llvm.dx.resource.handlefromheap`. For SPIR-V, the built-ins are lowered to 
`llvm.spv.resource.handlefromheap` and 
`llvm.spv.resource.counterhandlefromheap`.

Fixes #<!-- -->133831

Assisted by GPT 5.6 Sol and Claude Opus 4.8.

---

Patch is 44.34 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/221103.diff


21 Files Affected:

- (modified) clang/include/clang/Basic/Builtins.td (+12) 
- (modified) clang/include/clang/Sema/HLSLExternalSemaSource.h (+2) 
- (modified) clang/lib/CodeGen/CGHLSLBuiltins.cpp (+22) 
- (modified) clang/lib/CodeGen/CGHLSLRuntime.h (+2) 
- (modified) clang/lib/Headers/CMakeLists.txt (+1) 
- (modified) clang/lib/Headers/hlsl.h (+1) 
- (added) clang/lib/Headers/hlsl/hlsl_resources.h (+36) 
- (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp (+68) 
- (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h (+3) 
- (modified) clang/lib/Sema/HLSLExternalSemaSource.cpp (+27) 
- (modified) clang/lib/Sema/SemaHLSL.cpp (+26) 
- (modified) clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl (+18) 
- (added) clang/test/AST/HLSL/DynamicResources-AST.hlsl (+132) 
- (modified) clang/test/AST/HLSL/StructuredBuffers-AST.hlsl (+27) 
- (modified) clang/test/AST/HLSL/TypedBuffers-AST.hlsl (+17) 
- (added) clang/test/CodeGenHLSL/resources/dynamic-resources.hlsl (+109) 
- (modified) clang/test/SemaHLSL/Language/InitLists.hlsl (+1) 
- (modified) clang/test/SemaHLSL/Resources/Textures-SampleCmpLevelZero.hlsl 
(+3-2) 
- (added) clang/test/SemaHLSL/Resources/dynamic-resources-availability.hlsl 
(+13) 
- (added) clang/test/SemaHLSL/Resources/dynamic-resources.hlsl (+50) 
- (modified) llvm/include/llvm/IR/IntrinsicsSPIRV.td (+9) 


``````````diff
diff --git a/clang/include/clang/Basic/Builtins.td 
b/clang/include/clang/Basic/Builtins.td
index 49fe879c6add1..2b33b4a8541b3 100644
--- a/clang/include/clang/Basic/Builtins.td
+++ b/clang/include/clang/Basic/Builtins.td
@@ -5431,6 +5431,18 @@ def HLSLResourceCounterHandleFromImplicitBinding : 
LangBuiltin<"HLSL_LANG"> {
   let Prototype = "__hlsl_resource_t(__hlsl_resource_t, uint32_t, uint32_t)";
 }
 
+def HLSLResourceHandleFromHeap : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_resource_handlefromheap"];
+  let Attributes = [NoThrow];
+  let Prototype = "__hlsl_resource_t(__hlsl_resource_t, uint32_t)";
+}
+
+def HLSLResourceCounterHandleFromHeap : LangBuiltin<"HLSL_LANG"> {
+  let Spellings = ["__builtin_hlsl_resource_counterhandlefromheap"];
+  let Attributes = [NoThrow];
+  let Prototype = "__hlsl_resource_t(__hlsl_resource_t, uint32_t)";
+}
+
 def HLSLResourceNonUniformIndex : LangBuiltin<"HLSL_LANG"> {
   let Spellings = ["__builtin_hlsl_resource_nonuniformindex"];
   let Attributes = [NoThrow];
diff --git a/clang/include/clang/Sema/HLSLExternalSemaSource.h 
b/clang/include/clang/Sema/HLSLExternalSemaSource.h
index 77fd3fafc6d77..840cd3e0a082a 100644
--- a/clang/include/clang/Sema/HLSLExternalSemaSource.h
+++ b/clang/include/clang/Sema/HLSLExternalSemaSource.h
@@ -43,8 +43,10 @@ class HLSLExternalSemaSource : public ExternalSemaSource {
 
 private:
   void defineTrivialHLSLTypes();
+  void defineInternalHLSLTypes();
   void defineHLSLVectorAlias();
   void defineHLSLMatrixAlias();
+  void defineHeapResourceInfoTypes();
   void defineHLSLTypesWithForwardDeclarations();
   void defineHLSLAtomicIntrinsics();
   void onCompletion(CXXRecordDecl *Record, CompletionFunction Fn);
diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp 
b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index 062faadcdcab2..42c107405dff3 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -1063,6 +1063,28 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
     return EmitIntrinsicCall(IntrinsicID, {HandleTy, MainHandle->getType()},
                              Args);
   }
+  case Builtin::BI__builtin_hlsl_resource_handlefromheap: {
+    llvm::Type *HandleTy = CGM.getTypes().ConvertType(E->getType());
+    Value *IndexOp = EmitScalarExpr(E->getArg(1));
+    llvm::Intrinsic::ID IntrinsicID =
+        CGM.getHLSLRuntime().getCreateHandleFromHeapIntrinsic();
+    SmallVector<Value *> Args{IndexOp};
+    return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
+  }
+  case Builtin::BI__builtin_hlsl_resource_counterhandlefromheap: {
+    Value *MainHandle = EmitScalarExpr(E->getArg(0));
+    if (!CGM.getTriple().isSPIRV())
+      return MainHandle;
+
+    llvm::Type *HandleTy = CGM.getTypes().ConvertType(E->getType());
+    Value *IndexOp = EmitScalarExpr(E->getArg(1));
+    llvm::Intrinsic::ID IntrinsicID =
+        llvm::Intrinsic::spv_resource_counterhandlefromheap;
+    SmallVector<Value *> Args{MainHandle, IndexOp};
+    return EmitIntrinsicCall(IntrinsicID, {HandleTy, MainHandle->getType()},
+                             Args);
+  }
+
   case Builtin::BI__builtin_hlsl_resource_nonuniformindex: {
     Value *IndexOp = EmitScalarExpr(E->getArg(0));
     llvm::Type *RetTy = ConvertType(E->getType());
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h 
b/clang/lib/CodeGen/CGHLSLRuntime.h
index 381653e8f8345..2ceafcc94a0b8 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -186,6 +186,8 @@ class CGHLSLRuntime {
                                    resource_handlefrombinding)
   GENERATE_HLSL_INTRINSIC_FUNCTION(CreateHandleFromImplicitBinding,
                                    resource_handlefromimplicitbinding)
+  GENERATE_HLSL_INTRINSIC_FUNCTION(CreateHandleFromHeap,
+                                   resource_handlefromheap)
   GENERATE_HLSL_INTRINSIC_FUNCTION(NonUniformResourceIndex,
                                    resource_nonuniformindex)
   GENERATE_HLSL_INTRINSIC_FUNCTION(BufferUpdateCounter, resource_updatecounter)
diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt
index 3d845423759ac..9befd7b192af7 100644
--- a/clang/lib/Headers/CMakeLists.txt
+++ b/clang/lib/Headers/CMakeLists.txt
@@ -98,6 +98,7 @@ set(hlsl_subdir_files
   hlsl/hlsl_intrinsic_helpers.h
   hlsl/hlsl_intrinsics.h
   hlsl/hlsl_detail.h
+  hlsl/hlsl_resources.h
   hlsl/hlsl_spirv.h
   )
 set(hlsl_files
diff --git a/clang/lib/Headers/hlsl.h b/clang/lib/Headers/hlsl.h
index 8a144191c4695..ff50c9f9b7ac2 100644
--- a/clang/lib/Headers/hlsl.h
+++ b/clang/lib/Headers/hlsl.h
@@ -26,6 +26,7 @@
 #if __HLSL_VERSION <= __HLSL_202x
 #include "hlsl/hlsl_compat_overloads.h"
 #endif
+#include "hlsl/hlsl_resources.h"
 
 #ifdef __spirv__
 #include "hlsl/hlsl_spirv.h"
diff --git a/clang/lib/Headers/hlsl/hlsl_resources.h 
b/clang/lib/Headers/hlsl/hlsl_resources.h
new file mode 100644
index 0000000000000..d43c94dbff572
--- /dev/null
+++ b/clang/lib/Headers/hlsl/hlsl_resources.h
@@ -0,0 +1,36 @@
+//===----- hlsl_resources.h - HLSL definitions for resources ----------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _HLSL_HLSL_RESOURCES_H_
+#define _HLSL_HLSL_RESOURCES_H_
+
+namespace hlsl {
+
+#define _HLSL_AVAILABILITY(platform, version)                                  
\
+  __attribute__((availability(platform, introduced = version)))
+
+struct __hlsl_resource_descriptor_heap_struct {
+  __hlsl_heap_resource_info operator[](uint32_t Index) {
+    return __hlsl_heap_resource_info{Index};
+  }
+};
+
+struct __hlsl_sampler_descriptor_heap_struct {
+  __hlsl_heap_sampler_info operator[](uint32_t Index) {
+    return __hlsl_heap_sampler_info{Index};
+  }
+};
+
+_HLSL_AVAILABILITY(shadermodel, 6.6)
+static __hlsl_resource_descriptor_heap_struct ResourceDescriptorHeap;
+
+_HLSL_AVAILABILITY(shadermodel, 6.6)
+static __hlsl_sampler_descriptor_heap_struct SamplerDescriptorHeap;
+
+} // namespace hlsl
+#endif //_HLSL_HLSL_RESOURCES_H_
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp 
b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index 34e883264b5b3..15f78eadad4e2 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -1216,6 +1216,74 @@ 
BuiltinTypeDeclBuilder::addDefaultHandleConstructor(AccessSpecifier Access) {
       .finalize(Access);
 }
 
+// Adds constructor that takes __hlsl_heap_resource_info:
+// Resource::Resource(__hlsl_heap_resource_info info) {
+//   __handle = __builtin_hlsl_resource_handlefromheap(__handle, info.Index);
+// }
+BuiltinTypeDeclBuilder &
+BuiltinTypeDeclBuilder::addHeapResourceInfoConstructor(bool HasCounter) {
+  assert(!Record->isCompleteDefinition() && "record is already complete");
+
+  using PH = BuiltinTypeMethodBuilder::PlaceHolder;
+
+  ASTContext &AST = SemaRef.getASTContext();
+  QualType HandleType = getResourceHandleField()->getType();
+
+  QualType HeapResInfoType = lookupBuiltinType(
+      SemaRef, "__hlsl_heap_resource_info", Record->getDeclContext());
+  CXXRecordDecl *HeapResInfoDecl = HeapResInfoType->getAsCXXRecordDecl();
+
+  FieldDecl *IndexField = *HeapResInfoDecl->field_begin();
+  assert(IndexField && IndexField->getType() == AST.UnsignedIntTy &&
+         "Index field not as expected");
+
+  auto MB = BuiltinTypeMethodBuilder(*this, "", AST.VoidTy, false, true);
+  MB.addParam("HeapResInfo", HeapResInfoType)
+      .callBuiltin("__builtin_hlsl_resource_handlefromheap", HandleType,
+                   PH::Handle, MB.createMemberExpr(PH::_0, IndexField))
+      .assign(PH::Handle, PH::LastStmt);
+
+  if (HasCounter) {
+    QualType CounterHandleType = getResourceCounterHandleField()->getType();
+    MB.callBuiltin("__builtin_hlsl_resource_counterhandlefromheap",
+                   CounterHandleType, PH::Handle,
+                   MB.createMemberExpr(PH::_0, IndexField))
+        .assign(PH::CounterHandle, PH::LastStmt);
+  }
+
+  return MB.finalize();
+}
+
+// Adds constructor that takes __hlsl_heap_sampler_info:
+// Resource::Resource(__hlsl_heap_sampler_info info) {
+//   __handle = __builtin_hlsl_resource_handlefromheap(__handle, info.Index);
+// }
+BuiltinTypeDeclBuilder &
+BuiltinTypeDeclBuilder::addHeapSamplerInfoConstructor() {
+  assert(!Record->isCompleteDefinition() && "record is already complete");
+
+  using PH = BuiltinTypeMethodBuilder::PlaceHolder;
+
+  ASTContext &AST = SemaRef.getASTContext();
+  QualType HandleType = getResourceHandleField()->getType();
+
+  QualType HeapResInfoType = lookupBuiltinType(
+      SemaRef, "__hlsl_heap_sampler_info", Record->getDeclContext());
+  CXXRecordDecl *HeapResInfoDecl = HeapResInfoType->getAsCXXRecordDecl();
+
+  FieldDecl *IndexField = *HeapResInfoDecl->field_begin();
+  assert(IndexField && IndexField->getType() == AST.UnsignedIntTy &&
+         "Index field not as expected");
+
+  auto MB = BuiltinTypeMethodBuilder(*this, "", AST.VoidTy, false, true);
+  MB.addParam("HeapResInfo", HeapResInfoType);
+  MB.callBuiltin("__builtin_hlsl_resource_handlefromheap", HandleType,
+                 PH::Handle, MB.createMemberExpr(PH::_0, IndexField))
+      .assign(PH::Handle, PH::LastStmt);
+
+  return MB.finalize();
+}
+
 BuiltinTypeDeclBuilder &
 BuiltinTypeDeclBuilder::addStaticInitializationFunctions(bool HasCounter) {
   if (HasCounter) {
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h 
b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index 62dea7fab8064..226f1026876ca 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -99,6 +99,9 @@ class BuiltinTypeDeclBuilder {
   BuiltinTypeDeclBuilder &addDefaultHandleConstructor(
       AccessSpecifier Access = AccessSpecifier::AS_public);
   BuiltinTypeDeclBuilder &
+  addHeapResourceInfoConstructor(bool HasCounter = false);
+  BuiltinTypeDeclBuilder &addHeapSamplerInfoConstructor();
+  BuiltinTypeDeclBuilder &
   addCopyConstructor(AccessSpecifier Access = AccessSpecifier::AS_public);
   BuiltinTypeDeclBuilder &addCopyAssignmentOperator(
       AccessSpecifier Access = AccessSpecifier::AS_public);
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp 
b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index d2d9c97b98a57..75932dc8a136e 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -55,6 +55,7 @@ void HLSLExternalSemaSource::InitializeSema(Sema &S) {
   // Force external decls in the HLSL namespace to load from the PCH.
   (void)HLSLNamespace->getCanonicalDecl()->decls_begin();
   defineTrivialHLSLTypes();
+  defineInternalHLSLTypes();
   defineHLSLTypesWithForwardDeclarations();
   defineHLSLAtomicIntrinsics();
 
@@ -233,6 +234,29 @@ void HLSLExternalSemaSource::defineTrivialHLSLTypes() {
   defineHLSLMatrixAlias();
 }
 
+void HLSLExternalSemaSource::defineHeapResourceInfoTypes() {
+  ASTContext &AST = SemaPtr->getASTContext();
+  CXXRecordDecl *ResDecl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
+                                                  "__hlsl_heap_resource_info")
+                               .finalizeForwardDeclaration();
+  if (!ResDecl->isCompleteDefinition())
+    BuiltinTypeDeclBuilder(*SemaPtr, ResDecl)
+        .addMemberVariable("Index", AST.UnsignedIntTy, {})
+        .completeDefinition();
+
+  CXXRecordDecl *SampDecl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace,
+                                                   "__hlsl_heap_sampler_info")
+                                .finalizeForwardDeclaration();
+  if (!SampDecl->isCompleteDefinition())
+    BuiltinTypeDeclBuilder(*SemaPtr, SampDecl)
+        .addMemberVariable("Index", AST.UnsignedIntTy, {})
+        .completeDefinition();
+}
+
+void HLSLExternalSemaSource::defineInternalHLSLTypes() {
+  defineHeapResourceInfoTypes();
+}
+
 /// Set up common members and attributes for buffer types
 static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S,
                                               ResourceClass RC, bool IsROV,
@@ -242,6 +266,7 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl 
*Decl, Sema &S,
       .addDefaultHandleConstructor()
       .addCopyConstructor()
       .addCopyAssignmentOperator()
+      .addHeapResourceInfoConstructor(HasCounter)
       .addStaticInitializationFunctions(HasCounter);
 }
 
@@ -252,6 +277,7 @@ static BuiltinTypeDeclBuilder 
setupSamplerType(CXXRecordDecl *Decl, Sema &S) {
       .addDefaultHandleConstructor()
       .addCopyConstructor()
       .addCopyAssignmentOperator()
+      .addHeapSamplerInfoConstructor()
       .addStaticInitializationFunctions(false);
 }
 
@@ -361,6 +387,7 @@ static BuiltinTypeDeclBuilder 
setupTextureType(CXXRecordDecl *Decl, Sema &S,
   B.addDefaultHandleConstructor()
       .addCopyConstructor()
       .addCopyAssignmentOperator()
+      .addHeapResourceInfoConstructor()
       .addStaticInitializationFunctions(false);
 
   if (T.has(TexCap::Load))
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 06828b9ec7fc0..7c64266d855de 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -4397,9 +4397,35 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned 
BuiltinID, CallExpr *TheCall) {
   }
   case Builtin::BI__builtin_hlsl_resource_counterhandlefromimplicitbinding: {
     assert(TheCall->getNumArgs() == 3 && "expected 3 args");
+    // Update return type to be the attributed resource type from arg0
+    // with added IsCounter flag.
     QualType MainHandleTy = TheCall->getArg(0)->getType();
+    QualType CounterHandleTy =
+        createCounterHandleType(SemaRef.getASTContext(), MainHandleTy);
+    TheCall->setType(CounterHandleTy);
+    break;
+  }
+  case Builtin::BI__builtin_hlsl_resource_handlefromheap: {
+    if (SemaRef.checkArgCount(TheCall, 2) ||
+        CheckResourceHandle(&SemaRef, TheCall, 0) ||
+        CheckArgTypeMatches(&SemaRef, TheCall->getArg(1),
+                            SemaRef.getASTContext().UnsignedIntTy))
+      return true;
+
+    // Update return type to be the attributed resource type from arg0.
+    QualType ResourceTy = TheCall->getArg(0)->getType();
+    TheCall->setType(ResourceTy);
+    break;
+  }
+  case Builtin::BI__builtin_hlsl_resource_counterhandlefromheap: {
+    if (SemaRef.checkArgCount(TheCall, 2) ||
+        CheckResourceHandle(&SemaRef, TheCall, 0) ||
+        CheckArgTypeMatches(&SemaRef, TheCall->getArg(1),
+                            SemaRef.getASTContext().UnsignedIntTy))
+      return true;
     // Update return type to be the attributed resource type from arg0
     // with added IsCounter flag.
+    QualType MainHandleTy = TheCall->getArg(0)->getType();
     QualType CounterHandleTy =
         createCounterHandleType(SemaRef.getASTContext(), MainHandleTy);
     TheCall->setType(CounterHandleTy);
diff --git a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl 
b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
index d6d2aa0819e7b..3312045cf4def 100644
--- a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl
@@ -82,6 +82,24 @@ RESOURCE Buffer;
 // CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
 // CHECK-NEXT: AlwaysInlineAttr
 
+// Heap info constructor
+
+// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]] 'void 
(hlsl::__hlsl_heap_resource_info)' inline
+// CHECK-NEXT: ParmVarDecl {{.*}} HeapResInfo 'hlsl::__hlsl_heap_resource_info'
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: BinaryOperator {{.*}} '='
+// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
+// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t
+// CHECK-NEXT: ImplicitCastExpr {{.*}} '__hlsl_resource_t 
(*)(__hlsl_resource_t, unsigned int) noexcept' <BuiltinFnToFnPtr>
+// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} 
'__builtin_hlsl_resource_handlefromheap' '__hlsl_resource_t (__hlsl_resource_t, 
unsigned int) noexcept'
+// CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t {{.*}}' lvalue .__handle
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <LValueToRValue>
+// CHECK-NEXT: MemberExpr {{.*}} 'unsigned int' lvalue .Index
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::__hlsl_heap_resource_info' lvalue 
ParmVar {{.*}} 'HeapResInfo' 'hlsl::__hlsl_heap_resource_info'
+// CHECK-NEXT: AlwaysInlineAttr
+
 // Static __createFromBinding method
 
 // CHECK: CXXMethodDecl {{.*}} __createFromBinding 'hlsl::[[RESOURCE]] 
(unsigned int, unsigned int, int, unsigned int, const char *)' static
diff --git a/clang/test/AST/HLSL/DynamicResources-AST.hlsl 
b/clang/test/AST/HLSL/DynamicResources-AST.hlsl
new file mode 100644
index 0000000000000..00d181388a977
--- /dev/null
+++ b/clang/test/AST/HLSL/DynamicResources-AST.hlsl
@@ -0,0 +1,132 @@
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.6-library -ast-dump %s | FileCheck %s
+
+// Global variables for ResourceDescriptorHeap and SamplerDescriptorHeap
+// CHECK: VarDecl {{.*}} used ResourceDescriptorHeap 'hlsl_private 
__hlsl_resource_descriptor_heap_struct' static internal-linkage
+// CHECK-NEXT: AvailabilityAttr {{.*}} shadermodel 6.6 0 0 "" "" 0
+
+// CHECK: VarDecl {{.*}} used SamplerDescriptorHeap 'hlsl_private 
__hlsl_sampler_descriptor_heap_struct' static internal-linkage
+// CHECK-NEXT: AvailabilityAttr {{.*}} shadermodel 6.6 0 0 "" "" 0
+
+void useBuffer(RWBuffer<int> Buffer) {}
+
+// CHECK-LABEL: FunctionDecl {{.*}} testInvocations
+export void testInvocations(unsigned Index) {
+
+// Buf1 declaration with direct initialization
+// CHECK: VarDecl {{.*}} Buf1 'RWBuffer<int>':'hlsl::RWBuffer<int>' cinit
+// CHECK-NEXT: ExprWithCleanups{{.*}} 'RWBuffer<int>':'hlsl::RWBuffer<int>'
+
+// RWBuffer copy constructor
+// CHECK-NEXT: CXXConstructExpr {{.*}} 'RWBuffer<int>':'hlsl::RWBuffer<int>' 
'void (const hlsl::RWBuffer<int> &)'
+// CHECK-NEXT: MaterializeTemporaryExpr {{.*}} 'const RWBuffer<int>':'const 
hlsl::RWBuffer<int>' lvalue
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'const RWBuffer<int>':'const 
hlsl::RWBuffer<int>' <NoOp>
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'RWBuffer<int>':'hlsl::RWBuffer<int>' 
<ConstructorConversion>
+
+// RWBuffer heap info constructor
+// CHECK-NEXT: CXXConstructExpr {{.*}} 'RWBuffer<int>':'hlsl::RWBuffer<int>' 
'void (hlsl::__hlsl_heap_resource_info)'
+
+// __hlsl_heap_resource_info copy constructor
+// CHECK-NEXT: CXXConstructExpr {{.*}} 'hlsl::__hlsl_heap_resource_info' 'void 
(__hlsl_heap_resource_info &&) noexcept' elidable
+
+// Indexing into ResourceDescriptorHeap
+// CHECK-NEXT: MaterializeTemporaryExpr {{.*}} '__hlsl_heap_resource_info' 
xvalue
+// CHECK-NEXT: CXXOperatorCallExpr {{.*}} '__hlsl_heap_resource_info' '[]'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} '__hlsl_heap_resource_info 
(*)(uint32_t)' <FunctionToPointerDecay>
+// CHECK-NEXT: DeclRefExpr {{.*}} '__hlsl_heap_resource_info (uint32_t)' 
lvalue CXXMethod {{.*}} 'operator[]' '__hlsl_heap_resource_info (uint32_t)'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 
'hlsl::__hlsl_resource_descriptor_heap_struct' lvalue <AddressSpaceConversion>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl_private 
__hlsl_resource_descriptor_heap_struct' lvalue Var {{.*}} 
'ResourceDescriptorHeap' 'hlsl_private __hlsl_resource_descriptor_heap_struct'
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'unsigned int' <LValueToRValue>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' lvalue ParmVar {{.*}} 'Index' 
'unsigned int'
+
+  RWBuffer<int> Buf1 = ResourceDescriptorHeap[Index];
+
+// Buf2 declaration initialized with default constructor (handle is poison)
+// CHECK: VarDecl {{.*}} Buf2 'RWBuffer<int>':'hlsl::RWBuffer<int>' callinit
+// CHECK-NEXT: CXXConstructExpr {{.*}} 'RWBuffer<int>':'hlsl::RWBuffer<int>' 
'void ()'
+
+// Buf2 assignment operator
+// CHECK-NEXT: ExprWithCleanups
+// CHECK-NEXT: CXXOperatorCallExpr {{.*}} 'hlsl::RWBuffer<int>' lvalue '='
+// CHECK-NEXT: ImplicitCastExpr {{.*}} 'hlsl::RWBuffer<int> &(*)(const 
hlsl::RWBuffer<int> &)' <FunctionToPointerDecay>
+// CHECK-NEXT: DeclRefExpr {{.*}} 'hlsl::RWBuffer<int...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/221103
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to