[clang] [HLSL] Add `[[hlsl::raw_buffer]]` attribute (PR #107954)

Helena Kotas via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 16 14:12:45 PDT 2024


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

>From 1c66d2767ca20f42b6edaae834cc186be7d23712 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Mon, 9 Sep 2024 19:39:02 -0700
Subject: [PATCH 1/8] [HLSL] Add `[[hlsl::row_access]]` attribute

This PR introduces new HLSL resource type attribute [[hlsl::row_access]].
Presence of this attribute means that the resource must be accessed in 16-byte
blocks at-a-time, or four 32-bit components, also knows as rows.
This information is necessary in order to properly distinguish between a typed
buffer like `RWBuffer<float4>` which is translated to `dx.TypedBuffer` vs.
`RWStructuredBuffer<float4>` which does not have this access constraint and
will be translated to `dx.RawBuffer`.

Fixes #107907
---
 clang/include/clang/AST/Type.h                   | 11 ++++++++---
 clang/include/clang/AST/TypeProperties.td        |  5 ++++-
 clang/include/clang/Basic/Attr.td                |  6 ++++++
 clang/lib/AST/ASTStructuralEquivalence.cpp       |  4 ++--
 clang/lib/AST/TypePrinter.cpp                    |  3 +++
 clang/lib/Sema/HLSLExternalSemaSource.cpp        | 14 +++++++++-----
 clang/lib/Sema/SemaHLSL.cpp                      |  6 ++++++
 clang/lib/Sema/SemaType.cpp                      |  3 ++-
 .../ParserHLSL/hlsl_resource_handle_attrs.hlsl   |  4 ++--
 clang/test/ParserHLSL/hlsl_row_access_attr.hlsl  | 16 ++++++++++++++++
 .../ParserHLSL/hlsl_row_access_attr_error.hlsl   | 16 ++++++++++++++++
 11 files changed, 74 insertions(+), 14 deletions(-)
 create mode 100644 clang/test/ParserHLSL/hlsl_row_access_attr.hlsl
 create mode 100644 clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl

diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index ef36a73716454f..d8336e1960c64e 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -6169,9 +6169,13 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode {
     // Data gathered from HLSL resource attributes
     llvm::dxil::ResourceClass ResourceClass;
     uint8_t IsROV : 1;
-    Attributes(llvm::dxil::ResourceClass ResourceClass, bool IsROV)
-        : ResourceClass(ResourceClass), IsROV(IsROV) {}
-    Attributes() : ResourceClass(llvm::dxil::ResourceClass::UAV), IsROV(0) {}
+    uint8_t RowAccess : 1;
+    Attributes(llvm::dxil::ResourceClass ResourceClass, bool IsROV,
+               bool RowAccess)
+        : ResourceClass(ResourceClass), IsROV(IsROV), RowAccess(RowAccess) {}
+    Attributes()
+        : ResourceClass(llvm::dxil::ResourceClass::UAV), IsROV(0),
+          RowAccess(0) {}
   };
 
 private:
@@ -6204,6 +6208,7 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode {
     ID.AddPointer(Contained.getAsOpaquePtr());
     ID.AddInteger(static_cast<uint32_t>(Attrs.ResourceClass));
     ID.AddBoolean(Attrs.IsROV);
+    ID.AddBoolean(Attrs.RowAccess);
   }
 
   static bool classof(const Type *T) {
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 539a344cb0b690..f310996d144959 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -697,6 +697,9 @@ let Class = HLSLAttributedResourceType in {
   def : Property<"isROV", Bool> {
     let Read = [{ node->getAttrs().IsROV }];
   }
+  def : Property<"rowAccess", Bool> {
+    let Read = [{ node->getAttrs().RowAccess }];
+  }
   def : Property<"wrappedTy", QualType> {
     let Read = [{ node->getWrappedType() }];
   }
@@ -704,7 +707,7 @@ let Class = HLSLAttributedResourceType in {
     let Read = [{ node->getContainedType() }];
   }
   def : Creator<[{
-    HLSLAttributedResourceType::Attributes attrs(static_cast<llvm::dxil::ResourceClass>(resClass), isROV);
+    HLSLAttributedResourceType::Attributes attrs(static_cast<llvm::dxil::ResourceClass>(resClass), isROV, rowAccess);
     return ctx.getHLSLAttributedResourceType(wrappedTy, containedTy, attrs);
   }]>;
 }
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 9a7b163b2c6da8..7edf33dee93d0a 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -4669,6 +4669,12 @@ def HLSLResourceClass : TypeAttr {
   let Documentation = [InternalOnly];
 }
 
+def HLSLRowAccess : TypeAttr {
+  let Spellings = [CXX11<"hlsl", "row_access">];
+  let LangOpts = [HLSL]; 
+  let Documentation = [InternalOnly];
+}
+
 def HLSLGroupSharedAddressSpace : TypeAttr {
   let Spellings = [CustomKeyword<"groupshared">];
   let Subjects = SubjectList<[Var]>;
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index f13ca2d08d769f..9896e0f48aed58 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -808,8 +808,8 @@ static bool
 IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
                          const HLSLAttributedResourceType::Attributes &Attrs1,
                          const HLSLAttributedResourceType::Attributes &Attrs2) {
-  return std::tie(Attrs1.ResourceClass, Attrs1.IsROV) ==
-         std::tie(Attrs2.ResourceClass, Attrs2.IsROV);
+  return std::tie(Attrs1.ResourceClass, Attrs1.IsROV, Attrs1.RowAccess) ==
+         std::tie(Attrs2.ResourceClass, Attrs2.IsROV, Attrs2.RowAccess);
 }
 
 /// Determine structural equivalence of two types.
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index add6a5d10d61f7..61cd88dd642509 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1945,6 +1945,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
 
   case attr::HLSLResourceClass:
   case attr::HLSLROV:
+  case attr::HLSLRowAccess:
     llvm_unreachable("HLSL resource type attributes handled separately");
 
   case attr::OpenCLPrivateAddressSpace:
@@ -2078,6 +2079,8 @@ void TypePrinter::printHLSLAttributedResourceAfter(
      << ")]]";
   if (Attrs.IsROV)
     OS << " [[hlsl::is_rov()]]";
+  if (Attrs.RowAccess)
+    OS << " [[hlsl::row_access]]";
 }
 
 void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index 071e64fe56d48a..1722bb6aba84e6 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -111,6 +111,7 @@ struct BuiltinTypeDeclBuilder {
 
   BuiltinTypeDeclBuilder &
   addHandleMember(Sema &S, ResourceClass RC, ResourceKind RK, bool IsROV,
+                  bool RowAccess,
                   AccessSpecifier Access = AccessSpecifier::AS_private) {
     if (Record->isCompleteDefinition())
       return *this;
@@ -126,7 +127,9 @@ struct BuiltinTypeDeclBuilder {
     QualType AttributedResTy = QualType();
     SmallVector<const Attr *> Attrs = {
         HLSLResourceClassAttr::CreateImplicit(Record->getASTContext(), RC),
-        IsROV ? HLSLROVAttr::CreateImplicit(Record->getASTContext()) : nullptr};
+        IsROV ? HLSLROVAttr::CreateImplicit(Record->getASTContext()) : nullptr,
+        RowAccess ? HLSLRowAccessAttr::CreateImplicit(Record->getASTContext())
+                  : nullptr};
     Attr *ResourceAttr =
         HLSLResourceAttr::CreateImplicit(Record->getASTContext(), RK);
     if (CreateHLSLAttributedResourceType(S, Ty, Attrs, AttributedResTy))
@@ -495,9 +498,9 @@ void HLSLExternalSemaSource::defineTrivialHLSLTypes() {
 /// Set up common members and attributes for buffer types
 static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S,
                                               ResourceClass RC, ResourceKind RK,
-                                              bool IsROV) {
+                                              bool IsROV, bool RowAccess) {
   return BuiltinTypeDeclBuilder(Decl)
-      .addHandleMember(S, RC, RK, IsROV)
+      .addHandleMember(S, RC, RK, IsROV, RowAccess)
       .addDefaultHandleConstructor(S, RC);
 }
 
@@ -510,7 +513,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
   onCompletion(Decl, [this](CXXRecordDecl *Decl) {
     setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
                     ResourceKind::TypedBuffer,
-                    /*IsROV=*/false)
+                    /*IsROV=*/false, /*RowAccess=*/true)
         .addArraySubscriptOperators()
         .completeDefinition();
   });
@@ -521,7 +524,8 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
           .Record;
   onCompletion(Decl, [this](CXXRecordDecl *Decl) {
     setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
-                    ResourceKind::TypedBuffer, /*IsROV=*/true)
+                    ResourceKind::TypedBuffer, /*IsROV=*/true,
+                    /*RowAccess=*/true)
         .addArraySubscriptOperators()
         .completeDefinition();
   });
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 3b91303ac8cb8a..c2a1d7fa5eb844 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -593,6 +593,9 @@ bool clang::CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped,
     case attr::HLSLROV:
       ResAttrs.IsROV = true;
       break;
+    case attr::HLSLRowAccess:
+      ResAttrs.RowAccess = true;
+      break;
     default:
       llvm_unreachable("unhandled resource attribute type");
     }
@@ -645,6 +648,9 @@ bool SemaHLSL::handleResourceTypeAttr(const ParsedAttr &AL) {
   case ParsedAttr::AT_HLSLROV:
     A = HLSLROVAttr::Create(getASTContext(), AL.getLoc());
     break;
+  case ParsedAttr::AT_HLSLRowAccess:
+    A = HLSLRowAccessAttr::Create(getASTContext(), AL.getLoc());
+    break;
   default:
     llvm_unreachable("unhandled HLSL attribute");
   }
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 520dce870b7b78..34a963074e1dde 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -8843,7 +8843,8 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
       break;
     }
     case ParsedAttr::AT_HLSLResourceClass:
-    case ParsedAttr::AT_HLSLROV: {
+    case ParsedAttr::AT_HLSLROV:
+    case ParsedAttr::AT_HLSLRowAccess: {
       if (state.getSema().HLSL().handleResourceTypeAttr(attr))
         attr.setUsedAsTypeAttr();
       break;
diff --git a/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
index 6324a11fc8a2df..b8e843eb3448f2 100644
--- a/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
+++ b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
@@ -3,7 +3,7 @@
 // CHECK: -ClassTemplateSpecializationDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> class RWBuffer definition implicit_instantiation
 // CHECK: -TemplateArgument type 'float'
 // CHECK: `-BuiltinType 0x{{[0-9a-f]+}} 'float'
-// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]]':'float *'
+// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::row_access]]':'float *'
 // CHECK: -HLSLResourceAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit TypedBuffer
 RWBuffer<float> Buffer1;
 
@@ -11,6 +11,6 @@ RWBuffer<float> Buffer1;
 // CHECK: -TemplateArgument type 'vector<float, 4>'
 // CHECK: `-ExtVectorType 0x{{[0-9a-f]+}} 'vector<float, 4>' 4
 // CHECK: `-BuiltinType 0x{{[0-9a-f]+}} 'float'
-// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'vector<float *, 4> {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::is_rov()]]':'vector<float *, 4>'
+// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'vector<float *, 4> {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::is_rov()]] {{\[\[}}hlsl::row_access]]':'vector<float *, 4>'
 // CHECK: -HLSLResourceAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit TypedBuffer
 RasterizerOrderedBuffer<vector<float, 4> > BufferArray3[4];
diff --git a/clang/test/ParserHLSL/hlsl_row_access_attr.hlsl b/clang/test/ParserHLSL/hlsl_row_access_attr.hlsl
new file mode 100644
index 00000000000000..3bcaf53f7984ad
--- /dev/null
+++ b/clang/test/ParserHLSL/hlsl_row_access_attr.hlsl
@@ -0,0 +1,16 @@
+// 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:6:3, col:72> col:72 h1 '__hlsl_resource_t {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::row_access]]':'__hlsl_resource_t'
+struct MyBuffer {
+  __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::row_access]] h1;
+};
+
+// CHECK: VarDecl 0x{{[0-9a-f]+}} <line:10:1, col:70> col:70 h2 '__hlsl_resource_t {{\[\[}}hlsl::resource_class(SRV)]] {{\[\[}}hlsl::row_access]]':'__hlsl_resource_t'
+__hlsl_resource_t [[hlsl::row_access]] [[hlsl::resource_class(SRV)]] h2;
+
+// CHECK: FunctionDecl 0x{{[0-9a-f]+}} <line:14:1, line:16:1> line:14:6 f 'void ()
+// CHECK: VarDecl 0x{{[0-9a-f]+}} <col:3, col:72> col:72 h3 '__hlsl_resource_t {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::row_access]]':'__hlsl_resource_t'
+void f() {
+  __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::row_access]] h3;
+}
diff --git a/clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl b/clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl
new file mode 100644
index 00000000000000..7a3d17be7d02e0
--- /dev/null
+++ b/clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -o - %s -verify
+
+// expected-error at +1{{'row_access' attribute cannot be applied to a declaration}}
+[[hlsl::row_access]] __hlsl_resource_t res0;
+
+// expected-error at +1{{HLSL resource needs to have [[hlsl::resource_class()]] attribute}}
+__hlsl_resource_t [[hlsl::row_access]] res1;
+
+// expected-error at +1{{'row_access' attribute takes no arguments}}
+__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::row_access(3)]] res2;
+  
+// expected-error at +1{{use of undeclared identifier 'gibberish'}}
+__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::row_access(gibberish)]] res3;
+
+// duplicate attribute with the same meaning - no error
+__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::row_access]] [[hlsl::row_access]] res4;

>From 7fde3ae7668e44dafdb29b0ed1e9903cdc1e4ebd Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Mon, 9 Sep 2024 21:33:53 -0700
Subject: [PATCH 2/8] Prohibit duplicate row_access attribute

---
 clang/lib/Sema/SemaHLSL.cpp                           | 4 ++++
 clang/lib/Sema/SemaType.cpp                           | 6 +++++-
 clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl | 2 +-
 3 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index c2a1d7fa5eb844..5f741e3124461f 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -594,6 +594,10 @@ bool clang::CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped,
       ResAttrs.IsROV = true;
       break;
     case attr::HLSLRowAccess:
+      if (ResAttrs.RowAccess) {
+        S.Diag(A->getLocation(), diag::warn_duplicate_attribute_exact) << A;
+        return false;
+      }
       ResAttrs.RowAccess = true;
       break;
     default:
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 34a963074e1dde..79e4fa77e001e9 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -8845,7 +8845,11 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
     case ParsedAttr::AT_HLSLResourceClass:
     case ParsedAttr::AT_HLSLROV:
     case ParsedAttr::AT_HLSLRowAccess: {
-      if (state.getSema().HLSL().handleResourceTypeAttr(attr))
+      // Only collect HLSL resource type attributes that are in
+      // decl-specifier-seq; do not collect attributes on declarations or those
+      // that get to slide after declaration name.
+      if (TAL == TAL_DeclSpec &&
+          state.getSema().HLSL().handleResourceTypeAttr(attr))
         attr.setUsedAsTypeAttr();
       break;
     }
diff --git a/clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl b/clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl
index 7a3d17be7d02e0..e1a0349d90d146 100644
--- a/clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl
+++ b/clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl
@@ -12,5 +12,5 @@ __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::row_access(3)]] res2;
 // expected-error at +1{{use of undeclared identifier 'gibberish'}}
 __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::row_access(gibberish)]] res3;
 
-// duplicate attribute with the same meaning - no error
+// expected-warning at +1{{attribute 'row_access' is already applied}}
 __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::row_access]] [[hlsl::row_access]] res4;

>From 74890a8d42591a40c897e1afd0de6ccd8674c8fb Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Mon, 9 Sep 2024 22:37:00 -0700
Subject: [PATCH 3/8] update test

---
 clang/test/AST/HLSL/RWBuffer-AST.hlsl | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/clang/test/AST/HLSL/RWBuffer-AST.hlsl b/clang/test/AST/HLSL/RWBuffer-AST.hlsl
index 0e7803ce50a890..10bcf9b70d1121 100644
--- a/clang/test/AST/HLSL/RWBuffer-AST.hlsl
+++ b/clang/test/AST/HLSL/RWBuffer-AST.hlsl
@@ -30,7 +30,7 @@ RWBuffer<float> Buffer;
 // CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class RWBuffer definition
 
 // CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final
-// CHECK-NEXT: implicit h 'element_type * {{\[\[}}hlsl::resource_class(UAV)]]':'element_type *'
+// CHECK-NEXT: implicit h 'element_type * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::row_access]]':'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'
@@ -38,7 +38,7 @@ RWBuffer<float> Buffer;
 // CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
 // CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
 // CHECK-NEXT: ArraySubscriptExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' lvalue
-// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
+// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::row_access]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
 // CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'const RWBuffer<element_type>' lvalue implicit this
 // CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
 // CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
@@ -48,7 +48,7 @@ RWBuffer<float> Buffer;
 // CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
 // CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
 // CHECK-NEXT: ArraySubscriptExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' lvalue
-// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
+// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::row_access]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
 // CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'RWBuffer<element_type>' lvalue implicit this
 // CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
 // CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
@@ -58,5 +58,5 @@ RWBuffer<float> Buffer;
 // CHECK: TemplateArgument type 'float'
 // CHECK-NEXT: BuiltinType 0x{{[0-9A-Fa-f]+}} 'float'
 // CHECK-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final
-// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]]':'float *'
+// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::row_access]]':'float *'
 // CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit TypedBuffer

>From 57ac4eac318fdda6460aa7ebcbaa6dd8cbfd0118 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Tue, 10 Sep 2024 13:38:00 -0700
Subject: [PATCH 4/8] code review feedback

---
 clang/include/clang/AST/Type.h                        | 9 +++++++--
 clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl | 3 ---
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index d8336e1960c64e..051521f351a786 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -6168,14 +6168,19 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode {
   struct Attributes {
     // Data gathered from HLSL resource attributes
     llvm::dxil::ResourceClass ResourceClass;
+
+    LLVM_PREFERRED_TYPE(bool)
     uint8_t IsROV : 1;
+
+    LLVM_PREFERRED_TYPE(bool)
     uint8_t RowAccess : 1;
+
     Attributes(llvm::dxil::ResourceClass ResourceClass, bool IsROV,
                bool RowAccess)
         : ResourceClass(ResourceClass), IsROV(IsROV), RowAccess(RowAccess) {}
     Attributes()
-        : ResourceClass(llvm::dxil::ResourceClass::UAV), IsROV(0),
-          RowAccess(0) {}
+        : ResourceClass(llvm::dxil::ResourceClass::UAV), IsROV(false),
+          RowAccess(false) {}
   };
 
 private:
diff --git a/clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl b/clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl
index e1a0349d90d146..2caae0a240d7d6 100644
--- a/clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl
+++ b/clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl
@@ -3,9 +3,6 @@
 // expected-error at +1{{'row_access' attribute cannot be applied to a declaration}}
 [[hlsl::row_access]] __hlsl_resource_t res0;
 
-// expected-error at +1{{HLSL resource needs to have [[hlsl::resource_class()]] attribute}}
-__hlsl_resource_t [[hlsl::row_access]] res1;
-
 // expected-error at +1{{'row_access' attribute takes no arguments}}
 __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::row_access(3)]] res2;
   

>From 45c2077d0d31837192736de893e8051d96ff81ca Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Thu, 12 Sep 2024 14:32:56 -0700
Subject: [PATCH 5/8] Rename row_access to raw_buffer and do not add it to
 RWBuffer

---
 clang/include/clang/AST/Type.h                       | 10 +++++-----
 clang/include/clang/AST/TypeProperties.td            |  6 +++---
 clang/include/clang/Basic/Attr.td                    |  4 ++--
 clang/lib/AST/ASTStructuralEquivalence.cpp           |  4 ++--
 clang/lib/AST/TypePrinter.cpp                        |  6 +++---
 clang/lib/Sema/HLSLExternalSemaSource.cpp            | 12 ++++++------
 clang/lib/Sema/SemaHLSL.cpp                          | 10 +++++-----
 clang/lib/Sema/SemaType.cpp                          |  2 +-
 clang/test/AST/HLSL/RWBuffer-AST.hlsl                |  8 ++++----
 .../test/ParserHLSL/hlsl_resource_handle_attrs.hlsl  |  4 ++--
 clang/test/ParserHLSL/hlsl_row_access_attr.hlsl      | 12 ++++++------
 11 files changed, 39 insertions(+), 39 deletions(-)

diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 051521f351a786..5acb9a8f35d49e 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -6173,14 +6173,14 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode {
     uint8_t IsROV : 1;
 
     LLVM_PREFERRED_TYPE(bool)
-    uint8_t RowAccess : 1;
+    uint8_t RawBuffer : 1;
 
     Attributes(llvm::dxil::ResourceClass ResourceClass, bool IsROV,
-               bool RowAccess)
-        : ResourceClass(ResourceClass), IsROV(IsROV), RowAccess(RowAccess) {}
+               bool RawBuffer)
+        : ResourceClass(ResourceClass), IsROV(IsROV), RawBuffer(RawBuffer) {}
     Attributes()
         : ResourceClass(llvm::dxil::ResourceClass::UAV), IsROV(false),
-          RowAccess(false) {}
+          RawBuffer(false) {}
   };
 
 private:
@@ -6213,7 +6213,7 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode {
     ID.AddPointer(Contained.getAsOpaquePtr());
     ID.AddInteger(static_cast<uint32_t>(Attrs.ResourceClass));
     ID.AddBoolean(Attrs.IsROV);
-    ID.AddBoolean(Attrs.RowAccess);
+    ID.AddBoolean(Attrs.RawBuffer);
   }
 
   static bool classof(const Type *T) {
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index f310996d144959..bb7bfa8cd0b76e 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -697,8 +697,8 @@ let Class = HLSLAttributedResourceType in {
   def : Property<"isROV", Bool> {
     let Read = [{ node->getAttrs().IsROV }];
   }
-  def : Property<"rowAccess", Bool> {
-    let Read = [{ node->getAttrs().RowAccess }];
+  def : Property<"rawBuffer", Bool> {
+    let Read = [{ node->getAttrs().RawBuffer }];
   }
   def : Property<"wrappedTy", QualType> {
     let Read = [{ node->getWrappedType() }];
@@ -707,7 +707,7 @@ let Class = HLSLAttributedResourceType in {
     let Read = [{ node->getContainedType() }];
   }
   def : Creator<[{
-    HLSLAttributedResourceType::Attributes attrs(static_cast<llvm::dxil::ResourceClass>(resClass), isROV, rowAccess);
+    HLSLAttributedResourceType::Attributes attrs(static_cast<llvm::dxil::ResourceClass>(resClass), isROV, rawBuffer);
     return ctx.getHLSLAttributedResourceType(wrappedTy, containedTy, attrs);
   }]>;
 }
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 7edf33dee93d0a..fe5bacd8bbbe26 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -4669,8 +4669,8 @@ def HLSLResourceClass : TypeAttr {
   let Documentation = [InternalOnly];
 }
 
-def HLSLRowAccess : TypeAttr {
-  let Spellings = [CXX11<"hlsl", "row_access">];
+def HLSLRawBuffer : TypeAttr {
+  let Spellings = [CXX11<"hlsl", "raw_buffer">];
   let LangOpts = [HLSL]; 
   let Documentation = [InternalOnly];
 }
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 9896e0f48aed58..21f0562f9d72ae 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -808,8 +808,8 @@ static bool
 IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
                          const HLSLAttributedResourceType::Attributes &Attrs1,
                          const HLSLAttributedResourceType::Attributes &Attrs2) {
-  return std::tie(Attrs1.ResourceClass, Attrs1.IsROV, Attrs1.RowAccess) ==
-         std::tie(Attrs2.ResourceClass, Attrs2.IsROV, Attrs2.RowAccess);
+  return std::tie(Attrs1.ResourceClass, Attrs1.IsROV, Attrs1.RawBuffer) ==
+         std::tie(Attrs2.ResourceClass, Attrs2.IsROV, Attrs2.RawBuffer);
 }
 
 /// Determine structural equivalence of two types.
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 3bc08fd9c0dcfe..6c07abd3627c0e 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1945,7 +1945,7 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
 
   case attr::HLSLResourceClass:
   case attr::HLSLROV:
-  case attr::HLSLRowAccess:
+  case attr::HLSLRawBuffer:
     llvm_unreachable("HLSL resource type attributes handled separately");
 
   case attr::OpenCLPrivateAddressSpace:
@@ -2079,8 +2079,8 @@ void TypePrinter::printHLSLAttributedResourceAfter(
      << ")]]";
   if (Attrs.IsROV)
     OS << " [[hlsl::is_rov]]";
-  if (Attrs.RowAccess)
-    OS << " [[hlsl::row_access]]";
+  if (Attrs.RawBuffer)
+    OS << " [[hlsl::raw_buffer]]";
 }
 
 void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index 1722bb6aba84e6..80abdda8b7d3e9 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -111,7 +111,7 @@ struct BuiltinTypeDeclBuilder {
 
   BuiltinTypeDeclBuilder &
   addHandleMember(Sema &S, ResourceClass RC, ResourceKind RK, bool IsROV,
-                  bool RowAccess,
+                  bool RawBuffer,
                   AccessSpecifier Access = AccessSpecifier::AS_private) {
     if (Record->isCompleteDefinition())
       return *this;
@@ -128,7 +128,7 @@ struct BuiltinTypeDeclBuilder {
     SmallVector<const Attr *> Attrs = {
         HLSLResourceClassAttr::CreateImplicit(Record->getASTContext(), RC),
         IsROV ? HLSLROVAttr::CreateImplicit(Record->getASTContext()) : nullptr,
-        RowAccess ? HLSLRowAccessAttr::CreateImplicit(Record->getASTContext())
+        RawBuffer ? HLSLRawBufferAttr::CreateImplicit(Record->getASTContext())
                   : nullptr};
     Attr *ResourceAttr =
         HLSLResourceAttr::CreateImplicit(Record->getASTContext(), RK);
@@ -498,9 +498,9 @@ void HLSLExternalSemaSource::defineTrivialHLSLTypes() {
 /// Set up common members and attributes for buffer types
 static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S,
                                               ResourceClass RC, ResourceKind RK,
-                                              bool IsROV, bool RowAccess) {
+                                              bool IsROV, bool RawBuffer) {
   return BuiltinTypeDeclBuilder(Decl)
-      .addHandleMember(S, RC, RK, IsROV, RowAccess)
+      .addHandleMember(S, RC, RK, IsROV, RawBuffer)
       .addDefaultHandleConstructor(S, RC);
 }
 
@@ -513,7 +513,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
   onCompletion(Decl, [this](CXXRecordDecl *Decl) {
     setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
                     ResourceKind::TypedBuffer,
-                    /*IsROV=*/false, /*RowAccess=*/true)
+                    /*IsROV=*/false, /*RawBuffer=*/false)
         .addArraySubscriptOperators()
         .completeDefinition();
   });
@@ -525,7 +525,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
   onCompletion(Decl, [this](CXXRecordDecl *Decl) {
     setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
                     ResourceKind::TypedBuffer, /*IsROV=*/true,
-                    /*RowAccess=*/true)
+                    /*RawBuffer=*/false)
         .addArraySubscriptOperators()
         .completeDefinition();
   });
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 44607f70a456cc..5cb01aded7f7a9 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -598,12 +598,12 @@ bool clang::CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped,
       }
       ResAttrs.IsROV = true;
       break;
-    case attr::HLSLRowAccess:
-      if (ResAttrs.RowAccess) {
+    case attr::HLSLRawBuffer:
+      if (ResAttrs.RawBuffer) {
         S.Diag(A->getLocation(), diag::warn_duplicate_attribute_exact) << A;
         return false;
       }
-      ResAttrs.RowAccess = true;
+      ResAttrs.RawBuffer = true;
       break;
     default:
       llvm_unreachable("unhandled resource attribute type");
@@ -657,8 +657,8 @@ bool SemaHLSL::handleResourceTypeAttr(const ParsedAttr &AL) {
   case ParsedAttr::AT_HLSLROV:
     A = HLSLROVAttr::Create(getASTContext(), AL.getLoc());
     break;
-  case ParsedAttr::AT_HLSLRowAccess:
-    A = HLSLRowAccessAttr::Create(getASTContext(), AL.getLoc());
+  case ParsedAttr::AT_HLSLRawBuffer:
+    A = HLSLRawBufferAttr::Create(getASTContext(), AL.getLoc());
     break;
   default:
     llvm_unreachable("unhandled HLSL attribute");
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 79e4fa77e001e9..f36b1810d47286 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -8844,7 +8844,7 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
     }
     case ParsedAttr::AT_HLSLResourceClass:
     case ParsedAttr::AT_HLSLROV:
-    case ParsedAttr::AT_HLSLRowAccess: {
+    case ParsedAttr::AT_HLSLRawBuffer: {
       // Only collect HLSL resource type attributes that are in
       // decl-specifier-seq; do not collect attributes on declarations or those
       // that get to slide after declaration name.
diff --git a/clang/test/AST/HLSL/RWBuffer-AST.hlsl b/clang/test/AST/HLSL/RWBuffer-AST.hlsl
index 10bcf9b70d1121..0e7803ce50a890 100644
--- a/clang/test/AST/HLSL/RWBuffer-AST.hlsl
+++ b/clang/test/AST/HLSL/RWBuffer-AST.hlsl
@@ -30,7 +30,7 @@ RWBuffer<float> Buffer;
 // CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class RWBuffer definition
 
 // CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final
-// CHECK-NEXT: implicit h 'element_type * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::row_access]]':'element_type *'
+// CHECK-NEXT: implicit h 'element_type * {{\[\[}}hlsl::resource_class(UAV)]]':'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'
@@ -38,7 +38,7 @@ RWBuffer<float> Buffer;
 // CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
 // CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
 // CHECK-NEXT: ArraySubscriptExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' lvalue
-// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::row_access]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
+// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
 // CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'const RWBuffer<element_type>' lvalue implicit this
 // CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
 // CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
@@ -48,7 +48,7 @@ RWBuffer<float> Buffer;
 // CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
 // CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
 // CHECK-NEXT: ArraySubscriptExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' lvalue
-// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::row_access]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
+// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
 // CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'RWBuffer<element_type>' lvalue implicit this
 // CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
 // CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
@@ -58,5 +58,5 @@ RWBuffer<float> Buffer;
 // CHECK: TemplateArgument type 'float'
 // CHECK-NEXT: BuiltinType 0x{{[0-9A-Fa-f]+}} 'float'
 // CHECK-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final
-// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::row_access]]':'float *'
+// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]]':'float *'
 // CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit TypedBuffer
diff --git a/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
index f6a1e1fd0ee7a7..d7797345a387c0 100644
--- a/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
+++ b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
@@ -3,7 +3,7 @@
 // CHECK: -ClassTemplateSpecializationDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> class RWBuffer definition implicit_instantiation
 // CHECK: -TemplateArgument type 'float'
 // CHECK: `-BuiltinType 0x{{[0-9a-f]+}} 'float'
-// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::row_access]]':'float *'
+// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::raw_buffer]]':'float *'
 // CHECK: -HLSLResourceAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit TypedBuffer
 RWBuffer<float> Buffer1;
 
@@ -11,6 +11,6 @@ RWBuffer<float> Buffer1;
 // CHECK: -TemplateArgument type 'vector<float, 4>'
 // CHECK: `-ExtVectorType 0x{{[0-9a-f]+}} 'vector<float, 4>' 4
 // CHECK: `-BuiltinType 0x{{[0-9a-f]+}} 'float'
-// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'vector<float *, 4> {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::is_rov]] {{\[\[}}hlsl::row_access]]':'vector<float *, 4>'
+// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'vector<float *, 4> {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::is_rov]] {{\[\[}}hlsl::raw_buffer]]':'vector<float *, 4>'
 // CHECK: -HLSLResourceAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit TypedBuffer
 RasterizerOrderedBuffer<vector<float, 4> > BufferArray3[4];
diff --git a/clang/test/ParserHLSL/hlsl_row_access_attr.hlsl b/clang/test/ParserHLSL/hlsl_row_access_attr.hlsl
index 3bcaf53f7984ad..1955be63cf7607 100644
--- a/clang/test/ParserHLSL/hlsl_row_access_attr.hlsl
+++ b/clang/test/ParserHLSL/hlsl_row_access_attr.hlsl
@@ -1,16 +1,16 @@
 // 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:6:3, col:72> col:72 h1 '__hlsl_resource_t {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::row_access]]':'__hlsl_resource_t'
+// CHECK: FieldDecl 0x{{[0-9a-f]+}} <line:6:3, col:72> col:72 h1 '__hlsl_resource_t {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::raw_buffer]]':'__hlsl_resource_t'
 struct MyBuffer {
-  __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::row_access]] h1;
+  __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::raw_buffer]] h1;
 };
 
-// CHECK: VarDecl 0x{{[0-9a-f]+}} <line:10:1, col:70> col:70 h2 '__hlsl_resource_t {{\[\[}}hlsl::resource_class(SRV)]] {{\[\[}}hlsl::row_access]]':'__hlsl_resource_t'
-__hlsl_resource_t [[hlsl::row_access]] [[hlsl::resource_class(SRV)]] h2;
+// CHECK: VarDecl 0x{{[0-9a-f]+}} <line:10:1, col:70> col:70 h2 '__hlsl_resource_t {{\[\[}}hlsl::resource_class(SRV)]] {{\[\[}}hlsl::raw_buffer]]':'__hlsl_resource_t'
+__hlsl_resource_t [[hlsl::raw_buffer]] [[hlsl::resource_class(SRV)]] h2;
 
 // CHECK: FunctionDecl 0x{{[0-9a-f]+}} <line:14:1, line:16:1> line:14:6 f 'void ()
-// CHECK: VarDecl 0x{{[0-9a-f]+}} <col:3, col:72> col:72 h3 '__hlsl_resource_t {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::row_access]]':'__hlsl_resource_t'
+// CHECK: VarDecl 0x{{[0-9a-f]+}} <col:3, col:72> col:72 h3 '__hlsl_resource_t {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::raw_buffer]]':'__hlsl_resource_t'
 void f() {
-  __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::row_access]] h3;
+  __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::raw_buffer]] h3;
 }

>From cc52d89d8015d3c49da5ea4122af63aa219c47b2 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Thu, 12 Sep 2024 14:57:06 -0700
Subject: [PATCH 6/8] Update tests

---
 ...w_access_attr.hlsl => hlsl_raw_buffer_attr.hlsl} |  0
 .../test/ParserHLSL/hlsl_raw_buffer_attr_error.hlsl | 13 +++++++++++++
 .../test/ParserHLSL/hlsl_resource_handle_attrs.hlsl |  4 ++--
 .../test/ParserHLSL/hlsl_row_access_attr_error.hlsl | 13 -------------
 4 files changed, 15 insertions(+), 15 deletions(-)
 rename clang/test/ParserHLSL/{hlsl_row_access_attr.hlsl => hlsl_raw_buffer_attr.hlsl} (100%)
 create mode 100644 clang/test/ParserHLSL/hlsl_raw_buffer_attr_error.hlsl
 delete mode 100644 clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl

diff --git a/clang/test/ParserHLSL/hlsl_row_access_attr.hlsl b/clang/test/ParserHLSL/hlsl_raw_buffer_attr.hlsl
similarity index 100%
rename from clang/test/ParserHLSL/hlsl_row_access_attr.hlsl
rename to clang/test/ParserHLSL/hlsl_raw_buffer_attr.hlsl
diff --git a/clang/test/ParserHLSL/hlsl_raw_buffer_attr_error.hlsl b/clang/test/ParserHLSL/hlsl_raw_buffer_attr_error.hlsl
new file mode 100644
index 00000000000000..83273426017ed0
--- /dev/null
+++ b/clang/test/ParserHLSL/hlsl_raw_buffer_attr_error.hlsl
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -o - %s -verify
+
+// expected-error at +1{{'raw_buffer' attribute cannot be applied to a declaration}}
+[[hlsl::raw_buffer]] __hlsl_resource_t res0;
+
+// expected-error at +1{{'raw_buffer' attribute takes no arguments}}
+__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::raw_buffer(3)]] res2;
+  
+// expected-error at +1{{use of undeclared identifier 'gibberish'}}
+__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::raw_buffer(gibberish)]] res3;
+
+// expected-warning at +1{{attribute 'raw_buffer' is already applied}}
+__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::raw_buffer]] [[hlsl::raw_buffer]] res4;
diff --git a/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
index d7797345a387c0..7c3830a291970c 100644
--- a/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
+++ b/clang/test/ParserHLSL/hlsl_resource_handle_attrs.hlsl
@@ -3,7 +3,7 @@
 // CHECK: -ClassTemplateSpecializationDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> class RWBuffer definition implicit_instantiation
 // CHECK: -TemplateArgument type 'float'
 // CHECK: `-BuiltinType 0x{{[0-9a-f]+}} 'float'
-// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::raw_buffer]]':'float *'
+// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]]':'float *'
 // CHECK: -HLSLResourceAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit TypedBuffer
 RWBuffer<float> Buffer1;
 
@@ -11,6 +11,6 @@ RWBuffer<float> Buffer1;
 // CHECK: -TemplateArgument type 'vector<float, 4>'
 // CHECK: `-ExtVectorType 0x{{[0-9a-f]+}} 'vector<float, 4>' 4
 // CHECK: `-BuiltinType 0x{{[0-9a-f]+}} 'float'
-// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'vector<float *, 4> {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::is_rov]] {{\[\[}}hlsl::raw_buffer]]':'vector<float *, 4>'
+// CHECK: -FieldDecl 0x{{[0-9a-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'vector<float *, 4> {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::is_rov]]':'vector<float *, 4>'
 // CHECK: -HLSLResourceAttr 0x{{[0-9a-f]+}} <<invalid sloc>> Implicit TypedBuffer
 RasterizerOrderedBuffer<vector<float, 4> > BufferArray3[4];
diff --git a/clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl b/clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl
deleted file mode 100644
index 2caae0a240d7d6..00000000000000
--- a/clang/test/ParserHLSL/hlsl_row_access_attr_error.hlsl
+++ /dev/null
@@ -1,13 +0,0 @@
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -o - %s -verify
-
-// expected-error at +1{{'row_access' attribute cannot be applied to a declaration}}
-[[hlsl::row_access]] __hlsl_resource_t res0;
-
-// expected-error at +1{{'row_access' attribute takes no arguments}}
-__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::row_access(3)]] res2;
-  
-// expected-error at +1{{use of undeclared identifier 'gibberish'}}
-__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::row_access(gibberish)]] res3;
-
-// expected-warning at +1{{attribute 'row_access' is already applied}}
-__hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::row_access]] [[hlsl::row_access]] res4;

>From 94b617ee9e86ca96ab7f366de36f2e6b5233afa2 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Thu, 12 Sep 2024 15:45:35 -0700
Subject: [PATCH 7/8] add raw_buffer to StructuredBuffer and update tests

---
 clang/lib/Sema/HLSLExternalSemaSource.cpp     | 3 ++-
 clang/test/AST/HLSL/StructuredBuffer-AST.hlsl | 8 ++++----
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp
index 81ceab6b2c1aa4..51f047dc8aec76 100644
--- a/clang/lib/Sema/HLSLExternalSemaSource.cpp
+++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp
@@ -535,7 +535,8 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
              .Record;
   onCompletion(Decl, [this](CXXRecordDecl *Decl) {
     setupBufferType(Decl, *SemaPtr, ResourceClass::UAV,
-                    ResourceKind::TypedBuffer, /*IsROV=*/false)
+                    ResourceKind::TypedBuffer, /*IsROV=*/false,
+                    /*RawBuffer=*/true)
         .addArraySubscriptOperators()
         .completeDefinition();
   });
diff --git a/clang/test/AST/HLSL/StructuredBuffer-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffer-AST.hlsl
index 11d84ac7b85db2..0e75ce2a62e516 100644
--- a/clang/test/AST/HLSL/StructuredBuffer-AST.hlsl
+++ b/clang/test/AST/HLSL/StructuredBuffer-AST.hlsl
@@ -30,7 +30,7 @@ StructuredBuffer<float> Buffer;
 // CHECK-NEXT: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit class StructuredBuffer definition
 
 // CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final
-// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit h 'element_type * {{\[\[}}hlsl::resource_class(UAV)]]':'element_type *'
+// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit h 'element_type * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::raw_buffer]]':'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'
@@ -38,7 +38,7 @@ StructuredBuffer<float> Buffer;
 // CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
 // CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
 // CHECK-NEXT: ArraySubscriptExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' lvalue
-// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
+// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::raw_buffer]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
 // CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'const StructuredBuffer<element_type>' lvalue implicit this
 // CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
 // CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
@@ -48,7 +48,7 @@ StructuredBuffer<float> Buffer;
 // CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
 // CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <<invalid sloc>>
 // CHECK-NEXT: ArraySubscriptExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type' lvalue
-// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
+// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'element_type * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::raw_buffer]]':'element_type *' lvalue .h 0x{{[0-9A-Fa-f]+}}
 // CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'StructuredBuffer<element_type>' lvalue implicit this
 // CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Idx' 'unsigned int'
 // CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit always_inline
@@ -58,5 +58,5 @@ StructuredBuffer<float> Buffer;
 // CHECK: TemplateArgument type 'float'
 // CHECK-NEXT: BuiltinType 0x{{[0-9A-Fa-f]+}} 'float'
 // CHECK-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit final
-// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]]':'float *'
+// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> <invalid sloc> implicit referenced h 'float * {{\[\[}}hlsl::resource_class(UAV)]] {{\[\[}}hlsl::raw_buffer]]':'float *'
 // CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <<invalid sloc>> Implicit TypedBuffer

>From 124850901eb795d0dbf3ffb4c4c8c19cf1f33030 Mon Sep 17 00:00:00 2001
From: Helena Kotas <hekotas at microsoft.com>
Date: Mon, 16 Sep 2024 13:42:36 -0700
Subject: [PATCH 8/8] Update default constructor

---
 clang/include/clang/AST/Type.h | 5 ++---
 clang/lib/Sema/SemaHLSL.cpp    | 2 +-
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 5acb9a8f35d49e..dc87b84153e74a 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -6178,9 +6178,8 @@ class HLSLAttributedResourceType : public Type, public llvm::FoldingSetNode {
     Attributes(llvm::dxil::ResourceClass ResourceClass, bool IsROV,
                bool RawBuffer)
         : ResourceClass(ResourceClass), IsROV(IsROV), RawBuffer(RawBuffer) {}
-    Attributes()
-        : ResourceClass(llvm::dxil::ResourceClass::UAV), IsROV(false),
-          RawBuffer(false) {}
+
+    Attributes() : Attributes(llvm::dxil::ResourceClass::UAV, false, false) {}
   };
 
 private:
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 2bf6f9ff5054e6..aa44732d6b151f 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -570,7 +570,7 @@ bool clang::CreateHLSLAttributedResourceType(Sema &S, QualType Wrapped,
   assert(AttrList.size() && "expected list of resource attributes");
 
   QualType Contained = QualType();
-  HLSLAttributedResourceType::Attributes ResAttrs = {};
+  HLSLAttributedResourceType::Attributes ResAttrs;
 
   bool HasResourceClass = false;
   for (const Attr *A : AttrList) {



More information about the cfe-commits mailing list