[clang] b086e19 - [HLSL] Add IsArray resource attribute (#201163)

via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 12 00:55:07 PDT 2026


Author: Tim Corringham
Date: 2026-06-12T08:54:58+01:00
New Revision: b086e198e241fdcde57a3f9961e7d8d3c3ca4a99

URL: https://github.com/llvm/llvm-project/commit/b086e198e241fdcde57a3f9961e7d8d3c3ca4a99
DIFF: https://github.com/llvm/llvm-project/commit/b086e198e241fdcde57a3f9961e7d8d3c3ca4a99.diff

LOG: [HLSL] Add IsArray resource attribute (#201163)

First part of changes to add support for the IsArray resource attribute,
which will be used by the resource array types (Texture2DArray etc.).
These types will be implemented in subsequent changes.

This implements the attribute parsing and associated tests, and
implements the first part of #194910.

The Sema builtin argument checking and CodeGen will be included in a
subsequent PR which will implement a resource array type which will
allow those changes to be tested.

---------

Co-authored-by: Tim Corringham <tcorring at amd.com>

Added: 
    clang/test/ParserHLSL/hlsl_is_array_attr.hlsl
    clang/test/ParserHLSL/hlsl_is_array_attr_error.hlsl

Modified: 
    clang/include/clang/AST/TypeBase.h
    clang/include/clang/AST/TypeProperties.td
    clang/include/clang/Basic/Attr.td
    clang/lib/AST/ItaniumMangle.cpp
    clang/lib/AST/TypePrinter.cpp
    clang/lib/CodeGen/CGHLSLBuiltins.cpp
    clang/lib/Sema/SemaHLSL.cpp
    clang/lib/Sema/SemaType.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h
index e3141a82b54d2..e3844d0cefa78 100644
--- a/clang/include/clang/AST/TypeBase.h
+++ b/clang/include/clang/AST/TypeBase.h
@@ -6842,12 +6842,16 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode {
     LLVM_PREFERRED_TYPE(bool)
     uint8_t IsCounter : 1;
 
+    LLVM_PREFERRED_TYPE(bool)
+    uint8_t IsArray : 1;
+
     Attributes(llvm::dxil::ResourceClass ResourceClass,
                llvm::dxil::ResourceDimension ResourceDimension,
                bool IsROV = false, bool RawBuffer = false,
-               bool IsCounter = false)
+               bool IsCounter = false, bool IsArray = false)
         : ResourceClass(ResourceClass), ResourceDimension(ResourceDimension),
-          IsROV(IsROV), RawBuffer(RawBuffer), IsCounter(IsCounter) {}
+          IsROV(IsROV), RawBuffer(RawBuffer), IsCounter(IsCounter),
+          IsArray(IsArray) {}
 
     Attributes(llvm::dxil::ResourceClass ResourceClass)
         : Attributes(ResourceClass, llvm::dxil::ResourceDimension::Unknown) {}
@@ -6855,13 +6859,13 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode {
     Attributes()
         : Attributes(llvm::dxil::ResourceClass::UAV,
                      llvm::dxil::ResourceDimension::Unknown, false, false,
-                     false) {}
+                     false, false) {}
 
     friend bool operator==(const Attributes &LHS, const Attributes &RHS) {
       return std::tie(LHS.ResourceClass, LHS.ResourceDimension, LHS.IsROV,
-                      LHS.RawBuffer, LHS.IsCounter) ==
+                      LHS.RawBuffer, LHS.IsCounter, LHS.IsArray) ==
              std::tie(RHS.ResourceClass, RHS.ResourceDimension, RHS.IsROV,
-                      RHS.RawBuffer, RHS.IsCounter);
+                      RHS.RawBuffer, RHS.IsCounter, RHS.IsArray);
     }
     friend bool operator!=(const Attributes &LHS, const Attributes &RHS) {
       return !(LHS == RHS);
@@ -6906,6 +6910,7 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode {
     ID.AddBoolean(Attrs.IsROV);
     ID.AddBoolean(Attrs.RawBuffer);
     ID.AddBoolean(Attrs.IsCounter);
+    ID.AddBoolean(Attrs.IsArray);
   }
 
   static bool classof(const Type *T) {

diff  --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 0f3722b36774a..f16c10da430f9 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -681,11 +681,14 @@ let Class = HLSLAttributedResourceType in {
   def : Property<"containedTy", QualType> {
     let Read = [{ node->getContainedType() }];
   }
+  def : Property<"isArray", Bool> {
+    let Read = [{ node->getAttrs().IsArray }];
+  }
   def : Creator<[{
     HLSLAttributedResourceType::Attributes attrs(
         static_cast<llvm::dxil::ResourceClass>(resClass),
         static_cast<llvm::dxil::ResourceDimension>(resDimension), isROV,
-        rawBuffer, isCounter);
+        rawBuffer, isCounter, isArray);
     return ctx.getHLSLAttributedResourceType(wrappedTy, containedTy, attrs);
   }]>;
 }

diff  --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 7f7e9489782a7..a1e02e1478df1 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -5178,6 +5178,12 @@ def HLSLShader : InheritableAttr {
 }];
 }
 
+def HLSLIsArray : TypeAttr {
+  let Spellings = [CXX11<"hlsl", "is_array">];
+  let LangOpts = [HLSL];
+  let Documentation = [InternalOnly];
+}
+
 def HLSLROV : TypeAttr {
   let Spellings = [CXX11<"hlsl", "is_rov">];
   let LangOpts = [HLSL];

diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 2e74aeb558e3d..e5cdd6f31c507 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -4677,6 +4677,8 @@ void CXXNameMangler::mangleType(const HLSLAttributedResourceType *T) {
     Str += "_Raw";
   if (Attrs.IsCounter)
     Str += "_Counter";
+  if (Attrs.IsArray)
+    Str += "_Array";
   if (T->hasContainedType())
     Str += "_CT";
   mangleVendorQualifier(Str);

diff  --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index d85ed244f643a..53b869e019074 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1990,6 +1990,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
   case attr::HLSLContainedType:
   case attr::HLSLIsCounter:
   case attr::HLSLResourceDimension:
+  case attr::HLSLIsArray:
     llvm_unreachable("HLSL resource type attributes handled separately");
 
   case attr::OpenCLPrivateAddressSpace:
@@ -2169,6 +2170,8 @@ void TypePrinter::printHLSLAttributedResourceAfter(
     OS << " [[hlsl::raw_buffer]]";
   if (Attrs.IsCounter)
     OS << " [[hlsl::is_counter]]";
+  if (Attrs.IsArray)
+    OS << " [[hlsl::is_array]]";
 
   QualType ContainedTy = T->getContainedType();
   if (!ContainedTy.isNull()) {

diff  --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index 920816bd3d3f8..95b736ea60bc2 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -13,6 +13,7 @@
 #include "CGBuiltin.h"
 #include "CGHLSLRuntime.h"
 #include "CodeGenFunction.h"
+#include "clang/AST/HLSLResource.h"
 #include "clang/AST/MatrixUtils.h"
 #include "llvm/IR/MatrixBuilder.h"
 
@@ -457,11 +458,32 @@ static std::string getSpecConstantFunctionName(clang::QualType SpecConstantType,
   return Name;
 }
 
-static llvm::Type *getOffsetType(CodeGenModule &CGM, llvm::Type *CoordTy) {
+static const HLSLAttributedResourceType *
+getHandleAttributedType(QualType HandleQT) {
+  if (const auto *RT = HandleQT->getAs<HLSLAttributedResourceType>())
+    return RT;
+  // If the expr is a texture/sampler record (or similar), peel to __handle.
+  if (const HLSLAttributedResourceType *RT =
+          HLSLAttributedResourceType::findHandleTypeOnResource(
+              HandleQT.getTypePtr()))
+    return RT;
+  llvm_unreachable("attributed handle type not found");
+}
+
+static const HLSLAttributedResourceType *
+getRequiredHandleType(const CallExpr *E, unsigned ArgNo) {
+  return getHandleAttributedType(E->getArg(ArgNo)->getType());
+}
+
+static llvm::Type *getOffsetType(CodeGenModule &CGM,
+                                 const HLSLAttributedResourceType *RT) {
+  const auto &Attrs = RT->getAttrs();
+  unsigned OffsetSize =
+      clang::hlsl::getResourceDimensions(Attrs.ResourceDimension);
   llvm::Type *Int32Ty = CGM.Int32Ty;
-  if (auto *VT = dyn_cast<llvm::FixedVectorType>(CoordTy))
-    return llvm::FixedVectorType::get(Int32Ty, VT->getNumElements());
-  return Int32Ty;
+  if (OffsetSize == 1)
+    return Int32Ty;
+  return llvm::FixedVectorType::get(Int32Ty, OffsetSize);
 }
 
 static Value *emitHlslOffset(CodeGenFunction &CGF, const CallExpr *E,
@@ -607,13 +629,13 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
     Value *HandleOp = EmitScalarExpr(E->getArg(0));
     Value *SamplerOp = EmitScalarExpr(E->getArg(1));
     Value *CoordOp = EmitScalarExpr(E->getArg(2));
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
 
     SmallVector<Value *, 4> Args;
     Args.push_back(HandleOp);
     Args.push_back(SamplerOp);
     Args.push_back(CoordOp);
-    Args.push_back(
-        emitHlslOffset(*this, E, 3, getOffsetType(CGM, CoordOp->getType())));
+    Args.push_back(emitHlslOffset(*this, E, 3, getOffsetType(CGM, RT)));
 
     llvm::Type *RetTy = ConvertType(E->getType());
     if (E->getNumArgs() <= 4) {
@@ -632,14 +654,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
     Value *BiasOp = EmitScalarExpr(E->getArg(3));
     if (BiasOp->getType() != Builder.getFloatTy())
       BiasOp = Builder.CreateFPCast(BiasOp, Builder.getFloatTy());
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
 
     SmallVector<Value *, 6> Args; // Max 6 arguments for SampleBias
     Args.push_back(HandleOp);
     Args.push_back(SamplerOp);
     Args.push_back(CoordOp);
     Args.push_back(BiasOp);
-    Args.push_back(
-        emitHlslOffset(*this, E, 4, getOffsetType(CGM, CoordOp->getType())));
+    Args.push_back(emitHlslOffset(*this, E, 4, getOffsetType(CGM, RT)));
 
     llvm::Type *RetTy = ConvertType(E->getType());
     if (E->getNumArgs() <= 5)
@@ -656,6 +678,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
     Value *CoordOp = EmitScalarExpr(E->getArg(2));
     Value *DDXOp = EmitScalarExpr(E->getArg(3));
     Value *DDYOp = EmitScalarExpr(E->getArg(4));
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
 
     SmallVector<Value *, 7> Args;
     Args.push_back(HandleOp);
@@ -663,8 +686,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
     Args.push_back(CoordOp);
     Args.push_back(DDXOp);
     Args.push_back(DDYOp);
-    Args.push_back(
-        emitHlslOffset(*this, E, 5, getOffsetType(CGM, CoordOp->getType())));
+    Args.push_back(emitHlslOffset(*this, E, 5, getOffsetType(CGM, RT)));
 
     llvm::Type *RetTy = ConvertType(E->getType());
 
@@ -684,14 +706,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
     Value *LODOp = EmitScalarExpr(E->getArg(3));
     if (LODOp->getType() != Builder.getFloatTy())
       LODOp = Builder.CreateFPCast(LODOp, Builder.getFloatTy());
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
 
     SmallVector<Value *, 5> Args; // Max 5 arguments for SampleLevel
     Args.push_back(HandleOp);
     Args.push_back(SamplerOp);
     Args.push_back(CoordOp);
     Args.push_back(LODOp);
-    Args.push_back(
-        emitHlslOffset(*this, E, 4, getOffsetType(CGM, CoordOp->getType())));
+    Args.push_back(emitHlslOffset(*this, E, 4, getOffsetType(CGM, RT)));
 
     llvm::Type *RetTy = ConvertType(E->getType());
     return Builder.CreateIntrinsic(
@@ -714,13 +736,13 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
         Builder.CreateShuffleVector(CoordLODOp, Mask, "hlsl.load.coord");
     Value *LODOp =
         Builder.CreateExtractElement(CoordLODOp, NumElts - 1, "hlsl.load.lod");
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
 
     SmallVector<Value *, 4> Args;
     Args.push_back(HandleOp);
     Args.push_back(CoordOp);
     Args.push_back(LODOp);
-    Args.push_back(
-        emitHlslOffset(*this, E, 2, getOffsetType(CGM, CoordOp->getType())));
+    Args.push_back(emitHlslOffset(*this, E, 2, getOffsetType(CGM, RT)));
 
     llvm::Type *RetTy = ConvertType(E->getType());
     return Builder.CreateIntrinsic(
@@ -733,14 +755,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
     Value *CmpOp = EmitScalarExpr(E->getArg(3));
     if (CmpOp->getType() != Builder.getFloatTy())
       CmpOp = Builder.CreateFPCast(CmpOp, Builder.getFloatTy());
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
 
     SmallVector<Value *, 6> Args; // Max 6 arguments for SampleCmp
     Args.push_back(HandleOp);
     Args.push_back(SamplerOp);
     Args.push_back(CoordOp);
     Args.push_back(CmpOp);
-    Args.push_back(
-        emitHlslOffset(*this, E, 4, getOffsetType(CGM, CoordOp->getType())));
+    Args.push_back(emitHlslOffset(*this, E, 4, getOffsetType(CGM, RT)));
 
     llvm::Type *RetTy = ConvertType(E->getType());
     if (E->getNumArgs() <= 5) {
@@ -759,15 +781,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
     Value *CmpOp = EmitScalarExpr(E->getArg(3));
     if (CmpOp->getType() != Builder.getFloatTy())
       CmpOp = Builder.CreateFPCast(CmpOp, Builder.getFloatTy());
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
 
     SmallVector<Value *, 5> Args;
     Args.push_back(HandleOp);
     Args.push_back(SamplerOp);
     Args.push_back(CoordOp);
     Args.push_back(CmpOp);
-
-    Args.push_back(
-        emitHlslOffset(*this, E, 4, getOffsetType(CGM, CoordOp->getType())));
+    Args.push_back(emitHlslOffset(*this, E, 4, getOffsetType(CGM, RT)));
 
     llvm::Type *RetTy = ConvertType(E->getType());
     return Builder.CreateIntrinsic(
@@ -801,14 +822,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
     if (ComponentOp->getType() != Builder.getInt32Ty())
       ComponentOp = Builder.CreateIntCast(ComponentOp, Builder.getInt32Ty(),
                                           /*isSigned=*/false);
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
 
     SmallVector<Value *, 5> Args;
     Args.push_back(HandleOp);
     Args.push_back(SamplerOp);
     Args.push_back(CoordOp);
     Args.push_back(ComponentOp);
-    Args.push_back(
-        emitHlslOffset(*this, E, 4, getOffsetType(CGM, CoordOp->getType())));
+    Args.push_back(emitHlslOffset(*this, E, 4, getOffsetType(CGM, RT)));
 
     llvm::Type *RetTy = ConvertType(E->getType());
     return Builder.CreateIntrinsic(
@@ -836,8 +857,8 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
       Args.push_back(ComponentOp);
     }
 
-    Args.push_back(
-        emitHlslOffset(*this, E, 5, getOffsetType(CGM, CoordOp->getType())));
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
+    Args.push_back(emitHlslOffset(*this, E, 5, getOffsetType(CGM, RT)));
 
     llvm::Type *RetTy = ConvertType(E->getType());
     return Builder.CreateIntrinsic(

diff  --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 30aef43f7150f..0602402fb99f8 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2152,6 +2152,13 @@ bool clang::CreateHLSLAttributedResourceType(
       }
       ResAttrs.RawBuffer = true;
       break;
+    case attr::HLSLIsArray:
+      if (ResAttrs.IsArray) {
+        S.Diag(A->getLocation(), diag::warn_duplicate_attribute_exact) << A;
+        return false;
+      }
+      ResAttrs.IsArray = true;
+      break;
     case attr::HLSLIsCounter:
       if (ResAttrs.IsCounter) {
         S.Diag(A->getLocation(), diag::warn_duplicate_attribute_exact) << A;
@@ -2273,6 +2280,10 @@ bool SemaHLSL::handleResourceTypeAttr(QualType T, const ParsedAttr &AL) {
     A = HLSLIsCounterAttr::Create(getASTContext(), ACI);
     break;
 
+  case ParsedAttr::AT_HLSLIsArray:
+    A = HLSLIsArrayAttr::Create(getASTContext(), ACI);
+    break;
+
   case ParsedAttr::AT_HLSLContainedType: {
     if (AL.getNumArgs() != 1 && !AL.hasParsedType()) {
       Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 1;

diff  --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index ea4a6fb208dc3..d2bb312feadc1 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -9356,6 +9356,7 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
     case ParsedAttr::AT_HLSLResourceDimension:
     case ParsedAttr::AT_HLSLROV:
     case ParsedAttr::AT_HLSLRawBuffer:
+    case ParsedAttr::AT_HLSLIsArray:
     case ParsedAttr::AT_HLSLContainedType: {
       // Only collect HLSL resource type attributes that are in
       // decl-specifier-seq; do not collect attributes on declarations or those

diff  --git a/clang/test/ParserHLSL/hlsl_is_array_attr.hlsl b/clang/test/ParserHLSL/hlsl_is_array_attr.hlsl
new file mode 100644
index 0000000000000..618d5d9a86c33
--- /dev/null
+++ b/clang/test/ParserHLSL/hlsl_is_array_attr.hlsl
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -ast-dump -o - %s | FileCheck %s
+
+// CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} {{.*}} struct MyBuffer definition
+// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 4]]:3, col:70> col:70 h '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+struct MyBuffer {
+  __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::is_array]] h;
+};
+
+// CHECK: VarDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 3]]:1, col:68> col:68 res '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+__hlsl_resource_t [[hlsl::is_array]] [[hlsl::resource_class(SRV)]] res;
+
+// CHECK: FunctionDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 4]]:1, line:[[# @LINE + 6]]:1> line:[[# @LINE + 4]]:6 f 'void ()
+// CHECK: VarDecl 0x{{[0-9a-f]+}} <col:3, col:74> col:74 r '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_array]]
+void f() {
+  __hlsl_resource_t [[hlsl::resource_class(Sampler)]] [[hlsl::is_array]] r;
+}

diff  --git a/clang/test/ParserHLSL/hlsl_is_array_attr_error.hlsl b/clang/test/ParserHLSL/hlsl_is_array_attr_error.hlsl
new file mode 100644
index 0000000000000..1d19822c974da
--- /dev/null
+++ b/clang/test/ParserHLSL/hlsl_is_array_attr_error.hlsl
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -o - %s -verify
+
+// expected-error at +1{{'hlsl::is_array' attribute cannot be applied to a declaration}}
+[[hlsl::is_array]] __hlsl_resource_t res0;
+
+// expected-error at +1{{HLSL resource needs to have [[hlsl::resource_class()]] attribute}}
+__hlsl_resource_t [[hlsl::is_array]] res1;
+
+// expected-error at +1{{'hlsl::is_array' attribute takes no arguments}}
+__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::is_array(3)]] res2;
+
+// expected-error at +1{{use of undeclared identifier 'gibberish'}}
+__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::is_array(gibberish)]] res3;
+
+// expected-warning at +1{{attribute 'hlsl::is_array' is already applied}}
+__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::is_array]] [[hlsl::is_array]] res4;
+
+// expected-error at +2{{attribute 'hlsl::resource_class' can be used only on HLSL intangible type '__hlsl_resource_t'}}
+// expected-error at +1{{attribute 'hlsl::is_array' can be used only on HLSL intangible type '__hlsl_resource_t'}}
+float [[hlsl::resource_class(UAV)]] [[hlsl::is_array]] res5;


        


More information about the cfe-commits mailing list