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

>From 63c465b40512ad4c5fff84c0b2b022b49d46eaa7 Mon Sep 17 00:00:00 2001
From: Helena Kotas <heko...@microsoft.com>
Date: Tue, 28 Jan 2025 13:20:30 -0800
Subject: [PATCH 1/2] [HLSL] Constant buffer layout struct update

- create structs with public fields instead of classes with private fields
- add Packed attribute to prevent struct padding
- use __cblayout_ prefix in name
- filter out arrays of resources (bug fix)
- don't create implicit initializer for constant buffer decls
- update tests
---
 clang/lib/Sema/SemaDecl.cpp                   |   7 +
 clang/lib/Sema/SemaHLSL.cpp                   |  29 ++--
 .../AST/HLSL/ast-dump-comment-cbuffer.hlsl    |   3 -
 clang/test/AST/HLSL/cbuffer.hlsl              | 144 ++++++++++--------
 .../test/AST/HLSL/cbuffer_and_namespaces.hlsl |  30 ++--
 clang/test/AST/HLSL/pch_hlsl_buffer.hlsl      |   4 +-
 6 files changed, 121 insertions(+), 96 deletions(-)

diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index fe68eadc951b5f..ba424567b23e0b 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -14183,6 +14183,13 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
     if (getLangOpts().OpenCL &&
         Var->getType().getAddressSpace() == LangAS::opencl_local)
       return;
+
+    // In HLSL, objects in the hlsl_constat address space are initialized
+    // externaly, so don't synthesize an implicit initializer.
+    if (getLangOpts().HLSL &&
+        Var->getType().getAddressSpace() == LangAS::hlsl_constant)
+      return;
+
     // C++03 [dcl.init]p9:
     //   If no initializer is specified for an object, and the
     //   object is of (possibly cv-qualified) non-POD class type (or
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index aa99b44958eafd..97df01a5dd3074 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -269,8 +269,11 @@ static bool isZeroSizedArray(const ConstantArrayType *CAT) 
{
   return CAT != nullptr;
 }
 
-// Returns true if the record type is an HLSL resource class
-static bool isResourceRecordType(const Type *Ty) {
+// Returns true if the record type is an HLSL resource class or an array of
+// HLSL resource classes
+static bool isResourceRecordTypeOrArrayOf(const Type *Ty) {
+  while (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(Ty))
+    Ty = CAT->getArrayElementTypeNoTypeQual();
   return HLSLAttributedResourceType::findHandleTypeOnResource(Ty) != nullptr;
 }
 
@@ -279,11 +282,10 @@ static bool isResourceRecordType(const Type *Ty) {
 // array, or a builtin intangible type. Returns false it is a valid leaf 
element
 // type or if it is a record type that needs to be inspected further.
 static bool isInvalidConstantBufferLeafElementType(const Type *Ty) {
-  if (Ty->isRecordType()) {
-    if (isResourceRecordType(Ty) || Ty->getAsCXXRecordDecl()->isEmpty())
-      return true;
-    return false;
-  }
+  if (isResourceRecordTypeOrArrayOf(Ty))
+    return true;
+  if (Ty->isRecordType())
+    return Ty->getAsCXXRecordDecl()->isEmpty();
   if (Ty->isConstantArrayType() &&
       isZeroSizedArray(cast<ConstantArrayType>(Ty)))
     return true;
@@ -339,7 +341,7 @@ static IdentifierInfo *getHostLayoutStructName(Sema &S, 
NamedDecl *BaseDecl,
   ASTContext &AST = S.getASTContext();
 
   IdentifierInfo *NameBaseII = BaseDecl->getIdentifier();
-  llvm::SmallString<64> Name("__layout_");
+  llvm::SmallString<64> Name("__cblayout_");
   if (NameBaseII) {
     Name.append(NameBaseII->getName());
   } else {
@@ -393,7 +395,7 @@ static FieldDecl *createFieldForHostLayoutStruct(Sema &S, 
const Type *Ty,
   auto *Field = FieldDecl::Create(AST, LayoutStruct, SourceLocation(),
                                   SourceLocation(), II, QT, TSI, nullptr, 
false,
                                   InClassInitStyle::ICIS_NoInit);
-  Field->setAccess(AccessSpecifier::AS_private);
+  Field->setAccess(AccessSpecifier::AS_public);
   return Field;
 }
 
@@ -417,9 +419,11 @@ static CXXRecordDecl *createHostLayoutStruct(Sema &S,
   if (CXXRecordDecl *RD = findRecordDeclInContext(II, DC))
     return RD;
 
-  CXXRecordDecl *LS = CXXRecordDecl::Create(
-      AST, TagDecl::TagKind::Class, DC, SourceLocation(), SourceLocation(), 
II);
+  CXXRecordDecl *LS =
+      CXXRecordDecl::Create(AST, TagDecl::TagKind::Struct, DC, 
SourceLocation(),
+                            SourceLocation(), II);
   LS->setImplicit(true);
+  LS->addAttr(PackedAttr::CreateImplicit(AST));
   LS->startDefinition();
 
   // copy base struct, create HLSL Buffer compatible version if needed
@@ -472,8 +476,9 @@ void createHostLayoutStructForBuffer(Sema &S, 
HLSLBufferDecl *BufDecl) {
   IdentifierInfo *II = getHostLayoutStructName(S, BufDecl, true);
 
   CXXRecordDecl *LS =
-      CXXRecordDecl::Create(AST, TagDecl::TagKind::Class, BufDecl,
+      CXXRecordDecl::Create(AST, TagDecl::TagKind::Struct, BufDecl,
                             SourceLocation(), SourceLocation(), II);
+  LS->addAttr(PackedAttr::CreateImplicit(AST));
   LS->setImplicit(true);
   LS->startDefinition();
 
diff --git a/clang/test/AST/HLSL/ast-dump-comment-cbuffer.hlsl 
b/clang/test/AST/HLSL/ast-dump-comment-cbuffer.hlsl
index b2b3e13308da3f..eca2ed0211d1b7 100644
--- a/clang/test/AST/HLSL/ast-dump-comment-cbuffer.hlsl
+++ b/clang/test/AST/HLSL/ast-dump-comment-cbuffer.hlsl
@@ -27,6 +27,3 @@ cbuffer A {
 // AST-NEXT: TextComment {{.*}} Text=" CBuffer decl."
 // AST-NEXT: VarDecl {{.*}} a 'hlsl_constant float'
 // AST-NEXT: VarDecl {{.*}} b 'hlsl_constant int'
-// AST-NEXT: CXXRecordDecl {{.*}} implicit class __layout_A definition
-// AST: FieldDecl {{.*}} a 'float'
-// AST-NEXT: FieldDecl {{.*}} b 'int'
diff --git a/clang/test/AST/HLSL/cbuffer.hlsl b/clang/test/AST/HLSL/cbuffer.hlsl
index f516cf5099e82d..8254f0ee00b140 100644
--- a/clang/test/AST/HLSL/cbuffer.hlsl
+++ b/clang/test/AST/HLSL/cbuffer.hlsl
@@ -48,75 +48,83 @@ struct TwoFloats {
 // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer
 // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer
 cbuffer CB {
-  // CHECK: VarDecl {{.*}} col:9 used a1 'hlsl_constant float'
+  // CHECK: VarDecl {{.*}} used a1 'hlsl_constant float'
   float a1;
-  // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_CB 
definition
-  // CHECK: FieldDecl {{.*}} a1 'float'
+  // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB 
definition
+  // CHECK: PackedAttr
+  // CHECK-NEXT: FieldDecl {{.*}} a1 'float'
 }
-_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, 
__layout_CB), "");
+_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, 
__cblayout_CB), "");
 
 // Check that buffer layout struct does not include resources or empty types 
-// CHECK: HLSLBufferDecl {{.*}} line:62:9 cbuffer CB
+// CHECK: HLSLBufferDecl {{.*}} line:[[# @LINE + 3]]:9 cbuffer CB
 // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer
 // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer
 cbuffer CB {
-  // CHECK: VarDecl {{.*}} col:9 used a2 'hlsl_constant float'
+  // CHECK: VarDecl {{.*}} used a2 'hlsl_constant float'
   float a2;
-  // CHECK: VarDecl {{.*}} col:19 b2 'RWBuffer<float>':'hlsl::RWBuffer<float>'
+  // CHECK: VarDecl {{.*}} b2 'RWBuffer<float>':'hlsl::RWBuffer<float>'
   RWBuffer<float> b2; 
-  // CHECK: VarDecl {{.*}} col:15 c2 'EmptyStruct'
+  // CHECK: VarDecl {{.*}} c2 'EmptyStruct'
   EmptyStruct c2;
-  // CHECK: VarDecl {{.*}} col:9 d2 'float[0]'
+  // CHECK: VarDecl {{.*}} d2 'float[0]'
   float d2[0];
-  // CHECK: VarDecl {{.*}} col:9 e2 'hlsl_constant float'
+  // CHECK: VarDecl {{.*}} f2 'RWBuffer<float>[2]'
+  RWBuffer<float> f2[2];
+  // CHECK: VarDecl {{.*}} e2 'hlsl_constant float'
   float e2;
-  // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_CB_1 
definition
-  // CHECK: FieldDecl {{.*}} a2 'float'
+  // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB_1 
definition
+  // CHECK: PackedAttr
+  // CHECK-NEXT: FieldDecl {{.*}} a2 'float'
   // CHECK-NEXT: FieldDecl {{.*}} e2 'float'
 }
-_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, 
__layout_CB_1), "");
+_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, 
__cblayout_CB_1), "");
 
 // Check that layout struct is created for B and the empty struct C is removed
-// CHECK: HLSLBufferDecl {{.*}} line:83:9 cbuffer CB
+// CHECK: HLSLBufferDecl {{.*}} line:[[# @LINE + 3]]:9 cbuffer CB
 // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer
 // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer
 cbuffer CB {
-  // CHECK: VarDecl {{.*}} col:5 used s1 'hlsl_constant A'
+  // CHECK: VarDecl {{.*}} used s1 'hlsl_constant A'
   A s1;
-  // CHECK: VarDecl {{.*}} col:5 s2 'hlsl_constant B'
+  // CHECK: VarDecl {{.*}} s2 'hlsl_constant B'
   B s2;
-  // CHECK: VarDecl {{.*}} col:12 s3 'CTypedef':'C'
+  // CHECK: VarDecl {{.*}} s3 'CTypedef':'C'
   CTypedef s3;
-  // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_CB_2 
definition
-  // CHECK: FieldDecl {{.*}} s1 'A'
-  // CHECK: FieldDecl {{.*}} s2 '__layout_B'
+  // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB_2 
definition
+  // CHECK: PackedAttr
+  // CHECK-NEXT: FieldDecl {{.*}} s1 'A'
+  // CHECK-NEXT: FieldDecl {{.*}} s2 '__cblayout_B'
 }
-// CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_B definition
-// CHECK: FieldDecl {{.*}} a 'float'
+// CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_B 
definition
+// CHECK: PackedAttr
+// CHECK-NEXT: FieldDecl {{.*}} a 'float'
 
-_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, 
__layout_B), "");
-_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, 
__layout_CB_2), "");
+_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, 
__cblayout_B), "");
+_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, 
__cblayout_CB_2), "");
 
 // check that layout struct is created for D because of its base struct
-// CHECK: HLSLBufferDecl {{.*}} line:104:9 cbuffer CB
+// CHECK: HLSLBufferDecl {{.*}} line:[[# @LINE + 3]]:9 cbuffer CB
 // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer
 // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer
 cbuffer CB {
   // CHECK: VarDecl {{.*}} s4 'hlsl_constant D'
   D s4;
-  // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_CB_3 
definition
-  // CHECK: FieldDecl {{.*}} s4 '__layout_D'
+  // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB_3 
definition
+  // CHECK: PackedAttr
+  // CHECK-NEXT: FieldDecl {{.*}} s4 '__cblayout_D'
 }
-  // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_D 
definition
-  // CHECK: public '__layout_B'
-  // CHECK: FieldDecl {{.*}} b 'float'
-_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, 
__layout_D), "");
-_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, 
__layout_CB_3), "");
+  // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_D 
definition
+  // CHECK: public '__cblayout_B'
+  // CHECK: PackedAttr
+  // CHECK-NEXT: FieldDecl {{.*}} b 'float'
+_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, 
__cblayout_D), "");
+_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, 
__cblayout_CB_3), "");
 
 // check that layout struct is created for E because because its base struct
 // is empty and should be eliminated, and BTypedef should reuse the previously
-// defined '__layout_B' 
-// CHECK: HLSLBufferDecl {{.*}} line:122:9 cbuffer CB
+// defined '__cblayout_B' 
+// CHECK: HLSLBufferDecl {{.*}} line:[[# @LINE + 3]]:9 cbuffer CB
 // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer
 // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer
 cbuffer CB {
@@ -124,18 +132,20 @@ cbuffer CB {
   E s5;
   // CHECK: VarDecl {{.*}} s6 'hlsl_constant BTypedef':'hlsl_constant B'
   BTypedef s6;
-  // CHECK: CXXRecordDecl {{.*}}  implicit referenced class __layout_CB_4 
definition
-  // CHECK: FieldDecl {{.*}} s5 '__layout_E'
-  // CHECK: FieldDecl {{.*}} s6 '__layout_B'
+  // CHECK: CXXRecordDecl {{.*}}  implicit referenced struct __cblayout_CB_4 
definition
+  // CHECK: PackedAttr
+  // CHECK-NEXT: FieldDecl {{.*}} s5 '__cblayout_E'
+  // CHECK-NEXT: FieldDecl {{.*}} s6 '__cblayout_B'
 }
-  // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_E 
definition
-  // CHECK: FieldDecl {{.*}} c 'float'
-  // CHECK-NOT: CXXRecordDecl {{.*}} class __layout_B definition
-_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, 
__layout_E), "");
-_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, 
__layout_CB_4), "");
+// CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_E 
definition
+// CHECK: PackedAttr
+// CHECK-NEXT: FieldDecl {{.*}} c 'float'
+// CHECK-NOT: CXXRecordDecl {{.*}} struct __cblayout_B definition
+_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, 
__cblayout_E), "");
+_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, 
__cblayout_CB_4), "");
 
 // check that this produces empty layout struct
-// CHECK: HLSLBufferDecl {{.*}} line:141:9 cbuffer CB
+// CHECK: HLSLBufferDecl {{.*}} line:[[# @LINE + 3]]:9 cbuffer CB
 // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer
 // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer
 cbuffer CB {
@@ -149,27 +159,30 @@ cbuffer CB {
   RWBuffer<float> Buf;
   // CHECK: VarDecl {{.*}} ea 'EmptyArrayTypedef':'float[10][0]'
   EmptyArrayTypedef ea;
-  // CHECK: CXXRecordDecl {{.*}} implicit class __layout_CB_5 definition
+  // CHECK: CXXRecordDecl {{.*}} implicit struct __cblayout_CB_5 definition
+  // CHECK: PackedAttr
   // CHECK-NOT: FieldDecl
 }
 
 // check host layout struct with compatible base struct
-// CHECK: HLSLBufferDecl {{.*}} line:160:9 cbuffer CB
+// CHECK: HLSLBufferDecl {{.*}} line:[[# @LINE + 3]]:9 cbuffer CB
 // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer
 // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer
 cbuffer CB {
   // CHECK: VarDecl {{.*}} s8 'hlsl_constant F'
   F s8;
-  // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_CB_6 
definition
-  // CHECK: FieldDecl {{.*}} s8 '__layout_F'
+  // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB_6 
definition
+  // CHECK: PackedAttr
+  // CHECK-NEXT: FieldDecl {{.*}} s8 '__cblayout_F'
 }
-  // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_F 
definition
-  // CHECK: public 'A'
-_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, 
__layout_F), "");
-_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, 
__layout_CB_6), "");
+// CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_F 
definition
+// CHECK: public 'A'
+// CHECK: PackedAttr
+_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, 
__cblayout_F), "");
+_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, 
__cblayout_CB_6), "");
 
 // anonymous structs
-// CHECK: HLSLBufferDecl {{.*}} line:175:9 cbuffer CB
+// CHECK: HLSLBufferDecl {{.*}} line:[[# @LINE + 3]]:9 cbuffer CB
 // CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer
 // CHECK: HLSLResourceAttr {{.*}} Implicit CBuffer
 cbuffer CB {
@@ -182,7 +195,7 @@ cbuffer CB {
     // CHECK: FieldDecl {{.*}} f 'RWBuffer<float>':'hlsl::RWBuffer<float>'
     RWBuffer<float> f;
   } s9;
-  // CHECK: VarDecl {{.*}} s9 'hlsl_constant struct (unnamed struct at 
{{.*}}cbuffer.hlsl:177:3
+  // CHECK: VarDecl {{.*}} s9 'hlsl_constant struct (unnamed struct at 
{{.*}}cbuffer.hlsl:[[# @LINE - 8]]:3
   // CHECK: CXXRecordDecl {{.*}} struct definition
   struct {
     // CHECK: FieldDecl {{.*}} g 'float'
@@ -190,18 +203,21 @@ cbuffer CB {
     // CHECK: FieldDecl {{.*}} f 'RWBuffer<float>':'hlsl::RWBuffer<float>'
     RWBuffer<float> f;
   } s10;
-  // CHECK: VarDecl {{.*}} s10 'hlsl_constant struct (unnamed struct at 
{{.*}}cbuffer.hlsl:187:3
-  // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_anon 
definition
-  // CHECK: FieldDecl {{.*}} e 'float'
-  // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_anon_1 
definition
-  // CHECK: FieldDecl {{.*}} g 'float'
-  // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_CB_7 
definition
-  // CHECK: FieldDecl {{.*}} s9 '__layout_anon'
-  // CHECK: FieldDecl {{.*}} s10 '__layout_anon_1'
+  // CHECK: VarDecl {{.*}} s10 'hlsl_constant struct (unnamed struct at 
{{.*}}cbuffer.hlsl:[[# @LINE - 6]]:3
+  // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_anon 
definition
+  // CHECK: PackedAttr
+  // CHECK-NEXT: FieldDecl {{.*}} e 'float'
+  // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_anon_1 
definition
+  // CHECK: PackedAttr
+  // CHECK-NEXT: FieldDecl {{.*}} g 'float'
+  // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB_7 
definition
+  // CHECK: PackedAttr
+  // CHECK-NEXT: FieldDecl {{.*}} s9 '__cblayout_anon'
+  // CHECK-NEXT: FieldDecl {{.*}} s10 '__cblayout_anon_1'
 }
-_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, 
__layout_anon), "");
-_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, 
__layout_anon_1), "");
-_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, 
__layout_CB_7), "");
+_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, 
__cblayout_anon), "");
+_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(OneFloat, 
__cblayout_anon_1), "");
+_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(TwoFloats, 
__cblayout_CB_7), "");
 
 // Add uses for the constant buffer declarations so they are not optimized away
 export float foo() {
diff --git a/clang/test/AST/HLSL/cbuffer_and_namespaces.hlsl 
b/clang/test/AST/HLSL/cbuffer_and_namespaces.hlsl
index 12ce327d8be022..09596eda90b6ae 100644
--- a/clang/test/AST/HLSL/cbuffer_and_namespaces.hlsl
+++ b/clang/test/AST/HLSL/cbuffer_and_namespaces.hlsl
@@ -19,10 +19,10 @@ namespace NS1 {
       int b;
       EmptyStruct es;
     };
-    // CHECK: CXXRecordDecl {{.*}} implicit class __layout_Foo definition
+    // CHECK: CXXRecordDecl {{.*}} implicit struct __cblayout_Foo definition
     // CHECK: FieldDecl {{.*}} b 'int'
   };
-  // CHECK: CXXRecordDecl {{.*}} implicit class __layout_Foo definition
+  // CHECK: CXXRecordDecl {{.*}} implicit struct __cblayout_Foo definition
   // CHECK: FieldDecl {{.*}} a 'float'
 }
 
@@ -41,12 +41,12 @@ cbuffer CB1 {
   NS1::Foo foo2;
   // CHECK: VarDecl {{.*}} foo3 'hlsl_constant NS1::Bar::Foo'
   NS1::Bar::Foo foo3;
-  // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_CB1 
definition
-  // CHECK: FieldDecl {{.*}} foo1 '__layout_Foo'
-  // CHECK: FieldDecl {{.*}} foo2 'NS1::__layout_Foo'
-  // CHECK: FieldDecl {{.*}} foo3 'NS1::Bar::__layout_Foo'
+  // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB1 
definition
+  // CHECK: FieldDecl {{.*}} foo1 '__cblayout_Foo'
+  // CHECK: FieldDecl {{.*}} foo2 'NS1::__cblayout_Foo'
+  // CHECK: FieldDecl {{.*}} foo3 'NS1::Bar::__cblayout_Foo'
 }
-// CHECK: CXXRecordDecl {{.*}} implicit class __layout_Foo definition
+// CHECK: CXXRecordDecl {{.*}} implicit struct __cblayout_Foo definition
 // CHECK: FieldDecl {{.*}} c 'double'
 
 struct CB1ExpectedShape {
@@ -54,7 +54,7 @@ struct CB1ExpectedShape {
     float a2;
     int a;
 };
-_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(CB1ExpectedShape,
 __layout_CB1), "");
+_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(CB1ExpectedShape,
 __cblayout_CB1), "");
 
 namespace NS2 {
   struct Foo { 
@@ -73,13 +73,13 @@ namespace NS2 {
     NS1::Foo foo2;
     // CHECK: VarDecl {{.*}} foo3 'hlsl_constant NS1::Bar::Foo'
     NS1::Bar::Foo foo3;
-    // CHECK: CXXRecordDecl {{.*}} implicit referenced class __layout_CB2 
definition
-    // CHECK: FieldDecl {{.*}} foo0 '__layout_Foo'
-    // CHECK: FieldDecl {{.*}} foo1 'NS2::__layout_Foo'
-    // CHECK: FieldDecl {{.*}} foo2 'NS1::__layout_Foo'
-    // CHECK: FieldDecl {{.*}} foo3 'NS1::Bar::__layout_Foo'
+    // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB2 
definition
+    // CHECK: FieldDecl {{.*}} foo0 '__cblayout_Foo'
+    // CHECK: FieldDecl {{.*}} foo1 'NS2::__cblayout_Foo'
+    // CHECK: FieldDecl {{.*}} foo2 'NS1::__cblayout_Foo'
+    // CHECK: FieldDecl {{.*}} foo3 'NS1::Bar::__cblayout_Foo'
   }
-  // CHECK: CXXRecordDecl {{.*}} implicit class __layout_Foo definition
+  // CHECK: CXXRecordDecl {{.*}} implicit struct __cblayout_Foo definition
   // CHECK: FieldDecl {{.*}} d 'float[4]'
 }
 
@@ -89,7 +89,7 @@ struct CB2ExpectedShape {
     float a2;
     int a;
 };
-_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(CB2ExpectedShape,
 NS2::__layout_CB2), "");
+_Static_assert(__builtin_hlsl_is_scalarized_layout_compatible(CB2ExpectedShape,
 NS2::__cblayout_CB2), "");
 
 // Add uses for the constant buffer declarations so they are not optimized away
 // CHECK: ExportDecl
diff --git a/clang/test/AST/HLSL/pch_hlsl_buffer.hlsl 
b/clang/test/AST/HLSL/pch_hlsl_buffer.hlsl
index 98d7aba3978528..754948931ee538 100644
--- a/clang/test/AST/HLSL/pch_hlsl_buffer.hlsl
+++ b/clang/test/AST/HLSL/pch_hlsl_buffer.hlsl
@@ -21,14 +21,14 @@ float foo() {
 // CHECK-NEXT: HLSLResourceClassAttr {{.*}} Implicit CBuffer
 // CHECK-NEXT: HLSLResourceAttr {{.*}} Implicit CBuffer
 // CHECK-NEXT: VarDecl 0x[[A:[0-9a-f]+]] {{.*}} imported used a 'hlsl_constant 
float'
-// CHECK-NEXT: CXXRecordDecl {{.*}} imported implicit <undeserialized 
declarations> class __layout_A definition
+// CHECK-NEXT: CXXRecordDecl {{.*}} imported implicit <undeserialized 
declarations> struct __cblayout_A definition
 // CHECK: FieldDecl {{.*}} imported a 'float'
 
 // CHECK: HLSLBufferDecl {{.*}} line:11:9 imported <undeserialized 
declarations> tbuffer B
 // CHECK-NEXT: HLSLResourceClassAttr {{.*}} Implicit SRV
 // CHECK-NEXT: HLSLResourceAttr {{.*}} Implicit TBuffer
 // CHECK-NEXT: VarDecl 0x[[B:[0-9a-f]+]] {{.*}} imported used b 'hlsl_constant 
float'
-// CHECK-NEXT: CXXRecordDecl 0x{{[0-9a-f]+}} {{.*}} imported implicit 
<undeserialized declarations> class __layout_B definition
+// CHECK-NEXT: CXXRecordDecl 0x{{[0-9a-f]+}} {{.*}} imported implicit 
<undeserialized declarations> struct __cblayout_B definition
 // CHECK: FieldDecl 0x{{[0-9a-f]+}} {{.*}} imported b 'float'
 
 // CHECK-NEXT: FunctionDecl {{.*}} line:15:7 imported foo 'float ()'

>From c80415a22bf9b1e06928e84d8d0efa646fbaa5f9 Mon Sep 17 00:00:00 2001
From: Helena Kotas <heko...@microsoft.com>
Date: Tue, 28 Jan 2025 16:52:45 -0800
Subject: [PATCH 2/2] filter groupshared var decls

---
 clang/lib/Sema/SemaHLSL.cpp      | 3 ++-
 clang/test/AST/HLSL/cbuffer.hlsl | 2 ++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 97df01a5dd3074..b71dd2b273a1c6 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -484,7 +484,8 @@ void createHostLayoutStructForBuffer(Sema &S, 
HLSLBufferDecl *BufDecl) {
 
   for (Decl *D : BufDecl->decls()) {
     VarDecl *VD = dyn_cast<VarDecl>(D);
-    if (!VD || VD->getStorageClass() == SC_Static)
+    if (!VD || VD->getStorageClass() == SC_Static ||
+        VD->getType().getAddressSpace() == LangAS::hlsl_groupshared)
       continue;
     const Type *Ty = VD->getType()->getUnqualifiedDesugaredType();
     if (FieldDecl *FD =
diff --git a/clang/test/AST/HLSL/cbuffer.hlsl b/clang/test/AST/HLSL/cbuffer.hlsl
index 8254f0ee00b140..865db1201baa5b 100644
--- a/clang/test/AST/HLSL/cbuffer.hlsl
+++ b/clang/test/AST/HLSL/cbuffer.hlsl
@@ -71,6 +71,8 @@ cbuffer CB {
   float d2[0];
   // CHECK: VarDecl {{.*}} f2 'RWBuffer<float>[2]'
   RWBuffer<float> f2[2];
+  // CHECK: VarDecl {{.*}} g2 'groupshared float'
+  groupshared float g2;
   // CHECK: VarDecl {{.*}} e2 'hlsl_constant float'
   float e2;
   // CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_CB_1 
definition

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to