[clang] [llvm] [HLSL][RootSignature] Add parsing for RootFlags (PR #138055)

Finn Plummer via llvm-commits llvm-commits at lists.llvm.org
Fri May 9 11:18:51 PDT 2025


https://github.com/inbelic updated https://github.com/llvm/llvm-project/pull/138055

>From e1b21cc4d33dab2e100346443c998a678afc3dab Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Wed, 30 Apr 2025 23:14:07 +0000
Subject: [PATCH 1/6] pre-req: define missing lexer tokens for flags

---
 .../clang/Lex/HLSLRootSignatureTokenKinds.def | 19 +++++++++++++++++++
 .../Lex/LexHLSLRootSignatureTest.cpp          | 15 ++++++++++++++-
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
index d9edeff7ac567..c6f7f8928bc91 100644
--- a/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
+++ b/clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def
@@ -27,6 +27,9 @@
 #endif
 
 // Defines the various types of enum
+#ifndef ROOT_FLAG_ENUM
+#define ROOT_FLAG_ENUM(NAME, LIT) ENUM(NAME, LIT)
+#endif
 #ifndef UNBOUNDED_ENUM
 #define UNBOUNDED_ENUM(NAME, LIT) ENUM(NAME, LIT)
 #endif
@@ -74,6 +77,7 @@ PUNCTUATOR(minus,   '-')
 
 // RootElement Keywords:
 KEYWORD(RootSignature) // used only for diagnostic messaging
+KEYWORD(RootFlags)
 KEYWORD(DescriptorTable)
 KEYWORD(RootConstants)
 
@@ -101,6 +105,20 @@ UNBOUNDED_ENUM(unbounded, "unbounded")
 // Descriptor Range Offset Enum:
 DESCRIPTOR_RANGE_OFFSET_ENUM(DescriptorRangeOffsetAppend, "DESCRIPTOR_RANGE_OFFSET_APPEND")
 
+// Root Flag Enums:
+ROOT_FLAG_ENUM(AllowInputAssemblerInputLayout, "ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT")
+ROOT_FLAG_ENUM(DenyVertexShaderRootAccess, "DENY_VERTEX_SHADER_ROOT_ACCESS")
+ROOT_FLAG_ENUM(DenyHullShaderRootAccess, "DENY_HULL_SHADER_ROOT_ACCESS")
+ROOT_FLAG_ENUM(DenyDomainShaderRootAccess, "DENY_DOMAIN_SHADER_ROOT_ACCESS")
+ROOT_FLAG_ENUM(DenyGeometryShaderRootAccess, "DENY_GEOMETRY_SHADER_ROOT_ACCESS")
+ROOT_FLAG_ENUM(DenyPixelShaderRootAccess, "DENY_PIXEL_SHADER_ROOT_ACCESS")
+ROOT_FLAG_ENUM(DenyAmplificationShaderRootAccess, "DENY_AMPLIFICATION_SHADER_ROOT_ACCESS")
+ROOT_FLAG_ENUM(DenyMeshShaderRootAccess, "DENY_MESH_SHADER_ROOT_ACCESS")
+ROOT_FLAG_ENUM(AllowStreamOutput, "ALLOW_STREAM_OUTPUT")
+ROOT_FLAG_ENUM(LocalRootSignature, "LOCAL_ROOT_SIGNATURE")
+ROOT_FLAG_ENUM(CBVSRVUAVHeapDirectlyIndexed, "CBV_SRV_UAV_HEAP_DIRECTLY_INDEXED")
+ROOT_FLAG_ENUM(SamplerHeapDirectlyIndexed , "SAMPLER_HEAP_DIRECTLY_INDEXED")
+
 // Root Descriptor Flag Enums:
 ROOT_DESCRIPTOR_FLAG_ENUM(DataVolatile, "DATA_VOLATILE")
 ROOT_DESCRIPTOR_FLAG_ENUM(DataStaticWhileSetAtExecute, "DATA_STATIC_WHILE_SET_AT_EXECUTE")
@@ -128,6 +146,7 @@ SHADER_VISIBILITY_ENUM(Mesh, "SHADER_VISIBILITY_MESH")
 #undef DESCRIPTOR_RANGE_FLAG_ENUM_OFF
 #undef DESCRIPTOR_RANGE_FLAG_ENUM_ON
 #undef ROOT_DESCRIPTOR_FLAG_ENUM
+#undef ROOT_FLAG_ENUM
 #undef DESCRIPTOR_RANGE_OFFSET_ENUM
 #undef UNBOUNDED_ENUM
 #undef ENUM
diff --git a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
index a761257149c11..1f8d8be64e323 100644
--- a/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Lex/LexHLSLRootSignatureTest.cpp
@@ -128,7 +128,7 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexAllTokensTest) {
 
     RootSignature
 
-    DescriptorTable RootConstants
+    RootFlags DescriptorTable RootConstants
 
     num32BitConstants
 
@@ -139,6 +139,19 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexAllTokensTest) {
     unbounded
     DESCRIPTOR_RANGE_OFFSET_APPEND
 
+    allow_input_assembler_input_layout
+    deny_vertex_shader_root_access
+    deny_hull_shader_root_access
+    deny_domain_shader_root_access
+    deny_geometry_shader_root_access
+    deny_pixel_shader_root_access
+    deny_amplification_shader_root_access
+    deny_mesh_shader_root_access
+    allow_stream_output
+    local_root_signature
+    cbv_srv_uav_heap_directly_indexed
+    sampler_heap_directly_indexed
+
     DATA_VOLATILE
     DATA_STATIC_WHILE_SET_AT_EXECUTE
     DATA_STATIC

>From adc2168785e8104184b1b6f7e3983eb156e3b38d Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Wed, 30 Apr 2025 23:21:06 +0000
Subject: [PATCH 2/6] [HLSL][RootSignature] Add parsing for empty RootFlags

- defines the `RootFlags` in-memory enum
- defines a template of `parseRootFlags` that will allow handling of
parsing root flags
---
 .../clang/Parse/ParseHLSLRootSignature.h      |  1 +
 clang/lib/Parse/ParseHLSLRootSignature.cpp    | 25 +++++++++++++++++
 .../Parse/ParseHLSLRootSignatureTest.cpp      | 27 +++++++++++++++++++
 .../llvm/Frontend/HLSL/HLSLRootSignature.h    | 19 ++++++++++++-
 4 files changed, 71 insertions(+), 1 deletion(-)

diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index 2ac2083983741..915266f8a36ae 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -71,6 +71,7 @@ class RootSignatureParser {
   // expected, or, there is a lexing error
 
   /// Root Element parse methods:
+  std::optional<llvm::hlsl::rootsig::RootFlags> parseRootFlags();
   std::optional<llvm::hlsl::rootsig::RootConstants> parseRootConstants();
   std::optional<llvm::hlsl::rootsig::DescriptorTable> parseDescriptorTable();
   std::optional<llvm::hlsl::rootsig::DescriptorTableClause>
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 86bf30668db46..4f89edef2a5e2 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -27,6 +27,13 @@ RootSignatureParser::RootSignatureParser(SmallVector<RootElement> &Elements,
 bool RootSignatureParser::parse() {
   // Iterate as many RootElements as possible
   do {
+    if (tryConsumeExpectedToken(TokenKind::kw_RootFlags)) {
+      auto Flags = parseRootFlags();
+      if (!Flags.has_value())
+        return true;
+      Elements.push_back(*Flags);
+    }
+
     if (tryConsumeExpectedToken(TokenKind::kw_RootConstants)) {
       auto Constants = parseRootConstants();
       if (!Constants.has_value())
@@ -47,6 +54,24 @@ bool RootSignatureParser::parse() {
                               /*param of=*/TokenKind::kw_RootSignature);
 }
 
+std::optional<RootFlags> RootSignatureParser::parseRootFlags() {
+  assert(CurToken.TokKind == TokenKind::kw_RootFlags &&
+         "Expects to only be invoked starting at given keyword");
+
+  if (consumeExpectedToken(TokenKind::pu_l_paren, diag::err_expected_after,
+                           CurToken.TokKind))
+    return std::nullopt;
+
+  RootFlags Flags = RootFlags::None;
+
+  if (consumeExpectedToken(TokenKind::pu_r_paren,
+                           diag::err_hlsl_unexpected_end_of_params,
+                           /*param of=*/TokenKind::kw_RootFlags))
+    return std::nullopt;
+
+  return Flags;
+}
+
 std::optional<RootConstants> RootSignatureParser::parseRootConstants() {
   assert(CurToken.TokKind == TokenKind::kw_RootConstants &&
          "Expects to only be invoked starting at given keyword");
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index eda68531de34f..769729e8678fc 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -294,6 +294,33 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseRootConsantsTest) {
   ASSERT_TRUE(Consumer->isSatisfied());
 }
 
+TEST_F(ParseHLSLRootSignatureTest, ValidParseRootFlagsTest) {
+  const llvm::StringLiteral Source = R"cc(
+    RootFlags()
+  )cc";
+
+  TrivialModuleLoader ModLoader;
+  auto PP = createPP(Source, ModLoader);
+  auto TokLoc = SourceLocation();
+
+  hlsl::RootSignatureLexer Lexer(Source, TokLoc);
+  SmallVector<RootElement> Elements;
+  hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
+
+  // Test no diagnostics produced
+  Consumer->setNoDiag();
+
+  ASSERT_FALSE(Parser.parse());
+
+  ASSERT_EQ(Elements.size(), 1u);
+
+  RootElement Elem = Elements[0];
+  ASSERT_TRUE(std::holds_alternative<RootFlags>(Elem));
+  ASSERT_EQ(std::get<RootFlags>(Elem), RootFlags::None);
+
+  ASSERT_TRUE(Consumer->isSatisfied());
+}
+
 TEST_F(ParseHLSLRootSignatureTest, ValidTrailingCommaTest) {
   // This test will checks we can handling trailing commas ','
   const llvm::StringLiteral Source = R"cc(
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index 8b8324df18bb3..12a520e034b3f 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -23,6 +23,23 @@ namespace rootsig {
 
 // Definition of the various enumerations and flags
 
+enum class RootFlags : uint32_t {
+  None = 0,
+  AllowInputAssemblerInputLayout = 0x1,
+  DenyVertexShaderRootAccess = 0x2,
+  DenyHullShaderRootAccess = 0x4,
+  DenyDomainShaderRootAccess = 0x8,
+  DenyGeometryShaderRootAccess = 0x10,
+  DenyPixelShaderRootAccess = 0x20,
+  AllowStreamOutput = 0x40,
+  LocalRootSignature = 0x80,
+  DenyAmplificationShaderRootAccess = 0x100,
+  DenyMeshShaderRootAccess = 0x200,
+  CBVSRVUAVHeapDirectlyIndexed = 0x400,
+  SamplerHeapDirectlyIndexed = 0x800,
+  ValidFlags = 0x00000fff
+};
+
 enum class DescriptorRangeFlags : unsigned {
   None = 0,
   DescriptorsVolatile = 0x1,
@@ -98,7 +115,7 @@ struct DescriptorTableClause {
 
 // Models RootElement : RootConstants | DescriptorTable | DescriptorTableClause
 using RootElement =
-    std::variant<RootConstants, DescriptorTable, DescriptorTableClause>;
+    std::variant<RootFlags, RootConstants, DescriptorTable, DescriptorTableClause>;
 
 } // namespace rootsig
 } // namespace hlsl

>From b3752fb38e27742242f42eadd9c20553bb948649 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Wed, 30 Apr 2025 23:46:17 +0000
Subject: [PATCH 3/6] implement parsing of the flags

---
 clang/lib/Parse/ParseHLSLRootSignature.cpp    | 49 +++++++++++++++----
 .../Parse/ParseHLSLRootSignatureTest.cpp      | 27 +++++++++-
 2 files changed, 64 insertions(+), 12 deletions(-)

diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 4f89edef2a5e2..387ef33682be2 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -54,6 +54,15 @@ bool RootSignatureParser::parse() {
                               /*param of=*/TokenKind::kw_RootSignature);
 }
 
+template <typename FlagType>
+static FlagType maybeOrFlag(std::optional<FlagType> Flags, FlagType Flag) {
+  if (!Flags.has_value())
+    return Flag;
+
+  return static_cast<FlagType>(llvm::to_underlying(Flags.value()) |
+                               llvm::to_underlying(Flag));
+}
+
 std::optional<RootFlags> RootSignatureParser::parseRootFlags() {
   assert(CurToken.TokKind == TokenKind::kw_RootFlags &&
          "Expects to only be invoked starting at given keyword");
@@ -62,7 +71,36 @@ std::optional<RootFlags> RootSignatureParser::parseRootFlags() {
                            CurToken.TokKind))
     return std::nullopt;
 
-  RootFlags Flags = RootFlags::None;
+  std::optional<RootFlags> Flags = RootFlags::None;
+
+  // Handle the edge-case of '0' to specify no flags set
+  if (tryConsumeExpectedToken(TokenKind::int_literal)) {
+    if (!verifyZeroFlag()) {
+      getDiags().Report(CurToken.TokLoc, diag::err_expected) << "'0'";
+      return std::nullopt;
+    }
+  } else {
+    // Otherwise, parse as many flags as possible
+    TokenKind Expected[] = {
+  #define ROOT_FLAG_ENUM(NAME, LIT) TokenKind::en_##NAME,
+  #include "clang/Lex/HLSLRootSignatureTokenKinds.def"
+    };
+
+    do {
+      if (tryConsumeExpectedToken(Expected)) {
+        switch (CurToken.TokKind) {
+  #define ROOT_FLAG_ENUM(NAME, LIT) \
+    case TokenKind::en_##NAME:                                                   \
+      Flags =                                                                    \
+          maybeOrFlag<RootFlags>(Flags, RootFlags::NAME);  \
+      break;
+  #include "clang/Lex/HLSLRootSignatureTokenKinds.def"
+        default:
+          llvm_unreachable("Switch for consumed enum token was not provided");
+        }
+      }
+    } while (tryConsumeExpectedToken(TokenKind::pu_or));
+  }
 
   if (consumeExpectedToken(TokenKind::pu_r_paren,
                            diag::err_hlsl_unexpected_end_of_params,
@@ -492,15 +530,6 @@ RootSignatureParser::parseShaderVisibility() {
   return std::nullopt;
 }
 
-template <typename FlagType>
-static FlagType maybeOrFlag(std::optional<FlagType> Flags, FlagType Flag) {
-  if (!Flags.has_value())
-    return Flag;
-
-  return static_cast<FlagType>(llvm::to_underlying(Flags.value()) |
-                               llvm::to_underlying(Flag));
-}
-
 std::optional<llvm::hlsl::rootsig::DescriptorRangeFlags>
 RootSignatureParser::parseDescriptorRangeFlags() {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 769729e8678fc..a190b7db4fb2e 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -296,7 +296,22 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseRootConsantsTest) {
 
 TEST_F(ParseHLSLRootSignatureTest, ValidParseRootFlagsTest) {
   const llvm::StringLiteral Source = R"cc(
-    RootFlags()
+    RootFlags(),
+    RootFlags(0),
+    RootFlags(
+      deny_domain_shader_root_access |
+      deny_pixel_shader_root_access |
+      local_root_signature |
+      cbv_srv_uav_heap_directly_indexed |
+      deny_amplification_shader_root_access |
+      deny_geometry_shader_root_access |
+      deny_hull_shader_root_access |
+      deny_mesh_shader_root_access |
+      allow_stream_output |
+      sampler_heap_directly_indexed |
+      allow_input_assembler_input_layout |
+      deny_vertex_shader_root_access
+    )
   )cc";
 
   TrivialModuleLoader ModLoader;
@@ -312,12 +327,20 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseRootFlagsTest) {
 
   ASSERT_FALSE(Parser.parse());
 
-  ASSERT_EQ(Elements.size(), 1u);
+  ASSERT_EQ(Elements.size(), 3u);
 
   RootElement Elem = Elements[0];
   ASSERT_TRUE(std::holds_alternative<RootFlags>(Elem));
   ASSERT_EQ(std::get<RootFlags>(Elem), RootFlags::None);
 
+  Elem = Elements[1];
+  ASSERT_TRUE(std::holds_alternative<RootFlags>(Elem));
+  ASSERT_EQ(std::get<RootFlags>(Elem), RootFlags::None);
+
+  Elem = Elements[2];
+  ASSERT_TRUE(std::holds_alternative<RootFlags>(Elem));
+  ASSERT_EQ(std::get<RootFlags>(Elem), RootFlags::ValidFlags);
+
   ASSERT_TRUE(Consumer->isSatisfied());
 }
 

>From ddfbed4f607ae784e39f5b3fd923db7e4dff7ae1 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Wed, 30 Apr 2025 23:52:36 +0000
Subject: [PATCH 4/6] nfc: improve error message for non-zero flag diagnostic

- we shouldn't pass in a string to the diagnostic, instead we should
define the string properly and provide better context
---
 clang/include/clang/Basic/DiagnosticParseKinds.td    | 1 +
 clang/lib/Parse/ParseHLSLRootSignature.cpp           | 4 ++--
 clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp | 2 +-
 3 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 33e9296f39eeb..d2e0e5c1ab8f2 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1856,5 +1856,6 @@ def err_hlsl_unexpected_end_of_params
 def err_hlsl_rootsig_repeat_param : Error<"specified the same parameter '%0' multiple times">;
 def err_hlsl_rootsig_missing_param : Error<"did not specify mandatory parameter '%0'">;
 def err_hlsl_number_literal_overflow : Error<"integer literal is too large to be represented as a 32-bit %select{signed |}0 integer type">;
+def err_hlsl_rootsig_non_zero_flag : Error<"non-zero integer literal specified for flag value">;
 
 } // end of Parser diagnostics
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 387ef33682be2..d2c52c51bcc46 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -76,7 +76,7 @@ std::optional<RootFlags> RootSignatureParser::parseRootFlags() {
   // Handle the edge-case of '0' to specify no flags set
   if (tryConsumeExpectedToken(TokenKind::int_literal)) {
     if (!verifyZeroFlag()) {
-      getDiags().Report(CurToken.TokLoc, diag::err_expected) << "'0'";
+      getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_non_zero_flag);
       return std::nullopt;
     }
   } else {
@@ -538,7 +538,7 @@ RootSignatureParser::parseDescriptorRangeFlags() {
   // Handle the edge-case of '0' to specify no flags set
   if (tryConsumeExpectedToken(TokenKind::int_literal)) {
     if (!verifyZeroFlag()) {
-      getDiags().Report(CurToken.TokLoc, diag::err_expected) << "'0'";
+      getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_non_zero_flag);
       return std::nullopt;
     }
     return DescriptorRangeFlags::None;
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index a190b7db4fb2e..c97f8d0b392d1 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -616,7 +616,7 @@ TEST_F(ParseHLSLRootSignatureTest, InvalidNonZeroFlagsTest) {
   hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
 
   // Test correct diagnostic produced
-  Consumer->setExpected(diag::err_expected);
+  Consumer->setExpected(diag::err_hlsl_rootsig_non_zero_flag);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());

>From 9963bdfeeff139ccee15a996cf7ac7a84a4cd391 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Wed, 30 Apr 2025 23:55:40 +0000
Subject: [PATCH 5/6] clang-format

---
 clang/lib/Parse/ParseHLSLRootSignature.cpp        | 15 +++++++--------
 .../llvm/Frontend/HLSL/HLSLRootSignature.h        |  4 ++--
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index d2c52c51bcc46..5603900429844 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -82,19 +82,18 @@ std::optional<RootFlags> RootSignatureParser::parseRootFlags() {
   } else {
     // Otherwise, parse as many flags as possible
     TokenKind Expected[] = {
-  #define ROOT_FLAG_ENUM(NAME, LIT) TokenKind::en_##NAME,
-  #include "clang/Lex/HLSLRootSignatureTokenKinds.def"
+#define ROOT_FLAG_ENUM(NAME, LIT) TokenKind::en_##NAME,
+#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
     };
 
     do {
       if (tryConsumeExpectedToken(Expected)) {
         switch (CurToken.TokKind) {
-  #define ROOT_FLAG_ENUM(NAME, LIT) \
-    case TokenKind::en_##NAME:                                                   \
-      Flags =                                                                    \
-          maybeOrFlag<RootFlags>(Flags, RootFlags::NAME);  \
-      break;
-  #include "clang/Lex/HLSLRootSignatureTokenKinds.def"
+#define ROOT_FLAG_ENUM(NAME, LIT)                                              \
+  case TokenKind::en_##NAME:                                                   \
+    Flags = maybeOrFlag<RootFlags>(Flags, RootFlags::NAME);                    \
+    break;
+#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
         default:
           llvm_unreachable("Switch for consumed enum token was not provided");
         }
diff --git a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
index 12a520e034b3f..2ecaf69fc2f9c 100644
--- a/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
+++ b/llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h
@@ -114,8 +114,8 @@ struct DescriptorTableClause {
 };
 
 // Models RootElement : RootConstants | DescriptorTable | DescriptorTableClause
-using RootElement =
-    std::variant<RootFlags, RootConstants, DescriptorTable, DescriptorTableClause>;
+using RootElement = std::variant<RootFlags, RootConstants, DescriptorTable,
+                                 DescriptorTableClause>;
 
 } // namespace rootsig
 } // namespace hlsl

>From 08f42a90c4b00be5be5d12191da44645ee705b59 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienfinn at gmail.com>
Date: Fri, 9 May 2025 18:17:56 +0000
Subject: [PATCH 6/6] review: touch-up diag message

---
 clang/include/clang/Basic/DiagnosticParseKinds.td | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index d2e0e5c1ab8f2..3bbdc49946dac 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1856,6 +1856,6 @@ def err_hlsl_unexpected_end_of_params
 def err_hlsl_rootsig_repeat_param : Error<"specified the same parameter '%0' multiple times">;
 def err_hlsl_rootsig_missing_param : Error<"did not specify mandatory parameter '%0'">;
 def err_hlsl_number_literal_overflow : Error<"integer literal is too large to be represented as a 32-bit %select{signed |}0 integer type">;
-def err_hlsl_rootsig_non_zero_flag : Error<"non-zero integer literal specified for flag value">;
+def err_hlsl_rootsig_non_zero_flag : Error<"flag value is neither a literal 0 nor a named value">;
 
 } // end of Parser diagnostics



More information about the llvm-commits mailing list