[llvm-branch-commits] [clang] [HLSL][RootSignature] Allow for multiple parsing errors in `RootSignatureParser` (PR #147832)

Finn Plummer via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Fri Jul 11 16:49:44 PDT 2025


================
@@ -27,51 +36,68 @@ RootSignatureParser::RootSignatureParser(
 bool RootSignatureParser::parse() {
   // Iterate as many RootSignatureElements as possible, until we hit the
   // end of the stream
+  bool HadError = false;
   while (!peekExpectedToken(TokenKind::end_of_stream)) {
+    bool HadLocalError = false;
     if (tryConsumeExpectedToken(TokenKind::kw_RootFlags)) {
       SourceLocation ElementLoc = getTokenLocation(CurToken);
       auto Flags = parseRootFlags();
-      if (!Flags.has_value())
-        return true;
-      Elements.emplace_back(RootSignatureElement(ElementLoc, *Flags));
+      if (Flags.has_value())
+        Elements.emplace_back(RootSignatureElement(ElementLoc, *Flags));
+      else
+        HadLocalError = true;
     } else if (tryConsumeExpectedToken(TokenKind::kw_RootConstants)) {
       SourceLocation ElementLoc = getTokenLocation(CurToken);
       auto Constants = parseRootConstants();
-      if (!Constants.has_value())
-        return true;
-      Elements.emplace_back(RootSignatureElement(ElementLoc, *Constants));
+      if (Constants.has_value())
+        Elements.emplace_back(RootSignatureElement(ElementLoc, *Constants));
+      else
+        HadLocalError = true;
     } else if (tryConsumeExpectedToken(TokenKind::kw_DescriptorTable)) {
       SourceLocation ElementLoc = getTokenLocation(CurToken);
       auto Table = parseDescriptorTable();
-      if (!Table.has_value())
-        return true;
-      Elements.emplace_back(RootSignatureElement(ElementLoc, *Table));
+      if (Table.has_value())
+        Elements.emplace_back(RootSignatureElement(ElementLoc, *Table));
+      else {
+        HadLocalError = true;
+        // We are within a DescriptorTable, we will do our best to recover
+        // by skipping until we encounter the expected closing ')'.
+        skipUntilExpectedToken(TokenKind::pu_r_paren);
----------------
inbelic wrote:

This is only done on the descriptor table because we want to avoid accidently parsing an element of the descriptor table as a root element. So we need to "exit" the descriptor table scope. For instance:
```
DescriptorTable(
  SRV(s0, invalid),
  CBV(b0, numDescriptor = 2)
),
UAV(u0)
```
Parsing would fail here on the invalid token. We don't want to keep parsing the CBV as a root element, but we do want to try again starting at UAV. This is done because they have the same token.

Typing this out, I realized though that we actually need to skip until it is closed, not just to the next one.

Updated for this and added a test-case.


https://github.com/llvm/llvm-project/pull/147832


More information about the llvm-branch-commits mailing list