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

>From 95166f5e2bfb2816ce39d3abd1823486742109bd Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienf...@gmail.com>
Date: Wed, 9 Jul 2025 15:50:55 +0000
Subject: [PATCH 01/11] remove confusing hlsl_unexpected_end_of_params
 diagnostic

- It has been noted more than once that this diagnostic is confusing and
misleading. It can be more concise
---
 .../clang/Basic/DiagnosticParseKinds.td       |  2 --
 clang/lib/Parse/ParseHLSLRootSignature.cpp    | 29 +++++--------------
 clang/test/SemaHLSL/RootSignature-err.hlsl    |  8 ++---
 .../Parse/ParseHLSLRootSignatureTest.cpp      | 16 +++++-----
 4 files changed, 19 insertions(+), 36 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index fd8e5c3c6ad87..a4c524544be12 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1860,8 +1860,6 @@ def err_hlsl_virtual_inheritance
     : Error<"virtual inheritance is unsupported in HLSL">;
 
 // HLSL Root Signature Parser Diagnostics
-def err_hlsl_unexpected_end_of_params
-    : Error<"expected %0 to denote end of parameters, or, another valid 
parameter of %1">;
 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<
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 6c27ea22a2167..28ac35b614755 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -66,9 +66,7 @@ bool RootSignatureParser::parse() {
       break;
   }
 
-  return consumeExpectedToken(TokenKind::end_of_stream,
-                              diag::err_hlsl_unexpected_end_of_params,
-                              /*param of=*/TokenKind::kw_RootSignature);
+  return consumeExpectedToken(TokenKind::end_of_stream);
 }
 
 template <typename FlagType>
@@ -119,9 +117,7 @@ std::optional<llvm::dxbc::RootFlags> 
RootSignatureParser::parseRootFlags() {
     } while (tryConsumeExpectedToken(TokenKind::pu_or));
   }
 
-  if (consumeExpectedToken(TokenKind::pu_r_paren,
-                           diag::err_hlsl_unexpected_end_of_params,
-                           /*param of=*/TokenKind::kw_RootFlags))
+  if (consumeExpectedToken(TokenKind::pu_r_paren))
     return std::nullopt;
 
   return Flags;
@@ -141,9 +137,7 @@ std::optional<RootConstants> 
RootSignatureParser::parseRootConstants() {
   if (!Params.has_value())
     return std::nullopt;
 
-  if (consumeExpectedToken(TokenKind::pu_r_paren,
-                           diag::err_hlsl_unexpected_end_of_params,
-                           /*param of=*/TokenKind::kw_RootConstants))
+  if (consumeExpectedToken(TokenKind::pu_r_paren))
     return std::nullopt;
 
   // Check mandatory parameters where provided
@@ -208,9 +202,7 @@ std::optional<RootDescriptor> 
RootSignatureParser::parseRootDescriptor() {
   if (!Params.has_value())
     return std::nullopt;
 
-  if (consumeExpectedToken(TokenKind::pu_r_paren,
-                           diag::err_hlsl_unexpected_end_of_params,
-                           /*param of=*/DescriptorKind))
+  if (consumeExpectedToken(TokenKind::pu_r_paren))
     return std::nullopt;
 
   // Check mandatory parameters were provided
@@ -276,9 +268,7 @@ std::optional<DescriptorTable> 
RootSignatureParser::parseDescriptorTable() {
       break;
   }
 
-  if (consumeExpectedToken(TokenKind::pu_r_paren,
-                           diag::err_hlsl_unexpected_end_of_params,
-                           /*param of=*/TokenKind::kw_DescriptorTable))
+  if (consumeExpectedToken(TokenKind::pu_r_paren))
     return std::nullopt;
 
   // Fill in optional visibility
@@ -330,9 +320,7 @@ RootSignatureParser::parseDescriptorTableClause() {
   if (!Params.has_value())
     return std::nullopt;
 
-  if (consumeExpectedToken(TokenKind::pu_r_paren,
-                           diag::err_hlsl_unexpected_end_of_params,
-                           /*param of=*/ParamKind))
+  if (consumeExpectedToken(TokenKind::pu_r_paren))
     return std::nullopt;
 
   // Check mandatory parameters were provided
@@ -373,9 +361,7 @@ std::optional<StaticSampler> 
RootSignatureParser::parseStaticSampler() {
   if (!Params.has_value())
     return std::nullopt;
 
-  if (consumeExpectedToken(TokenKind::pu_r_paren,
-                           diag::err_hlsl_unexpected_end_of_params,
-                           /*param of=*/TokenKind::kw_StaticSampler))
+  if (consumeExpectedToken(TokenKind::pu_r_paren))
     return std::nullopt;
 
   // Check mandatory parameters were provided
@@ -1282,7 +1268,6 @@ bool RootSignatureParser::consumeExpectedToken(TokenKind 
Expected,
   case diag::err_expected:
     DB << Expected;
     break;
-  case diag::err_hlsl_unexpected_end_of_params:
   case diag::err_expected_either:
   case diag::err_expected_after:
     DB << Expected << Context;
diff --git a/clang/test/SemaHLSL/RootSignature-err.hlsl 
b/clang/test/SemaHLSL/RootSignature-err.hlsl
index 50807d611e91a..7e300e5cb8718 100644
--- a/clang/test/SemaHLSL/RootSignature-err.hlsl
+++ b/clang/test/SemaHLSL/RootSignature-err.hlsl
@@ -17,10 +17,10 @@ void bad_root_signature_2() {}
 [RootSignature(""), RootSignature("")] // expected-warning {{attribute 
'RootSignature' is already applied}}
 void bad_root_signature_3() {}
 
-[RootSignature("DescriptorTable(), invalid")] // expected-error {{expected end 
of stream to denote end of parameters, or, another valid parameter of 
RootSignature}}
+[RootSignature("DescriptorTable(), invalid")] // expected-error {{expected end 
of stream}}
 void bad_root_signature_4() {}
 
-// expected-error@+1 {{expected ')' to denote end of parameters, or, another 
valid parameter of RootConstants}}
+// expected-error@+1 {{expected ')'}}
 [RootSignature("RootConstants(b0, num32BitConstants = 1, invalid)")]
 void bad_root_signature_5() {}
 
@@ -31,10 +31,10 @@ void bad_root_signature_5() {}
 // CHECK: [[@LINE-2]]:42: note: expanded from macro 'MultiLineRootSignature'
 // CHECK-NEXT: [[@LINE-3]] | "RootConstants(num32BitConstants = 3, b0, 
invalid)"
 // CHECK-NEXT:             |                                         ^
-// expected-error@+1 {{expected ')' to denote end of parameters, or, another 
valid parameter of RootConstants}}
+// expected-error@+1 {{expected ')'}}
 [RootSignature(MultiLineRootSignature)]
 void bad_root_signature_6() {}
 
-// expected-error@+1 {{expected end of stream to denote end of parameters, or, 
another valid parameter of RootSignature}}
+// expected-error@+1 {{expected end of stream}}
 [RootSignature("RootFlags() RootConstants(b0, num32BitConstants = 1))")]
 void bad_root_signature_7() {}
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp 
b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 5b1ab149f4497..baa772bab99ed 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -843,7 +843,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseUnexpectedTokenTest) {
                                    Signature, *PP);
 
   // Test correct diagnostic produced
-  Consumer->setExpected(diag::err_hlsl_unexpected_end_of_params);
+  Consumer->setExpected(diag::err_expected);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());
@@ -865,7 +865,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseInvalidTokenTest) {
                                    Signature, *PP);
 
   // Test correct diagnostic produced - invalid token
-  Consumer->setExpected(diag::err_hlsl_unexpected_end_of_params);
+  Consumer->setExpected(diag::err_expected);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());
@@ -1258,7 +1258,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRootElementMissingCommaTest) {
                                    Signature, *PP);
 
   // Test correct diagnostic produced
-  Consumer->setExpected(diag::err_hlsl_unexpected_end_of_params);
+  Consumer->setExpected(diag::err_expected);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());
@@ -1285,7 +1285,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidDescriptorTableMissingCommaTest) {
                                    Signature, *PP);
 
   // Test correct diagnostic produced
-  Consumer->setExpected(diag::err_hlsl_unexpected_end_of_params);
+  Consumer->setExpected(diag::err_expected);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());
@@ -1312,7 +1312,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRootConstantParamsCommaTest) {
                                    Signature, *PP);
 
   // Test correct diagnostic produced
-  Consumer->setExpected(diag::err_hlsl_unexpected_end_of_params);
+  Consumer->setExpected(diag::err_expected);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());
@@ -1339,7 +1339,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRootDescriptorParamsCommaTest) {
                                    Signature, *PP);
 
   // Test correct diagnostic produced
-  Consumer->setExpected(diag::err_hlsl_unexpected_end_of_params);
+  Consumer->setExpected(diag::err_expected);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());
@@ -1368,7 +1368,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidDescriptorClauseParamsCommaTest) {
                                    Signature, *PP);
 
   // Test correct diagnostic produced
-  Consumer->setExpected(diag::err_hlsl_unexpected_end_of_params);
+  Consumer->setExpected(diag::err_expected);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());
@@ -1395,7 +1395,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidStaticSamplerCommaTest) {
                                    Signature, *PP);
 
   // Test correct diagnostic produced
-  Consumer->setExpected(diag::err_hlsl_unexpected_end_of_params);
+  Consumer->setExpected(diag::err_expected);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());

>From 24a2bea7fa745f3909f632369e8f8aaa7fff0b2a Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienf...@gmail.com>
Date: Wed, 9 Jul 2025 16:07:51 +0000
Subject: [PATCH 02/11] add invalid_param diagnostic to differentiate between
 missing comma vs invalid token

---
 .../clang/Basic/DiagnosticParseKinds.td       |  1 +
 .../clang/Parse/ParseHLSLRootSignature.h      |  6 ++-
 clang/lib/Parse/ParseHLSLRootSignature.cpp    | 38 +++++++++++++++++--
 clang/test/SemaHLSL/RootSignature-err.hlsl    | 27 ++++++++++---
 .../Parse/ParseHLSLRootSignatureTest.cpp      |  4 +-
 5 files changed, 63 insertions(+), 13 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index a4c524544be12..4671b3aad303c 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1860,6 +1860,7 @@ def err_hlsl_virtual_inheritance
     : Error<"virtual inheritance is unsupported in HLSL">;
 
 // HLSL Root Signature Parser Diagnostics
+def err_hlsl_invalid_param : Error<"invalid parameter of %0">;
 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<
diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h 
b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index 500e79a7ba574..0c12421723feb 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -100,7 +100,8 @@ class RootSignatureParser {
     std::optional<llvm::dxbc::RootDescriptorFlags> Flags;
   };
   std::optional<ParsedRootDescriptorParams>
-  parseRootDescriptorParams(RootSignatureToken::Kind RegType);
+  parseRootDescriptorParams(RootSignatureToken::Kind DescKind,
+                            RootSignatureToken::Kind RegType);
 
   struct ParsedClauseParams {
     std::optional<llvm::hlsl::rootsig::Register> Reg;
@@ -110,7 +111,8 @@ class RootSignatureParser {
     std::optional<llvm::dxbc::DescriptorRangeFlags> Flags;
   };
   std::optional<ParsedClauseParams>
-  parseDescriptorTableClauseParams(RootSignatureToken::Kind RegType);
+  parseDescriptorTableClauseParams(RootSignatureToken::Kind ClauseKind,
+                                   RootSignatureToken::Kind RegType);
 
   struct ParsedStaticSamplerParams {
     std::optional<llvm::hlsl::rootsig::Register> Reg;
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 28ac35b614755..41c1fb24614f7 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -59,6 +59,11 @@ bool RootSignatureParser::parse() {
       if (!Sampler.has_value())
         return true;
       Elements.emplace_back(RootSignatureElement(ElementLoc, *Sampler));
+    } else {
+      consumeNextToken(); // let diagnostic be at the start of invalid token
+      reportDiag(diag::err_hlsl_invalid_param)
+          << /*param of*/ TokenKind::kw_RootSignature;
+      return true;
     }
 
     // ',' denotes another element, otherwise, expected to be at end of stream
@@ -198,7 +203,7 @@ std::optional<RootDescriptor> 
RootSignatureParser::parseRootDescriptor() {
   }
   Descriptor.setDefaultFlags(Version);
 
-  auto Params = parseRootDescriptorParams(ExpectedReg);
+  auto Params = parseRootDescriptorParams(DescriptorKind, ExpectedReg);
   if (!Params.has_value())
     return std::nullopt;
 
@@ -261,6 +266,11 @@ std::optional<DescriptorTable> 
RootSignatureParser::parseDescriptorTable() {
       Visibility = parseShaderVisibility();
       if (!Visibility.has_value())
         return std::nullopt;
+    } else {
+      consumeNextToken(); // let diagnostic be at the start of invalid token
+      reportDiag(diag::err_hlsl_invalid_param)
+          << /*param of*/ TokenKind::kw_DescriptorTable;
+      return std::nullopt;
     }
 
     // ',' denotes another element, otherwise, expected to be at ')'
@@ -316,7 +326,7 @@ RootSignatureParser::parseDescriptorTableClause() {
   }
   Clause.setDefaultFlags(Version);
 
-  auto Params = parseDescriptorTableClauseParams(ExpectedReg);
+  auto Params = parseDescriptorTableClauseParams(ParamKind, ExpectedReg);
   if (!Params.has_value())
     return std::nullopt;
 
@@ -474,6 +484,11 @@ RootSignatureParser::parseRootConstantParams() {
       if (!Visibility.has_value())
         return std::nullopt;
       Params.Visibility = Visibility;
+    } else {
+      consumeNextToken(); // let diagnostic be at the start of invalid token
+      reportDiag(diag::err_hlsl_invalid_param)
+          << /*param of*/ TokenKind::kw_RootConstants;
+      return std::nullopt;
     }
 
     // ',' denotes another element, otherwise, expected to be at ')'
@@ -485,7 +500,8 @@ RootSignatureParser::parseRootConstantParams() {
 }
 
 std::optional<RootSignatureParser::ParsedRootDescriptorParams>
-RootSignatureParser::parseRootDescriptorParams(TokenKind RegType) {
+RootSignatureParser::parseRootDescriptorParams(TokenKind DescKind,
+                                               TokenKind RegType) {
   assert(CurToken.TokKind == TokenKind::pu_l_paren &&
          "Expects to only be invoked starting at given token");
 
@@ -543,6 +559,10 @@ RootSignatureParser::parseRootDescriptorParams(TokenKind 
RegType) {
       if (!Flags.has_value())
         return std::nullopt;
       Params.Flags = Flags;
+    } else {
+      consumeNextToken(); // let diagnostic be at the start of invalid token
+      reportDiag(diag::err_hlsl_invalid_param) << /*param of*/ DescKind;
+      return std::nullopt;
     }
 
     // ',' denotes another element, otherwise, expected to be at ')'
@@ -554,7 +574,8 @@ RootSignatureParser::parseRootDescriptorParams(TokenKind 
RegType) {
 }
 
 std::optional<RootSignatureParser::ParsedClauseParams>
-RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
+RootSignatureParser::parseDescriptorTableClauseParams(TokenKind ClauseKind,
+                                                      TokenKind RegType) {
   assert(CurToken.TokKind == TokenKind::pu_l_paren &&
          "Expects to only be invoked starting at given token");
 
@@ -638,6 +659,10 @@ 
RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
       if (!Flags.has_value())
         return std::nullopt;
       Params.Flags = Flags;
+    } else {
+      consumeNextToken(); // let diagnostic be at the start of invalid token
+      reportDiag(diag::err_hlsl_invalid_param) << /*param of*/ ClauseKind;
+      return std::nullopt;
     }
 
     // ',' denotes another element, otherwise, expected to be at ')'
@@ -833,6 +858,11 @@ RootSignatureParser::parseStaticSamplerParams() {
       if (!Visibility.has_value())
         return std::nullopt;
       Params.Visibility = Visibility;
+    } else {
+      consumeNextToken(); // let diagnostic be at the start of invalid token
+      reportDiag(diag::err_hlsl_invalid_param)
+          << /*param of*/ TokenKind::kw_StaticSampler;
+      return std::nullopt;
     }
 
     // ',' denotes another element, otherwise, expected to be at ')'
diff --git a/clang/test/SemaHLSL/RootSignature-err.hlsl 
b/clang/test/SemaHLSL/RootSignature-err.hlsl
index 7e300e5cb8718..188cf6de182fa 100644
--- a/clang/test/SemaHLSL/RootSignature-err.hlsl
+++ b/clang/test/SemaHLSL/RootSignature-err.hlsl
@@ -17,10 +17,11 @@ void bad_root_signature_2() {}
 [RootSignature(""), RootSignature("")] // expected-warning {{attribute 
'RootSignature' is already applied}}
 void bad_root_signature_3() {}
 
-[RootSignature("DescriptorTable(), invalid")] // expected-error {{expected end 
of stream}}
+// expected-error@+1 {{invalid parameter of RootSignature}}
+[RootSignature("DescriptorTable(), invalid")]
 void bad_root_signature_4() {}
 
-// expected-error@+1 {{expected ')'}}
+// expected-error@+1 {{invalid parameter of RootConstants}}
 [RootSignature("RootConstants(b0, num32BitConstants = 1, invalid)")]
 void bad_root_signature_5() {}
 
@@ -28,13 +29,29 @@ void bad_root_signature_5() {}
  "CBV(b0)," \
  "RootConstants(num32BitConstants = 3, b0, invalid)"
 
-// CHECK: [[@LINE-2]]:42: note: expanded from macro 'MultiLineRootSignature'
+// CHECK: [[@LINE-2]]:44: note: expanded from macro 'MultiLineRootSignature'
 // CHECK-NEXT: [[@LINE-3]] | "RootConstants(num32BitConstants = 3, b0, 
invalid)"
-// CHECK-NEXT:             |                                         ^
-// expected-error@+1 {{expected ')'}}
+// CHECK-NEXT:             |                                           ^
+// expected-error@+1 {{invalid parameter of RootConstants}}
 [RootSignature(MultiLineRootSignature)]
 void bad_root_signature_6() {}
 
 // expected-error@+1 {{expected end of stream}}
 [RootSignature("RootFlags() RootConstants(b0, num32BitConstants = 1))")]
 void bad_root_signature_7() {}
+
+// expected-error@+1 {{invalid parameter of RootConstants}}
+[RootSignature("RootConstants(b0, num32BitConstantsTypo = 1))")]
+void bad_root_signature_8() {}
+
+// expected-error@+1 {{invalid parameter of UAV}}
+[RootSignature("UAV(b3")]
+void bad_root_signature_9() {}
+
+// expected-error@+1 {{invalid parameter of SRV}}
+[RootSignature("DescriptorTable(SRV(s1, invalid))")]
+void bad_root_signature_10() {}
+
+// expected-error@+1 {{invalid parameter of DescriptorTable}}
+[RootSignature("DescriptorTable(invalid))")]
+void bad_root_signature_11() {}
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp 
b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index baa772bab99ed..76121a5844242 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -865,7 +865,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseInvalidTokenTest) {
                                    Signature, *PP);
 
   // Test correct diagnostic produced - invalid token
-  Consumer->setExpected(diag::err_expected);
+  Consumer->setExpected(diag::err_hlsl_invalid_param);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());
@@ -886,7 +886,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseUnexpectedEndOfStreamTest) {
   hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
                                    Signature, *PP);
 
-  // Test correct diagnostic produced - end of stream
+  // Test correct diagnostic produced - expected '(' after DescriptorTable
   Consumer->setExpected(diag::err_expected_after);
 
   ASSERT_TRUE(Parser.parse());

>From 4edb7fa000026935accfd993ff4ca1f4eed68c2e Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienf...@gmail.com>
Date: Wed, 9 Jul 2025 16:19:28 +0000
Subject: [PATCH 03/11] keep test of missing comma

---
 clang/test/SemaHLSL/RootSignature-err.hlsl | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/SemaHLSL/RootSignature-err.hlsl 
b/clang/test/SemaHLSL/RootSignature-err.hlsl
index 188cf6de182fa..0fff28ec57970 100644
--- a/clang/test/SemaHLSL/RootSignature-err.hlsl
+++ b/clang/test/SemaHLSL/RootSignature-err.hlsl
@@ -21,8 +21,8 @@ void bad_root_signature_3() {}
 [RootSignature("DescriptorTable(), invalid")]
 void bad_root_signature_4() {}
 
-// expected-error@+1 {{invalid parameter of RootConstants}}
-[RootSignature("RootConstants(b0, num32BitConstants = 1, invalid)")]
+// expected-error@+1 {{expected ')'}}
+[RootSignature("RootConstants(b0 num32BitConstants = 1)")]
 void bad_root_signature_5() {}
 
 #define MultiLineRootSignature \

>From b17b40c5b6f8e68a83f8ad7cedc3c0a51589c945 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienf...@gmail.com>
Date: Wed, 9 Jul 2025 16:29:56 +0000
Subject: [PATCH 04/11] audit use of err_expected_after

the order of the parameters is switched as opposed to either and this
was not caught in the unit tests
---
 clang/lib/Parse/ParseHLSLRootSignature.cpp |  4 +++-
 clang/test/SemaHLSL/RootSignature-err.hlsl | 12 ++++++++++++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 41c1fb24614f7..028e21b8a6bf2 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -1299,9 +1299,11 @@ bool RootSignatureParser::consumeExpectedToken(TokenKind 
Expected,
     DB << Expected;
     break;
   case diag::err_expected_either:
-  case diag::err_expected_after:
     DB << Expected << Context;
     break;
+  case diag::err_expected_after:
+    DB << Context << Expected;
+    break;
   default:
     break;
   }
diff --git a/clang/test/SemaHLSL/RootSignature-err.hlsl 
b/clang/test/SemaHLSL/RootSignature-err.hlsl
index 0fff28ec57970..8c5fdc016234c 100644
--- a/clang/test/SemaHLSL/RootSignature-err.hlsl
+++ b/clang/test/SemaHLSL/RootSignature-err.hlsl
@@ -55,3 +55,15 @@ void bad_root_signature_10() {}
 // expected-error@+1 {{invalid parameter of DescriptorTable}}
 [RootSignature("DescriptorTable(invalid))")]
 void bad_root_signature_11() {}
+
+// expected-error@+1 {{expected integer literal after '+'}}
+[RootSignature("CBV(space = +invalid))")]
+void bad_root_signature_12() {}
+
+// expected-error@+1 {{expected integer literal after '='}}
+[RootSignature("CBV(space = invalid))")]
+void bad_root_signature_13() {}
+
+// expected-error@+1 {{expected '(' after UAV}}
+[RootSignature("UAV invalid")]
+void bad_root_signature_14() {}

>From bbd8921c962a6982f10881257a3ec37d6f2d2b90 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienf...@gmail.com>
Date: Wed, 9 Jul 2025 16:36:06 +0000
Subject: [PATCH 05/11] nfc: prepare to extend diagnostic to values as well

---
 .../clang/Basic/DiagnosticParseKinds.td       |  2 +-
 clang/lib/Parse/ParseHLSLRootSignature.cpp    | 22 ++++++++++---------
 .../Parse/ParseHLSLRootSignatureTest.cpp      |  2 +-
 3 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td 
b/clang/include/clang/Basic/DiagnosticParseKinds.td
index 4671b3aad303c..becca29c12dc0 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1860,7 +1860,7 @@ def err_hlsl_virtual_inheritance
     : Error<"virtual inheritance is unsupported in HLSL">;
 
 // HLSL Root Signature Parser Diagnostics
-def err_hlsl_invalid_param : Error<"invalid parameter of %0">;
+def err_hlsl_invalid_token : Error<"invalid %select{parameter|value}0 of %1">;
 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<
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 028e21b8a6bf2..9d63c8f65040c 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -61,8 +61,8 @@ bool RootSignatureParser::parse() {
       Elements.emplace_back(RootSignatureElement(ElementLoc, *Sampler));
     } else {
       consumeNextToken(); // let diagnostic be at the start of invalid token
-      reportDiag(diag::err_hlsl_invalid_param)
-          << /*param of*/ TokenKind::kw_RootSignature;
+      reportDiag(diag::err_hlsl_invalid_token)
+          << /*parameter=*/0 << /*param of*/ TokenKind::kw_RootSignature;
       return true;
     }
 
@@ -268,8 +268,8 @@ std::optional<DescriptorTable> 
RootSignatureParser::parseDescriptorTable() {
         return std::nullopt;
     } else {
       consumeNextToken(); // let diagnostic be at the start of invalid token
-      reportDiag(diag::err_hlsl_invalid_param)
-          << /*param of*/ TokenKind::kw_DescriptorTable;
+      reportDiag(diag::err_hlsl_invalid_token)
+          << /*parameter=*/0 << /*param of*/ TokenKind::kw_DescriptorTable;
       return std::nullopt;
     }
 
@@ -486,8 +486,8 @@ RootSignatureParser::parseRootConstantParams() {
       Params.Visibility = Visibility;
     } else {
       consumeNextToken(); // let diagnostic be at the start of invalid token
-      reportDiag(diag::err_hlsl_invalid_param)
-          << /*param of*/ TokenKind::kw_RootConstants;
+      reportDiag(diag::err_hlsl_invalid_token)
+          << /*parameter=*/0 << /*param of*/ TokenKind::kw_RootConstants;
       return std::nullopt;
     }
 
@@ -561,7 +561,8 @@ RootSignatureParser::parseRootDescriptorParams(TokenKind 
DescKind,
       Params.Flags = Flags;
     } else {
       consumeNextToken(); // let diagnostic be at the start of invalid token
-      reportDiag(diag::err_hlsl_invalid_param) << /*param of*/ DescKind;
+      reportDiag(diag::err_hlsl_invalid_token)
+          << /*parameter=*/0 << /*param of*/ DescKind;
       return std::nullopt;
     }
 
@@ -661,7 +662,8 @@ 
RootSignatureParser::parseDescriptorTableClauseParams(TokenKind ClauseKind,
       Params.Flags = Flags;
     } else {
       consumeNextToken(); // let diagnostic be at the start of invalid token
-      reportDiag(diag::err_hlsl_invalid_param) << /*param of*/ ClauseKind;
+      reportDiag(diag::err_hlsl_invalid_token)
+          << /*parameter=*/0 << /*param of*/ ClauseKind;
       return std::nullopt;
     }
 
@@ -860,8 +862,8 @@ RootSignatureParser::parseStaticSamplerParams() {
       Params.Visibility = Visibility;
     } else {
       consumeNextToken(); // let diagnostic be at the start of invalid token
-      reportDiag(diag::err_hlsl_invalid_param)
-          << /*param of*/ TokenKind::kw_StaticSampler;
+      reportDiag(diag::err_hlsl_invalid_token)
+          << /*parameter=*/0 << /*param of*/ TokenKind::kw_StaticSampler;
       return std::nullopt;
     }
 
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp 
b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 76121a5844242..e4b3b4ca5c8a6 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -865,7 +865,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseInvalidTokenTest) {
                                    Signature, *PP);
 
   // Test correct diagnostic produced - invalid token
-  Consumer->setExpected(diag::err_hlsl_invalid_param);
+  Consumer->setExpected(diag::err_hlsl_invalid_token);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());

>From c3a4642c5869324a88b70ed867b0ee62da4ff8e7 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienf...@gmail.com>
Date: Wed, 9 Jul 2025 16:51:02 +0000
Subject: [PATCH 06/11] extend invalid_token diagnostic to enum parsing

---
 .../clang/Parse/ParseHLSLRootSignature.h      | 15 +++--
 clang/lib/Parse/ParseHLSLRootSignature.cpp    | 60 ++++++++++++-------
 clang/test/SemaHLSL/RootSignature-err.hlsl    | 24 ++++++++
 .../Parse/ParseHLSLRootSignatureTest.cpp      | 27 +++++++++
 4 files changed, 101 insertions(+), 25 deletions(-)

diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h 
b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index 0c12421723feb..b3a0f131483bd 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -137,11 +137,16 @@ class RootSignatureParser {
   std::optional<float> parseFloatParam();
 
   /// Parsing methods of various enums
-  std::optional<llvm::dxbc::ShaderVisibility> parseShaderVisibility();
-  std::optional<llvm::dxbc::SamplerFilter> parseSamplerFilter();
-  std::optional<llvm::dxbc::TextureAddressMode> parseTextureAddressMode();
-  std::optional<llvm::dxbc::ComparisonFunc> parseComparisonFunc();
-  std::optional<llvm::dxbc::StaticBorderColor> parseStaticBorderColor();
+  std::optional<llvm::dxbc::ShaderVisibility>
+  parseShaderVisibility(RootSignatureToken::Kind Context);
+  std::optional<llvm::dxbc::SamplerFilter>
+  parseSamplerFilter(RootSignatureToken::Kind Context);
+  std::optional<llvm::dxbc::TextureAddressMode>
+  parseTextureAddressMode(RootSignatureToken::Kind Context);
+  std::optional<llvm::dxbc::ComparisonFunc>
+  parseComparisonFunc(RootSignatureToken::Kind Context);
+  std::optional<llvm::dxbc::StaticBorderColor>
+  parseStaticBorderColor(RootSignatureToken::Kind Context);
   std::optional<llvm::dxbc::RootDescriptorFlags> parseRootDescriptorFlags();
   std::optional<llvm::dxbc::DescriptorRangeFlags> parseDescriptorRangeFlags();
 
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 9d63c8f65040c..16f2426e3d006 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -263,7 +263,7 @@ std::optional<DescriptorTable> 
RootSignatureParser::parseDescriptorTable() {
       if (consumeExpectedToken(TokenKind::pu_equal))
         return std::nullopt;
 
-      Visibility = parseShaderVisibility();
+      Visibility = parseShaderVisibility(TokenKind::kw_visibility);
       if (!Visibility.has_value())
         return std::nullopt;
     } else {
@@ -480,7 +480,7 @@ RootSignatureParser::parseRootConstantParams() {
       if (consumeExpectedToken(TokenKind::pu_equal))
         return std::nullopt;
 
-      auto Visibility = parseShaderVisibility();
+      auto Visibility = parseShaderVisibility(TokenKind::kw_visibility);
       if (!Visibility.has_value())
         return std::nullopt;
       Params.Visibility = Visibility;
@@ -541,7 +541,7 @@ RootSignatureParser::parseRootDescriptorParams(TokenKind 
DescKind,
       if (consumeExpectedToken(TokenKind::pu_equal))
         return std::nullopt;
 
-      auto Visibility = parseShaderVisibility();
+      auto Visibility = parseShaderVisibility(TokenKind::kw_visibility);
       if (!Visibility.has_value())
         return std::nullopt;
       Params.Visibility = Visibility;
@@ -702,7 +702,7 @@ RootSignatureParser::parseStaticSamplerParams() {
       if (consumeExpectedToken(TokenKind::pu_equal))
         return std::nullopt;
 
-      auto Filter = parseSamplerFilter();
+      auto Filter = parseSamplerFilter(TokenKind::kw_filter);
       if (!Filter.has_value())
         return std::nullopt;
       Params.Filter = Filter;
@@ -716,7 +716,7 @@ RootSignatureParser::parseStaticSamplerParams() {
       if (consumeExpectedToken(TokenKind::pu_equal))
         return std::nullopt;
 
-      auto AddressU = parseTextureAddressMode();
+      auto AddressU = parseTextureAddressMode(TokenKind::kw_addressU);
       if (!AddressU.has_value())
         return std::nullopt;
       Params.AddressU = AddressU;
@@ -730,7 +730,7 @@ RootSignatureParser::parseStaticSamplerParams() {
       if (consumeExpectedToken(TokenKind::pu_equal))
         return std::nullopt;
 
-      auto AddressV = parseTextureAddressMode();
+      auto AddressV = parseTextureAddressMode(TokenKind::kw_addressV);
       if (!AddressV.has_value())
         return std::nullopt;
       Params.AddressV = AddressV;
@@ -744,7 +744,7 @@ RootSignatureParser::parseStaticSamplerParams() {
       if (consumeExpectedToken(TokenKind::pu_equal))
         return std::nullopt;
 
-      auto AddressW = parseTextureAddressMode();
+      auto AddressW = parseTextureAddressMode(TokenKind::kw_addressW);
       if (!AddressW.has_value())
         return std::nullopt;
       Params.AddressW = AddressW;
@@ -786,7 +786,7 @@ RootSignatureParser::parseStaticSamplerParams() {
       if (consumeExpectedToken(TokenKind::pu_equal))
         return std::nullopt;
 
-      auto CompFunc = parseComparisonFunc();
+      auto CompFunc = parseComparisonFunc(TokenKind::kw_comparisonFunc);
       if (!CompFunc.has_value())
         return std::nullopt;
       Params.CompFunc = CompFunc;
@@ -800,7 +800,7 @@ RootSignatureParser::parseStaticSamplerParams() {
       if (consumeExpectedToken(TokenKind::pu_equal))
         return std::nullopt;
 
-      auto BorderColor = parseStaticBorderColor();
+      auto BorderColor = parseStaticBorderColor(TokenKind::kw_borderColor);
       if (!BorderColor.has_value())
         return std::nullopt;
       Params.BorderColor = BorderColor;
@@ -856,7 +856,7 @@ RootSignatureParser::parseStaticSamplerParams() {
       if (consumeExpectedToken(TokenKind::pu_equal))
         return std::nullopt;
 
-      auto Visibility = parseShaderVisibility();
+      auto Visibility = parseShaderVisibility(TokenKind::kw_visibility);
       if (!Visibility.has_value())
         return std::nullopt;
       Params.Visibility = Visibility;
@@ -952,7 +952,7 @@ std::optional<float> RootSignatureParser::parseFloatParam() 
{
 }
 
 std::optional<llvm::dxbc::ShaderVisibility>
-RootSignatureParser::parseShaderVisibility() {
+RootSignatureParser::parseShaderVisibility(TokenKind Context) {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
 
@@ -961,8 +961,12 @@ RootSignatureParser::parseShaderVisibility() {
 #include "clang/Lex/HLSLRootSignatureTokenKinds.def"
   };
 
-  if (!tryConsumeExpectedToken(Expected))
+  if (!tryConsumeExpectedToken(Expected)) {
+    consumeNextToken(); // consume token to point at invalid token
+    reportDiag(diag::err_hlsl_invalid_token)
+        << /*value=*/1 << /*value of*/ Context;
     return std::nullopt;
+  }
 
   switch (CurToken.TokKind) {
 #define SHADER_VISIBILITY_ENUM(NAME, LIT)                                      
\
@@ -978,7 +982,7 @@ RootSignatureParser::parseShaderVisibility() {
 }
 
 std::optional<llvm::dxbc::SamplerFilter>
-RootSignatureParser::parseSamplerFilter() {
+RootSignatureParser::parseSamplerFilter(TokenKind Context) {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
 
@@ -987,8 +991,12 @@ RootSignatureParser::parseSamplerFilter() {
 #include "clang/Lex/HLSLRootSignatureTokenKinds.def"
   };
 
-  if (!tryConsumeExpectedToken(Expected))
+  if (!tryConsumeExpectedToken(Expected)) {
+    consumeNextToken(); // consume token to point at invalid token
+    reportDiag(diag::err_hlsl_invalid_token)
+        << /*value=*/1 << /*value of*/ Context;
     return std::nullopt;
+  }
 
   switch (CurToken.TokKind) {
 #define FILTER_ENUM(NAME, LIT)                                                 
\
@@ -1004,7 +1012,7 @@ RootSignatureParser::parseSamplerFilter() {
 }
 
 std::optional<llvm::dxbc::TextureAddressMode>
-RootSignatureParser::parseTextureAddressMode() {
+RootSignatureParser::parseTextureAddressMode(TokenKind Context) {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
 
@@ -1013,8 +1021,12 @@ RootSignatureParser::parseTextureAddressMode() {
 #include "clang/Lex/HLSLRootSignatureTokenKinds.def"
   };
 
-  if (!tryConsumeExpectedToken(Expected))
+  if (!tryConsumeExpectedToken(Expected)) {
+    consumeNextToken(); // consume token to point at invalid token
+    reportDiag(diag::err_hlsl_invalid_token)
+        << /*value=*/1 << /*value of*/ Context;
     return std::nullopt;
+  }
 
   switch (CurToken.TokKind) {
 #define TEXTURE_ADDRESS_MODE_ENUM(NAME, LIT)                                   
\
@@ -1030,7 +1042,7 @@ RootSignatureParser::parseTextureAddressMode() {
 }
 
 std::optional<llvm::dxbc::ComparisonFunc>
-RootSignatureParser::parseComparisonFunc() {
+RootSignatureParser::parseComparisonFunc(TokenKind Context) {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
 
@@ -1039,8 +1051,12 @@ RootSignatureParser::parseComparisonFunc() {
 #include "clang/Lex/HLSLRootSignatureTokenKinds.def"
   };
 
-  if (!tryConsumeExpectedToken(Expected))
+  if (!tryConsumeExpectedToken(Expected)) {
+    consumeNextToken(); // consume token to point at invalid token
+    reportDiag(diag::err_hlsl_invalid_token)
+        << /*value=*/1 << /*value of*/ Context;
     return std::nullopt;
+  }
 
   switch (CurToken.TokKind) {
 #define COMPARISON_FUNC_ENUM(NAME, LIT)                                        
\
@@ -1056,7 +1072,7 @@ RootSignatureParser::parseComparisonFunc() {
 }
 
 std::optional<llvm::dxbc::StaticBorderColor>
-RootSignatureParser::parseStaticBorderColor() {
+RootSignatureParser::parseStaticBorderColor(TokenKind Context) {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
 
@@ -1065,8 +1081,12 @@ RootSignatureParser::parseStaticBorderColor() {
 #include "clang/Lex/HLSLRootSignatureTokenKinds.def"
   };
 
-  if (!tryConsumeExpectedToken(Expected))
+  if (!tryConsumeExpectedToken(Expected)) {
+    consumeNextToken(); // consume token to point at invalid token
+    reportDiag(diag::err_hlsl_invalid_token)
+        << /*value=*/1 << /*value of*/ Context;
     return std::nullopt;
+  }
 
   switch (CurToken.TokKind) {
 #define STATIC_BORDER_COLOR_ENUM(NAME, LIT)                                    
\
diff --git a/clang/test/SemaHLSL/RootSignature-err.hlsl 
b/clang/test/SemaHLSL/RootSignature-err.hlsl
index 8c5fdc016234c..060514fb232a1 100644
--- a/clang/test/SemaHLSL/RootSignature-err.hlsl
+++ b/clang/test/SemaHLSL/RootSignature-err.hlsl
@@ -67,3 +67,27 @@ void bad_root_signature_13() {}
 // expected-error@+1 {{expected '(' after UAV}}
 [RootSignature("UAV invalid")]
 void bad_root_signature_14() {}
+
+// expected-error@+1 {{invalid value of visibility}}
+[RootSignature("StaticSampler(s0, visibility = visibility_typo)")]
+void bad_root_signature_15() {}
+
+// expected-error@+1 {{invalid value of filter}}
+[RootSignature("StaticSampler(s0, filter = filter_typo)")]
+void bad_root_signature_16() {}
+
+// expected-error@+1 {{invalid value of addressU}}
+[RootSignature("StaticSampler(s0, addressU = addressU_typo)")]
+void bad_root_signature_17() {}
+
+// expected-error@+1 {{invalid value of addressV}}
+[RootSignature("StaticSampler(s0, addressV = addressV_typo)")]
+void bad_root_signature_18() {}
+
+// expected-error@+1 {{invalid value of comparisonFunc}}
+[RootSignature("StaticSampler(s0, comparisonFunc = comparisonFunc_typo)")]
+void bad_root_signature_19() {}
+
+// expected-error@+1 {{invalid value of borderColor}}
+[RootSignature("StaticSampler(s0, borderColor = borderColor_typo)")]
+void bad_root_signature_20() {}
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp 
b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index e4b3b4ca5c8a6..a16da73a38dbf 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -1401,4 +1401,31 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidStaticSamplerCommaTest) {
   ASSERT_TRUE(Consumer->isSatisfied());
 }
 
+TEST_F(ParseHLSLRootSignatureTest, InvalidVisibilityValueTest) {
+  // This test will check that an error is produced when there is a invalid
+  // value of a parameter
+  const llvm::StringLiteral Source = R"cc(
+    UAV(
+      u0,
+      visibility = SHADER_VISIBILITY_TYPO
+    )
+  )cc";
+
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
+  TrivialModuleLoader ModLoader;
+  auto PP = createPP(Source, ModLoader);
+
+  SmallVector<RootSignatureElement> Elements;
+  hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
+                                   Signature, *PP);
+
+  // Test correct diagnostic produced
+  Consumer->setExpected(diag::err_hlsl_invalid_token);
+  ASSERT_TRUE(Parser.parse());
+
+  ASSERT_TRUE(Consumer->isSatisfied());
+}
+
 } // anonymous namespace

>From b32343063a62681e3aefd46d1b21018c84476e26 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienf...@gmail.com>
Date: Wed, 9 Jul 2025 17:00:31 +0000
Subject: [PATCH 07/11] extend invalid_token diagnostic to flag parsing

---
 .../clang/Parse/ParseHLSLRootSignature.h       |  6 ++++--
 clang/lib/Parse/ParseHLSLRootSignature.cpp     | 18 ++++++++++++++----
 clang/test/SemaHLSL/RootSignature-err.hlsl     |  8 ++++++++
 3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/clang/include/clang/Parse/ParseHLSLRootSignature.h 
b/clang/include/clang/Parse/ParseHLSLRootSignature.h
index b3a0f131483bd..404bccea10c99 100644
--- a/clang/include/clang/Parse/ParseHLSLRootSignature.h
+++ b/clang/include/clang/Parse/ParseHLSLRootSignature.h
@@ -147,8 +147,10 @@ class RootSignatureParser {
   parseComparisonFunc(RootSignatureToken::Kind Context);
   std::optional<llvm::dxbc::StaticBorderColor>
   parseStaticBorderColor(RootSignatureToken::Kind Context);
-  std::optional<llvm::dxbc::RootDescriptorFlags> parseRootDescriptorFlags();
-  std::optional<llvm::dxbc::DescriptorRangeFlags> parseDescriptorRangeFlags();
+  std::optional<llvm::dxbc::RootDescriptorFlags>
+  parseRootDescriptorFlags(RootSignatureToken::Kind Context);
+  std::optional<llvm::dxbc::DescriptorRangeFlags>
+  parseDescriptorRangeFlags(RootSignatureToken::Kind Context);
 
   /// Use NumericLiteralParser to convert CurToken.NumSpelling into a unsigned
   /// 32-bit integer
diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 16f2426e3d006..06564e32d3be9 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -555,7 +555,7 @@ RootSignatureParser::parseRootDescriptorParams(TokenKind 
DescKind,
       if (consumeExpectedToken(TokenKind::pu_equal))
         return std::nullopt;
 
-      auto Flags = parseRootDescriptorFlags();
+      auto Flags = parseRootDescriptorFlags(TokenKind::kw_flags);
       if (!Flags.has_value())
         return std::nullopt;
       Params.Flags = Flags;
@@ -656,7 +656,7 @@ 
RootSignatureParser::parseDescriptorTableClauseParams(TokenKind ClauseKind,
       if (consumeExpectedToken(TokenKind::pu_equal))
         return std::nullopt;
 
-      auto Flags = parseDescriptorRangeFlags();
+      auto Flags = parseDescriptorRangeFlags(TokenKind::kw_flags);
       if (!Flags.has_value())
         return std::nullopt;
       Params.Flags = Flags;
@@ -1102,7 +1102,7 @@ RootSignatureParser::parseStaticBorderColor(TokenKind 
Context) {
 }
 
 std::optional<llvm::dxbc::RootDescriptorFlags>
-RootSignatureParser::parseRootDescriptorFlags() {
+RootSignatureParser::parseRootDescriptorFlags(TokenKind Context) {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
 
@@ -1134,6 +1134,11 @@ RootSignatureParser::parseRootDescriptorFlags() {
       default:
         llvm_unreachable("Switch for consumed enum token was not provided");
       }
+    } else {
+      consumeNextToken(); // consume token to point at invalid token
+      reportDiag(diag::err_hlsl_invalid_token)
+          << /*value=*/1 << /*value of*/ Context;
+      return std::nullopt;
     }
   } while (tryConsumeExpectedToken(TokenKind::pu_or));
 
@@ -1141,7 +1146,7 @@ RootSignatureParser::parseRootDescriptorFlags() {
 }
 
 std::optional<llvm::dxbc::DescriptorRangeFlags>
-RootSignatureParser::parseDescriptorRangeFlags() {
+RootSignatureParser::parseDescriptorRangeFlags(TokenKind Context) {
   assert(CurToken.TokKind == TokenKind::pu_equal &&
          "Expects to only be invoked starting at given keyword");
 
@@ -1173,6 +1178,11 @@ RootSignatureParser::parseDescriptorRangeFlags() {
       default:
         llvm_unreachable("Switch for consumed enum token was not provided");
       }
+    } else {
+      consumeNextToken(); // consume token to point at invalid token
+      reportDiag(diag::err_hlsl_invalid_token)
+          << /*value=*/1 << /*value of*/ Context;
+      return std::nullopt;
     }
   } while (tryConsumeExpectedToken(TokenKind::pu_or));
 
diff --git a/clang/test/SemaHLSL/RootSignature-err.hlsl 
b/clang/test/SemaHLSL/RootSignature-err.hlsl
index 060514fb232a1..d96b594b858c2 100644
--- a/clang/test/SemaHLSL/RootSignature-err.hlsl
+++ b/clang/test/SemaHLSL/RootSignature-err.hlsl
@@ -91,3 +91,11 @@ void bad_root_signature_19() {}
 // expected-error@+1 {{invalid value of borderColor}}
 [RootSignature("StaticSampler(s0, borderColor = borderColor_typo)")]
 void bad_root_signature_20() {}
+
+// expected-error@+1 {{invalid value of flags}}
+[RootSignature("CBV(b0, flags = DATA_VOLATILE | root_descriptor_flag_typo)")]
+void bad_root_signature_21() {}
+
+// expected-error@+1 {{invalid value of flags}}
+[RootSignature("DescriptorTable(SRV(t0, flags = descriptor_range_flag_typo)")]
+void bad_root_signature_22() {}

>From 8187a65789e8776513e9b3ea9756da62fddd4ad7 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienf...@gmail.com>
Date: Wed, 9 Jul 2025 17:07:42 +0000
Subject: [PATCH 08/11] extend invalid_token diagnostic to RootFlags enum

---
 clang/lib/Parse/ParseHLSLRootSignature.cpp | 9 +++++++++
 clang/test/SemaHLSL/RootSignature-err.hlsl | 4 ++++
 2 files changed, 13 insertions(+)

diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 06564e32d3be9..8a6324155046a 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -93,6 +93,10 @@ std::optional<llvm::dxbc::RootFlags> 
RootSignatureParser::parseRootFlags() {
 
   std::optional<llvm::dxbc::RootFlags> Flags = llvm::dxbc::RootFlags::None;
 
+  // Handle valid empty case
+  if (tryConsumeExpectedToken(TokenKind::pu_r_paren))
+    return Flags;
+
   // Handle the edge-case of '0' to specify no flags set
   if (tryConsumeExpectedToken(TokenKind::int_literal)) {
     if (!verifyZeroFlag()) {
@@ -118,6 +122,11 @@ std::optional<llvm::dxbc::RootFlags> 
RootSignatureParser::parseRootFlags() {
         default:
           llvm_unreachable("Switch for consumed enum token was not provided");
         }
+      } else {
+        consumeNextToken(); // consume token to point at invalid token
+        reportDiag(diag::err_hlsl_invalid_token)
+            << /*value=*/1 << /*value of*/ TokenKind::kw_RootFlags;
+        return std::nullopt;
       }
     } while (tryConsumeExpectedToken(TokenKind::pu_or));
   }
diff --git a/clang/test/SemaHLSL/RootSignature-err.hlsl 
b/clang/test/SemaHLSL/RootSignature-err.hlsl
index d96b594b858c2..be68b7059aa8e 100644
--- a/clang/test/SemaHLSL/RootSignature-err.hlsl
+++ b/clang/test/SemaHLSL/RootSignature-err.hlsl
@@ -99,3 +99,7 @@ void bad_root_signature_21() {}
 // expected-error@+1 {{invalid value of flags}}
 [RootSignature("DescriptorTable(SRV(t0, flags = descriptor_range_flag_typo)")]
 void bad_root_signature_22() {}
+
+// expected-error@+1 {{invalid value of RootFlags}}
+[RootSignature("RootFlags(local_root_signature | root_flag_typo)")]
+void bad_root_signature_23() {}

>From 6d48044edf53d679d9c6a36d88219b401d05944d Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienf...@gmail.com>
Date: Wed, 9 Jul 2025 17:52:05 +0000
Subject: [PATCH 09/11] improve err_expected to err_expected_either at end of
 params

---
 clang/lib/Parse/ParseHLSLRootSignature.cpp    | 21 ++++++++++++-------
 clang/test/SemaHLSL/RootSignature-err.hlsl    |  4 ++--
 .../Parse/ParseHLSLRootSignatureTest.cpp      | 14 ++++++-------
 3 files changed, 23 insertions(+), 16 deletions(-)

diff --git a/clang/lib/Parse/ParseHLSLRootSignature.cpp 
b/clang/lib/Parse/ParseHLSLRootSignature.cpp
index 8a6324155046a..87de627a98fb7 100644
--- a/clang/lib/Parse/ParseHLSLRootSignature.cpp
+++ b/clang/lib/Parse/ParseHLSLRootSignature.cpp
@@ -71,7 +71,8 @@ bool RootSignatureParser::parse() {
       break;
   }
 
-  return consumeExpectedToken(TokenKind::end_of_stream);
+  return consumeExpectedToken(TokenKind::end_of_stream,
+                              diag::err_expected_either, TokenKind::pu_comma);
 }
 
 template <typename FlagType>
@@ -131,7 +132,8 @@ std::optional<llvm::dxbc::RootFlags> 
RootSignatureParser::parseRootFlags() {
     } while (tryConsumeExpectedToken(TokenKind::pu_or));
   }
 
-  if (consumeExpectedToken(TokenKind::pu_r_paren))
+  if (consumeExpectedToken(TokenKind::pu_r_paren, diag::err_expected_either,
+                           TokenKind::pu_comma))
     return std::nullopt;
 
   return Flags;
@@ -151,7 +153,8 @@ std::optional<RootConstants> 
RootSignatureParser::parseRootConstants() {
   if (!Params.has_value())
     return std::nullopt;
 
-  if (consumeExpectedToken(TokenKind::pu_r_paren))
+  if (consumeExpectedToken(TokenKind::pu_r_paren, diag::err_expected_either,
+                           TokenKind::pu_comma))
     return std::nullopt;
 
   // Check mandatory parameters where provided
@@ -216,7 +219,8 @@ std::optional<RootDescriptor> 
RootSignatureParser::parseRootDescriptor() {
   if (!Params.has_value())
     return std::nullopt;
 
-  if (consumeExpectedToken(TokenKind::pu_r_paren))
+  if (consumeExpectedToken(TokenKind::pu_r_paren, diag::err_expected_either,
+                           TokenKind::pu_comma))
     return std::nullopt;
 
   // Check mandatory parameters were provided
@@ -287,7 +291,8 @@ std::optional<DescriptorTable> 
RootSignatureParser::parseDescriptorTable() {
       break;
   }
 
-  if (consumeExpectedToken(TokenKind::pu_r_paren))
+  if (consumeExpectedToken(TokenKind::pu_r_paren, diag::err_expected_either,
+                           TokenKind::pu_comma))
     return std::nullopt;
 
   // Fill in optional visibility
@@ -339,7 +344,8 @@ RootSignatureParser::parseDescriptorTableClause() {
   if (!Params.has_value())
     return std::nullopt;
 
-  if (consumeExpectedToken(TokenKind::pu_r_paren))
+  if (consumeExpectedToken(TokenKind::pu_r_paren, diag::err_expected_either,
+                           TokenKind::pu_comma))
     return std::nullopt;
 
   // Check mandatory parameters were provided
@@ -380,7 +386,8 @@ std::optional<StaticSampler> 
RootSignatureParser::parseStaticSampler() {
   if (!Params.has_value())
     return std::nullopt;
 
-  if (consumeExpectedToken(TokenKind::pu_r_paren))
+  if (consumeExpectedToken(TokenKind::pu_r_paren, diag::err_expected_either,
+                           TokenKind::pu_comma))
     return std::nullopt;
 
   // Check mandatory parameters were provided
diff --git a/clang/test/SemaHLSL/RootSignature-err.hlsl 
b/clang/test/SemaHLSL/RootSignature-err.hlsl
index be68b7059aa8e..b69807132e795 100644
--- a/clang/test/SemaHLSL/RootSignature-err.hlsl
+++ b/clang/test/SemaHLSL/RootSignature-err.hlsl
@@ -21,7 +21,7 @@ void bad_root_signature_3() {}
 [RootSignature("DescriptorTable(), invalid")]
 void bad_root_signature_4() {}
 
-// expected-error@+1 {{expected ')'}}
+// expected-error@+1 {{expected ')' or ','}}
 [RootSignature("RootConstants(b0 num32BitConstants = 1)")]
 void bad_root_signature_5() {}
 
@@ -36,7 +36,7 @@ void bad_root_signature_5() {}
 [RootSignature(MultiLineRootSignature)]
 void bad_root_signature_6() {}
 
-// expected-error@+1 {{expected end of stream}}
+// expected-error@+1 {{expected end of stream or ','}}
 [RootSignature("RootFlags() RootConstants(b0, num32BitConstants = 1))")]
 void bad_root_signature_7() {}
 
diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp 
b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index a16da73a38dbf..597004eaba971 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -843,7 +843,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidParseUnexpectedTokenTest) {
                                    Signature, *PP);
 
   // Test correct diagnostic produced
-  Consumer->setExpected(diag::err_expected);
+  Consumer->setExpected(diag::err_expected_either);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());
@@ -1258,7 +1258,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRootElementMissingCommaTest) {
                                    Signature, *PP);
 
   // Test correct diagnostic produced
-  Consumer->setExpected(diag::err_expected);
+  Consumer->setExpected(diag::err_expected_either);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());
@@ -1285,7 +1285,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidDescriptorTableMissingCommaTest) {
                                    Signature, *PP);
 
   // Test correct diagnostic produced
-  Consumer->setExpected(diag::err_expected);
+  Consumer->setExpected(diag::err_expected_either);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());
@@ -1312,7 +1312,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRootConstantParamsCommaTest) {
                                    Signature, *PP);
 
   // Test correct diagnostic produced
-  Consumer->setExpected(diag::err_expected);
+  Consumer->setExpected(diag::err_expected_either);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());
@@ -1339,7 +1339,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidRootDescriptorParamsCommaTest) {
                                    Signature, *PP);
 
   // Test correct diagnostic produced
-  Consumer->setExpected(diag::err_expected);
+  Consumer->setExpected(diag::err_expected_either);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());
@@ -1368,7 +1368,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidDescriptorClauseParamsCommaTest) {
                                    Signature, *PP);
 
   // Test correct diagnostic produced
-  Consumer->setExpected(diag::err_expected);
+  Consumer->setExpected(diag::err_expected_either);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());
@@ -1395,7 +1395,7 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidStaticSamplerCommaTest) {
                                    Signature, *PP);
 
   // Test correct diagnostic produced
-  Consumer->setExpected(diag::err_expected);
+  Consumer->setExpected(diag::err_expected_either);
   ASSERT_TRUE(Parser.parse());
 
   ASSERT_TRUE(Consumer->isSatisfied());

>From 522b08467c40282feb8566b648b8c16f86232942 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienf...@gmail.com>
Date: Wed, 9 Jul 2025 18:05:01 +0000
Subject: [PATCH 10/11] improve unit test coverge of invalid values

---
 .../Parse/ParseHLSLRootSignatureTest.cpp      | 210 ++++++++++++++++++
 1 file changed, 210 insertions(+)

diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp 
b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 597004eaba971..429724ad24f72 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -1428,4 +1428,214 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidVisibilityValueTest) {
   ASSERT_TRUE(Consumer->isSatisfied());
 }
 
+TEST_F(ParseHLSLRootSignatureTest, InvalidRegisterValueTest) {
+  // This test will check that an error is produced when there is a invalid
+  // value of a parameter
+  const llvm::StringLiteral Source = R"cc(
+    StaticSampler(
+      b0
+    )
+  )cc";
+
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
+  TrivialModuleLoader ModLoader;
+  auto PP = createPP(Source, ModLoader);
+
+  SmallVector<RootSignatureElement> Elements;
+  hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
+                                   Signature, *PP);
+
+  // Test correct diagnostic produced
+  Consumer->setExpected(diag::err_hlsl_invalid_token);
+  ASSERT_TRUE(Parser.parse());
+
+  ASSERT_TRUE(Consumer->isSatisfied());
+}
+
+TEST_F(ParseHLSLRootSignatureTest, InvalidFilterValueTest) {
+  // This test will check that an error is produced when there is a invalid
+  // value of a parameter
+  const llvm::StringLiteral Source = R"cc(
+    StaticSampler(
+      s0,
+      filter = FILTER_TYPO
+    )
+  )cc";
+
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
+  TrivialModuleLoader ModLoader;
+  auto PP = createPP(Source, ModLoader);
+
+  SmallVector<RootSignatureElement> Elements;
+  hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
+                                   Signature, *PP);
+
+  // Test correct diagnostic produced
+  Consumer->setExpected(diag::err_hlsl_invalid_token);
+  ASSERT_TRUE(Parser.parse());
+
+  ASSERT_TRUE(Consumer->isSatisfied());
+}
+
+TEST_F(ParseHLSLRootSignatureTest, InvalidTextureAddressModeValueTest) {
+  // This test will check that an error is produced when there is a invalid
+  // value of a parameter
+  const llvm::StringLiteral Source = R"cc(
+    StaticSampler(
+      s0,
+      addressU = TEXTURE_ADDRESS_MODE_TYPO
+    )
+  )cc";
+
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
+  TrivialModuleLoader ModLoader;
+  auto PP = createPP(Source, ModLoader);
+
+  SmallVector<RootSignatureElement> Elements;
+  hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
+                                   Signature, *PP);
+
+  // Test correct diagnostic produced
+  Consumer->setExpected(diag::err_hlsl_invalid_token);
+  ASSERT_TRUE(Parser.parse());
+
+  ASSERT_TRUE(Consumer->isSatisfied());
+}
+
+TEST_F(ParseHLSLRootSignatureTest, InvalidComparisonFuncValueTest) {
+  // This test will check that an error is produced when there is a invalid
+  // value of a parameter
+  const llvm::StringLiteral Source = R"cc(
+    StaticSampler(
+      s0,
+      comparisonFunc = COMPARISON_FUNC_TYPO
+    )
+  )cc";
+
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
+  TrivialModuleLoader ModLoader;
+  auto PP = createPP(Source, ModLoader);
+
+  SmallVector<RootSignatureElement> Elements;
+  hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
+                                   Signature, *PP);
+
+  // Test correct diagnostic produced
+  Consumer->setExpected(diag::err_hlsl_invalid_token);
+  ASSERT_TRUE(Parser.parse());
+
+  ASSERT_TRUE(Consumer->isSatisfied());
+}
+
+TEST_F(ParseHLSLRootSignatureTest, InvalidStaticBorderColorValueTest) {
+  // This test will check that an error is produced when there is a invalid
+  // value of a parameter
+  const llvm::StringLiteral Source = R"cc(
+    StaticSampler(
+      s0,
+      borderColor = STATIC_BORDER_COLOR_TYPO
+    )
+  )cc";
+
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
+  TrivialModuleLoader ModLoader;
+  auto PP = createPP(Source, ModLoader);
+
+  SmallVector<RootSignatureElement> Elements;
+  hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
+                                   Signature, *PP);
+
+  // Test correct diagnostic produced
+  Consumer->setExpected(diag::err_hlsl_invalid_token);
+  ASSERT_TRUE(Parser.parse());
+
+  ASSERT_TRUE(Consumer->isSatisfied());
+}
+
+TEST_F(ParseHLSLRootSignatureTest, InvalidRootFlagsValueTest) {
+  // This test will check that an error is produced when there is a invalid
+  // value of a parameter
+  const llvm::StringLiteral Source = R"cc(
+    RootFlags( ROOT_FLAG_TYPO )
+  )cc";
+
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
+  TrivialModuleLoader ModLoader;
+  auto PP = createPP(Source, ModLoader);
+
+  SmallVector<RootSignatureElement> Elements;
+  hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
+                                   Signature, *PP);
+
+  // Test correct diagnostic produced
+  Consumer->setExpected(diag::err_hlsl_invalid_token);
+  ASSERT_TRUE(Parser.parse());
+
+  ASSERT_TRUE(Consumer->isSatisfied());
+}
+
+TEST_F(ParseHLSLRootSignatureTest, InvalidRootDescriptorFlagsValueTest) {
+  // This test will check that an error is produced when there is a invalid
+  // value of a parameter
+  const llvm::StringLiteral Source = R"cc(
+    CBV( flags = DATA_STATIC | ROOT_DESRIPTOR_FLAG_TYPO )
+  )cc";
+
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
+  TrivialModuleLoader ModLoader;
+  auto PP = createPP(Source, ModLoader);
+
+  SmallVector<RootSignatureElement> Elements;
+  hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
+                                   Signature, *PP);
+
+  // Test correct diagnostic produced
+  Consumer->setExpected(diag::err_hlsl_invalid_token);
+  ASSERT_TRUE(Parser.parse());
+
+  ASSERT_TRUE(Consumer->isSatisfied());
+}
+
+TEST_F(ParseHLSLRootSignatureTest, InvalidDescriptorRangeFlagsValueTest) {
+  // This test will check that an error is produced when there is a invalid
+  // value of a parameter
+  const llvm::StringLiteral Source = R"cc(
+    DescriptorTable(
+      CBV(
+        flags = DATA_STATIC | DESRIPTOR_RANGE_FLAG_TYPO | DESCRIPTORS_VOLATILE
+      )
+    )
+  )cc";
+
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
+  TrivialModuleLoader ModLoader;
+  auto PP = createPP(Source, ModLoader);
+
+  SmallVector<RootSignatureElement> Elements;
+  hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
+                                   Signature, *PP);
+
+  // Test correct diagnostic produced
+  Consumer->setExpected(diag::err_hlsl_invalid_token);
+  ASSERT_TRUE(Parser.parse());
+
+  ASSERT_TRUE(Consumer->isSatisfied());
+}
+
 } // anonymous namespace

>From 70448a3e3daae9ebac71df5b995bc93025b7a644 Mon Sep 17 00:00:00 2001
From: Finn Plummer <canadienf...@gmail.com>
Date: Wed, 9 Jul 2025 18:49:46 +0000
Subject: [PATCH 11/11] improve unit test coverage of invalid parameters

---
 .../Parse/ParseHLSLRootSignatureTest.cpp      | 106 ++++++++++++++++++
 1 file changed, 106 insertions(+)

diff --git a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp 
b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
index 429724ad24f72..4b24800489c8e 100644
--- a/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
+++ b/clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp
@@ -1401,6 +1401,112 @@ TEST_F(ParseHLSLRootSignatureTest, 
InvalidStaticSamplerCommaTest) {
   ASSERT_TRUE(Consumer->isSatisfied());
 }
 
+TEST_F(ParseHLSLRootSignatureTest, InvalidRootDescriptorParamTest) {
+  // This test will check that an error is produced when there is a invalid
+  // value of a parameter
+  const llvm::StringLiteral Source = R"cc(
+    SRV(t0, invalid)
+  )cc";
+
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
+  TrivialModuleLoader ModLoader;
+  auto PP = createPP(Source, ModLoader);
+
+  SmallVector<RootSignatureElement> Elements;
+  hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
+                                   Signature, *PP);
+
+  // Test correct diagnostic produced
+  Consumer->setExpected(diag::err_hlsl_invalid_token);
+  ASSERT_TRUE(Parser.parse());
+
+  ASSERT_TRUE(Consumer->isSatisfied());
+}
+
+TEST_F(ParseHLSLRootSignatureTest, InvalidDescriptorTableParamTest) {
+  // This test will check that an error is produced when there is a invalid
+  // value of a parameter
+  const llvm::StringLiteral Source = R"cc(
+    DescriptorTable(
+      visibility = SHADER_VISIBILITY_ALL,
+      invalid
+    )
+  )cc";
+
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
+  TrivialModuleLoader ModLoader;
+  auto PP = createPP(Source, ModLoader);
+
+  SmallVector<RootSignatureElement> Elements;
+  hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
+                                   Signature, *PP);
+
+  // Test correct diagnostic produced
+  Consumer->setExpected(diag::err_hlsl_invalid_token);
+  ASSERT_TRUE(Parser.parse());
+
+  ASSERT_TRUE(Consumer->isSatisfied());
+}
+
+TEST_F(ParseHLSLRootSignatureTest, InvalidDescriptorTableClauseParamTest) {
+  // This test will check that an error is produced when there is a invalid
+  // value of a parameter
+  const llvm::StringLiteral Source = R"cc(
+    DescriptorTable(
+      CBV(invalid)
+    )
+  )cc";
+
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
+  TrivialModuleLoader ModLoader;
+  auto PP = createPP(Source, ModLoader);
+
+  SmallVector<RootSignatureElement> Elements;
+  hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
+                                   Signature, *PP);
+
+  // Test correct diagnostic produced
+  Consumer->setExpected(diag::err_hlsl_invalid_token);
+  ASSERT_TRUE(Parser.parse());
+
+  ASSERT_TRUE(Consumer->isSatisfied());
+}
+
+TEST_F(ParseHLSLRootSignatureTest, InvalidStaticSamplerParamTest) {
+  // This test will check that an error is produced when there is a invalid
+  // value of a parameter
+  const llvm::StringLiteral Source = R"cc(
+    StaticSampler(
+      s0,
+      filter = FILTER_MAXIMUM_MIN_POINT_MAG_LINEAR_MIP_POINT,
+      invalid,
+      comparisonFunc = COMPARISON_EQUAL,
+    )
+  )cc";
+
+  auto Ctx = createMinimalASTContext();
+  StringLiteral *Signature = wrapSource(Ctx, Source);
+
+  TrivialModuleLoader ModLoader;
+  auto PP = createPP(Source, ModLoader);
+
+  SmallVector<RootSignatureElement> Elements;
+  hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
+                                   Signature, *PP);
+
+  // Test correct diagnostic produced
+  Consumer->setExpected(diag::err_hlsl_invalid_token);
+  ASSERT_TRUE(Parser.parse());
+
+  ASSERT_TRUE(Consumer->isSatisfied());
+}
+
 TEST_F(ParseHLSLRootSignatureTest, InvalidVisibilityValueTest) {
   // This test will check that an error is produced when there is a invalid
   // value of a parameter

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

Reply via email to