From e9615c14ce8f4f598c975bff6cfb6b5b8784a73b Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Mon, 21 Sep 2026 22:43:46 -0500 Subject: [PATCH] [202x] Fix nesting cbuffers in namespaces This is a long-standing bug in DXC, but in HLSL 202x since we're addressing a bunch of other issues around cbuffer/tbuffer semantics we also will address this here. With this change declarations placed inside a cbuffer are targeted to the enclosing declaration context which must be either a namespace or the top-level translation unit declaration context. --- docs/ReleaseNotes.md | 2 ++ tools/clang/lib/Sema/SemaHLSL.cpp | 3 ++ .../test/CodeGenDXIL/cbuffer.namespace.hlsl | 23 ++++++++++++ .../test/CodeGenSPIRV/cbuffer.namespace.hlsl | 22 ++++++++++++ .../v202x/buffer-namespace-decl-context.hlsl | 35 +++++++++++++++++++ 5 files changed, 85 insertions(+) create mode 100644 tools/clang/test/CodeGenDXIL/cbuffer.namespace.hlsl create mode 100644 tools/clang/test/CodeGenSPIRV/cbuffer.namespace.hlsl create mode 100644 tools/clang/test/SemaHLSL/v202x/buffer-namespace-decl-context.hlsl diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md index 375d68d2fa..14e035c081 100644 --- a/docs/ReleaseNotes.md +++ b/docs/ReleaseNotes.md @@ -63,6 +63,8 @@ line upon naming the release. Refer to previous for appropriate section names. - The `shared` and `uniform` keywords are removed in HLSL 202x, with compatibility warnings available for earlier language versions [#8482](https://github.com/microsoft/DirectXShaderCompiler/issues/8482). +- Starting with HLSL 202x, `cbuffer` and `tbuffer` declarations and their + members belong to their enclosing namespace. #### SPIR-V diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index 274adae6d7..fee88a1812 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -15446,6 +15446,9 @@ HLSLBufferDecl::Create(ASTContext &C, DeclContext *lexicalParent, bool cbuffer, std::vector &BufferAttributes, SourceLocation LBrace) { DeclContext *DC = C.getTranslationUnitDecl(); + // In HLSL 202x, buffers and their members belong to the enclosing namespace. + if (C.getLangOpts().HLSLVersion >= hlsl::LangStd::v202x) + DC = lexicalParent; HLSLBufferDecl *result = ::new (C) HLSLBufferDecl( DC, cbuffer, constantbuffer, KwLoc, Id, IdLoc, BufferAttributes, LBrace); if (DC != lexicalParent) { diff --git a/tools/clang/test/CodeGenDXIL/cbuffer.namespace.hlsl b/tools/clang/test/CodeGenDXIL/cbuffer.namespace.hlsl new file mode 100644 index 0000000000..ec436c2d69 --- /dev/null +++ b/tools/clang/test/CodeGenDXIL/cbuffer.namespace.hlsl @@ -0,0 +1,23 @@ +// RUN: %dxc -T ps_6_0 -E main -HV 202x %s | FileCheck %s + +// CHECK: ; cbuffer SceneConstants +// CHECK: ; cbuffer SceneConstants +// CHECK: ; Resource Bindings: +// CHECK-DAG: ; SceneConstants{{ +}}cbuffer{{ +}}NA{{ +}}NA{{ +}}CB0{{ +}}cb3{{ +}}1 +// CHECK-DAG: ; SceneConstants{{ +}}cbuffer{{ +}}NA{{ +}}NA{{ +}}CB1{{ +}}cb4{{ +}}1 + +namespace First { +cbuffer SceneConstants : register(b3) { + float Value; +} +} + +namespace Second { +cbuffer SceneConstants : register(b4) { + float Value; +} +} + +float4 main() : SV_Target { + return First::Value + Second::Value; +} diff --git a/tools/clang/test/CodeGenSPIRV/cbuffer.namespace.hlsl b/tools/clang/test/CodeGenSPIRV/cbuffer.namespace.hlsl new file mode 100644 index 0000000000..8e755a2779 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/cbuffer.namespace.hlsl @@ -0,0 +1,22 @@ +// RUN: %dxc -T ps_6_0 -E main -HV 202x -spirv -fcgl %s | FileCheck %s + +// CHECK-DAG: OpDecorate [[FIRST:%[^ ]+]] Binding 3 +// CHECK-DAG: OpDecorate [[SECOND:%[^ ]+]] Binding 4 +// CHECK-DAG: [[FIRST]] = OpVariable {{%[^ ]+}} Uniform +// CHECK-DAG: [[SECOND]] = OpVariable {{%[^ ]+}} Uniform + +namespace First { +cbuffer SceneConstants : register(b3) { + float Value; +} +} + +namespace Second { +cbuffer SceneConstants : register(b4) { + float Value; +} +} + +float4 main() : SV_Target { + return First::Value + Second::Value; +} diff --git a/tools/clang/test/SemaHLSL/v202x/buffer-namespace-decl-context.hlsl b/tools/clang/test/SemaHLSL/v202x/buffer-namespace-decl-context.hlsl new file mode 100644 index 0000000000..92cfff7502 --- /dev/null +++ b/tools/clang/test/SemaHLSL/v202x/buffer-namespace-decl-context.hlsl @@ -0,0 +1,35 @@ +// RUN: %dxc -T lib_6_3 -HV 202x -verify %s +// RUN: %dxc -T lib_6_3 -HV 202x -ast-dump %s 2>&1 | FileCheck %s + +// expected-no-diagnostics + +namespace First { +// CHECK: NamespaceDecl {{.*}} First +// CHECK-NEXT: {{.*}}HLSLBufferDecl {{0x[0-9a-f]+}} <{{.*}}> {{.*}} cbuffer Constants +cbuffer Constants { + float FirstValue; +} + +// CHECK: HLSLBufferDecl {{0x[0-9a-f]+}} <{{.*}}> {{.*}} tbuffer Textures +tbuffer Textures { + float FirstTextureValue; +} +} + +namespace Second { +// CHECK: NamespaceDecl {{.*}} Second +// CHECK-NEXT: {{.*}}HLSLBufferDecl {{0x[0-9a-f]+}} <{{.*}}> {{.*}} cbuffer Constants +cbuffer Constants { + float SecondValue; +} + +// CHECK: HLSLBufferDecl {{0x[0-9a-f]+}} <{{.*}}> {{.*}} tbuffer Textures +tbuffer Textures { + float SecondTextureValue; +} +} + +float4 main() : SV_Target { + return First::FirstValue + First::FirstTextureValue + + Second::SecondValue + Second::SecondTextureValue; +}