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