[llvm-branch-commits] [clang] [llvm] [HLSL][RootSignature] Implement Parsing of Descriptor Tables (PR #122982)

via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Wed Jan 29 15:53:59 PST 2025


================
@@ -169,5 +220,399 @@ bool RootSignatureLexer::LexToken(RootSignatureToken &Result) {
   return false;
 }
 
+// Parser Definitions
+
+RootSignatureParser::RootSignatureParser(
+    SmallVector<RootElement> &Elements,
+    const SmallVector<RootSignatureToken> &Tokens, DiagnosticsEngine &Diags)
+    : Elements(Elements), Diags(Diags) {
+  CurTok = Tokens.begin();
+  LastTok = Tokens.end();
+}
+
+bool RootSignatureParser::Parse() {
+  // Handle edge-case of empty RootSignature()
+  if (CurTok == LastTok)
+    return false;
+
+  bool First = true;
+  // Iterate as many RootElements as possible
+  while (!ParseRootElement(First)) {
+    First = false;
+    // Avoid use of ConsumeNextToken here to skip incorrect end of tokens error
+    CurTok++;
+    if (CurTok == LastTok)
+      return false;
+    if (EnsureExpectedToken(TokenKind::pu_comma))
+      return true;
+  }
+
+  return true;
+}
+
+bool RootSignatureParser::ParseRootElement(bool First) {
+  if (First && EnsureExpectedToken(TokenKind::kw_DescriptorTable))
+    return true;
+  if (!First && ConsumeExpectedToken(TokenKind::kw_DescriptorTable))
+    return true;
+
+  // Dispatch onto the correct parse method
+  switch (CurTok->Kind) {
+  case TokenKind::kw_DescriptorTable:
+    return ParseDescriptorTable();
+  default:
+    llvm_unreachable("Switch for an expected token was not provided");
+    return true;
+  }
+}
+
+bool RootSignatureParser::ParseDescriptorTable() {
+  DescriptorTable Table;
+
+  if (ConsumeExpectedToken(TokenKind::pu_l_paren))
+    return true;
+
+  // Empty case:
+  if (!TryConsumeExpectedToken(TokenKind::pu_r_paren)) {
+    Elements.push_back(Table);
+    return false;
+  }
+
+  bool SeenVisibility = false;
+  // Iterate through all the defined clauses
+  do {
+    // Handle the visibility parameter
+    if (!TryConsumeExpectedToken(TokenKind::kw_visibility)) {
+      if (SeenVisibility) {
+        Diags.Report(CurTok->TokLoc, diag::err_hlsl_rootsig_repeat_param)
+            << FormatTokenKinds(CurTok->Kind);
+        return true;
+      }
+      SeenVisibility = true;
+      if (ParseParam(&Table.Visibility))
+        return true;
+      continue;
+    }
+
+    // Otherwise, we expect a clause
+    if (ParseDescriptorTableClause())
+      return true;
+    Table.NumClauses++;
+  } while (!TryConsumeExpectedToken(TokenKind::pu_comma));
+
+  if (ConsumeExpectedToken(TokenKind::pu_r_paren))
+    return true;
+
+  Elements.push_back(Table);
+  return false;
+}
+
+bool RootSignatureParser::ParseDescriptorTableClause() {
+  if (ConsumeExpectedToken({TokenKind::kw_CBV, TokenKind::kw_SRV,
+                            TokenKind::kw_UAV, TokenKind::kw_Sampler}))
+    return true;
+
+  DescriptorTableClause Clause;
+  switch (CurTok->Kind) {
+  case TokenKind::kw_CBV:
+    Clause.Type = ClauseType::CBuffer;
+    break;
+  case TokenKind::kw_SRV:
+    Clause.Type = ClauseType::SRV;
+    break;
+  case TokenKind::kw_UAV:
+    Clause.Type = ClauseType::UAV;
+    break;
+  case TokenKind::kw_Sampler:
+    Clause.Type = ClauseType::Sampler;
+    break;
+  default:
+    llvm_unreachable("Switch for an expected token was not provided");
+    return true;
+  }
+  Clause.SetDefaultFlags();
----------------
joaosaffran wrote:

It might be interesting to move this to its own method, since it can be reused when handling root descriptors.

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


More information about the llvm-branch-commits mailing list