[clang] [HLSL] Make HLSLAttributedResourceType canonical and add code paths to convert HLSL types to DirectX target types (PR #110327)

Helena Kotas via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 11 12:57:32 PDT 2024


https://github.com/hekota updated https://github.com/llvm/llvm-project/pull/110327

>From 4f235c0e9c539cdaa2bab9a7f8228f33c0fea2b8 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Thu, 26 Sep 2024 14:34:16 -0700
Subject: [PATCH 1/9] Add codegen for existing resource types and make
 HLSLAttributedResourceType canonical.

---
 clang/include/clang/AST/Type.h                | 34 +++++++----
 clang/include/clang/Basic/TypeNodes.td        |  2 +-
 clang/lib/AST/ASTContext.cpp                  | 25 ++++++++-
 clang/lib/AST/ASTStructuralEquivalence.cpp    | 15 +----
 clang/lib/AST/DeclCXX.cpp                     |  6 +-
 clang/lib/AST/ExprConstant.cpp                |  1 +
 clang/lib/AST/ItaniumMangle.cpp               | 24 ++++++++
 clang/lib/AST/MicrosoftMangle.cpp             | 26 +++++++++
 clang/lib/AST/Type.cpp                        |  5 ++
 clang/lib/CodeGen/CodeGenFunction.cpp         |  1 +
 clang/lib/CodeGen/CodeGenTypes.cpp            |  3 +
 clang/lib/CodeGen/ItaniumCXXABI.cpp           |  6 ++
 clang/lib/CodeGen/Targets/DirectX.cpp         | 49 ++++++++++++----
 clang/lib/Sema/HLSLExternalSemaSource.cpp     |  2 -
 clang/lib/Sema/SemaLookup.cpp                 |  3 +
 clang/lib/Sema/SemaOverload.cpp               | 17 ++++++
 clang/lib/Sema/SemaTemplate.cpp               |  7 +++
 clang/lib/Sema/SemaTemplateDeduction.cpp      | 11 ++++
 clang/test/AST/HLSL/RWBuffer-AST.hlsl         |  2 -
 .../builtins/RWBuffer-elementtype.hlsl        | 14 +++++
 .../StructuredBuffer-elementtype.hlsl         | 14 +++++
 .../CodeGenHLSL/builtins/hlsl_resource_t.hlsl | 56 +++++++++++++++++--
 .../ParserHLSL/hlsl_contained_type_attr.hlsl  | 13 ++---
 clang/test/ParserHLSL/hlsl_is_rov_attr.hlsl   |  9 +--
 .../test/ParserHLSL/hlsl_raw_buffer_attr.hlsl |  9 +--
 .../ParserHLSL/hlsl_resource_class_attr.hlsl  | 17 ++----
 .../hlsl_resource_handle_attrs.hlsl           |  2 -
 27 files changed, 290 insertions(+), 83 deletions(-)

diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index dc87b84153e74a..f97217dead2139 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2659,6 +2659,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
 #include "clang/Basic/HLSLIntangibleTypes.def"
   bool isHLSLSpecificType() const; // Any HLSL specific type
   bool isHLSLIntangibleType() const; // Any HLSL intangible type
+  bool isHLSLAttributedResourceType() const;
 
   /// Determines if this type, which must satisfy
   /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather
@@ -6180,6 +6181,14 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode {
         : ResourceClass(ResourceClass), IsROV(IsROV), RawBuffer(RawBuffer) {}
 
     Attributes() : Attributes(llvm::dxil::ResourceClass::UAV, false, false) {}
+
+    friend bool operator==(const Attributes &LHS, const Attributes &RHS) {
+      return std::tie(LHS.ResourceClass, LHS.IsROV, LHS.RawBuffer) ==
+             std::tie(RHS.ResourceClass, RHS.IsROV, RHS.RawBuffer);
+    }
+    friend bool operator!=(const Attributes &LHS, const Attributes &RHS) {
+      return !(LHS == RHS);
+    }
   };
 
 private:
@@ -6189,18 +6198,19 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode {
   QualType ContainedType;
   const Attributes Attrs;
 
-  HLSLAttributedResourceType(QualType Canon, QualType Wrapped,
-                             QualType Contained, const Attributes &Attrs)
-      : Type(HLSLAttributedResource, Canon, Wrapped->getDependence()),
+  HLSLAttributedResourceType(QualType Wrapped, QualType Contained,
+                             const Attributes &Attrs)
+      : Type(HLSLAttributedResource, QualType(), Wrapped->getDependence()),
         WrappedType(Wrapped), ContainedType(Contained), Attrs(Attrs) {}
 
 public:
   QualType getWrappedType() const { return WrappedType; }
   QualType getContainedType() const { return ContainedType; }
+  bool hasContainedType() const { return !ContainedType.isNull(); }
   const Attributes &getAttrs() const { return Attrs; }
 
-  bool isSugared() const { return true; }
-  QualType desugar() const { return getWrappedType(); }
+  bool isSugared() const { return false; }
+  QualType desugar() const { return QualType(this, 0); }
 
   void Profile(llvm::FoldingSetNodeID &ID) {
     Profile(ID, WrappedType, ContainedType, Attrs);
@@ -8344,17 +8354,19 @@ inline bool Type::isOpenCLSpecificType() const {
   }
 #include "clang/Basic/HLSLIntangibleTypes.def"
 
-inline bool Type::isHLSLSpecificType() const {
+inline bool Type::isHLSLIntangibleType() const {
 #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) is##Id##Type() ||
   return
 #include "clang/Basic/HLSLIntangibleTypes.def"
-      false; // end boolean or operation
+      isHLSLAttributedResourceType();
 }
 
-inline bool Type::isHLSLIntangibleType() const {
-  // All HLSL specific types are currently intangible type as well, but that
-  // might change in the future.
-  return isHLSLSpecificType();
+inline bool Type::isHLSLSpecificType() const {
+  return isHLSLIntangibleType() || isa<HLSLAttributedResourceType>(this);
+}
+
+inline bool Type::isHLSLAttributedResourceType() const {
+  return isa<HLSLAttributedResourceType>(this);
 }
 
 inline bool Type::isTemplateTypeParmType() const {
diff --git a/clang/include/clang/Basic/TypeNodes.td b/clang/include/clang/Basic/TypeNodes.td
index 8cca392cddc174..7e550ca2992f35 100644
--- a/clang/include/clang/Basic/TypeNodes.td
+++ b/clang/include/clang/Basic/TypeNodes.td
@@ -93,7 +93,7 @@ def EnumType : TypeNode<TagType>, LeafType;
 def ElaboratedType : TypeNode<Type>, NeverCanonical;
 def AttributedType : TypeNode<Type>, NeverCanonical;
 def BTFTagAttributedType : TypeNode<Type>, NeverCanonical;
-def HLSLAttributedResourceType : TypeNode<Type>, NeverCanonical;
+def HLSLAttributedResourceType : TypeNode<Type>;
 def TemplateTypeParmType : TypeNode<Type>, AlwaysDependent, LeafType;
 def SubstTemplateTypeParmType : TypeNode<Type>, NeverCanonical;
 def SubstTemplateTypeParmPackType : TypeNode<Type>, AlwaysDependent;
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index cda8b02cc8499a..b41620505a0b16 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3437,6 +3437,9 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
     OS << II->getLength() << II->getName();
     return;
   }
+  case Type::HLSLAttributedResource:
+    llvm_unreachable("not yet implemented");
+    break;
   case Type::DeducedTemplateSpecialization:
   case Type::Auto:
 #define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
@@ -4108,6 +4111,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
   case Type::BitInt:
   case Type::DependentBitInt:
   case Type::ArrayParameter:
+  case Type::HLSLAttributedResource:
     llvm_unreachable("type should never be variably-modified");
 
   // These types can be variably-modified but should never need to
@@ -5233,9 +5237,8 @@ QualType ASTContext::getHLSLAttributedResourceType(
   if (Ty)
     return QualType(Ty, 0);
 
-  QualType Canon = getCanonicalType(Wrapped);
   Ty = new (*this, alignof(HLSLAttributedResourceType))
-      HLSLAttributedResourceType(Canon, Wrapped, Contained, Attrs);
+      HLSLAttributedResourceType(Wrapped, Contained, Attrs);
 
   Types.push_back(Ty);
   HLSLAttributedResourceTypes.InsertNode(Ty, InsertPos);
@@ -9106,6 +9109,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
   case Type::DeducedTemplateSpecialization:
     return;
 
+  case Type::HLSLAttributedResource:
+    llvm_unreachable("unexpected type");
+
   case Type::ArrayParameter:
   case Type::Pipe:
 #define ABSTRACT_TYPE(KIND, BASE)
@@ -11533,6 +11539,18 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, bool OfBlockPointer,
       return {};
     return LHS;
   }
+  case Type::HLSLAttributedResource: {
+    const HLSLAttributedResourceType *LHSTy =
+        LHS->castAs<HLSLAttributedResourceType>();
+    const HLSLAttributedResourceType *RHSTy =
+        RHS->castAs<HLSLAttributedResourceType>();
+
+    if (LHSTy->getWrappedType() == RHSTy->getWrappedType() &&
+        LHSTy->getContainedType() == RHSTy->getContainedType() &&
+        LHSTy->getAttrs() == RHSTy->getAttrs())
+      return LHS;
+    return {};
+  }
   }
 
   llvm_unreachable("Invalid Type::Class!");
@@ -13672,6 +13690,9 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
         TX->getDepth(), TX->getIndex(), TX->isParameterPack(),
         getCommonDecl(TX->getDecl(), TY->getDecl()));
   }
+  case Type::HLSLAttributedResource: {
+    llvm_unreachable("not yet implemented");
+  }
   }
   llvm_unreachable("Unknown Type Class");
 }
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 21f0562f9d72ae..120ddc0f26c0d7 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -802,16 +802,6 @@ static bool IsEquivalentExceptionSpec(StructuralEquivalenceContext &Context,
   return true;
 }
 
-// Determine structural equivalence of two instances of
-// HLSLAttributedResourceType::Attributes
-static bool
-IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                         const HLSLAttributedResourceType::Attributes &Attrs1,
-                         const HLSLAttributedResourceType::Attributes &Attrs2) {
-  return std::tie(Attrs1.ResourceClass, Attrs1.IsROV, Attrs1.RawBuffer) ==
-         std::tie(Attrs2.ResourceClass, Attrs2.IsROV, Attrs2.RawBuffer);
-}
-
 /// Determine structural equivalence of two types.
 static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
                                      QualType T1, QualType T2) {
@@ -1115,9 +1105,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
             Context, cast<HLSLAttributedResourceType>(T1)->getContainedType(),
             cast<HLSLAttributedResourceType>(T2)->getContainedType()))
       return false;
-    if (!IsStructurallyEquivalent(
-            Context, cast<HLSLAttributedResourceType>(T1)->getAttrs(),
-            cast<HLSLAttributedResourceType>(T2)->getAttrs()))
+    if (cast<HLSLAttributedResourceType>(T1)->getAttrs() !=
+        cast<HLSLAttributedResourceType>(T2)->getAttrs())
       return false;
     break;
 
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 01143391edab40..8d0b5171fc9ae3 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -1411,10 +1411,10 @@ void CXXRecordDecl::addedMember(Decl *D) {
         Ty = Ty->getArrayElementTypeNoTypeQual();
 
       Ty = Ty->getUnqualifiedDesugaredType();
-      if (Ty->isBuiltinType())
-        data().IsHLSLIntangible |= Ty->isHLSLIntangibleType();
-      else if (const RecordType *RT = dyn_cast<RecordType>(Ty))
+      if (const RecordType *RT = dyn_cast<RecordType>(Ty))
         data().IsHLSLIntangible |= RT->getAsCXXRecordDecl()->isHLSLIntangible();
+      else
+        data().IsHLSLIntangible |= Ty->isHLSLIntangibleType();
     }
   }
 
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 960eae36ed1f51..dab54133248393 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -12163,6 +12163,7 @@ GCCTypeClass EvaluateBuiltinClassifyType(QualType T,
   case Type::ObjCInterface:
   case Type::ObjCObjectPointer:
   case Type::Pipe:
+  case Type::HLSLAttributedResource:
     // Classify all other types that don't fit into the regular
     // classification the same way.
     return GCCTypeClass::None;
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index b6e1da0c3192da..9bda078d9fac81 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -4488,6 +4488,30 @@ void CXXNameMangler::mangleType(const ArrayParameterType *T) {
   mangleType(cast<ConstantArrayType>(T));
 }
 
+void CXXNameMangler::mangleType(const HLSLAttributedResourceType *T) {
+  mangleType(T->getWrappedType());
+  const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
+  switch (Attrs.ResourceClass) {
+  case llvm::dxil::ResourceClass::UAV:
+    Out << 'U';
+    break;
+  case llvm::dxil::ResourceClass::SRV:
+    Out << 'T';
+    break;
+  case llvm::dxil::ResourceClass::CBuffer:
+    Out << 'C';
+    break;
+  case llvm::dxil::ResourceClass::Sampler:
+    Out << 'S';
+    break;
+  }
+  mangleNumber(Attrs.IsROV);
+  mangleNumber(Attrs.RawBuffer);
+
+  if (!T->hasContainedType())
+    mangleType(T->getContainedType());
+}
+
 void CXXNameMangler::mangleIntegerLiteral(QualType T,
                                           const llvm::APSInt &Value) {
   //  <expr-primary> ::= L <type> <value number> E # integer literal
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 7b069c66aed598..16df5c99c623ce 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -32,6 +32,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/CRC.h"
+#include "llvm/Support/DXILABI.h"
 #include "llvm/Support/MD5.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/StringSaver.h"
@@ -3753,6 +3754,31 @@ void MicrosoftCXXNameMangler::mangleType(const DependentBitIntType *T,
   Error(Range.getBegin(), "DependentBitInt type") << Range;
 }
 
+void MicrosoftCXXNameMangler::mangleType(const HLSLAttributedResourceType *T,
+                                         Qualifiers, SourceRange Range) {
+  mangleType(T->getWrappedType(), SourceRange(), QMM_Escape);
+  const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
+  switch (Attrs.ResourceClass) {
+  case llvm::dxil::ResourceClass::UAV:
+    Out << 'U';
+    break;
+  case llvm::dxil::ResourceClass::SRV:
+    Out << 'T';
+    break;
+  case llvm::dxil::ResourceClass::CBuffer:
+    Out << 'C';
+    break;
+  case llvm::dxil::ResourceClass::Sampler:
+    Out << 'S';
+    break;
+  }
+  mangleNumber(Attrs.IsROV);
+  mangleNumber(Attrs.RawBuffer);
+
+  if (T->hasContainedType())
+    mangleType(T->getContainedType(), SourceRange(), QMM_Escape);
+}
+
 // <this-adjustment> ::= <no-adjustment> | <static-adjustment> |
 //                       <virtual-adjustment>
 // <no-adjustment>      ::= A # private near
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index a55e6c8bf02611..99fc3c676c2c98 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -4575,6 +4575,8 @@ static CachedProperties computeCachedProperties(const Type *T) {
     return Cache::get(cast<AtomicType>(T)->getValueType());
   case Type::Pipe:
     return Cache::get(cast<PipeType>(T)->getElementType());
+  case Type::HLSLAttributedResource:
+    return Cache::get(cast<HLSLAttributedResourceType>(T)->getWrappedType());
   }
 
   llvm_unreachable("unhandled type class");
@@ -4664,6 +4666,8 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
     return computeTypeLinkageInfo(cast<AtomicType>(T)->getValueType());
   case Type::Pipe:
     return computeTypeLinkageInfo(cast<PipeType>(T)->getElementType());
+  case Type::HLSLAttributedResource:
+    llvm_unreachable("not yet implemented");
   }
 
   llvm_unreachable("unhandled type class");
@@ -4846,6 +4850,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
   case Type::BitInt:
   case Type::DependentBitInt:
   case Type::ArrayParameter:
+  case Type::HLSLAttributedResource:
     return false;
   }
   llvm_unreachable("bad type kind!");
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index eda96f3e352ce3..ddbd5e2f1aa311 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -296,6 +296,7 @@ TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) {
     case Type::ObjCObject:
     case Type::ObjCInterface:
     case Type::ArrayParameter:
+    case Type::HLSLAttributedResource:
       return TEK_Aggregate;
 
     // We operate on atomic values according to their underlying type.
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index 77c1b27cebf401..bacb0a04cb7c86 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -742,6 +742,9 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
     ResultType = llvm::Type::getIntNTy(getLLVMContext(), EIT->getNumBits());
     break;
   }
+  case Type::HLSLAttributedResource:
+    ResultType = CGM.getHLSLRuntime().convertHLSLSpecificType(Ty);
+    break;
   }
 
   assert(ResultType && "Didn't convert a type?");
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index dcc35d5689831e..8533ccb2129c34 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3943,6 +3943,9 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
     // abi::__pointer_to_member_type_info.
     VTableName = "_ZTVN10__cxxabiv129__pointer_to_member_type_infoE";
     break;
+
+  case Type::HLSLAttributedResource:
+    llvm_unreachable("not yet implemented");
   }
 
   llvm::Constant *VTable = nullptr;
@@ -4205,6 +4208,9 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
   case Type::Atomic:
     // No fields, at least for the moment.
     break;
+
+  case Type::HLSLAttributedResource:
+    llvm_unreachable("not yet implemented");
   }
 
   llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
diff --git a/clang/lib/CodeGen/Targets/DirectX.cpp b/clang/lib/CodeGen/Targets/DirectX.cpp
index 13da2c630629d7..cf6ac849777369 100644
--- a/clang/lib/CodeGen/Targets/DirectX.cpp
+++ b/clang/lib/CodeGen/Targets/DirectX.cpp
@@ -29,19 +29,48 @@ class DirectXTargetCodeGenInfo : public TargetCodeGenInfo {
 
 llvm::Type *DirectXTargetCodeGenInfo::getHLSLType(CodeGenModule &CGM,
                                                   const Type *Ty) const {
-  auto *BuiltinTy = dyn_cast<BuiltinType>(Ty);
-  if (!BuiltinTy || BuiltinTy->getKind() != BuiltinType::HLSLResource)
+  auto *ResType = dyn_cast<HLSLAttributedResourceType>(Ty);
+  if (!ResType)
     return nullptr;
 
   llvm::LLVMContext &Ctx = CGM.getLLVMContext();
-  // FIXME: translate __hlsl_resource_t to target("dx.TypedBuffer", <4 x float>,
-  // 1, 0, 0) only for now (RWBuffer<float4>); more work us needed to determine
-  // the target ext type and its parameters based on the handle type
-  // attributes (not yet implemented)
-  llvm::FixedVectorType *ElemType =
-      llvm::FixedVectorType::get(llvm::Type::getFloatTy(Ctx), 4);
-  unsigned Flags[] = {/*IsWriteable*/ 1, /*IsROV*/ 0, /*IsSigned*/ 0};
-  return llvm::TargetExtType::get(Ctx, "dx.TypedBuffer", {ElemType}, Flags);
+  const HLSLAttributedResourceType::Attributes &ResAttrs = ResType->getAttrs();
+  switch (ResAttrs.ResourceClass) {
+  case llvm::dxil::ResourceClass::UAV:
+  case llvm::dxil::ResourceClass::SRV: {
+    // convert element type
+    QualType ContainedTy = ResType->getContainedType();
+    llvm::Type *ElemType = nullptr;
+    if (!ContainedTy.isNull())
+      ElemType = CGM.getTypes().ConvertType(ContainedTy);
+
+    if (ResAttrs.RawBuffer) {
+      // RawBuffer needs element type
+      if (ContainedTy.isNull())
+        return nullptr;
+      return llvm::TargetExtType::get(Ctx, "dx.RawBuffer", {ElemType},
+                                      {/*IsWriteable*/ ResAttrs.ResourceClass ==
+                                           llvm::dxil::ResourceClass::UAV,
+                                       /*IsROV*/ ResAttrs.IsROV});
+    }
+
+    // TypedBuffer needs element type
+    if (ContainedTy.isNull())
+      return nullptr;
+    return llvm::TargetExtType::get(
+        Ctx, "dx.TypedBuffer", {ElemType},
+        {/*IsWriteable*/ ResAttrs.ResourceClass ==
+             llvm::dxil::ResourceClass::UAV,
+         /*IsROV*/ ResAttrs.IsROV,
+         /*IsSigned*/ ContainedTy->isSignedIntegerType()});
+  }
+  case llvm::dxil::ResourceClass::CBuffer:
+    llvm_unreachable("dx.CBuffer handles are not implemented yet");
+    break;
+  case llvm::dxil::ResourceClass::Sampler:
+    llvm_unreachable("dx.Sampler handles are not implemented yet");
+    break;
+  }
 }
 
 } // namespace
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index ca521dc0bcd26b..d2f032dfd5e9ba 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -211,8 +211,6 @@ struct BuiltinTypeDeclBuilder {
   BuiltinTypeDeclBuilder &addArraySubscriptOperator(bool IsConst) {
     if (Record->isCompleteDefinition())
       return *this;
-    assert(Fields.count("h") > 0 &&
-           "Subscript operator must be added after the handle.");
 
     FieldDecl *Handle = Fields["h"];
     ASTContext &AST = Record->getASTContext();
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index f3f62474d06441..e5db11369221a4 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -3215,6 +3215,9 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) {
     // Array parameter types are treated as fundamental types.
     case Type::ArrayParameter:
       break;
+
+    case Type::HLSLAttributedResource:
+      T = cast<HLSLAttributedResourceType>(T)->getWrappedType().getTypePtr();
     }
 
     if (Queue.empty())
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 0c1e054f7c30a4..16c2d0f74a3d34 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1785,6 +1785,23 @@ TryImplicitConversion(Sema &S, Expr *From, QualType ToType,
     return ICS;
   }
 
+  if (S.getLangOpts().HLSL && ToType->isHLSLAttributedResourceType() &&
+      FromType->isHLSLAttributedResourceType()) {
+    auto *ToResType = cast<HLSLAttributedResourceType>(ToType);
+    auto *FromResType = cast<HLSLAttributedResourceType>(FromType);
+    if (S.Context.hasSameUnqualifiedType(ToResType->getWrappedType(),
+                                         FromResType->getWrappedType()) &&
+        S.Context.hasSameUnqualifiedType(ToResType->getContainedType(),
+                                         FromResType->getContainedType()) &&
+        ToResType->getAttrs() == FromResType->getAttrs()) {
+      ICS.setStandard();
+      ICS.Standard.setAsIdentityConversion();
+      ICS.Standard.setFromType(FromType);
+      ICS.Standard.setAllToTypes(ToType);
+      return ICS;
+    }
+  }
+
   return TryUserDefinedConversion(S, From, ToType, SuppressUserConversions,
                                   AllowExplicit, InOverloadResolution, CStyle,
                                   AllowObjCWritebackConversion,
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 99423b01114cc6..1db56adf954526 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -6078,6 +6078,13 @@ bool UnnamedLocalNoLinkageFinder::VisitNestedNameSpecifier(
   llvm_unreachable("Invalid NestedNameSpecifier::Kind!");
 }
 
+bool UnnamedLocalNoLinkageFinder::VisitHLSLAttributedResourceType(
+    const HLSLAttributedResourceType *T) {
+  if (T->hasContainedType() && Visit(T->getContainedType()))
+    return true;
+  return Visit(T->getWrappedType());
+}
+
 bool Sema::CheckTemplateArgument(TypeSourceInfo *ArgInfo) {
   assert(ArgInfo && "invalid TypeSourceInfo");
   QualType Arg = ArgInfo->getType();
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index cc095ae67ac400..ae5097f4236ae1 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2449,6 +2449,7 @@ static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch(
     case Type::PackExpansion:
     case Type::Pipe:
     case Type::ArrayParameter:
+    case Type::HLSLAttributedResource:
       // No template argument deduction for these types
       return TemplateDeductionResult::Success;
 
@@ -6872,6 +6873,16 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
                                OnlyDeduced, Depth, Used);
     break;
 
+  case Type::HLSLAttributedResource:
+    MarkUsedTemplateParameters(
+        Ctx, cast<HLSLAttributedResourceType>(T)->getWrappedType(), OnlyDeduced,
+        Depth, Used);
+    if (cast<HLSLAttributedResourceType>(T)->hasContainedType())
+      MarkUsedTemplateParameters(
+          Ctx, cast<HLSLAttributedResourceType>(T)->getContainedType(),
+          OnlyDeduced, Depth, Used);
+    break;
+
   // None of these types have any template parameters in them.
   case Type::Builtin:
   case Type::VariableArray:
diff --git a/clang/test/AST/HLSL/RWBuffer-AST.hlsl b/clang/test/AST/HLSL/RWBuffer-AST.hlsl
index a95be63da5dc17..c92bfa23e78a42 100644
--- a/clang/test/AST/HLSL/RWBuffer-AST.hlsl
+++ b/clang/test/AST/HLSL/RWBuffer-AST.hlsl
@@ -32,7 +32,6 @@ RWBuffer<float> Buffer;
 // CHECK-NEXT: implicit h 'element_type *
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
 // CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
-// CHECK-SAME:':'element_type *'
 // CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit TypedBuffer
 
 // CHECK: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> operator[] 'element_type &const (unsigned int) const'
@@ -69,5 +68,4 @@ RWBuffer<float> Buffer;
 // CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit h 'float *
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] 
 // CHECK-SAME{LITERAL}: [[hlsl::contained_type(float)]]
-// CHECK-SAME: ':'float *'
 // CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit TypedBuffer
diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl
index 036c9c28ef2779..b7b0eaac38e8f1 100644
--- a/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl
@@ -1,5 +1,19 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.2-compute -finclude-default-header -fnative-half-type -emit-llvm -o - %s | FileCheck %s
 
+// CHECK: %"class.hlsl::RWBuffer" = type { target("dx.TypedBuffer", i16, 1, 0, 1), i16 }
+// CHECK: %"class.hlsl::RWBuffer.0" = type { target("dx.TypedBuffer", i16, 1, 0, 0), i16 }
+// CHECK: %"class.hlsl::RWBuffer.1" = type { target("dx.TypedBuffer", i32, 1, 0, 1), i32 }
+// CHECK: %"class.hlsl::RWBuffer.2" = type { target("dx.TypedBuffer", i32, 1, 0, 0), i32 }
+// CHECK: %"class.hlsl::RWBuffer.3" = type { target("dx.TypedBuffer", i64, 1, 0, 1), i64 }
+// CHECK: %"class.hlsl::RWBuffer.4" = type { target("dx.TypedBuffer", i64, 1, 0, 0), i64 }
+// CHECK: %"class.hlsl::RWBuffer.5" = type { target("dx.TypedBuffer", half, 1, 0, 0), half }
+// CHECK: %"class.hlsl::RWBuffer.6" = type { target("dx.TypedBuffer", float, 1, 0, 0), float }
+// CHECK: %"class.hlsl::RWBuffer.7" = type { target("dx.TypedBuffer", double, 1, 0, 0), double }
+// CHECK: %"class.hlsl::RWBuffer.8" = type { target("dx.TypedBuffer", <4 x i16>, 1, 0, 0), <4 x i16> }
+// CHECK: %"class.hlsl::RWBuffer.9" = type { target("dx.TypedBuffer", <3 x i32>, 1, 0, 0), <3 x i32> }
+// CHECK: %"class.hlsl::RWBuffer.10" = type { target("dx.TypedBuffer", <2 x half>, 1, 0, 0), <2 x half> }
+// CHECK: %"class.hlsl::RWBuffer.11" = type { target("dx.TypedBuffer", <3 x float>, 1, 0, 0), <3 x float> }
+
 RWBuffer<int16_t> BufI16;
 RWBuffer<uint16_t> BufU16;
 RWBuffer<int> BufI32;
diff --git a/clang/test/CodeGenHLSL/builtins/StructuredBuffer-elementtype.hlsl b/clang/test/CodeGenHLSL/builtins/StructuredBuffer-elementtype.hlsl
index 8ddf8a6004403e..f2b63d704d88d6 100644
--- a/clang/test/CodeGenHLSL/builtins/StructuredBuffer-elementtype.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/StructuredBuffer-elementtype.hlsl
@@ -1,5 +1,19 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.2-compute -finclude-default-header -fnative-half-type -emit-llvm -o - %s | FileCheck %s
 
+// CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", i16, 1, 0), i16 }
+// CHECK: %"class.hlsl::StructuredBuffer.0" = type { target("dx.RawBuffer", i16, 1, 0), i16 }
+// CHECK: %"class.hlsl::StructuredBuffer.1" = type { target("dx.RawBuffer", i32, 1, 0), i32 }
+// CHECK: %"class.hlsl::StructuredBuffer.2" = type { target("dx.RawBuffer", i32, 1, 0), i32 }
+// CHECK: %"class.hlsl::StructuredBuffer.3" = type { target("dx.RawBuffer", i64, 1, 0), i64 }
+// CHECK: %"class.hlsl::StructuredBuffer.4" = type { target("dx.RawBuffer", i64, 1, 0), i64 }
+// CHECK: %"class.hlsl::StructuredBuffer.5" = type { target("dx.RawBuffer", half, 1, 0), half }
+// CHECK: %"class.hlsl::StructuredBuffer.6" = type { target("dx.RawBuffer", float, 1, 0), float }
+// CHECK: %"class.hlsl::StructuredBuffer.7" = type { target("dx.RawBuffer", double, 1, 0), double }
+// CHECK: %"class.hlsl::StructuredBuffer.8" = type { target("dx.RawBuffer", <4 x i16>, 1, 0), <4 x i16> }
+// CHECK: %"class.hlsl::StructuredBuffer.9" = type { target("dx.RawBuffer", <3 x i32>, 1, 0), <3 x i32> }
+// CHECK: %"class.hlsl::StructuredBuffer.10" = type { target("dx.RawBuffer", <2 x half>, 1, 0), <2 x half> }
+// CHECK: %"class.hlsl::StructuredBuffer.11" = type { target("dx.RawBuffer", <3 x float>, 1, 0), <3 x float> }
+
 StructuredBuffer<int16_t> BufI16;
 StructuredBuffer<uint16_t> BufU16;
 StructuredBuffer<int> BufI32;
diff --git a/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl b/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl
index ce973309034781..8d3a2b39530029 100644
--- a/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl
@@ -1,9 +1,53 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -O1 -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -finclude-default-header -x hlsl -emit-llvm -o - %s | FileCheck %s
 
-void foo(__hlsl_resource_t res);
+using handle_float_t = __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::contained_type(float)]];
 
-// CHECK: define void @"?bar@@YAXU__hlsl_resource_t@@@Z"(target("dx.TypedBuffer", <4 x float>, 1, 0, 0) %[[PARAM:[a-zA-Z0-9]+]])
-// CHECK: call void @"?foo@@YAXU__hlsl_resource_t@@@Z"(target("dx.TypedBuffer", <4 x float>, 1, 0, 0) %[[PARAM]])
-void bar(__hlsl_resource_t a) {
-    foo(a);
+// CHECK: %"class.hlsl::RWBuffer" = type { target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
+// CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", %struct.MyStruct = type { <4 x float>, <2 x i32>, [8 x i8] }, 1, 0)
+
+// CHECK: define void @"?fa@@YAXU__hlsl_resource_t@@UA at A@M at Z"(ptr noundef byval(target("dx.TypedBuffer", float, 1, 0, 0)) align 4 %a)
+// CHECK: call void @"?foo1@@YAXU__hlsl_resource_t@@UA at A@M at Z"(ptr noundef byval(target("dx.TypedBuffer", float, 1, 0, 0)) align 4 %a)
+// CHECK: declare void @"?foo1@@YAXU__hlsl_resource_t@@UA at A@M at Z"(ptr noundef byval(target("dx.TypedBuffer", float, 1, 0, 0)) align 4)
+
+void foo1(handle_float_t res);
+
+void fa(handle_float_t a) {
+    foo1(a);
+}
+
+// CHECK: define void @"?fb@@YAXU__hlsl_resource_t@@UA at A@M at Z"(ptr noundef byval(target("dx.TypedBuffer", float, 1, 0, 0)) align 4 %a)
+void fb(handle_float_t a) {
+    handle_float_t b = a;
 }
+
+// CHECK: define void @"?fc@@YAXV?$RWBuffer at T?$__vector at M$03 at __clang@@@hlsl@@@Z"(ptr noundef byval(%"class.hlsl::RWBuffer") align 16 %a)
+// CHECK: call void @"?foo2@@YAXV?$RWBuffer at T?$__vector at M$03 at __clang@@@hlsl@@@Z"(ptr noundef byval(%"class.hlsl::RWBuffer") align 16 %agg.tmp)  
+// CHECK: declare void @"?foo2@@YAXV?$RWBuffer at T?$__vector at M$03 at __clang@@@hlsl@@@Z"(ptr noundef byval(%"class.hlsl::RWBuffer") align 16)
+void foo2(RWBuffer<float4> buf);
+
+void fc(RWBuffer<float4> a) {
+  foo2(a);
+}
+
+void fd(RWBuffer<float4> a) {
+  RWBuffer<float4> b = a;
+}
+
+struct MyStruct {
+  float4 f;
+  int2 i;
+};
+
+// CHECK: define void @"?fe@@YAXV?$StructuredBuffer at UMyStruct@@@hlsl@@@Z"(ptr noundef byval(%"class.hlsl::StructuredBuffer") align 16 %a)
+// CHECK: call void @"?foo3@@YAXV?$StructuredBuffer at UMyStruct@@@hlsl@@@Z"(ptr noundef byval(%"class.hlsl::StructuredBuffer") align 16 %agg.tmp)
+// CHECK: declare void @"?foo3@@YAXV?$StructuredBuffer at UMyStruct@@@hlsl@@@Z"(ptr noundef byval(%"class.hlsl::StructuredBuffer") align 16)
+void foo3(StructuredBuffer<MyStruct> buf);
+
+void fe(StructuredBuffer<MyStruct> a) {
+  foo3(a);
+}
+
+void ff(StructuredBuffer<MyStruct> a) {
+  StructuredBuffer<MyStruct> b = a;
+}
+
diff --git a/clang/test/ParserHLSL/hlsl_contained_type_attr.hlsl b/clang/test/ParserHLSL/hlsl_contained_type_attr.hlsl
index 2b7bd31023222e..5a72aa242e581d 100644
--- a/clang/test/ParserHLSL/hlsl_contained_type_attr.hlsl
+++ b/clang/test/ParserHLSL/hlsl_contained_type_attr.hlsl
@@ -2,27 +2,24 @@
 
 typedef vector<float, 4> float4;
 
-// CHECK: -TypeAliasDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 5]]:1, col:83>
+// CHECK: -TypeAliasDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 4]]:1, col:83>
 // CHECK: -HLSLAttributedResourceType 0x{{[0-9a-f]+}} '__hlsl_resource_t
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
 // CHECK-SAME{LITERAL}: [[hlsl::contained_type(int)]]
-// CHECK-SAME: ' sugar
 using ResourceIntAliasT = __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::contained_type(int)]];
 ResourceIntAliasT h1;
 
-// CHECK: -VarDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 4]]:1, col:82> col:82 h2 '__hlsl_resource_t 
+// CHECK: -VarDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 3]]:1, col:82> col:82 h2 '__hlsl_resource_t 
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
 // CHECK-SAME{LITERAL}: [[hlsl::contained_type(float4)]]
-// CHECK-SAME: ':'__hlsl_resource_t'
 __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::contained_type(float4)]] h2;
 
-// CHECK: ClassTemplateDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 7]]:1, line:[[# @LINE + 9]]:1> line:[[# @LINE + 7]]:30 S
+// CHECK: ClassTemplateDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 6]]:1, line:[[# @LINE + 8]]:1> line:[[# @LINE + 6]]:30 S
 // CHECK: TemplateTypeParmDecl 0x{{[0-9a-f]+}} <col:11, col:20> col:20 referenced typename depth 0 index 0 T
-// CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} <col:23, line:[[# @LINE + 7]]:1> line:[[# @LINE + 5]]:30 struct S definition
-// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 5]]:3, col:79> col:79 h '__hlsl_resource_t
+// CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} <col:23, line:[[# @LINE + 6]]:1> line:[[# @LINE + 4]]:30 struct S definition
+// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 4]]:3, col:79> col:79 h '__hlsl_resource_t
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
 // CHECK-SAME{LITERAL}: [[hlsl::contained_type(T)]]
-// CHECK-SAME: ':'__hlsl_resource_t'
 template <typename T> struct S {
   __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::contained_type(T)]] h;
 };
diff --git a/clang/test/ParserHLSL/hlsl_is_rov_attr.hlsl b/clang/test/ParserHLSL/hlsl_is_rov_attr.hlsl
index fdf2aacf4a4ded..836d129c8d0002 100644
--- a/clang/test/ParserHLSL/hlsl_is_rov_attr.hlsl
+++ b/clang/test/ParserHLSL/hlsl_is_rov_attr.hlsl
@@ -1,25 +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 + 5]]:3, col:68> col:68 h '__hlsl_resource_t
+// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 4]]:3, col:68> col:68 h '__hlsl_resource_t
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
 // CHECK-SAME{LITERAL}: [[hlsl::is_rov]]
-// CHECK-SAME: ':'__hlsl_resource_t'
 struct MyBuffer {
   __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::is_rov]] h;
 };
 
-// CHECK: VarDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 4]]:1, col:66> col:66 res '__hlsl_resource_t
+// CHECK: VarDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 3]]:1, col:66> col:66 res '__hlsl_resource_t
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
 // CHECK-SAME{LITERAL}: [[hlsl::is_rov]]
-// CHECK-SAME: ':'__hlsl_resource_t'
 __hlsl_resource_t [[hlsl::is_rov]] [[hlsl::resource_class(SRV)]] res;
 
-// CHECK: FunctionDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 5]]:1, line:[[# @LINE + 7]]:1> line:[[# @LINE + 5]]:6 f 'void ()
+// 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:72> col:72 r '__hlsl_resource_t
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
 // CHECK-SAME{LITERAL}: [[hlsl::is_rov]]
-// CHECK-SAME: ':'__hlsl_resource_t'
 void f() {
   __hlsl_resource_t [[hlsl::resource_class(Sampler)]] [[hlsl::is_rov]] r;
 }
diff --git a/clang/test/ParserHLSL/hlsl_raw_buffer_attr.hlsl b/clang/test/ParserHLSL/hlsl_raw_buffer_attr.hlsl
index 71bf300ee7aec5..84c924eec24efc 100644
--- a/clang/test/ParserHLSL/hlsl_raw_buffer_attr.hlsl
+++ b/clang/test/ParserHLSL/hlsl_raw_buffer_attr.hlsl
@@ -1,25 +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 + 5]]:3, col:72> col:72 h1 '__hlsl_resource_t
+// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 4]]:3, col:72> col:72 h1 '__hlsl_resource_t
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
 // CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]]
-// CHECK-SAME: ':'__hlsl_resource_t'
 struct MyBuffer {
   __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::raw_buffer]] h1;
 };
 
-// CHECK: VarDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 4]]:1, col:70> col:70 h2 '__hlsl_resource_t
+// CHECK: VarDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 3]]:1, col:70> col:70 h2 '__hlsl_resource_t
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
 // CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]]
-// CHECK-SAME: ':'__hlsl_resource_t'
 __hlsl_resource_t [[hlsl::raw_buffer]] [[hlsl::resource_class(SRV)]] h2;
 
-// CHECK: FunctionDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 5]]:1, line:[[# @LINE + 7]]:1> line:[[# @LINE + 5]]:6 f 'void ()
+// 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:72> col:72 h3 '__hlsl_resource_t
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
 // CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]]
-// CHECK-SAME: ':'__hlsl_resource_t'
 void f() {
   __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::raw_buffer]] h3;
 }
diff --git a/clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl b/clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl
index 305fd95ab1ebc7..fbada8b4b99f75 100644
--- a/clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl
+++ b/clang/test/ParserHLSL/hlsl_resource_class_attr.hlsl
@@ -1,33 +1,29 @@
 // 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:51> col:51 h '__hlsl_resource_t
+// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 3]]:3, col:51> col:51 h '__hlsl_resource_t
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
-// CHECK-SAME: ':'__hlsl_resource_t'
 struct MyBuffer {
   __hlsl_resource_t [[hlsl::resource_class(UAV)]] h;
 };
 
-// CHECK: VarDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 3]]:1, col:49> col:49 res '__hlsl_resource_t
+// CHECK: VarDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 2]]:1, col:49> col:49 res '__hlsl_resource_t
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
-// CHECK-SAME: ':'__hlsl_resource_t'
 __hlsl_resource_t [[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: FunctionDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 3]]:1, line:[[# @LINE + 5]]:1> line:[[# @LINE + 3]]:6 f 'void ()
 // CHECK: VarDecl 0x{{[0-9a-f]+}} <col:3, col:55> col:55 r '__hlsl_resource_t
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(Sampler)]]
-// CHECK-SAME: ':'__hlsl_resource_t'
 void f() {
   __hlsl_resource_t [[hlsl::resource_class(Sampler)]] r;
 }
 
-// CHECK: ClassTemplateDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 7]]:1, line:[[# @LINE + 9]]:1> line:[[# @LINE + 7]]:29 MyBuffer2
+// CHECK: ClassTemplateDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 6]]:1, line:[[# @LINE + 8]]:1> line:[[# @LINE + 6]]:29 MyBuffer2
 // CHECK: TemplateTypeParmDecl 0x{{[0-9a-f]+}} <col:10, col:19> col:19 typename depth 0 index 0 T
-// CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} <col:22, line:[[# @LINE + 7]]:1> line:[[# @LINE + 5]]:29 struct MyBuffer2 definition
+// CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} <col:22, line:[[# @LINE + 6]]:1> line:[[# @LINE + 4]]:29 struct MyBuffer2 definition
 // CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} <col:22, col:29> col:29 implicit struct MyBuffer2
-// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 4]]:3, col:51> col:51 h '__hlsl_resource_t
+// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:[[# @LINE + 3]]:3, col:51> col:51 h '__hlsl_resource_t
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
-// CHECK-SAME: ':'__hlsl_resource_t'
 template<typename T> struct MyBuffer2 {
   __hlsl_resource_t [[hlsl::resource_class(UAV)]] h;
 };
@@ -38,5 +34,4 @@ template<typename T> struct MyBuffer2 {
 // CHECK: CXXRecordDecl 0x{{[0-9a-f]+}} <col:22, col:29> col:29 implicit struct MyBuffer2
 // CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:[[# @LINE - 7]]:3, col:51> col:51 h '__hlsl_resource_t
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
-// CHECK-SAME: ':'__hlsl_resource_t'
 MyBuffer2<float> myBuffer2;
diff --git a/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
index 5e4ed96561a300..9083163edd036d 100644
--- a/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
+++ b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
@@ -6,7 +6,6 @@
 // CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit h 'float *
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
 // CHECK-SAME{LITERAL}: [[hlsl::contained_type(float)]]
-// CHECK-SAME: ':'float *'
 // CHECK: -HLSLResourceAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit TypedBuffer
 RWBuffer<float> Buffer1;
 
@@ -18,6 +17,5 @@ RWBuffer<float> Buffer1;
 // CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]
 // CHECK-SAME{LITERAL}: [[hlsl::is_rov]]
 // CHECK-SAME{LITERAL}: [[hlsl::contained_type(vector<float, 4>)]]
-// CHECK-SAME: ':'vector<float *, 4>'
 // CHECK: -HLSLResourceAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit TypedBuffer
 RasterizerOrderedBuffer<vector<float, 4> > BufferArray3[4];

>From e84c90246c4bdd1f0301ce88ac9055dfa3a9c5b0 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Mon, 30 Sep 2024 12:29:34 -0700
Subject: [PATCH 2/9] Rearrange the getHLSLType code and map resource class to
 HLSL virtual register letter for mangling

---
 clang/lib/AST/ItaniumMangle.cpp               |  9 ++---
 clang/lib/AST/MicrosoftMangle.cpp             |  9 ++---
 clang/lib/CodeGen/Targets/DirectX.cpp         | 36 ++++++++-----------
 .../CodeGenHLSL/builtins/hlsl_resource_t.hlsl |  8 ++---
 4 files changed, 28 insertions(+), 34 deletions(-)

diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 43fe85505ff542..7feb60e109ec3e 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -4495,18 +4495,19 @@ void CXXNameMangler::mangleType(const ArrayParameterType *T) {
 void CXXNameMangler::mangleType(const HLSLAttributedResourceType *T) {
   mangleType(T->getWrappedType());
   const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
+  // map resource class to HLSL virtual register letter
   switch (Attrs.ResourceClass) {
   case llvm::dxil::ResourceClass::UAV:
-    Out << 'U';
+    Out << 'u';
     break;
   case llvm::dxil::ResourceClass::SRV:
-    Out << 'T';
+    Out << 't';
     break;
   case llvm::dxil::ResourceClass::CBuffer:
-    Out << 'C';
+    Out << 'b';
     break;
   case llvm::dxil::ResourceClass::Sampler:
-    Out << 'S';
+    Out << 's';
     break;
   }
   mangleNumber(Attrs.IsROV);
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 16df5c99c623ce..a96000c294ec9a 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -3758,18 +3758,19 @@ void MicrosoftCXXNameMangler::mangleType(const HLSLAttributedResourceType *T,
                                          Qualifiers, SourceRange Range) {
   mangleType(T->getWrappedType(), SourceRange(), QMM_Escape);
   const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
+  // map resource class to HLSL virtual register letter
   switch (Attrs.ResourceClass) {
   case llvm::dxil::ResourceClass::UAV:
-    Out << 'U';
+    Out << 'u';
     break;
   case llvm::dxil::ResourceClass::SRV:
-    Out << 'T';
+    Out << 't';
     break;
   case llvm::dxil::ResourceClass::CBuffer:
-    Out << 'C';
+    Out << 'b';
     break;
   case llvm::dxil::ResourceClass::Sampler:
-    Out << 'S';
+    Out << 's';
     break;
   }
   mangleNumber(Attrs.IsROV);
diff --git a/clang/lib/CodeGen/Targets/DirectX.cpp b/clang/lib/CodeGen/Targets/DirectX.cpp
index cf6ac849777369..a33398657f7dd8 100644
--- a/clang/lib/CodeGen/Targets/DirectX.cpp
+++ b/clang/lib/CodeGen/Targets/DirectX.cpp
@@ -38,31 +38,23 @@ llvm::Type *DirectXTargetCodeGenInfo::getHLSLType(CodeGenModule &CGM,
   switch (ResAttrs.ResourceClass) {
   case llvm::dxil::ResourceClass::UAV:
   case llvm::dxil::ResourceClass::SRV: {
-    // convert element type
+    // TypedBuffer and RawBuffer both need element type
     QualType ContainedTy = ResType->getContainedType();
-    llvm::Type *ElemType = nullptr;
-    if (!ContainedTy.isNull())
-      ElemType = CGM.getTypes().ConvertType(ContainedTy);
-
-    if (ResAttrs.RawBuffer) {
-      // RawBuffer needs element type
-      if (ContainedTy.isNull())
-        return nullptr;
-      return llvm::TargetExtType::get(Ctx, "dx.RawBuffer", {ElemType},
-                                      {/*IsWriteable*/ ResAttrs.ResourceClass ==
-                                           llvm::dxil::ResourceClass::UAV,
-                                       /*IsROV*/ ResAttrs.IsROV});
-    }
-
-    // TypedBuffer needs element type
     if (ContainedTy.isNull())
       return nullptr;
-    return llvm::TargetExtType::get(
-        Ctx, "dx.TypedBuffer", {ElemType},
-        {/*IsWriteable*/ ResAttrs.ResourceClass ==
-             llvm::dxil::ResourceClass::UAV,
-         /*IsROV*/ ResAttrs.IsROV,
-         /*IsSigned*/ ContainedTy->isSignedIntegerType()});
+
+    // convert element type
+    llvm::Type *ElemType = CGM.getTypes().ConvertType(ContainedTy);
+
+    const char* TypeName = ResAttrs.RawBuffer ? "dx.RawBuffer" : "dx.TypedBuffer";
+    SmallVector<unsigned, 3> Ints = {
+      /*IsWriteable*/ ResAttrs.ResourceClass == llvm::dxil::ResourceClass::UAV,
+      /*IsROV*/ ResAttrs.IsROV
+    };
+    if (!ResAttrs.RawBuffer)
+      Ints.push_back(/*IsSigned*/ ContainedTy->isSignedIntegerType());
+    
+    return llvm::TargetExtType::get(Ctx, TypeName, {ElemType}, Ints);
   }
   case llvm::dxil::ResourceClass::CBuffer:
     llvm_unreachable("dx.CBuffer handles are not implemented yet");
diff --git a/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl b/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl
index 8d3a2b39530029..1d085c3230987c 100644
--- a/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl
@@ -5,9 +5,9 @@ using handle_float_t = __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::c
 // CHECK: %"class.hlsl::RWBuffer" = type { target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
 // CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", %struct.MyStruct = type { <4 x float>, <2 x i32>, [8 x i8] }, 1, 0)
 
-// CHECK: define void @"?fa@@YAXU__hlsl_resource_t@@UA at A@M at Z"(ptr noundef byval(target("dx.TypedBuffer", float, 1, 0, 0)) align 4 %a)
-// CHECK: call void @"?foo1@@YAXU__hlsl_resource_t@@UA at A@M at Z"(ptr noundef byval(target("dx.TypedBuffer", float, 1, 0, 0)) align 4 %a)
-// CHECK: declare void @"?foo1@@YAXU__hlsl_resource_t@@UA at A@M at Z"(ptr noundef byval(target("dx.TypedBuffer", float, 1, 0, 0)) align 4)
+// CHECK: define void @"?fa@@YAXU__hlsl_resource_t@@uA at A@M at Z"(ptr noundef byval(target("dx.TypedBuffer", float, 1, 0, 0)) align 4 %a)
+// CHECK: call void @"?foo1@@YAXU__hlsl_resource_t@@uA at A@M at Z"(ptr noundef byval(target("dx.TypedBuffer", float, 1, 0, 0)) align 4 %a)
+// CHECK: declare void @"?foo1@@YAXU__hlsl_resource_t@@uA at A@M at Z"(ptr noundef byval(target("dx.TypedBuffer", float, 1, 0, 0)) align 4)
 
 void foo1(handle_float_t res);
 
@@ -15,7 +15,7 @@ void fa(handle_float_t a) {
     foo1(a);
 }
 
-// CHECK: define void @"?fb@@YAXU__hlsl_resource_t@@UA at A@M at Z"(ptr noundef byval(target("dx.TypedBuffer", float, 1, 0, 0)) align 4 %a)
+// CHECK: define void @"?fb@@YAXU__hlsl_resource_t@@uA at A@M at Z"(ptr noundef byval(target("dx.TypedBuffer", float, 1, 0, 0)) align 4 %a)
 void fb(handle_float_t a) {
     handle_float_t b = a;
 }

>From c163d064d8ef884745e0e1edebc6bf09fb4a409d Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Mon, 30 Sep 2024 13:08:13 -0700
Subject: [PATCH 3/9] clang-format

---
 clang/lib/CodeGen/Targets/DirectX.cpp | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/clang/lib/CodeGen/Targets/DirectX.cpp b/clang/lib/CodeGen/Targets/DirectX.cpp
index a33398657f7dd8..2a9fb340cf5daf 100644
--- a/clang/lib/CodeGen/Targets/DirectX.cpp
+++ b/clang/lib/CodeGen/Targets/DirectX.cpp
@@ -46,14 +46,14 @@ llvm::Type *DirectXTargetCodeGenInfo::getHLSLType(CodeGenModule &CGM,
     // convert element type
     llvm::Type *ElemType = CGM.getTypes().ConvertType(ContainedTy);
 
-    const char* TypeName = ResAttrs.RawBuffer ? "dx.RawBuffer" : "dx.TypedBuffer";
-    SmallVector<unsigned, 3> Ints = {
-      /*IsWriteable*/ ResAttrs.ResourceClass == llvm::dxil::ResourceClass::UAV,
-      /*IsROV*/ ResAttrs.IsROV
-    };
+    const char *TypeName =
+        ResAttrs.RawBuffer ? "dx.RawBuffer" : "dx.TypedBuffer";
+    SmallVector<unsigned, 3> Ints = {/*IsWriteable*/ ResAttrs.ResourceClass ==
+                                         llvm::dxil::ResourceClass::UAV,
+                                     /*IsROV*/ ResAttrs.IsROV};
     if (!ResAttrs.RawBuffer)
       Ints.push_back(/*IsSigned*/ ContainedTy->isSignedIntegerType());
-    
+
     return llvm::TargetExtType::get(Ctx, TypeName, {ElemType}, Ints);
   }
   case llvm::dxil::ResourceClass::CBuffer:

>From 2ecca538c97e7acf660e087a7a1b186047886bb9 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Tue, 1 Oct 2024 10:55:56 -0700
Subject: [PATCH 4/9] Update HLSLAttributedResourceType evaluation kind to
 TEK_Scalar (was TEK_Aggregate)

TEK_Aggregate is not a good fit for the resource type.
---
 clang/lib/CodeGen/CodeGenFunction.cpp                | 2 +-
 clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index ddbd5e2f1aa311..fc9cad30a6066f 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -282,6 +282,7 @@ TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) {
     case Type::ObjCObjectPointer:
     case Type::Pipe:
     case Type::BitInt:
+    case Type::HLSLAttributedResource:
       return TEK_Scalar;
 
     // Complexes.
@@ -296,7 +297,6 @@ TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) {
     case Type::ObjCObject:
     case Type::ObjCInterface:
     case Type::ArrayParameter:
-    case Type::HLSLAttributedResource:
       return TEK_Aggregate;
 
     // We operate on atomic values according to their underlying type.
diff --git a/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl b/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl
index 1d085c3230987c..26b057136d4055 100644
--- a/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl
@@ -5,9 +5,9 @@ using handle_float_t = __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::c
 // CHECK: %"class.hlsl::RWBuffer" = type { target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
 // CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", %struct.MyStruct = type { <4 x float>, <2 x i32>, [8 x i8] }, 1, 0)
 
-// CHECK: define void @"?fa@@YAXU__hlsl_resource_t@@uA at A@M at Z"(ptr noundef byval(target("dx.TypedBuffer", float, 1, 0, 0)) align 4 %a)
-// CHECK: call void @"?foo1@@YAXU__hlsl_resource_t@@uA at A@M at Z"(ptr noundef byval(target("dx.TypedBuffer", float, 1, 0, 0)) align 4 %a)
-// CHECK: declare void @"?foo1@@YAXU__hlsl_resource_t@@uA at A@M at Z"(ptr noundef byval(target("dx.TypedBuffer", float, 1, 0, 0)) align 4)
+// CHECK: define void @"?fa@@YAXU__hlsl_resource_t@@uA at A@M at Z"(target("dx.TypedBuffer", float, 1, 0, 0) %a)
+// CHECK: call void @"?foo1@@YAXU__hlsl_resource_t@@uA at A@M at Z"(target("dx.TypedBuffer", float, 1, 0, 0)
+// CHECK: declare void @"?foo1@@YAXU__hlsl_resource_t@@uA at A@M at Z"(target("dx.TypedBuffer", float, 1, 0, 0))
 
 void foo1(handle_float_t res);
 
@@ -15,7 +15,7 @@ void fa(handle_float_t a) {
     foo1(a);
 }
 
-// CHECK: define void @"?fb@@YAXU__hlsl_resource_t@@uA at A@M at Z"(ptr noundef byval(target("dx.TypedBuffer", float, 1, 0, 0)) align 4 %a)
+// CHECK: define void @"?fb@@YAXU__hlsl_resource_t@@uA at A@M at Z"(target("dx.TypedBuffer", float, 1, 0, 0) %a)
 void fb(handle_float_t a) {
     handle_float_t b = a;
 }

>From fa0b778d873d5a270e64e8d31046ec5ed7c74b8d Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Wed, 2 Oct 2024 10:49:13 -0700
Subject: [PATCH 5/9] update mangling based on feedback

---
 clang/lib/AST/ItaniumMangle.cpp               | 26 ++++++++++++-------
 clang/lib/AST/MicrosoftMangle.cpp             | 23 +---------------
 .../CodeGenHLSL/builtins/hlsl_resource_t.hlsl |  8 +++---
 3 files changed, 21 insertions(+), 36 deletions(-)

diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 7feb60e109ec3e..93a7da5c27cf27 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -4493,28 +4493,34 @@ void CXXNameMangler::mangleType(const ArrayParameterType *T) {
 }
 
 void CXXNameMangler::mangleType(const HLSLAttributedResourceType *T) {
-  mangleType(T->getWrappedType());
+  llvm::SmallString<64> Str("_Res");
   const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
   // map resource class to HLSL virtual register letter
   switch (Attrs.ResourceClass) {
-  case llvm::dxil::ResourceClass::UAV:
-    Out << 'u';
+  case llvm::dxil::ResourceClass::UAV: 
+    Str += "_u";
     break;
-  case llvm::dxil::ResourceClass::SRV:
-    Out << 't';
+  case llvm::dxil::ResourceClass::SRV: 
+    Str += "_t";
     break;
   case llvm::dxil::ResourceClass::CBuffer:
-    Out << 'b';
+    Str += "_b";
     break;
   case llvm::dxil::ResourceClass::Sampler:
-    Out << 's';
+    Str += "_s";
     break;
   }
-  mangleNumber(Attrs.IsROV);
-  mangleNumber(Attrs.RawBuffer);
+  mangleVendorQualifier(Str);
+  if (Attrs.IsROV)
+    mangleVendorQualifier("_ROV");
+  if (Attrs.RawBuffer)
+    mangleVendorQualifier("_Raw");
 
-  if (!T->hasContainedType())
+  if (!T->hasContainedType()) {
+    mangleVendorQualifier("__CT");
     mangleType(T->getContainedType());
+  }
+  mangleType(T->getWrappedType());
 }
 
 void CXXNameMangler::mangleIntegerLiteral(QualType T,
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index a96000c294ec9a..4f8404bfb4ce13 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -3756,28 +3756,7 @@ void MicrosoftCXXNameMangler::mangleType(const DependentBitIntType *T,
 
 void MicrosoftCXXNameMangler::mangleType(const HLSLAttributedResourceType *T,
                                          Qualifiers, SourceRange Range) {
-  mangleType(T->getWrappedType(), SourceRange(), QMM_Escape);
-  const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
-  // map resource class to HLSL virtual register letter
-  switch (Attrs.ResourceClass) {
-  case llvm::dxil::ResourceClass::UAV:
-    Out << 'u';
-    break;
-  case llvm::dxil::ResourceClass::SRV:
-    Out << 't';
-    break;
-  case llvm::dxil::ResourceClass::CBuffer:
-    Out << 'b';
-    break;
-  case llvm::dxil::ResourceClass::Sampler:
-    Out << 's';
-    break;
-  }
-  mangleNumber(Attrs.IsROV);
-  mangleNumber(Attrs.RawBuffer);
-
-  if (T->hasContainedType())
-    mangleType(T->getContainedType(), SourceRange(), QMM_Escape);
+  mangleArtificialTagType(TagTypeKind::Struct, "HLSLAttributedResourceType", {"__hlsl"});
 }
 
 // <this-adjustment> ::= <no-adjustment> | <static-adjustment> |
diff --git a/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl b/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl
index 26b057136d4055..329f1b65b2af30 100644
--- a/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl
@@ -5,9 +5,9 @@ using handle_float_t = __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::c
 // CHECK: %"class.hlsl::RWBuffer" = type { target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
 // CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", %struct.MyStruct = type { <4 x float>, <2 x i32>, [8 x i8] }, 1, 0)
 
-// CHECK: define void @"?fa@@YAXU__hlsl_resource_t@@uA at A@M at Z"(target("dx.TypedBuffer", float, 1, 0, 0) %a)
-// CHECK: call void @"?foo1@@YAXU__hlsl_resource_t@@uA at A@M at Z"(target("dx.TypedBuffer", float, 1, 0, 0)
-// CHECK: declare void @"?foo1@@YAXU__hlsl_resource_t@@uA at A@M at Z"(target("dx.TypedBuffer", float, 1, 0, 0))
+// CHECK: define void @"?fa@@YAXUHLSLAttributedResourceType at __hlsl@@@Z"(target("dx.TypedBuffer", float, 1, 0, 0) %a)
+// CHECK: call void @"?foo1@@YAXUHLSLAttributedResourceType at __hlsl@@@Z"(target("dx.TypedBuffer", float, 1, 0, 0) %0)
+// CHECK: declare void @"?foo1@@YAXUHLSLAttributedResourceType at __hlsl@@@Z"(target("dx.TypedBuffer", float, 1, 0, 0))
 
 void foo1(handle_float_t res);
 
@@ -15,7 +15,7 @@ void fa(handle_float_t a) {
     foo1(a);
 }
 
-// CHECK: define void @"?fb@@YAXU__hlsl_resource_t@@uA at A@M at Z"(target("dx.TypedBuffer", float, 1, 0, 0) %a)
+// CHECK: define void @"?fb@@YAXUHLSLAttributedResourceType at __hlsl@@@Z"(target("dx.TypedBuffer", float, 1, 0, 0) %a)
 void fb(handle_float_t a) {
     handle_float_t b = a;
 }

>From 0fe1bce70a447271950c4563cf22c19dab27cd09 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Wed, 2 Oct 2024 11:25:11 -0700
Subject: [PATCH 6/9] clang-format

---
 clang/lib/AST/ItaniumMangle.cpp   | 4 ++--
 clang/lib/AST/MicrosoftMangle.cpp | 3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 93a7da5c27cf27..0ff73e8e3c328d 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -4497,10 +4497,10 @@ void CXXNameMangler::mangleType(const HLSLAttributedResourceType *T) {
   const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();
   // map resource class to HLSL virtual register letter
   switch (Attrs.ResourceClass) {
-  case llvm::dxil::ResourceClass::UAV: 
+  case llvm::dxil::ResourceClass::UAV:
     Str += "_u";
     break;
-  case llvm::dxil::ResourceClass::SRV: 
+  case llvm::dxil::ResourceClass::SRV:
     Str += "_t";
     break;
   case llvm::dxil::ResourceClass::CBuffer:
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 4f8404bfb4ce13..85a0e5633db9d7 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -3756,7 +3756,8 @@ void MicrosoftCXXNameMangler::mangleType(const DependentBitIntType *T,
 
 void MicrosoftCXXNameMangler::mangleType(const HLSLAttributedResourceType *T,
                                          Qualifiers, SourceRange Range) {
-  mangleArtificialTagType(TagTypeKind::Struct, "HLSLAttributedResourceType", {"__hlsl"});
+  mangleArtificialTagType(TagTypeKind::Struct, "HLSLAttributedResourceType",
+                          {"__hlsl"});
 }
 
 // <this-adjustment> ::= <no-adjustment> | <static-adjustment> |

>From 7710bfb6ea054de760552ad6e57715df5ccb6cf6 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Tue, 8 Oct 2024 21:38:30 -0700
Subject: [PATCH 7/9] cr feedback - remove include, update error messages

---
 clang/lib/AST/ASTContext.cpp          | 6 ++----
 clang/lib/AST/MicrosoftMangle.cpp     | 1 -
 clang/lib/CodeGen/ItaniumCXXABI.cpp   | 4 ++--
 clang/lib/CodeGen/Targets/DirectX.cpp | 2 +-
 4 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 9b47b8e3491bb0..a3a728b1d3f5c4 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -3438,7 +3438,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
     return;
   }
   case Type::HLSLAttributedResource:
-    llvm_unreachable("not yet implemented");
+    llvm_unreachable("should never get here");
     break;
   case Type::DeducedTemplateSpecialization:
   case Type::Auto:
@@ -13386,6 +13386,7 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
     SUGAR_FREE_TYPE(Record)
     SUGAR_FREE_TYPE(SubstTemplateTypeParmPack)
     SUGAR_FREE_TYPE(UnresolvedUsing)
+    SUGAR_FREE_TYPE(HLSLAttributedResource)
 #undef SUGAR_FREE_TYPE
 #define NON_UNIQUE_TYPE(Class) UNEXPECTED_TYPE(Class, "non-unique")
     NON_UNIQUE_TYPE(TypeOfExpr)
@@ -13690,9 +13691,6 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
         TX->getDepth(), TX->getIndex(), TX->isParameterPack(),
         getCommonDecl(TX->getDecl(), TY->getDecl()));
   }
-  case Type::HLSLAttributedResource: {
-    llvm_unreachable("not yet implemented");
-  }
   }
   llvm_unreachable("Unknown Type Class");
 }
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index 85a0e5633db9d7..82e9f5d5b27233 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -32,7 +32,6 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/CRC.h"
-#include "llvm/Support/DXILABI.h"
 #include "llvm/Support/MD5.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/StringSaver.h"
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 8533ccb2129c34..406536cfdd17d3 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3945,7 +3945,7 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
     break;
 
   case Type::HLSLAttributedResource:
-    llvm_unreachable("not yet implemented");
+    llvm_unreachable("HLSL doesn't support virtual functions");
   }
 
   llvm::Constant *VTable = nullptr;
@@ -4210,7 +4210,7 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
     break;
 
   case Type::HLSLAttributedResource:
-    llvm_unreachable("not yet implemented");
+    llvm_unreachable("HLSL doesn't support RTTI");
   }
 
   llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
diff --git a/clang/lib/CodeGen/Targets/DirectX.cpp b/clang/lib/CodeGen/Targets/DirectX.cpp
index 2a9fb340cf5daf..303a4309d62fcf 100644
--- a/clang/lib/CodeGen/Targets/DirectX.cpp
+++ b/clang/lib/CodeGen/Targets/DirectX.cpp
@@ -46,7 +46,7 @@ llvm::Type *DirectXTargetCodeGenInfo::getHLSLType(CodeGenModule &CGM,
     // convert element type
     llvm::Type *ElemType = CGM.getTypes().ConvertType(ContainedTy);
 
-    const char *TypeName =
+    llvm::StringRef TypeName =
         ResAttrs.RawBuffer ? "dx.RawBuffer" : "dx.TypedBuffer";
     SmallVector<unsigned, 3> Ints = {/*IsWriteable*/ ResAttrs.ResourceClass ==
                                          llvm::dxil::ResourceClass::UAV,

>From 869ddc54b09b53c3ed60032f570135a354c97f9d Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Thu, 10 Oct 2024 08:40:24 -0700
Subject: [PATCH 8/9] cr feedback - update itanium mangling of flags, do not
 compare wrapped type

---
 clang/lib/AST/ASTContext.cpp    |  8 +++++---
 clang/lib/AST/ItaniumMangle.cpp | 11 ++++++-----
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index a3a728b1d3f5c4..93ad5f8bede4ca 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -11544,10 +11544,12 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, bool OfBlockPointer,
         LHS->castAs<HLSLAttributedResourceType>();
     const HLSLAttributedResourceType *RHSTy =
         RHS->castAs<HLSLAttributedResourceType>();
+    assert(LHSTy->getWrappedType() == RHSTy->getWrappedType() &&
+           LHSTy->getWrappedType()->isHLSLResourceType() &&
+           "HLSLAttributedResourceType should always wrap __hlsl_resource_t");
 
-    if (LHSTy->getWrappedType() == RHSTy->getWrappedType() &&
-        LHSTy->getContainedType() == RHSTy->getContainedType() &&
-        LHSTy->getAttrs() == RHSTy->getAttrs())
+    if (LHSTy->getAttrs() == RHSTy->getAttrs() &&
+        LHSTy->getContainedType() == RHSTy->getContainedType())
       return LHS;
     return {};
   }
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 0ff73e8e3c328d..5890abcd1e965c 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -4510,14 +4510,15 @@ void CXXNameMangler::mangleType(const HLSLAttributedResourceType *T) {
     Str += "_s";
     break;
   }
-  mangleVendorQualifier(Str);
   if (Attrs.IsROV)
-    mangleVendorQualifier("_ROV");
+    Str += "_ROV";
   if (Attrs.RawBuffer)
-    mangleVendorQualifier("_Raw");
+    Str += "_Raw";
+  if (T->hasContainedType())
+    Str += "_CT";
+  mangleVendorQualifier(Str);
 
-  if (!T->hasContainedType()) {
-    mangleVendorQualifier("__CT");
+  if (T->hasContainedType()) {
     mangleType(T->getContainedType());
   }
   mangleType(T->getWrappedType());

>From ddf3d05172014310774acc721c0f2c25e001a389 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Thu, 10 Oct 2024 18:26:00 -0700
Subject: [PATCH 9/9] update tests after merge

---
 clang/lib/AST/MicrosoftMangle.cpp             |  3 +-
 .../builtins/RWBuffer-elementtype.hlsl        | 30 +++++++++++--------
 .../StructuredBuffer-elementtype.hlsl         | 30 +++++++++++--------
 .../CodeGenHLSL/builtins/hlsl_resource_t.hlsl | 20 ++++++-------
 4 files changed, 45 insertions(+), 38 deletions(-)

diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index ef63c1c283dc70..3931fcaa352961 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -3756,8 +3756,7 @@ void MicrosoftCXXNameMangler::mangleType(const DependentBitIntType *T,
 
 void MicrosoftCXXNameMangler::mangleType(const HLSLAttributedResourceType *T,
                                          Qualifiers, SourceRange Range) {
-  mangleArtificialTagType(TagTypeKind::Struct, "HLSLAttributedResourceType",
-                          {"__hlsl"});
+  llvm_unreachable("HLSL uses Itanium name mangling");
 }
 
 // <this-adjustment> ::= <no-adjustment> | <static-adjustment> |
diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl
index dae16aaea00a64..fa81b53fd9bddc 100644
--- a/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-elementtype.hlsl
@@ -1,18 +1,22 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.2-compute -finclude-default-header -fnative-half-type -emit-llvm -o - %s | FileCheck %s
 
-// CHECK: %"class.hlsl::RWBuffer" = type { target("dx.TypedBuffer", i16, 1, 0, 1), i16 }
-// CHECK: %"class.hlsl::RWBuffer.0" = type { target("dx.TypedBuffer", i16, 1, 0, 0), i16 }
-// CHECK: %"class.hlsl::RWBuffer.1" = type { target("dx.TypedBuffer", i32, 1, 0, 1), i32 }
-// CHECK: %"class.hlsl::RWBuffer.2" = type { target("dx.TypedBuffer", i32, 1, 0, 0), i32 }
-// CHECK: %"class.hlsl::RWBuffer.3" = type { target("dx.TypedBuffer", i64, 1, 0, 1), i64 }
-// CHECK: %"class.hlsl::RWBuffer.4" = type { target("dx.TypedBuffer", i64, 1, 0, 0), i64 }
-// CHECK: %"class.hlsl::RWBuffer.5" = type { target("dx.TypedBuffer", half, 1, 0, 0), half }
-// CHECK: %"class.hlsl::RWBuffer.6" = type { target("dx.TypedBuffer", float, 1, 0, 0), float }
-// CHECK: %"class.hlsl::RWBuffer.7" = type { target("dx.TypedBuffer", double, 1, 0, 0), double }
-// CHECK: %"class.hlsl::RWBuffer.8" = type { target("dx.TypedBuffer", <4 x i16>, 1, 0, 0), <4 x i16> }
-// CHECK: %"class.hlsl::RWBuffer.9" = type { target("dx.TypedBuffer", <3 x i32>, 1, 0, 0), <3 x i32> }
-// CHECK: %"class.hlsl::RWBuffer.10" = type { target("dx.TypedBuffer", <2 x half>, 1, 0, 0), <2 x half> }
-// CHECK: %"class.hlsl::RWBuffer.11" = type { target("dx.TypedBuffer", <3 x float>, 1, 0, 0), <3 x float> }
+// NOTE: The type name number and whether the struct is packed or not will mostly
+// likely change once subscript operators are properly implemented (llvm/llvm-project#95956) 
+// and theinterim field of the contained type is removed.
+
+// CHECK: %"class.hlsl::RWBuffer" = type <{ target("dx.TypedBuffer", i16, 1, 0, 1)
+// CHECK: %"class.hlsl::RWBuffer.0" = type <{ target("dx.TypedBuffer", i16, 1, 0, 0)
+// CHECK: %"class.hlsl::RWBuffer.2" = type { target("dx.TypedBuffer", i32, 1, 0, 1)
+// CHECK: %"class.hlsl::RWBuffer.3" = type { target("dx.TypedBuffer", i32, 1, 0, 0)
+// CHECK: %"class.hlsl::RWBuffer.4" = type { target("dx.TypedBuffer", i64, 1, 0, 1)
+// CHECK: %"class.hlsl::RWBuffer.5" = type { target("dx.TypedBuffer", i64, 1, 0, 0)
+// CHECK: %"class.hlsl::RWBuffer.6" = type <{ target("dx.TypedBuffer", half, 1, 0, 0)
+// CHECK: %"class.hlsl::RWBuffer.8" = type { target("dx.TypedBuffer", float, 1, 0, 0)
+// CHECK: %"class.hlsl::RWBuffer.9" = type { target("dx.TypedBuffer", double, 1, 0, 0)
+// CHECK: %"class.hlsl::RWBuffer.10" = type { target("dx.TypedBuffer", <4 x i16>, 1, 0, 0)
+// CHECK: %"class.hlsl::RWBuffer.11" = type { target("dx.TypedBuffer", <3 x i32>, 1, 0, 0)
+// CHECK: %"class.hlsl::RWBuffer.12" = type { target("dx.TypedBuffer", <2 x half>, 1, 0, 0)
+// CHECK: %"class.hlsl::RWBuffer.13" = type { target("dx.TypedBuffer", <3 x float>, 1, 0, 0)
 
 RWBuffer<int16_t> BufI16;
 RWBuffer<uint16_t> BufU16;
diff --git a/clang/test/CodeGenHLSL/builtins/StructuredBuffer-elementtype.hlsl b/clang/test/CodeGenHLSL/builtins/StructuredBuffer-elementtype.hlsl
index c1c663d17e41ce..a99c7f98a1afb6 100644
--- a/clang/test/CodeGenHLSL/builtins/StructuredBuffer-elementtype.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/StructuredBuffer-elementtype.hlsl
@@ -1,18 +1,22 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.2-compute -finclude-default-header -fnative-half-type -emit-llvm -o - %s | FileCheck %s
 
-// CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", i16, 1, 0), i16 }
-// CHECK: %"class.hlsl::StructuredBuffer.0" = type { target("dx.RawBuffer", i16, 1, 0), i16 }
-// CHECK: %"class.hlsl::StructuredBuffer.1" = type { target("dx.RawBuffer", i32, 1, 0), i32 }
-// CHECK: %"class.hlsl::StructuredBuffer.2" = type { target("dx.RawBuffer", i32, 1, 0), i32 }
-// CHECK: %"class.hlsl::StructuredBuffer.3" = type { target("dx.RawBuffer", i64, 1, 0), i64 }
-// CHECK: %"class.hlsl::StructuredBuffer.4" = type { target("dx.RawBuffer", i64, 1, 0), i64 }
-// CHECK: %"class.hlsl::StructuredBuffer.5" = type { target("dx.RawBuffer", half, 1, 0), half }
-// CHECK: %"class.hlsl::StructuredBuffer.6" = type { target("dx.RawBuffer", float, 1, 0), float }
-// CHECK: %"class.hlsl::StructuredBuffer.7" = type { target("dx.RawBuffer", double, 1, 0), double }
-// CHECK: %"class.hlsl::StructuredBuffer.8" = type { target("dx.RawBuffer", <4 x i16>, 1, 0), <4 x i16> }
-// CHECK: %"class.hlsl::StructuredBuffer.9" = type { target("dx.RawBuffer", <3 x i32>, 1, 0), <3 x i32> }
-// CHECK: %"class.hlsl::StructuredBuffer.10" = type { target("dx.RawBuffer", <2 x half>, 1, 0), <2 x half> }
-// CHECK: %"class.hlsl::StructuredBuffer.11" = type { target("dx.RawBuffer", <3 x float>, 1, 0), <3 x float> }
+// NOTE: The number in type name and whether the struct is packed or not will mostly
+// likely change once subscript operators are properly implemented (llvm/llvm-project#95956) 
+// and theinterim field of the contained type is removed.
+
+// CHECK: %"class.hlsl::StructuredBuffer" = type <{ target("dx.RawBuffer", i16, 1, 0)
+// CHECK: %"class.hlsl::StructuredBuffer.0" = type <{ target("dx.RawBuffer", i16, 1, 0)
+// CHECK: %"class.hlsl::StructuredBuffer.2" = type { target("dx.RawBuffer", i32, 1, 0)
+// CHECK: %"class.hlsl::StructuredBuffer.3" = type { target("dx.RawBuffer", i32, 1, 0)
+// CHECK: %"class.hlsl::StructuredBuffer.4" = type { target("dx.RawBuffer", i64, 1, 0)
+// CHECK: %"class.hlsl::StructuredBuffer.5" = type { target("dx.RawBuffer", i64, 1, 0)
+// CHECK: %"class.hlsl::StructuredBuffer.6" = type <{ target("dx.RawBuffer", half, 1, 0) 
+// CHECK: %"class.hlsl::StructuredBuffer.8" = type { target("dx.RawBuffer", float, 1, 0)
+// CHECK: %"class.hlsl::StructuredBuffer.9" = type { target("dx.RawBuffer", double, 1, 0)
+// CHECK: %"class.hlsl::StructuredBuffer.10" = type { target("dx.RawBuffer", <4 x i16>, 1, 0)
+// CHECK: %"class.hlsl::StructuredBuffer.11" = type { target("dx.RawBuffer", <3 x i32>, 1, 0)
+// CHECK: %"class.hlsl::StructuredBuffer.12" = type { target("dx.RawBuffer", <2 x half>, 1, 0)
+// CHECK: %"class.hlsl::StructuredBuffer.13" = type { target("dx.RawBuffer", <3 x float>, 1, 0)
 
 StructuredBuffer<int16_t> BufI16;
 StructuredBuffer<uint16_t> BufU16;
diff --git a/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl b/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl
index 329f1b65b2af30..6751cf2703ce0e 100644
--- a/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl
+++ b/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl
@@ -5,9 +5,9 @@ using handle_float_t = __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::c
 // CHECK: %"class.hlsl::RWBuffer" = type { target("dx.TypedBuffer", <4 x float>, 1, 0, 0)
 // CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", %struct.MyStruct = type { <4 x float>, <2 x i32>, [8 x i8] }, 1, 0)
 
-// CHECK: define void @"?fa@@YAXUHLSLAttributedResourceType at __hlsl@@@Z"(target("dx.TypedBuffer", float, 1, 0, 0) %a)
-// CHECK: call void @"?foo1@@YAXUHLSLAttributedResourceType at __hlsl@@@Z"(target("dx.TypedBuffer", float, 1, 0, 0) %0)
-// CHECK: declare void @"?foo1@@YAXUHLSLAttributedResourceType at __hlsl@@@Z"(target("dx.TypedBuffer", float, 1, 0, 0))
+// CHECK: define void @_Z2faU9_Res_u_CTfu17__hlsl_resource_t(target("dx.TypedBuffer", float, 1, 0, 0) %a)
+// CHECK: call void @_Z4foo1U9_Res_u_CTfu17__hlsl_resource_t(target("dx.TypedBuffer", float, 1, 0, 0) %0)
+// CHECK: declare void @_Z4foo1U9_Res_u_CTfu17__hlsl_resource_t(target("dx.TypedBuffer", float, 1, 0, 0))
 
 void foo1(handle_float_t res);
 
@@ -15,14 +15,14 @@ void fa(handle_float_t a) {
     foo1(a);
 }
 
-// CHECK: define void @"?fb@@YAXUHLSLAttributedResourceType at __hlsl@@@Z"(target("dx.TypedBuffer", float, 1, 0, 0) %a)
+// CHECK: define void @_Z2fbU9_Res_u_CTfu17__hlsl_resource_t(target("dx.TypedBuffer", float, 1, 0, 0) %a)
 void fb(handle_float_t a) {
     handle_float_t b = a;
 }
 
-// CHECK: define void @"?fc@@YAXV?$RWBuffer at T?$__vector at M$03 at __clang@@@hlsl@@@Z"(ptr noundef byval(%"class.hlsl::RWBuffer") align 16 %a)
-// CHECK: call void @"?foo2@@YAXV?$RWBuffer at T?$__vector at M$03 at __clang@@@hlsl@@@Z"(ptr noundef byval(%"class.hlsl::RWBuffer") align 16 %agg.tmp)  
-// CHECK: declare void @"?foo2@@YAXV?$RWBuffer at T?$__vector at M$03 at __clang@@@hlsl@@@Z"(ptr noundef byval(%"class.hlsl::RWBuffer") align 16)
+// CHECK: define void @_Z2fcN4hlsl8RWBufferIDv4_fEE(ptr noundef byval(%"class.hlsl::RWBuffer") align 16 %a)
+// CHECK: call void @_Z4foo2N4hlsl8RWBufferIDv4_fEE(ptr noundef byval(%"class.hlsl::RWBuffer") align 16 %agg.tmp)
+// CHECK: declare void @_Z4foo2N4hlsl8RWBufferIDv4_fEE(ptr noundef byval(%"class.hlsl::RWBuffer") align 16)
 void foo2(RWBuffer<float4> buf);
 
 void fc(RWBuffer<float4> a) {
@@ -38,9 +38,9 @@ struct MyStruct {
   int2 i;
 };
 
-// CHECK: define void @"?fe@@YAXV?$StructuredBuffer at UMyStruct@@@hlsl@@@Z"(ptr noundef byval(%"class.hlsl::StructuredBuffer") align 16 %a)
-// CHECK: call void @"?foo3@@YAXV?$StructuredBuffer at UMyStruct@@@hlsl@@@Z"(ptr noundef byval(%"class.hlsl::StructuredBuffer") align 16 %agg.tmp)
-// CHECK: declare void @"?foo3@@YAXV?$StructuredBuffer at UMyStruct@@@hlsl@@@Z"(ptr noundef byval(%"class.hlsl::StructuredBuffer") align 16)
+// CHECK: define void @_Z2feN4hlsl16StructuredBufferI8MyStructEE(ptr noundef byval(%"class.hlsl::StructuredBuffer") align 16 %a)
+// CHECK: call void @_Z4foo3N4hlsl16StructuredBufferI8MyStructEE(ptr noundef byval(%"class.hlsl::StructuredBuffer") align 16 %agg.tmp)
+// CHECK: declare void @_Z4foo3N4hlsl16StructuredBufferI8MyStructEE(ptr noundef byval(%"class.hlsl::StructuredBuffer") align 16)
 void foo3(StructuredBuffer<MyStruct> buf);
 
 void fe(StructuredBuffer<MyStruct> a) {



More information about the cfe-commits mailing list