https://github.com/tcorringham updated 
https://github.com/llvm/llvm-project/pull/201163

>From 375b0ff1c5b0795200df4789ab4fd324e86a3c9e Mon Sep 17 00:00:00 2001
From: Tim Corringham <[email protected]>
Date: Mon, 11 May 2026 16:57:44 +0100
Subject: [PATCH 1/5] [HLSL] Add IsArray resource attribute

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.

As it is difficult to make a meaningful test without a type that uses
the IsArray attribute, no new tests are included in this commit.
For now, existing tests will check that these changes do not impact any
existing types.  Comprehensive tests will be included with the
implementation of each array type.

Fixes #194910
---
 clang/include/clang/AST/TypeBase.h            |  13 +-
 clang/include/clang/AST/TypeProperties.td     |   5 +-
 clang/include/clang/Basic/Attr.td             |   6 +
 clang/lib/AST/ItaniumMangle.cpp               |   2 +
 clang/lib/AST/TypePrinter.cpp                 |   3 +
 clang/lib/CodeGen/CGHLSLBuiltins.cpp          |  77 +++++--
 clang/lib/CodeGen/Targets/DirectX.cpp         |  17 +-
 clang/lib/CodeGen/Targets/SPIR.cpp            |   2 +-
 clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 204 ++++++++++--------
 clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h   |  41 ++--
 clang/lib/Sema/HLSLExternalSemaSource.cpp     |  29 +--
 clang/lib/Sema/SemaHLSL.cpp                   |  31 ++-
 12 files changed, 269 insertions(+), 161 deletions(-)

diff --git a/clang/include/clang/AST/TypeBase.h 
b/clang/include/clang/AST/TypeBase.h
index c64eee11fd91e..3b775eea6f4bf 100644
--- a/clang/include/clang/AST/TypeBase.h
+++ b/clang/include/clang/AST/TypeBase.h
@@ -6847,12 +6847,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) {}
@@ -6864,9 +6868,9 @@ class HLSLAttributedResourceType : public Type, public 
llvm::FoldingSetNode {
 
     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);
@@ -6911,6 +6915,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 32f72e8da960e..e64fd925b78a6 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -5172,6 +5172,12 @@ def HLSLShader : InheritableAttr {
 }];
 }
 
+def HLSLArrayed : TypeAttr {
+  let Spellings = [CXX11<"hlsl", "is_arrayed">];
+  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 85a01c6f4f727..f0527a4aa77cf 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 80f5b90ba35c4..f82c2219e4f76 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::HLSLArrayed:
     llvm_unreachable("HLSL resource type attributes handled separately");
 
   case attr::OpenCLPrivateAddressSpace:
@@ -2162,6 +2163,8 @@ void TypePrinter::printHLSLAttributedResourceAfter(
     OS << " [[hlsl::raw_buffer]]";
   if (Attrs.IsCounter)
     OS << " [[hlsl::is_counter]]";
+  if (Attrs.IsArray)
+    OS << " [[hlsl::is_arrayed]]";
 
   QualType ContainedTy = T->getContainedType();
   if (!ContainedTy.isNull()) {
diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp 
b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index bf599e2d77aa8..6266365dc0460 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 "llvm/IR/MatrixBuilder.h"
 
 using namespace clang;
@@ -456,11 +457,24 @@ 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.
+  return HLSLAttributedResourceType::findHandleTypeOnResource(
+      HandleQT.getTypePtr());
+}
+
+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,
@@ -606,13 +620,15 @@ 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 =
+        getHandleAttributedType(E->getArg(0)->getType());
+    assert(RT && "resource builtin requires attributed handle type");
 
     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) {
@@ -631,14 +647,16 @@ 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 =
+        getHandleAttributedType(E->getArg(0)->getType());
+    assert(RT && "resource builtin requires attributed handle type");
 
     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)
@@ -655,6 +673,9 @@ 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 =
+        getHandleAttributedType(E->getArg(0)->getType());
+    assert(RT && "resource builtin requires attributed handle type");
 
     SmallVector<Value *, 7> Args;
     Args.push_back(HandleOp);
@@ -662,8 +683,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());
 
@@ -683,14 +703,16 @@ 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 =
+        getHandleAttributedType(E->getArg(0)->getType());
+    assert(RT && "resource builtin requires attributed handle type");
 
     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(
@@ -713,13 +735,15 @@ 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 =
+        getHandleAttributedType(E->getArg(0)->getType());
+    assert(RT && "resource builtin requires attributed handle type");
 
     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(
@@ -732,14 +756,16 @@ 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 =
+        getHandleAttributedType(E->getArg(0)->getType());
+    assert(RT && "resource builtin requires attributed handle type");
 
     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) {
@@ -758,15 +784,16 @@ 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 =
+        getHandleAttributedType(E->getArg(0)->getType());
+    assert(RT && "resource builtin requires attributed handle type");
 
     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(
@@ -800,14 +827,16 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
     if (ComponentOp->getType() != Builder.getInt32Ty())
       ComponentOp = Builder.CreateIntCast(ComponentOp, Builder.getInt32Ty(),
                                           /*isSigned=*/false);
+    const HLSLAttributedResourceType *RT =
+        getHandleAttributedType(E->getArg(0)->getType());
+    assert(RT && "resource builtin requires attributed handle type");
 
     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(
@@ -835,8 +864,10 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
       Args.push_back(ComponentOp);
     }
 
-    Args.push_back(
-        emitHlslOffset(*this, E, 5, getOffsetType(CGM, CoordOp->getType())));
+    const HLSLAttributedResourceType *RT =
+        getHandleAttributedType(E->getArg(0)->getType());
+    assert(RT && "resource builtin requires attributed handle type");
+    Args.push_back(emitHlslOffset(*this, E, 5, getOffsetType(CGM, RT)));
 
     llvm::Type *RetTy = ConvertType(E->getType());
     return Builder.CreateIntrinsic(
diff --git a/clang/lib/CodeGen/Targets/DirectX.cpp 
b/clang/lib/CodeGen/Targets/DirectX.cpp
index e5b01c21e9e2f..2b2567849ef93 100644
--- a/clang/lib/CodeGen/Targets/DirectX.cpp
+++ b/clang/lib/CodeGen/Targets/DirectX.cpp
@@ -94,19 +94,28 @@ llvm::Type *DirectXTargetCodeGenInfo::getHLSLType(
       llvm::dxil::ResourceKind RK = llvm::dxil::ResourceKind::Invalid;
       switch (ResAttrs.ResourceDimension) {
       case llvm::dxil::ResourceDimension::Dim1D:
-        RK = llvm::dxil::ResourceKind::Texture1D;
+        if (ResAttrs.IsArray)
+          RK = llvm::dxil::ResourceKind::Texture1DArray;
+        else
+          RK = llvm::dxil::ResourceKind::Texture1D;
         break;
       case llvm::dxil::ResourceDimension::Dim2D:
-        RK = llvm::dxil::ResourceKind::Texture2D;
+        if (ResAttrs.IsArray)
+          RK = llvm::dxil::ResourceKind::Texture2DArray;
+        else
+          RK = llvm::dxil::ResourceKind::Texture2D;
         break;
       case llvm::dxil::ResourceDimension::Dim3D:
         RK = llvm::dxil::ResourceKind::Texture3D;
         break;
       case llvm::dxil::ResourceDimension::Cube:
-        RK = llvm::dxil::ResourceKind::TextureCube;
+        if (ResAttrs.IsArray)
+          RK = llvm::dxil::ResourceKind::TextureCubeArray;
+        else
+          RK = llvm::dxil::ResourceKind::TextureCube;
         break;
       default:
-        llvm_unreachable("Unsupported resource dimension for textur.");
+        llvm_unreachable("Unsupported resource dimension for texture.");
       }
       Ints.push_back(static_cast<unsigned>(RK));
     }
diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp 
b/clang/lib/CodeGen/Targets/SPIR.cpp
index 0a96d612c8a87..88e7c7f9482a4 100644
--- a/clang/lib/CodeGen/Targets/SPIR.cpp
+++ b/clang/lib/CodeGen/Targets/SPIR.cpp
@@ -922,7 +922,7 @@ llvm::Type 
*CommonSPIRTargetCodeGenInfo::getSPIRVImageTypeFromHLSLResource(
   IntParams[1] = 2;
 
   // Arrayed
-  IntParams[2] = 0;
+  IntParams[2] = static_cast<unsigned>(attributes.IsArray);
 
   // MS
   IntParams[3] = 0;
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp 
b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index de170c86400d2..34dd3896943eb 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -1036,10 +1036,10 @@ BuiltinTypeDeclBuilder::addMemberVariable(StringRef 
Name, QualType Type,
 BuiltinTypeDeclBuilder &
 BuiltinTypeDeclBuilder::addBufferHandles(ResourceClass RC, bool IsROV,
                                          bool RawBuffer, bool HasCounter,
-                                         AccessSpecifier Access) {
+                                         bool IsArray, AccessSpecifier Access) 
{
   QualType ElementTy = getHandleElementType();
-  addHandleMember(RC, ResourceDimension::Unknown, IsROV, RawBuffer, ElementTy,
-                  Access);
+  addHandleMember(RC, ResourceDimension::Unknown, IsROV, RawBuffer, IsArray,
+                  ElementTy, Access);
   if (HasCounter)
     addCounterHandleMember(RC, IsROV, RawBuffer, ElementTy, Access);
   return *this;
@@ -1047,16 +1047,17 @@ BuiltinTypeDeclBuilder::addBufferHandles(ResourceClass 
RC, bool IsROV,
 
 BuiltinTypeDeclBuilder &
 BuiltinTypeDeclBuilder::addTextureHandle(ResourceClass RC, bool IsROV,
-                                         ResourceDimension RD,
+                                         bool IsArray, ResourceDimension RD,
                                          AccessSpecifier Access) {
-  addHandleMember(RC, RD, IsROV, /*RawBuffer=*/false, getHandleElementType(),
-                  Access);
+  addHandleMember(RC, RD, IsROV, /*RawBuffer=*/false, IsArray,
+                  getHandleElementType(), Access);
   return *this;
 }
 
 BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addSamplerHandle() {
   addHandleMember(ResourceClass::Sampler, ResourceDimension::Unknown,
-                  /*IsROV=*/false, /*RawBuffer=*/false, 
getHandleElementType());
+                  /*IsROV=*/false, /*RawBuffer=*/false, /*IsArray=*/false,
+                  getHandleElementType());
   return *this;
 }
 
@@ -1111,22 +1112,22 @@ CXXRecordDecl 
*BuiltinTypeDeclBuilder::addPrivateNestedRecord(StringRef Name) {
 
 BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember(
     ResourceClass RC, ResourceDimension RD, bool IsROV, bool RawBuffer,
-    QualType ElementTy, AccessSpecifier Access) {
+    bool IsArray, QualType ElementTy, AccessSpecifier Access) {
   return addResourceMember("__handle", RC, RD, IsROV, RawBuffer,
-                           /*IsCounter=*/false, ElementTy, Access);
+                           /*IsCounter=*/false, IsArray, ElementTy, Access);
 }
 
 BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCounterHandleMember(
     ResourceClass RC, bool IsROV, bool RawBuffer, QualType ElementTy,
     AccessSpecifier Access) {
   return addResourceMember("__counter_handle", RC, ResourceDimension::Unknown,
-                           IsROV, RawBuffer,
-                           /*IsCounter=*/true, ElementTy, Access);
+                           IsROV, RawBuffer, /*IsCounter=*/true,
+                           /*IsArray=*/false, ElementTy, Access);
 }
 
 BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addResourceMember(
     StringRef MemberName, ResourceClass RC, ResourceDimension RD, bool IsROV,
-    bool RawBuffer, bool IsCounter, QualType ElementTy,
+    bool RawBuffer, bool IsCounter, bool IsArray, QualType ElementTy,
     AccessSpecifier Access) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
 
@@ -1151,6 +1152,8 @@ BuiltinTypeDeclBuilder 
&BuiltinTypeDeclBuilder::addResourceMember(
           : nullptr};
   if (IsCounter)
     Attrs.push_back(HLSLIsCounterAttr::CreateImplicit(Ctx));
+  if (IsArray)
+    Attrs.push_back(HLSLArrayedAttr::CreateImplicit(Ctx));
 
   if (CreateHLSLAttributedResourceType(SemaRef, Ctx.HLSLResourceTy, Attrs,
                                        AttributedResTy))
@@ -1405,13 +1408,14 @@ 
BuiltinTypeDeclBuilder::addCopyAssignmentOperator(AccessSpecifier Access) {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addArraySubscriptOperators(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addArraySubscriptOperators(ResourceDimension Dim,
+                                                   bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
 
   uint32_t VecSize = 1;
   if (Dim != ResourceDimension::Unknown)
-    VecSize = getResourceDimensions(Dim);
+    VecSize = getResourceDimensions(Dim) + (IsArray ? 1 : 0);
 
   QualType IndexTy = VecSize > 1
                          ? AST.getExtVectorType(AST.UnsignedIntTy, VecSize)
@@ -1446,7 +1450,8 @@ BuiltinTypeDeclBuilder 
&BuiltinTypeDeclBuilder::addLoadMethods() {
 CXXRecordDecl *BuiltinTypeDeclBuilder::addMipsSliceType(ResourceDimension Dim,
                                                         QualType ReturnType) {
   ASTContext &AST = Record->getASTContext();
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t VecSize =
+      getResourceDimensions(Dim) + (getResourceAttrs().IsArray ? 1 : 0);
   QualType IntTy = AST.IntTy;
   QualType IndexTy = VecSize > 1 ? AST.getExtVectorType(IntTy, VecSize) : 
IntTy;
   QualType CoordLevelTy = AST.getExtVectorType(IntTy, VecSize + 1);
@@ -1459,7 +1464,8 @@ CXXRecordDecl 
*BuiltinTypeDeclBuilder::addMipsSliceType(ResourceDimension Dim,
   BuiltinTypeDeclBuilder MipsSliceBuilder(SemaRef, MipsSliceRecord);
   MipsSliceBuilder.addFriend(Record)
       .addHandleMember(getResourceAttrs().ResourceClass, Dim,
-                       getResourceAttrs().IsROV, false, ReturnType,
+                       getResourceAttrs().IsROV, /*RawBuffer=*/false,
+                       getResourceAttrs().IsArray, ReturnType,
                        AccessSpecifier::AS_public)
       .addMemberVariable("__level", IntTy, {}, AccessSpecifier::AS_public)
       .addDefaultHandleConstructor(AccessSpecifier::AS_protected)
@@ -1502,7 +1508,8 @@ CXXRecordDecl 
*BuiltinTypeDeclBuilder::addMipsType(ResourceDimension Dim,
   BuiltinTypeDeclBuilder MipsBuilder(SemaRef, MipsRecord);
   MipsBuilder.addFriend(Record)
       .addHandleMember(getResourceAttrs().ResourceClass, Dim,
-                       getResourceAttrs().IsROV, false, ReturnType,
+                       getResourceAttrs().IsROV, /*RawBuffer=*/false,
+                       getResourceAttrs().IsArray, ReturnType,
                        AccessSpecifier::AS_public)
       .addDefaultHandleConstructor(AccessSpecifier::AS_protected)
       .addCopyConstructor(AccessSpecifier::AS_protected)
@@ -1553,13 +1560,15 @@ BuiltinTypeDeclBuilder::addMipsMember(ResourceDimension 
Dim) {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addTextureLoadMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addTextureLoadMethods(ResourceDimension Dim,
+                                              bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 2 : 1);
   QualType IntTy = AST.IntTy;
-  QualType OffsetTy = AST.getExtVectorType(IntTy, VecSize);
-  QualType LocationTy = AST.getExtVectorType(IntTy, VecSize + 1);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
+  QualType LocationTy = AST.getExtVectorType(IntTy, CoordSize);
   QualType ReturnType = getHandleElementType();
 
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
@@ -1627,23 +1636,24 @@ 
BuiltinTypeDeclBuilder::addByteAddressBufferStoreMethods() {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addSampleMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addSampleMethods(ResourceDimension Dim, bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = getHandleElementType();
   QualType SamplerStateType =
       lookupBuiltinType(SemaRef, "SamplerState", Record->getDeclContext());
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
-  QualType Float2Ty = AST.getExtVectorType(FloatTy, VecSize);
+  QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
-  QualType Int2Ty = AST.getExtVectorType(IntTy, VecSize);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
 
   // T Sample(SamplerState s, float2 location)
   BuiltinTypeMethodBuilder(*this, "Sample", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
                    PH::LastStmt, PH::_1)
@@ -1653,8 +1663,8 @@ 
BuiltinTypeDeclBuilder::addSampleMethods(ResourceDimension Dim) {
   // T Sample(SamplerState s, float2 location, int2 offset)
   BuiltinTypeMethodBuilder(*this, "Sample", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
-      .addParam("Offset", Int2Ty)
+      .addParam("Location", CoordTy)
+      .addParam("Offset", OffsetTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
                    PH::LastStmt, PH::_1, PH::_2)
@@ -1664,8 +1674,8 @@ 
BuiltinTypeDeclBuilder::addSampleMethods(ResourceDimension Dim) {
   // T Sample(SamplerState s, float2 location, int2 offset, float clamp)
   return BuiltinTypeMethodBuilder(*this, "Sample", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
-      .addParam("Offset", Int2Ty)
+      .addParam("Location", CoordTy)
+      .addParam("Offset", OffsetTy)
       .addParam("Clamp", FloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample", ReturnType, PH::Handle,
@@ -1675,23 +1685,25 @@ 
BuiltinTypeDeclBuilder::addSampleMethods(ResourceDimension Dim) {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addSampleBiasMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addSampleBiasMethods(ResourceDimension Dim,
+                                             bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = getHandleElementType();
   QualType SamplerStateType =
       lookupBuiltinType(SemaRef, "SamplerState", Record->getDeclContext());
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
-  QualType Float2Ty = AST.getExtVectorType(FloatTy, VecSize);
+  QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
-  QualType Int2Ty = AST.getExtVectorType(IntTy, VecSize);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
 
   // T SampleBias(SamplerState s, float2 location, float bias)
   BuiltinTypeMethodBuilder(*this, "SampleBias", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("Bias", FloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_bias", ReturnType,
@@ -1702,9 +1714,9 @@ 
BuiltinTypeDeclBuilder::addSampleBiasMethods(ResourceDimension Dim) {
   // T SampleBias(SamplerState s, float2 location, float bias, int2 offset)
   BuiltinTypeMethodBuilder(*this, "SampleBias", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("Bias", FloatTy)
-      .addParam("Offset", Int2Ty)
+      .addParam("Offset", OffsetTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_bias", ReturnType,
                    PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
@@ -1715,9 +1727,9 @@ 
BuiltinTypeDeclBuilder::addSampleBiasMethods(ResourceDimension Dim) {
   // float clamp)
   return BuiltinTypeMethodBuilder(*this, "SampleBias", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("Bias", FloatTy)
-      .addParam("Offset", Int2Ty)
+      .addParam("Offset", OffsetTy)
       .addParam("Clamp", FloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_bias", ReturnType,
@@ -1727,25 +1739,28 @@ 
BuiltinTypeDeclBuilder::addSampleBiasMethods(ResourceDimension Dim) {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addSampleGradMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addSampleGradMethods(ResourceDimension Dim,
+                                             bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = getHandleElementType();
   QualType SamplerStateType =
       lookupBuiltinType(SemaRef, "SamplerState", Record->getDeclContext());
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
-  QualType Float2Ty = AST.getExtVectorType(FloatTy, VecSize);
+  QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
+  QualType OffsetFloatTy = AST.getExtVectorType(FloatTy, OffsetSize);
   QualType IntTy = AST.IntTy;
-  QualType Int2Ty = AST.getExtVectorType(IntTy, VecSize);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
 
   // T SampleGrad(SamplerState s, float2 location, float2 ddx, float2 ddy)
   BuiltinTypeMethodBuilder(*this, "SampleGrad", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
-      .addParam("DDX", Float2Ty)
-      .addParam("DDY", Float2Ty)
+      .addParam("Location", CoordTy)
+      .addParam("DDX", OffsetFloatTy)
+      .addParam("DDY", OffsetFloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_grad", ReturnType,
                    PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
@@ -1756,10 +1771,10 @@ 
BuiltinTypeDeclBuilder::addSampleGradMethods(ResourceDimension Dim) {
   // int2 offset)
   BuiltinTypeMethodBuilder(*this, "SampleGrad", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
-      .addParam("DDX", Float2Ty)
-      .addParam("DDY", Float2Ty)
-      .addParam("Offset", Int2Ty)
+      .addParam("Location", CoordTy)
+      .addParam("DDX", OffsetFloatTy)
+      .addParam("DDY", OffsetFloatTy)
+      .addParam("Offset", OffsetTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_grad", ReturnType,
                    PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3, PH::_4)
@@ -1770,10 +1785,10 @@ 
BuiltinTypeDeclBuilder::addSampleGradMethods(ResourceDimension Dim) {
   // int2 offset, float clamp)
   return BuiltinTypeMethodBuilder(*this, "SampleGrad", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
-      .addParam("DDX", Float2Ty)
-      .addParam("DDY", Float2Ty)
-      .addParam("Offset", Int2Ty)
+      .addParam("Location", CoordTy)
+      .addParam("DDX", OffsetFloatTy)
+      .addParam("DDY", OffsetFloatTy)
+      .addParam("Offset", OffsetTy)
       .addParam("Clamp", FloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_grad", ReturnType,
@@ -1784,23 +1799,25 @@ 
BuiltinTypeDeclBuilder::addSampleGradMethods(ResourceDimension Dim) {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addSampleLevelMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addSampleLevelMethods(ResourceDimension Dim,
+                                              bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = getHandleElementType();
   QualType SamplerStateType =
       lookupBuiltinType(SemaRef, "SamplerState", Record->getDeclContext());
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
-  QualType Float2Ty = AST.getExtVectorType(FloatTy, VecSize);
+  QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
-  QualType Int2Ty = AST.getExtVectorType(IntTy, VecSize);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
 
   // T SampleLevel(SamplerState s, float2 location, float lod)
   BuiltinTypeMethodBuilder(*this, "SampleLevel", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("LOD", FloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_level", ReturnType,
@@ -1811,9 +1828,9 @@ 
BuiltinTypeDeclBuilder::addSampleLevelMethods(ResourceDimension Dim) {
   // T SampleLevel(SamplerState s, float2 location, float lod, int2 offset)
   return BuiltinTypeMethodBuilder(*this, "SampleLevel", ReturnType)
       .addParam("Sampler", SamplerStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("LOD", FloatTy)
-      .addParam("Offset", Int2Ty)
+      .addParam("Offset", OffsetTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_level", ReturnType,
                    PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
@@ -1822,23 +1839,25 @@ 
BuiltinTypeDeclBuilder::addSampleLevelMethods(ResourceDimension Dim) {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addSampleCmpMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addSampleCmpMethods(ResourceDimension Dim,
+                                            bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = AST.FloatTy;
   QualType SamplerComparisonStateType = lookupBuiltinType(
       SemaRef, "SamplerComparisonState", Record->getDeclContext());
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
-  QualType Float2Ty = AST.getExtVectorType(FloatTy, VecSize);
+  QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
-  QualType Int2Ty = AST.getExtVectorType(IntTy, VecSize);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
 
   // T SampleCmp(SamplerComparisonState s, float2 location, float 
compare_value)
   BuiltinTypeMethodBuilder(*this, "SampleCmp", ReturnType)
       .addParam("Sampler", SamplerComparisonStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("CompareValue", FloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_cmp", ReturnType, 
PH::Handle,
@@ -1850,9 +1869,9 @@ 
BuiltinTypeDeclBuilder::addSampleCmpMethods(ResourceDimension Dim) {
   // int2 offset)
   BuiltinTypeMethodBuilder(*this, "SampleCmp", ReturnType)
       .addParam("Sampler", SamplerComparisonStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("CompareValue", FloatTy)
-      .addParam("Offset", Int2Ty)
+      .addParam("Offset", OffsetTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_cmp", ReturnType, 
PH::Handle,
                    PH::LastStmt, PH::_1, PH::_2, PH::_3)
@@ -1863,9 +1882,9 @@ 
BuiltinTypeDeclBuilder::addSampleCmpMethods(ResourceDimension Dim) {
   // int2 offset, float clamp)
   return BuiltinTypeMethodBuilder(*this, "SampleCmp", ReturnType)
       .addParam("Sampler", SamplerComparisonStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("CompareValue", FloatTy)
-      .addParam("Offset", Int2Ty)
+      .addParam("Offset", OffsetTy)
       .addParam("Clamp", FloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_cmp", ReturnType, 
PH::Handle,
@@ -1875,24 +1894,26 @@ 
BuiltinTypeDeclBuilder::addSampleCmpMethods(ResourceDimension Dim) {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addSampleCmpLevelZeroMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addSampleCmpLevelZeroMethods(ResourceDimension Dim,
+                                                     bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = AST.FloatTy;
   QualType SamplerComparisonStateType = lookupBuiltinType(
       SemaRef, "SamplerComparisonState", Record->getDeclContext());
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
-  QualType Float2Ty = AST.getExtVectorType(FloatTy, VecSize);
+  QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
-  QualType Int2Ty = AST.getExtVectorType(IntTy, VecSize);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
 
   // T SampleCmpLevelZero(SamplerComparisonState s, float2 location, float
   // compare_value)
   BuiltinTypeMethodBuilder(*this, "SampleCmpLevelZero", ReturnType)
       .addParam("Sampler", SamplerComparisonStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("CompareValue", FloatTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_cmp_level_zero", ReturnType,
@@ -1904,9 +1925,9 @@ 
BuiltinTypeDeclBuilder::addSampleCmpLevelZeroMethods(ResourceDimension Dim) {
   // compare_value, int2 offset)
   return BuiltinTypeMethodBuilder(*this, "SampleCmpLevelZero", ReturnType)
       .addParam("Sampler", SamplerComparisonStateType)
-      .addParam("Location", Float2Ty)
+      .addParam("Location", CoordTy)
       .addParam("CompareValue", FloatTy)
-      .addParam("Offset", Int2Ty)
+      .addParam("Offset", OffsetTy)
       .accessHandleFieldOnResource(PH::_0)
       .callBuiltin("__builtin_hlsl_resource_sample_cmp_level_zero", ReturnType,
                    PH::Handle, PH::LastStmt, PH::_1, PH::_2, PH::_3)
@@ -2008,18 +2029,19 @@ QualType BuiltinTypeDeclBuilder::getGatherReturnType() {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addGatherMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addGatherMethods(ResourceDimension Dim, bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = getGatherReturnType();
 
   QualType SamplerStateType =
       lookupBuiltinType(SemaRef, "SamplerState", Record->getDeclContext());
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
   QualType LocationTy = AST.FloatTy;
-  QualType Float2Ty = AST.getExtVectorType(LocationTy, VecSize);
+  QualType CoordTy = AST.getExtVectorType(LocationTy, CoordSize);
   QualType IntTy = AST.IntTy;
-  QualType OffsetTy = AST.getExtVectorType(IntTy, VecSize);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
 
   // Overloads for Gather, GatherRed, GatherGreen, GatherBlue, GatherAlpha
@@ -2037,7 +2059,7 @@ 
BuiltinTypeDeclBuilder::addGatherMethods(ResourceDimension Dim) {
     // ret GatherVariant(SamplerState s, float2 location)
     BuiltinTypeMethodBuilder(*this, V.Name, ReturnType)
         .addParam("Sampler", SamplerStateType)
-        .addParam("Location", Float2Ty)
+        .addParam("Location", CoordTy)
         .accessHandleFieldOnResource(PH::_0)
         .callBuiltin("__builtin_hlsl_resource_gather", ReturnType, PH::Handle,
                      PH::LastStmt, PH::_1,
@@ -2047,7 +2069,7 @@ 
BuiltinTypeDeclBuilder::addGatherMethods(ResourceDimension Dim) {
     // ret GatherVariant(SamplerState s, float2 location, int2 offset)
     BuiltinTypeMethodBuilder(*this, V.Name, ReturnType)
         .addParam("Sampler", SamplerStateType)
-        .addParam("Location", Float2Ty)
+        .addParam("Location", CoordTy)
         .addParam("Offset", OffsetTy)
         .accessHandleFieldOnResource(PH::_0)
         .callBuiltin("__builtin_hlsl_resource_gather", ReturnType, PH::Handle,
@@ -2060,18 +2082,20 @@ 
BuiltinTypeDeclBuilder::addGatherMethods(ResourceDimension Dim) {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addGatherCmpMethods(ResourceDimension Dim) {
+BuiltinTypeDeclBuilder::addGatherCmpMethods(ResourceDimension Dim,
+                                            bool IsArray) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = AST.getExtVectorType(AST.FloatTy, 4);
 
   QualType SamplerComparisonStateType = lookupBuiltinType(
       SemaRef, "SamplerComparisonState", Record->getDeclContext());
-  uint32_t VecSize = getResourceDimensions(Dim);
+  uint32_t OffsetSize = getResourceDimensions(Dim);
+  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
-  QualType Float2Ty = AST.getExtVectorType(FloatTy, VecSize);
+  QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
-  QualType Int2Ty = AST.getExtVectorType(IntTy, VecSize);
+  QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
   using PH = BuiltinTypeMethodBuilder::PlaceHolder;
 
   // Overloads for GatherCmp, GatherCmpRed, GatherCmpGreen, GatherCmpBlue,
@@ -2091,7 +2115,7 @@ 
BuiltinTypeDeclBuilder::addGatherCmpMethods(ResourceDimension Dim) {
     // compare_value)
     BuiltinTypeMethodBuilder(*this, V.Name, ReturnType)
         .addParam("Sampler", SamplerComparisonStateType)
-        .addParam("Location", Float2Ty)
+        .addParam("Location", CoordTy)
         .addParam("CompareValue", FloatTy)
         .accessHandleFieldOnResource(PH::_0)
         .callBuiltin("__builtin_hlsl_resource_gather_cmp", ReturnType,
@@ -2103,9 +2127,9 @@ 
BuiltinTypeDeclBuilder::addGatherCmpMethods(ResourceDimension Dim) {
     // compare_value, int2 offset)
     BuiltinTypeMethodBuilder(*this, V.Name, ReturnType)
         .addParam("Sampler", SamplerComparisonStateType)
-        .addParam("Location", Float2Ty)
+        .addParam("Location", CoordTy)
         .addParam("CompareValue", FloatTy)
-        .addParam("Offset", Int2Ty)
+        .addParam("Offset", OffsetTy)
         .accessHandleFieldOnResource(PH::_0)
         .callBuiltin("__builtin_hlsl_resource_gather_cmp", ReturnType,
                      PH::Handle, PH::LastStmt, PH::_1, PH::_2,
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h 
b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index f8fc2eeb3af55..41cb1d47a2ee7 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -77,15 +77,17 @@ class BuiltinTypeDeclBuilder {
 
   BuiltinTypeDeclBuilder &
   addBufferHandles(ResourceClass RC, bool IsROV, bool RawBuffer,
-                   bool HasCounter,
+                   bool HasCounter, bool IsArray,
                    AccessSpecifier Access = AccessSpecifier::AS_private);
   BuiltinTypeDeclBuilder &
-  addTextureHandle(ResourceClass RC, bool IsROV, ResourceDimension RD,
+  addTextureHandle(ResourceClass RC, bool IsROV, bool IsArray,
+                   ResourceDimension RD,
                    AccessSpecifier Access = AccessSpecifier::AS_private);
   BuiltinTypeDeclBuilder &addSamplerHandle();
   BuiltinTypeDeclBuilder &addConstantBufferConversionToType();
-  BuiltinTypeDeclBuilder &addArraySubscriptOperators(
-      ResourceDimension Dim = ResourceDimension::Unknown);
+  BuiltinTypeDeclBuilder &
+  addArraySubscriptOperators(ResourceDimension Dim = 
ResourceDimension::Unknown,
+                             bool IsArray = false);
 
   // Builtin types constructors
   BuiltinTypeDeclBuilder &addDefaultHandleConstructor(
@@ -100,18 +102,27 @@ class BuiltinTypeDeclBuilder {
 
   // Builtin types methods
   BuiltinTypeDeclBuilder &addLoadMethods();
-  BuiltinTypeDeclBuilder &addTextureLoadMethods(ResourceDimension Dim);
+  BuiltinTypeDeclBuilder &addTextureLoadMethods(ResourceDimension Dim,
+                                                bool IsArray = false);
   BuiltinTypeDeclBuilder &addByteAddressBufferLoadMethods();
   BuiltinTypeDeclBuilder &addByteAddressBufferStoreMethods();
-  BuiltinTypeDeclBuilder &addSampleMethods(ResourceDimension Dim);
-  BuiltinTypeDeclBuilder &addSampleBiasMethods(ResourceDimension Dim);
-  BuiltinTypeDeclBuilder &addSampleGradMethods(ResourceDimension Dim);
-  BuiltinTypeDeclBuilder &addSampleLevelMethods(ResourceDimension Dim);
-  BuiltinTypeDeclBuilder &addSampleCmpMethods(ResourceDimension Dim);
-  BuiltinTypeDeclBuilder &addSampleCmpLevelZeroMethods(ResourceDimension Dim);
+  BuiltinTypeDeclBuilder &addSampleMethods(ResourceDimension Dim,
+                                           bool IsArray = false);
+  BuiltinTypeDeclBuilder &addSampleBiasMethods(ResourceDimension Dim,
+                                               bool IsArray = false);
+  BuiltinTypeDeclBuilder &addSampleGradMethods(ResourceDimension Dim,
+                                               bool IsArray = false);
+  BuiltinTypeDeclBuilder &addSampleLevelMethods(ResourceDimension Dim,
+                                                bool IsArray = false);
+  BuiltinTypeDeclBuilder &addSampleCmpMethods(ResourceDimension Dim,
+                                              bool IsArray = false);
+  BuiltinTypeDeclBuilder &addSampleCmpLevelZeroMethods(ResourceDimension Dim,
+                                                       bool IsArray = false);
   BuiltinTypeDeclBuilder &addCalculateLodMethods(ResourceDimension Dim);
-  BuiltinTypeDeclBuilder &addGatherMethods(ResourceDimension Dim);
-  BuiltinTypeDeclBuilder &addGatherCmpMethods(ResourceDimension Dim);
+  BuiltinTypeDeclBuilder &addGatherMethods(ResourceDimension Dim,
+                                           bool IsArray = false);
+  BuiltinTypeDeclBuilder &addGatherCmpMethods(ResourceDimension Dim,
+                                              bool IsArray = false);
   BuiltinTypeDeclBuilder &addIncrementCounterMethod();
   BuiltinTypeDeclBuilder &addDecrementCounterMethod();
   BuiltinTypeDeclBuilder &addHandleAccessFunction(DeclarationName &Name,
@@ -138,7 +149,7 @@ class BuiltinTypeDeclBuilder {
   BuiltinTypeDeclBuilder &
   addResourceMember(StringRef MemberName, ResourceClass RC,
                     ResourceDimension RD, bool IsROV, bool RawBuffer,
-                    bool IsCounter, QualType ElementTy,
+                    bool IsCounter, bool IsArray, QualType ElementTy,
                     AccessSpecifier Access = AccessSpecifier::AS_private);
   BuiltinTypeDeclBuilder &addFriend(CXXRecordDecl *Friend);
   CXXRecordDecl *addPrivateNestedRecord(StringRef Name);
@@ -146,7 +157,7 @@ class BuiltinTypeDeclBuilder {
   CXXRecordDecl *addMipsType(ResourceDimension Dim, QualType ReturnType);
   BuiltinTypeDeclBuilder &
   addHandleMember(ResourceClass RC, ResourceDimension RD, bool IsROV,
-                  bool RawBuffer, QualType ElementTy,
+                  bool RawBuffer, bool IsArray, QualType ElementTy,
                   AccessSpecifier Access = AccessSpecifier::AS_private);
   BuiltinTypeDeclBuilder &
   addCounterHandleMember(ResourceClass RC, bool IsROV, bool RawBuffer,
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp 
b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index e57bad6f5c548..bba537864b9b1 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -234,7 +234,7 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl 
*Decl, Sema &S,
                                               ResourceClass RC, bool IsROV,
                                               bool RawBuffer, bool HasCounter) 
{
   return BuiltinTypeDeclBuilder(S, Decl)
-      .addBufferHandles(RC, IsROV, RawBuffer, HasCounter)
+      .addBufferHandles(RC, IsROV, RawBuffer, HasCounter, /*IsArray=*/false)
       .addDefaultHandleConstructor()
       .addCopyConstructor()
       .addCopyAssignmentOperator()
@@ -254,26 +254,27 @@ static BuiltinTypeDeclBuilder 
setupSamplerType(CXXRecordDecl *Decl, Sema &S) {
 /// Set up common members and attributes for texture types
 static BuiltinTypeDeclBuilder setupTextureType(CXXRecordDecl *Decl, Sema &S,
                                                ResourceClass RC, bool IsROV,
+                                               bool IsArray,
                                                ResourceDimension Dim) {
   return BuiltinTypeDeclBuilder(S, Decl)
-      .addTextureHandle(RC, IsROV, Dim)
-      .addTextureLoadMethods(Dim)
-      .addArraySubscriptOperators(Dim)
+      .addTextureHandle(RC, IsROV, IsArray, Dim)
+      .addTextureLoadMethods(Dim, IsArray)
+      .addArraySubscriptOperators(Dim, IsArray)
       .addMipsMember(Dim)
       .addDefaultHandleConstructor()
       .addCopyConstructor()
       .addCopyAssignmentOperator()
       .addStaticInitializationFunctions(false)
-      .addSampleMethods(Dim)
-      .addSampleBiasMethods(Dim)
-      .addSampleGradMethods(Dim)
-      .addSampleLevelMethods(Dim)
-      .addSampleCmpMethods(Dim)
-      .addSampleCmpLevelZeroMethods(Dim)
+      .addSampleMethods(Dim, IsArray)
+      .addSampleBiasMethods(Dim, IsArray)
+      .addSampleGradMethods(Dim, IsArray)
+      .addSampleLevelMethods(Dim, IsArray)
+      .addSampleCmpMethods(Dim, IsArray)
+      .addSampleCmpLevelZeroMethods(Dim, IsArray)
       .addCalculateLodMethods(Dim)
       .addGetDimensionsMethods(Dim)
-      .addGatherMethods(Dim)
-      .addGatherCmpMethods(Dim);
+      .addGatherMethods(Dim, IsArray)
+      .addGatherCmpMethods(Dim, IsArray);
 }
 
 // Add a partial specialization for a template. The `TextureTemplate` is
@@ -673,7 +674,7 @@ void 
HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
 
   onCompletion(Decl, [this](CXXRecordDecl *Decl) {
     setupTextureType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
-                     ResourceDimension::Dim2D)
+                     /*IsArray=*/false, ResourceDimension::Dim2D)
         .completeDefinition();
   });
 
@@ -681,7 +682,7 @@ void 
HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
       *SemaPtr, HLSLNamespace, Decl->getDescribedClassTemplate());
   onCompletion(PartialSpec, [this](CXXRecordDecl *Decl) {
     setupTextureType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
-                     ResourceDimension::Dim2D)
+                     /*IsArray=*/false, ResourceDimension::Dim2D)
         .completeDefinition();
   });
 }
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 04148fcd008d5..bebd8228aba0c 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2141,6 +2141,13 @@ bool clang::CreateHLSLAttributedResourceType(
       }
       ResAttrs.RawBuffer = true;
       break;
+    case attr::HLSLArrayed:
+      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;
@@ -3593,7 +3600,8 @@ static bool CheckIndexType(Sema *S, CallExpr *TheCall, 
unsigned IndexArgIndex) {
 
   unsigned int ExpectedDim = 1;
   if (ResAttrs.ResourceDimension != llvm::dxil::ResourceDimension::Unknown)
-    ExpectedDim = getResourceDimensions(ResAttrs.ResourceDimension);
+    ExpectedDim = getResourceDimensions(ResAttrs.ResourceDimension) +
+                  (ResAttrs.IsArray ? 1 : 0);
 
   if (ActualDim != ExpectedDim) {
     S->Diag(TheCall->getArg(IndexArgIndex)->getBeginLoc(),
@@ -3648,7 +3656,8 @@ static bool CheckVectorElementCount(Sema *S, QualType 
PassedType,
 
 enum class SampleKind { Sample, Bias, Grad, Level, Cmp, CmpLevelZero };
 
-static bool CheckTextureSamplerAndLocation(Sema &S, CallExpr *TheCall) {
+static bool CheckTextureSamplerAndLocation(Sema &S, CallExpr *TheCall,
+                                           bool IncludeArraySlice = true) {
   // Check the texture handle.
   if (CheckResourceHandle(&S, TheCall, 0,
                           [](const HLSLAttributedResourceType *ResType) {
@@ -3670,7 +3679,8 @@ static bool CheckTextureSamplerAndLocation(Sema &S, 
CallExpr *TheCall) {
 
   // Check the location.
   unsigned ExpectedDim =
-      getResourceDimensions(ResourceTy->getAttrs().ResourceDimension);
+      getResourceDimensions(ResourceTy->getAttrs().ResourceDimension) +
+      (IncludeArraySlice && ResourceTy->getAttrs().IsArray ? 1 : 0);
   if (CheckVectorElementCount(&S, TheCall->getArg(2)->getType(),
                               S.Context.FloatTy, ExpectedDim,
                               TheCall->getBeginLoc()))
@@ -3683,7 +3693,9 @@ static bool CheckCalculateLodBuiltin(Sema &S, CallExpr 
*TheCall) {
   if (S.checkArgCount(TheCall, 3))
     return true;
 
-  if (CheckTextureSamplerAndLocation(S, TheCall))
+  // CalculateLevelOfDetail location uses resource dimension only (e.g. float2
+  // for 2D), not an extra array slice component like Sample/Gather.
+  if (CheckTextureSamplerAndLocation(S, TheCall, /*IncludeArraySlice=*/false))
     return true;
 
   TheCall->setType(S.Context.FloatTy);
@@ -3789,11 +3801,12 @@ static bool CheckLoadLevelBuiltin(Sema &S, CallExpr 
*TheCall) {
   auto *ResourceTy =
       TheCall->getArg(0)->getType()->castAs<HLSLAttributedResourceType>();
 
-  // Check the location + lod (int3 for Texture2D).
-  unsigned ExpectedDim =
+  // Check the location + lod (int3 for Texture2D, int4 for Texture2DArray).
+  unsigned ResourceDim =
       getResourceDimensions(ResourceTy->getAttrs().ResourceDimension);
+  unsigned LocationDim = ResourceDim + (ResourceTy->getAttrs().IsArray ? 1 : 
0);
   QualType CoordLODTy = TheCall->getArg(1)->getType();
-  if (CheckVectorElementCount(&S, CoordLODTy, S.Context.IntTy, ExpectedDim + 1,
+  if (CheckVectorElementCount(&S, CoordLODTy, S.Context.IntTy, LocationDim + 1,
                               TheCall->getArg(1)->getBeginLoc()))
     return true;
 
@@ -3806,10 +3819,10 @@ static bool CheckLoadLevelBuiltin(Sema &S, CallExpr 
*TheCall) {
     return true;
   }
 
-  // Check the offset operand.
+  // Check the offset operand (int2 for 2D textures; no array slice).
   if (TheCall->getNumArgs() > 2) {
     if (CheckVectorElementCount(&S, TheCall->getArg(2)->getType(),
-                                S.Context.IntTy, ExpectedDim,
+                                S.Context.IntTy, ResourceDim,
                                 TheCall->getArg(2)->getBeginLoc()))
       return true;
   }

>From 4d94b511f6466613343c15da545c6e5a1e0b2f41 Mon Sep 17 00:00:00 2001
From: Tim Corringham <[email protected]>
Date: Wed, 3 Jun 2026 15:45:16 +0100
Subject: [PATCH 2/5] Change IsArray to IsArrayed

Changed HLSLArrayed to HLSLIsArrayed, and IsArray to IsArrayed,
throughout to make naming more consistent. No functional change.
---
 clang/include/clang/AST/TypeBase.h            | 12 +--
 clang/include/clang/AST/TypeProperties.td     |  6 +-
 clang/include/clang/Basic/Attr.td             |  2 +-
 clang/lib/AST/ItaniumMangle.cpp               |  2 +-
 clang/lib/AST/TypePrinter.cpp                 |  4 +-
 clang/lib/CodeGen/Targets/DirectX.cpp         |  6 +-
 clang/lib/CodeGen/Targets/SPIR.cpp            |  2 +-
 clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 75 ++++++++++---------
 clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h   | 28 +++----
 clang/lib/Sema/HLSLExternalSemaSource.cpp     | 30 ++++----
 clang/lib/Sema/SemaHLSL.cpp                   | 13 ++--
 11 files changed, 91 insertions(+), 89 deletions(-)

diff --git a/clang/include/clang/AST/TypeBase.h 
b/clang/include/clang/AST/TypeBase.h
index 3b775eea6f4bf..521549e0c11c1 100644
--- a/clang/include/clang/AST/TypeBase.h
+++ b/clang/include/clang/AST/TypeBase.h
@@ -6848,15 +6848,15 @@ class HLSLAttributedResourceType : public Type, public 
llvm::FoldingSetNode {
     uint8_t IsCounter : 1;
 
     LLVM_PREFERRED_TYPE(bool)
-    uint8_t IsArray : 1;
+    uint8_t IsArrayed : 1;
 
     Attributes(llvm::dxil::ResourceClass ResourceClass,
                llvm::dxil::ResourceDimension ResourceDimension,
                bool IsROV = false, bool RawBuffer = false,
-               bool IsCounter = false, bool IsArray = false)
+               bool IsCounter = false, bool IsArrayed = false)
         : ResourceClass(ResourceClass), ResourceDimension(ResourceDimension),
           IsROV(IsROV), RawBuffer(RawBuffer), IsCounter(IsCounter),
-          IsArray(IsArray) {}
+          IsArrayed(IsArrayed) {}
 
     Attributes(llvm::dxil::ResourceClass ResourceClass)
         : Attributes(ResourceClass, llvm::dxil::ResourceDimension::Unknown) {}
@@ -6868,9 +6868,9 @@ class HLSLAttributedResourceType : public Type, public 
llvm::FoldingSetNode {
 
     friend bool operator==(const Attributes &LHS, const Attributes &RHS) {
       return std::tie(LHS.ResourceClass, LHS.ResourceDimension, LHS.IsROV,
-                      LHS.RawBuffer, LHS.IsCounter, LHS.IsArray) ==
+                      LHS.RawBuffer, LHS.IsCounter, LHS.IsArrayed) ==
              std::tie(RHS.ResourceClass, RHS.ResourceDimension, RHS.IsROV,
-                      RHS.RawBuffer, RHS.IsCounter, RHS.IsArray);
+                      RHS.RawBuffer, RHS.IsCounter, RHS.IsArrayed);
     }
     friend bool operator!=(const Attributes &LHS, const Attributes &RHS) {
       return !(LHS == RHS);
@@ -6915,7 +6915,7 @@ class HLSLAttributedResourceType : public Type, public 
llvm::FoldingSetNode {
     ID.AddBoolean(Attrs.IsROV);
     ID.AddBoolean(Attrs.RawBuffer);
     ID.AddBoolean(Attrs.IsCounter);
-    ID.AddBoolean(Attrs.IsArray);
+    ID.AddBoolean(Attrs.IsArrayed);
   }
 
   static bool classof(const Type *T) {
diff --git a/clang/include/clang/AST/TypeProperties.td 
b/clang/include/clang/AST/TypeProperties.td
index f16c10da430f9..3f0e1e9d4603e 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -681,14 +681,14 @@ let Class = HLSLAttributedResourceType in {
   def : Property<"containedTy", QualType> {
     let Read = [{ node->getContainedType() }];
   }
-  def : Property<"isArray", Bool> {
-    let Read = [{ node->getAttrs().IsArray }];
+  def : Property<"isArrayed", Bool> {
+    let Read = [{ node->getAttrs().IsArrayed }];
   }
   def : Creator<[{
     HLSLAttributedResourceType::Attributes attrs(
         static_cast<llvm::dxil::ResourceClass>(resClass),
         static_cast<llvm::dxil::ResourceDimension>(resDimension), isROV,
-        rawBuffer, isCounter, isArray);
+        rawBuffer, isCounter, isArrayed);
     return ctx.getHLSLAttributedResourceType(wrappedTy, containedTy, attrs);
   }]>;
 }
diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index e64fd925b78a6..1ada030e5b8c8 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -5172,7 +5172,7 @@ def HLSLShader : InheritableAttr {
 }];
 }
 
-def HLSLArrayed : TypeAttr {
+def HLSLIsArrayed : TypeAttr {
   let Spellings = [CXX11<"hlsl", "is_arrayed">];
   let LangOpts = [HLSL];
   let Documentation = [InternalOnly];
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index f0527a4aa77cf..bbfb2793e5a1a 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -4677,7 +4677,7 @@ void CXXNameMangler::mangleType(const 
HLSLAttributedResourceType *T) {
     Str += "_Raw";
   if (Attrs.IsCounter)
     Str += "_Counter";
-  if (Attrs.IsArray)
+  if (Attrs.IsArrayed)
     Str += "_Array";
   if (T->hasContainedType())
     Str += "_CT";
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index f82c2219e4f76..0341b9b1f63fb 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1990,7 +1990,7 @@ void TypePrinter::printAttributedAfter(const 
AttributedType *T,
   case attr::HLSLContainedType:
   case attr::HLSLIsCounter:
   case attr::HLSLResourceDimension:
-  case attr::HLSLArrayed:
+  case attr::HLSLIsArrayed:
     llvm_unreachable("HLSL resource type attributes handled separately");
 
   case attr::OpenCLPrivateAddressSpace:
@@ -2163,7 +2163,7 @@ void TypePrinter::printHLSLAttributedResourceAfter(
     OS << " [[hlsl::raw_buffer]]";
   if (Attrs.IsCounter)
     OS << " [[hlsl::is_counter]]";
-  if (Attrs.IsArray)
+  if (Attrs.IsArrayed)
     OS << " [[hlsl::is_arrayed]]";
 
   QualType ContainedTy = T->getContainedType();
diff --git a/clang/lib/CodeGen/Targets/DirectX.cpp 
b/clang/lib/CodeGen/Targets/DirectX.cpp
index 2b2567849ef93..52868dd94c123 100644
--- a/clang/lib/CodeGen/Targets/DirectX.cpp
+++ b/clang/lib/CodeGen/Targets/DirectX.cpp
@@ -94,13 +94,13 @@ llvm::Type *DirectXTargetCodeGenInfo::getHLSLType(
       llvm::dxil::ResourceKind RK = llvm::dxil::ResourceKind::Invalid;
       switch (ResAttrs.ResourceDimension) {
       case llvm::dxil::ResourceDimension::Dim1D:
-        if (ResAttrs.IsArray)
+        if (ResAttrs.IsArrayed)
           RK = llvm::dxil::ResourceKind::Texture1DArray;
         else
           RK = llvm::dxil::ResourceKind::Texture1D;
         break;
       case llvm::dxil::ResourceDimension::Dim2D:
-        if (ResAttrs.IsArray)
+        if (ResAttrs.IsArrayed)
           RK = llvm::dxil::ResourceKind::Texture2DArray;
         else
           RK = llvm::dxil::ResourceKind::Texture2D;
@@ -109,7 +109,7 @@ llvm::Type *DirectXTargetCodeGenInfo::getHLSLType(
         RK = llvm::dxil::ResourceKind::Texture3D;
         break;
       case llvm::dxil::ResourceDimension::Cube:
-        if (ResAttrs.IsArray)
+        if (ResAttrs.IsArrayed)
           RK = llvm::dxil::ResourceKind::TextureCubeArray;
         else
           RK = llvm::dxil::ResourceKind::TextureCube;
diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp 
b/clang/lib/CodeGen/Targets/SPIR.cpp
index 88e7c7f9482a4..f2a7bcfad2896 100644
--- a/clang/lib/CodeGen/Targets/SPIR.cpp
+++ b/clang/lib/CodeGen/Targets/SPIR.cpp
@@ -922,7 +922,7 @@ llvm::Type 
*CommonSPIRTargetCodeGenInfo::getSPIRVImageTypeFromHLSLResource(
   IntParams[1] = 2;
 
   // Arrayed
-  IntParams[2] = static_cast<unsigned>(attributes.IsArray);
+  IntParams[2] = static_cast<unsigned>(attributes.IsArrayed);
 
   // MS
   IntParams[3] = 0;
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp 
b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index 34dd3896943eb..1a0b39a27ca48 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -1033,12 +1033,11 @@ BuiltinTypeDeclBuilder::addMemberVariable(StringRef 
Name, QualType Type,
   return *this;
 }
 
-BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addBufferHandles(ResourceClass RC, bool IsROV,
-                                         bool RawBuffer, bool HasCounter,
-                                         bool IsArray, AccessSpecifier Access) 
{
+BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addBufferHandles(
+    ResourceClass RC, bool IsROV, bool RawBuffer, bool HasCounter,
+    bool IsArrayed, AccessSpecifier Access) {
   QualType ElementTy = getHandleElementType();
-  addHandleMember(RC, ResourceDimension::Unknown, IsROV, RawBuffer, IsArray,
+  addHandleMember(RC, ResourceDimension::Unknown, IsROV, RawBuffer, IsArrayed,
                   ElementTy, Access);
   if (HasCounter)
     addCounterHandleMember(RC, IsROV, RawBuffer, ElementTy, Access);
@@ -1047,16 +1046,16 @@ BuiltinTypeDeclBuilder::addBufferHandles(ResourceClass 
RC, bool IsROV,
 
 BuiltinTypeDeclBuilder &
 BuiltinTypeDeclBuilder::addTextureHandle(ResourceClass RC, bool IsROV,
-                                         bool IsArray, ResourceDimension RD,
+                                         bool IsArrayed, ResourceDimension RD,
                                          AccessSpecifier Access) {
-  addHandleMember(RC, RD, IsROV, /*RawBuffer=*/false, IsArray,
+  addHandleMember(RC, RD, IsROV, /*RawBuffer=*/false, IsArrayed,
                   getHandleElementType(), Access);
   return *this;
 }
 
 BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addSamplerHandle() {
   addHandleMember(ResourceClass::Sampler, ResourceDimension::Unknown,
-                  /*IsROV=*/false, /*RawBuffer=*/false, /*IsArray=*/false,
+                  /*IsROV=*/false, /*RawBuffer=*/false, /*IsArrayed=*/false,
                   getHandleElementType());
   return *this;
 }
@@ -1112,9 +1111,9 @@ CXXRecordDecl 
*BuiltinTypeDeclBuilder::addPrivateNestedRecord(StringRef Name) {
 
 BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addHandleMember(
     ResourceClass RC, ResourceDimension RD, bool IsROV, bool RawBuffer,
-    bool IsArray, QualType ElementTy, AccessSpecifier Access) {
+    bool IsArrayed, QualType ElementTy, AccessSpecifier Access) {
   return addResourceMember("__handle", RC, RD, IsROV, RawBuffer,
-                           /*IsCounter=*/false, IsArray, ElementTy, Access);
+                           /*IsCounter=*/false, IsArrayed, ElementTy, Access);
 }
 
 BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addCounterHandleMember(
@@ -1122,12 +1121,12 @@ BuiltinTypeDeclBuilder 
&BuiltinTypeDeclBuilder::addCounterHandleMember(
     AccessSpecifier Access) {
   return addResourceMember("__counter_handle", RC, ResourceDimension::Unknown,
                            IsROV, RawBuffer, /*IsCounter=*/true,
-                           /*IsArray=*/false, ElementTy, Access);
+                           /*IsArrayed=*/false, ElementTy, Access);
 }
 
 BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addResourceMember(
     StringRef MemberName, ResourceClass RC, ResourceDimension RD, bool IsROV,
-    bool RawBuffer, bool IsCounter, bool IsArray, QualType ElementTy,
+    bool RawBuffer, bool IsCounter, bool IsArrayed, QualType ElementTy,
     AccessSpecifier Access) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
 
@@ -1152,8 +1151,8 @@ BuiltinTypeDeclBuilder 
&BuiltinTypeDeclBuilder::addResourceMember(
           : nullptr};
   if (IsCounter)
     Attrs.push_back(HLSLIsCounterAttr::CreateImplicit(Ctx));
-  if (IsArray)
-    Attrs.push_back(HLSLArrayedAttr::CreateImplicit(Ctx));
+  if (IsArrayed)
+    Attrs.push_back(HLSLIsArrayedAttr::CreateImplicit(Ctx));
 
   if (CreateHLSLAttributedResourceType(SemaRef, Ctx.HLSLResourceTy, Attrs,
                                        AttributedResTy))
@@ -1409,13 +1408,13 @@ 
BuiltinTypeDeclBuilder::addCopyAssignmentOperator(AccessSpecifier Access) {
 
 BuiltinTypeDeclBuilder &
 BuiltinTypeDeclBuilder::addArraySubscriptOperators(ResourceDimension Dim,
-                                                   bool IsArray) {
+                                                   bool IsArrayed) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
 
   uint32_t VecSize = 1;
   if (Dim != ResourceDimension::Unknown)
-    VecSize = getResourceDimensions(Dim) + (IsArray ? 1 : 0);
+    VecSize = getResourceDimensions(Dim) + (IsArrayed ? 1 : 0);
 
   QualType IndexTy = VecSize > 1
                          ? AST.getExtVectorType(AST.UnsignedIntTy, VecSize)
@@ -1451,7 +1450,7 @@ CXXRecordDecl 
*BuiltinTypeDeclBuilder::addMipsSliceType(ResourceDimension Dim,
                                                         QualType ReturnType) {
   ASTContext &AST = Record->getASTContext();
   uint32_t VecSize =
-      getResourceDimensions(Dim) + (getResourceAttrs().IsArray ? 1 : 0);
+      getResourceDimensions(Dim) + (getResourceAttrs().IsArrayed ? 1 : 0);
   QualType IntTy = AST.IntTy;
   QualType IndexTy = VecSize > 1 ? AST.getExtVectorType(IntTy, VecSize) : 
IntTy;
   QualType CoordLevelTy = AST.getExtVectorType(IntTy, VecSize + 1);
@@ -1465,7 +1464,7 @@ CXXRecordDecl 
*BuiltinTypeDeclBuilder::addMipsSliceType(ResourceDimension Dim,
   MipsSliceBuilder.addFriend(Record)
       .addHandleMember(getResourceAttrs().ResourceClass, Dim,
                        getResourceAttrs().IsROV, /*RawBuffer=*/false,
-                       getResourceAttrs().IsArray, ReturnType,
+                       getResourceAttrs().IsArrayed, ReturnType,
                        AccessSpecifier::AS_public)
       .addMemberVariable("__level", IntTy, {}, AccessSpecifier::AS_public)
       .addDefaultHandleConstructor(AccessSpecifier::AS_protected)
@@ -1509,7 +1508,7 @@ CXXRecordDecl 
*BuiltinTypeDeclBuilder::addMipsType(ResourceDimension Dim,
   MipsBuilder.addFriend(Record)
       .addHandleMember(getResourceAttrs().ResourceClass, Dim,
                        getResourceAttrs().IsROV, /*RawBuffer=*/false,
-                       getResourceAttrs().IsArray, ReturnType,
+                       getResourceAttrs().IsArrayed, ReturnType,
                        AccessSpecifier::AS_public)
       .addDefaultHandleConstructor(AccessSpecifier::AS_protected)
       .addCopyConstructor(AccessSpecifier::AS_protected)
@@ -1561,11 +1560,11 @@ BuiltinTypeDeclBuilder::addMipsMember(ResourceDimension 
Dim) {
 
 BuiltinTypeDeclBuilder &
 BuiltinTypeDeclBuilder::addTextureLoadMethods(ResourceDimension Dim,
-                                              bool IsArray) {
+                                              bool IsArrayed) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   uint32_t OffsetSize = getResourceDimensions(Dim);
-  uint32_t CoordSize = OffsetSize + (IsArray ? 2 : 1);
+  uint32_t CoordSize = OffsetSize + (IsArrayed ? 2 : 1);
   QualType IntTy = AST.IntTy;
   QualType OffsetTy = AST.getExtVectorType(IntTy, OffsetSize);
   QualType LocationTy = AST.getExtVectorType(IntTy, CoordSize);
@@ -1636,14 +1635,15 @@ 
BuiltinTypeDeclBuilder::addByteAddressBufferStoreMethods() {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addSampleMethods(ResourceDimension Dim, bool IsArray) {
+BuiltinTypeDeclBuilder::addSampleMethods(ResourceDimension Dim,
+                                         bool IsArrayed) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = getHandleElementType();
   QualType SamplerStateType =
       lookupBuiltinType(SemaRef, "SamplerState", Record->getDeclContext());
   uint32_t OffsetSize = getResourceDimensions(Dim);
-  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
+  uint32_t CoordSize = OffsetSize + (IsArrayed ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
   QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
@@ -1686,14 +1686,14 @@ 
BuiltinTypeDeclBuilder::addSampleMethods(ResourceDimension Dim, bool IsArray) {
 
 BuiltinTypeDeclBuilder &
 BuiltinTypeDeclBuilder::addSampleBiasMethods(ResourceDimension Dim,
-                                             bool IsArray) {
+                                             bool IsArrayed) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = getHandleElementType();
   QualType SamplerStateType =
       lookupBuiltinType(SemaRef, "SamplerState", Record->getDeclContext());
   uint32_t OffsetSize = getResourceDimensions(Dim);
-  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
+  uint32_t CoordSize = OffsetSize + (IsArrayed ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
   QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
@@ -1740,14 +1740,14 @@ 
BuiltinTypeDeclBuilder::addSampleBiasMethods(ResourceDimension Dim,
 
 BuiltinTypeDeclBuilder &
 BuiltinTypeDeclBuilder::addSampleGradMethods(ResourceDimension Dim,
-                                             bool IsArray) {
+                                             bool IsArrayed) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = getHandleElementType();
   QualType SamplerStateType =
       lookupBuiltinType(SemaRef, "SamplerState", Record->getDeclContext());
   uint32_t OffsetSize = getResourceDimensions(Dim);
-  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
+  uint32_t CoordSize = OffsetSize + (IsArrayed ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
   QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType OffsetFloatTy = AST.getExtVectorType(FloatTy, OffsetSize);
@@ -1800,14 +1800,14 @@ 
BuiltinTypeDeclBuilder::addSampleGradMethods(ResourceDimension Dim,
 
 BuiltinTypeDeclBuilder &
 BuiltinTypeDeclBuilder::addSampleLevelMethods(ResourceDimension Dim,
-                                              bool IsArray) {
+                                              bool IsArrayed) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = getHandleElementType();
   QualType SamplerStateType =
       lookupBuiltinType(SemaRef, "SamplerState", Record->getDeclContext());
   uint32_t OffsetSize = getResourceDimensions(Dim);
-  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
+  uint32_t CoordSize = OffsetSize + (IsArrayed ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
   QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
@@ -1840,14 +1840,14 @@ 
BuiltinTypeDeclBuilder::addSampleLevelMethods(ResourceDimension Dim,
 
 BuiltinTypeDeclBuilder &
 BuiltinTypeDeclBuilder::addSampleCmpMethods(ResourceDimension Dim,
-                                            bool IsArray) {
+                                            bool IsArrayed) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = AST.FloatTy;
   QualType SamplerComparisonStateType = lookupBuiltinType(
       SemaRef, "SamplerComparisonState", Record->getDeclContext());
   uint32_t OffsetSize = getResourceDimensions(Dim);
-  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
+  uint32_t CoordSize = OffsetSize + (IsArrayed ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
   QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
@@ -1895,14 +1895,14 @@ 
BuiltinTypeDeclBuilder::addSampleCmpMethods(ResourceDimension Dim,
 
 BuiltinTypeDeclBuilder &
 BuiltinTypeDeclBuilder::addSampleCmpLevelZeroMethods(ResourceDimension Dim,
-                                                     bool IsArray) {
+                                                     bool IsArrayed) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = AST.FloatTy;
   QualType SamplerComparisonStateType = lookupBuiltinType(
       SemaRef, "SamplerComparisonState", Record->getDeclContext());
   uint32_t OffsetSize = getResourceDimensions(Dim);
-  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
+  uint32_t CoordSize = OffsetSize + (IsArrayed ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
   QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
@@ -2029,7 +2029,8 @@ QualType BuiltinTypeDeclBuilder::getGatherReturnType() {
 }
 
 BuiltinTypeDeclBuilder &
-BuiltinTypeDeclBuilder::addGatherMethods(ResourceDimension Dim, bool IsArray) {
+BuiltinTypeDeclBuilder::addGatherMethods(ResourceDimension Dim,
+                                         bool IsArrayed) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = getGatherReturnType();
@@ -2037,7 +2038,7 @@ 
BuiltinTypeDeclBuilder::addGatherMethods(ResourceDimension Dim, bool IsArray) {
   QualType SamplerStateType =
       lookupBuiltinType(SemaRef, "SamplerState", Record->getDeclContext());
   uint32_t OffsetSize = getResourceDimensions(Dim);
-  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
+  uint32_t CoordSize = OffsetSize + (IsArrayed ? 1 : 0);
   QualType LocationTy = AST.FloatTy;
   QualType CoordTy = AST.getExtVectorType(LocationTy, CoordSize);
   QualType IntTy = AST.IntTy;
@@ -2083,7 +2084,7 @@ 
BuiltinTypeDeclBuilder::addGatherMethods(ResourceDimension Dim, bool IsArray) {
 
 BuiltinTypeDeclBuilder &
 BuiltinTypeDeclBuilder::addGatherCmpMethods(ResourceDimension Dim,
-                                            bool IsArray) {
+                                            bool IsArrayed) {
   assert(!Record->isCompleteDefinition() && "record is already complete");
   ASTContext &AST = Record->getASTContext();
   QualType ReturnType = AST.getExtVectorType(AST.FloatTy, 4);
@@ -2091,7 +2092,7 @@ 
BuiltinTypeDeclBuilder::addGatherCmpMethods(ResourceDimension Dim,
   QualType SamplerComparisonStateType = lookupBuiltinType(
       SemaRef, "SamplerComparisonState", Record->getDeclContext());
   uint32_t OffsetSize = getResourceDimensions(Dim);
-  uint32_t CoordSize = OffsetSize + (IsArray ? 1 : 0);
+  uint32_t CoordSize = OffsetSize + (IsArrayed ? 1 : 0);
   QualType FloatTy = AST.FloatTy;
   QualType CoordTy = AST.getExtVectorType(FloatTy, CoordSize);
   QualType IntTy = AST.IntTy;
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h 
b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index 41cb1d47a2ee7..49b149fb92794 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -77,17 +77,17 @@ class BuiltinTypeDeclBuilder {
 
   BuiltinTypeDeclBuilder &
   addBufferHandles(ResourceClass RC, bool IsROV, bool RawBuffer,
-                   bool HasCounter, bool IsArray,
+                   bool HasCounter, bool IsArrayed,
                    AccessSpecifier Access = AccessSpecifier::AS_private);
   BuiltinTypeDeclBuilder &
-  addTextureHandle(ResourceClass RC, bool IsROV, bool IsArray,
+  addTextureHandle(ResourceClass RC, bool IsROV, bool IsArrayed,
                    ResourceDimension RD,
                    AccessSpecifier Access = AccessSpecifier::AS_private);
   BuiltinTypeDeclBuilder &addSamplerHandle();
   BuiltinTypeDeclBuilder &addConstantBufferConversionToType();
   BuiltinTypeDeclBuilder &
   addArraySubscriptOperators(ResourceDimension Dim = 
ResourceDimension::Unknown,
-                             bool IsArray = false);
+                             bool IsArrayed = false);
 
   // Builtin types constructors
   BuiltinTypeDeclBuilder &addDefaultHandleConstructor(
@@ -103,26 +103,26 @@ class BuiltinTypeDeclBuilder {
   // Builtin types methods
   BuiltinTypeDeclBuilder &addLoadMethods();
   BuiltinTypeDeclBuilder &addTextureLoadMethods(ResourceDimension Dim,
-                                                bool IsArray = false);
+                                                bool IsArrayed = false);
   BuiltinTypeDeclBuilder &addByteAddressBufferLoadMethods();
   BuiltinTypeDeclBuilder &addByteAddressBufferStoreMethods();
   BuiltinTypeDeclBuilder &addSampleMethods(ResourceDimension Dim,
-                                           bool IsArray = false);
+                                           bool IsArrayed = false);
   BuiltinTypeDeclBuilder &addSampleBiasMethods(ResourceDimension Dim,
-                                               bool IsArray = false);
+                                               bool IsArrayed = false);
   BuiltinTypeDeclBuilder &addSampleGradMethods(ResourceDimension Dim,
-                                               bool IsArray = false);
+                                               bool IsArrayed = false);
   BuiltinTypeDeclBuilder &addSampleLevelMethods(ResourceDimension Dim,
-                                                bool IsArray = false);
+                                                bool IsArrayed = false);
   BuiltinTypeDeclBuilder &addSampleCmpMethods(ResourceDimension Dim,
-                                              bool IsArray = false);
+                                              bool IsArrayed = false);
   BuiltinTypeDeclBuilder &addSampleCmpLevelZeroMethods(ResourceDimension Dim,
-                                                       bool IsArray = false);
+                                                       bool IsArrayed = false);
   BuiltinTypeDeclBuilder &addCalculateLodMethods(ResourceDimension Dim);
   BuiltinTypeDeclBuilder &addGatherMethods(ResourceDimension Dim,
-                                           bool IsArray = false);
+                                           bool IsArrayed = false);
   BuiltinTypeDeclBuilder &addGatherCmpMethods(ResourceDimension Dim,
-                                              bool IsArray = false);
+                                              bool IsArrayed = false);
   BuiltinTypeDeclBuilder &addIncrementCounterMethod();
   BuiltinTypeDeclBuilder &addDecrementCounterMethod();
   BuiltinTypeDeclBuilder &addHandleAccessFunction(DeclarationName &Name,
@@ -149,7 +149,7 @@ class BuiltinTypeDeclBuilder {
   BuiltinTypeDeclBuilder &
   addResourceMember(StringRef MemberName, ResourceClass RC,
                     ResourceDimension RD, bool IsROV, bool RawBuffer,
-                    bool IsCounter, bool IsArray, QualType ElementTy,
+                    bool IsCounter, bool IsArrayed, QualType ElementTy,
                     AccessSpecifier Access = AccessSpecifier::AS_private);
   BuiltinTypeDeclBuilder &addFriend(CXXRecordDecl *Friend);
   CXXRecordDecl *addPrivateNestedRecord(StringRef Name);
@@ -157,7 +157,7 @@ class BuiltinTypeDeclBuilder {
   CXXRecordDecl *addMipsType(ResourceDimension Dim, QualType ReturnType);
   BuiltinTypeDeclBuilder &
   addHandleMember(ResourceClass RC, ResourceDimension RD, bool IsROV,
-                  bool RawBuffer, bool IsArray, QualType ElementTy,
+                  bool RawBuffer, bool IsArrayed, QualType ElementTy,
                   AccessSpecifier Access = AccessSpecifier::AS_private);
   BuiltinTypeDeclBuilder &
   addCounterHandleMember(ResourceClass RC, bool IsROV, bool RawBuffer,
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp 
b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index bba537864b9b1..a7504073ef117 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -234,7 +234,7 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl 
*Decl, Sema &S,
                                               ResourceClass RC, bool IsROV,
                                               bool RawBuffer, bool HasCounter) 
{
   return BuiltinTypeDeclBuilder(S, Decl)
-      .addBufferHandles(RC, IsROV, RawBuffer, HasCounter, /*IsArray=*/false)
+      .addBufferHandles(RC, IsROV, RawBuffer, HasCounter, /*IsArrayed=*/false)
       .addDefaultHandleConstructor()
       .addCopyConstructor()
       .addCopyAssignmentOperator()
@@ -254,27 +254,27 @@ static BuiltinTypeDeclBuilder 
setupSamplerType(CXXRecordDecl *Decl, Sema &S) {
 /// Set up common members and attributes for texture types
 static BuiltinTypeDeclBuilder setupTextureType(CXXRecordDecl *Decl, Sema &S,
                                                ResourceClass RC, bool IsROV,
-                                               bool IsArray,
+                                               bool IsArrayed,
                                                ResourceDimension Dim) {
   return BuiltinTypeDeclBuilder(S, Decl)
-      .addTextureHandle(RC, IsROV, IsArray, Dim)
-      .addTextureLoadMethods(Dim, IsArray)
-      .addArraySubscriptOperators(Dim, IsArray)
+      .addTextureHandle(RC, IsROV, IsArrayed, Dim)
+      .addTextureLoadMethods(Dim, IsArrayed)
+      .addArraySubscriptOperators(Dim, IsArrayed)
       .addMipsMember(Dim)
       .addDefaultHandleConstructor()
       .addCopyConstructor()
       .addCopyAssignmentOperator()
       .addStaticInitializationFunctions(false)
-      .addSampleMethods(Dim, IsArray)
-      .addSampleBiasMethods(Dim, IsArray)
-      .addSampleGradMethods(Dim, IsArray)
-      .addSampleLevelMethods(Dim, IsArray)
-      .addSampleCmpMethods(Dim, IsArray)
-      .addSampleCmpLevelZeroMethods(Dim, IsArray)
+      .addSampleMethods(Dim, IsArrayed)
+      .addSampleBiasMethods(Dim, IsArrayed)
+      .addSampleGradMethods(Dim, IsArrayed)
+      .addSampleLevelMethods(Dim, IsArrayed)
+      .addSampleCmpMethods(Dim, IsArrayed)
+      .addSampleCmpLevelZeroMethods(Dim, IsArrayed)
       .addCalculateLodMethods(Dim)
       .addGetDimensionsMethods(Dim)
-      .addGatherMethods(Dim, IsArray)
-      .addGatherCmpMethods(Dim, IsArray);
+      .addGatherMethods(Dim, IsArrayed)
+      .addGatherCmpMethods(Dim, IsArrayed);
 }
 
 // Add a partial specialization for a template. The `TextureTemplate` is
@@ -674,7 +674,7 @@ void 
HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
 
   onCompletion(Decl, [this](CXXRecordDecl *Decl) {
     setupTextureType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
-                     /*IsArray=*/false, ResourceDimension::Dim2D)
+                     /*IsArrayed=*/false, ResourceDimension::Dim2D)
         .completeDefinition();
   });
 
@@ -682,7 +682,7 @@ void 
HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
       *SemaPtr, HLSLNamespace, Decl->getDescribedClassTemplate());
   onCompletion(PartialSpec, [this](CXXRecordDecl *Decl) {
     setupTextureType(Decl, *SemaPtr, ResourceClass::SRV, /*IsROV=*/false,
-                     /*IsArray=*/false, ResourceDimension::Dim2D)
+                     /*IsArrayed=*/false, ResourceDimension::Dim2D)
         .completeDefinition();
   });
 }
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index bebd8228aba0c..3d67e1e37fff6 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2141,12 +2141,12 @@ bool clang::CreateHLSLAttributedResourceType(
       }
       ResAttrs.RawBuffer = true;
       break;
-    case attr::HLSLArrayed:
-      if (ResAttrs.IsArray) {
+    case attr::HLSLIsArrayed:
+      if (ResAttrs.IsArrayed) {
         S.Diag(A->getLocation(), diag::warn_duplicate_attribute_exact) << A;
         return false;
       }
-      ResAttrs.IsArray = true;
+      ResAttrs.IsArrayed = true;
       break;
     case attr::HLSLIsCounter:
       if (ResAttrs.IsCounter) {
@@ -3601,7 +3601,7 @@ static bool CheckIndexType(Sema *S, CallExpr *TheCall, 
unsigned IndexArgIndex) {
   unsigned int ExpectedDim = 1;
   if (ResAttrs.ResourceDimension != llvm::dxil::ResourceDimension::Unknown)
     ExpectedDim = getResourceDimensions(ResAttrs.ResourceDimension) +
-                  (ResAttrs.IsArray ? 1 : 0);
+                  (ResAttrs.IsArrayed ? 1 : 0);
 
   if (ActualDim != ExpectedDim) {
     S->Diag(TheCall->getArg(IndexArgIndex)->getBeginLoc(),
@@ -3680,7 +3680,7 @@ static bool CheckTextureSamplerAndLocation(Sema &S, 
CallExpr *TheCall,
   // Check the location.
   unsigned ExpectedDim =
       getResourceDimensions(ResourceTy->getAttrs().ResourceDimension) +
-      (IncludeArraySlice && ResourceTy->getAttrs().IsArray ? 1 : 0);
+      (IncludeArraySlice && ResourceTy->getAttrs().IsArrayed ? 1 : 0);
   if (CheckVectorElementCount(&S, TheCall->getArg(2)->getType(),
                               S.Context.FloatTy, ExpectedDim,
                               TheCall->getBeginLoc()))
@@ -3804,7 +3804,8 @@ static bool CheckLoadLevelBuiltin(Sema &S, CallExpr 
*TheCall) {
   // Check the location + lod (int3 for Texture2D, int4 for Texture2DArray).
   unsigned ResourceDim =
       getResourceDimensions(ResourceTy->getAttrs().ResourceDimension);
-  unsigned LocationDim = ResourceDim + (ResourceTy->getAttrs().IsArray ? 1 : 
0);
+  unsigned LocationDim =
+      ResourceDim + (ResourceTy->getAttrs().IsArrayed ? 1 : 0);
   QualType CoordLODTy = TheCall->getArg(1)->getType();
   if (CheckVectorElementCount(&S, CoordLODTy, S.Context.IntTy, LocationDim + 1,
                               TheCall->getArg(1)->getBeginLoc()))

>From 3274453b6970b3b6a058157b566ae28dd60a8d40 Mon Sep 17 00:00:00 2001
From: Tim Corringham <[email protected]>
Date: Thu, 4 Jun 2026 08:31:34 +0100
Subject: [PATCH 3/5] Refactor use of getHandleAttributedType()

Simplified the use of getHandleAttributedType() by moving the assert
that followed each use into the function, and added a helper function
getRequiredHandleType() to reduce the previous call sites to a single
line.
---
 clang/lib/CodeGen/CGHLSLBuiltins.cpp | 48 +++++++++++-----------------
 1 file changed, 19 insertions(+), 29 deletions(-)

diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp 
b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index 6266365dc0460..492298d90b96c 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -462,8 +462,16 @@ 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.
-  return HLSLAttributedResourceType::findHandleTypeOnResource(
-      HandleQT.getTypePtr());
+  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,
@@ -620,9 +628,7 @@ 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 =
-        getHandleAttributedType(E->getArg(0)->getType());
-    assert(RT && "resource builtin requires attributed handle type");
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
 
     SmallVector<Value *, 4> Args;
     Args.push_back(HandleOp);
@@ -647,9 +653,7 @@ 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 =
-        getHandleAttributedType(E->getArg(0)->getType());
-    assert(RT && "resource builtin requires attributed handle type");
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
 
     SmallVector<Value *, 6> Args; // Max 6 arguments for SampleBias
     Args.push_back(HandleOp);
@@ -673,9 +677,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 =
-        getHandleAttributedType(E->getArg(0)->getType());
-    assert(RT && "resource builtin requires attributed handle type");
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
 
     SmallVector<Value *, 7> Args;
     Args.push_back(HandleOp);
@@ -703,9 +705,7 @@ 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 =
-        getHandleAttributedType(E->getArg(0)->getType());
-    assert(RT && "resource builtin requires attributed handle type");
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
 
     SmallVector<Value *, 5> Args; // Max 5 arguments for SampleLevel
     Args.push_back(HandleOp);
@@ -735,9 +735,7 @@ 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 =
-        getHandleAttributedType(E->getArg(0)->getType());
-    assert(RT && "resource builtin requires attributed handle type");
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
 
     SmallVector<Value *, 4> Args;
     Args.push_back(HandleOp);
@@ -756,9 +754,7 @@ 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 =
-        getHandleAttributedType(E->getArg(0)->getType());
-    assert(RT && "resource builtin requires attributed handle type");
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
 
     SmallVector<Value *, 6> Args; // Max 6 arguments for SampleCmp
     Args.push_back(HandleOp);
@@ -784,9 +780,7 @@ 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 =
-        getHandleAttributedType(E->getArg(0)->getType());
-    assert(RT && "resource builtin requires attributed handle type");
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
 
     SmallVector<Value *, 5> Args;
     Args.push_back(HandleOp);
@@ -827,9 +821,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
     if (ComponentOp->getType() != Builder.getInt32Ty())
       ComponentOp = Builder.CreateIntCast(ComponentOp, Builder.getInt32Ty(),
                                           /*isSigned=*/false);
-    const HLSLAttributedResourceType *RT =
-        getHandleAttributedType(E->getArg(0)->getType());
-    assert(RT && "resource builtin requires attributed handle type");
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
 
     SmallVector<Value *, 5> Args;
     Args.push_back(HandleOp);
@@ -864,9 +856,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned 
BuiltinID,
       Args.push_back(ComponentOp);
     }
 
-    const HLSLAttributedResourceType *RT =
-        getHandleAttributedType(E->getArg(0)->getType());
-    assert(RT && "resource builtin requires attributed handle type");
+    const HLSLAttributedResourceType *RT = getRequiredHandleType(E, 0);
     Args.push_back(emitHlslOffset(*this, E, 5, getOffsetType(CGM, RT)));
 
     llvm::Type *RetTy = ConvertType(E->getType());

>From 89c9009e8ac5a7532a0c4397fb0e166fe1caf154 Mon Sep 17 00:00:00 2001
From: Tim Corringham <[email protected]>
Date: Thu, 4 Jun 2026 13:49:28 +0100
Subject: [PATCH 4/5] Add IsArrayed to resource type attribute handling

The IsArrayed attribute was missing from the attribute handling for
resource types, preventing TypePrinter from outputting the attribute
when it was present. A trivial fix corrects this omission.
---
 clang/include/clang/AST/TypeBase.h | 2 +-
 clang/lib/Sema/SemaHLSL.cpp        | 4 ++++
 clang/lib/Sema/SemaType.cpp        | 1 +
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/AST/TypeBase.h 
b/clang/include/clang/AST/TypeBase.h
index 521549e0c11c1..df75985b8057e 100644
--- a/clang/include/clang/AST/TypeBase.h
+++ b/clang/include/clang/AST/TypeBase.h
@@ -6864,7 +6864,7 @@ 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,
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 3d67e1e37fff6..de4aa4146a204 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -2269,6 +2269,10 @@ bool SemaHLSL::handleResourceTypeAttr(QualType T, const 
ParsedAttr &AL) {
     A = HLSLIsCounterAttr::Create(getASTContext(), ACI);
     break;
 
+  case ParsedAttr::AT_HLSLIsArrayed:
+    A = HLSLIsArrayedAttr::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 0e6532a6e2178..809479f65a8b9 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -9344,6 +9344,7 @@ static void processTypeAttrs(TypeProcessingState &state, 
QualType &type,
     case ParsedAttr::AT_HLSLResourceDimension:
     case ParsedAttr::AT_HLSLROV:
     case ParsedAttr::AT_HLSLRawBuffer:
+    case ParsedAttr::AT_HLSLIsArrayed:
     case ParsedAttr::AT_HLSLContainedType: {
       // Only collect HLSL resource type attributes that are in
       // decl-specifier-seq; do not collect attributes on declarations or those

>From 83ff0d5e4e4e89504fa0ff78cb83adb393a6f733 Mon Sep 17 00:00:00 2001
From: Tim Corringham <[email protected]>
Date: Thu, 4 Jun 2026 14:09:10 +0100
Subject: [PATCH 5/5] Add tests for is_array attribute

Add tests to check the is_array attribute is handled as expected.
---
 .../test/ParserHLSL/hlsl_is_arrayed_attr.hlsl | 22 +++++++++++++++++++
 .../hlsl_is_arrayed_attr_error.hlsl           | 20 +++++++++++++++++
 2 files changed, 42 insertions(+)
 create mode 100644 clang/test/ParserHLSL/hlsl_is_arrayed_attr.hlsl
 create mode 100644 clang/test/ParserHLSL/hlsl_is_arrayed_attr_error.hlsl

diff --git a/clang/test/ParserHLSL/hlsl_is_arrayed_attr.hlsl 
b/clang/test/ParserHLSL/hlsl_is_arrayed_attr.hlsl
new file mode 100644
index 0000000000000..283708b7429e9
--- /dev/null
+++ b/clang/test/ParserHLSL/hlsl_is_arrayed_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:72> col:72 h 
'__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_arrayed]]
+struct MyBuffer {
+  __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::is_arrayed]] h;
+};
+
+// CHECK: VarDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 3]]:1, col:70> col:70 res 
'__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_arrayed]]
+__hlsl_resource_t [[hlsl::is_arrayed]] [[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:76> col:76 r '__hlsl_resource_t
+// CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
+// CHECK-SAME{LITERAL}: [[hlsl::is_arrayed]]
+void f() {
+  __hlsl_resource_t [[hlsl::resource_class(Sampler)]] [[hlsl::is_arrayed]] r;
+}
diff --git a/clang/test/ParserHLSL/hlsl_is_arrayed_attr_error.hlsl 
b/clang/test/ParserHLSL/hlsl_is_arrayed_attr_error.hlsl
new file mode 100644
index 0000000000000..c62fb90a08b3d
--- /dev/null
+++ b/clang/test/ParserHLSL/hlsl_is_arrayed_attr_error.hlsl
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -o - %s 
-verify
+
+// expected-error@+1{{'hlsl::is_arrayed' attribute cannot be applied to a 
declaration}}
+[[hlsl::is_arrayed]] __hlsl_resource_t res0;
+
+// expected-error@+1{{HLSL resource needs to have [[hlsl::resource_class()]] 
attribute}}
+__hlsl_resource_t [[hlsl::is_arrayed]] res1;
+
+// expected-error@+1{{'hlsl::is_arrayed' attribute takes no arguments}}
+__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::is_arrayed(3)]] res2;
+
+// expected-error@+1{{use of undeclared identifier 'gibberish'}}
+__hlsl_resource_t [[hlsl::resource_class(UAV)]] 
[[hlsl::is_arrayed(gibberish)]] res3;
+
+// expected-warning@+1{{attribute 'hlsl::is_arrayed' is already applied}}
+__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::is_arrayed]] 
[[hlsl::is_arrayed]] res4;
+
+// expected-error@+2{{attribute 'hlsl::resource_class' can be used only on 
HLSL intangible type '__hlsl_resource_t'}}
+// expected-error@+1{{attribute 'hlsl::is_arrayed' can be used only on HLSL 
intangible type '__hlsl_resource_t'}}
+float [[hlsl::resource_class(UAV)]] [[hlsl::is_arrayed]] res5;

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

Reply via email to