================
@@ -89,37 +88,178 @@ bool RootSignatureParser::parseDescriptorTableClause() {
           CurToken.TokKind == TokenKind::kw_UAV ||
           CurToken.TokKind == TokenKind::kw_Sampler) &&
          "Expects to only be invoked starting at given keyword");
+  TokenKind ParamKind = CurToken.TokKind; // retain for diagnostics
 
   DescriptorTableClause Clause;
-  switch (CurToken.TokKind) {
+  TokenKind ExpectedRegister;
+  switch (ParamKind) {
   default:
     llvm_unreachable("Switch for consumed token was not provided");
   case TokenKind::kw_CBV:
     Clause.Type = ClauseType::CBuffer;
+    ExpectedRegister = TokenKind::bReg;
     break;
   case TokenKind::kw_SRV:
     Clause.Type = ClauseType::SRV;
+    ExpectedRegister = TokenKind::tReg;
     break;
   case TokenKind::kw_UAV:
     Clause.Type = ClauseType::UAV;
+    ExpectedRegister = TokenKind::uReg;
     break;
   case TokenKind::kw_Sampler:
     Clause.Type = ClauseType::Sampler;
+    ExpectedRegister = TokenKind::sReg;
     break;
   }
 
   if (consumeExpectedToken(TokenKind::pu_l_paren, diag::err_expected_after,
-                           CurToken.TokKind))
+                           ParamKind))
     return true;
 
-  if (consumeExpectedToken(TokenKind::pu_r_paren, diag::err_expected_after,
-                           CurToken.TokKind))
+  llvm::SmallDenseMap<TokenKind, ParamType> Params = {
+      {ExpectedRegister, &Clause.Register},
+      {TokenKind::kw_space, &Clause.Space},
+  };
+  llvm::SmallDenseSet<TokenKind> Mandatory = {
+      ExpectedRegister,
+  };
+
+  if (parseParams(Params, Mandatory))
+    return true;
+
+  if (consumeExpectedToken(TokenKind::pu_r_paren,
+                           diag::err_hlsl_unexpected_end_of_params,
+                           /*param of=*/ParamKind))
     return true;
 
   Elements.push_back(Clause);
   return false;
 }
 
+// Helper struct defined to use the overloaded notation of std::visit.
+template <class... Ts> struct ParseParamTypeMethods : Ts... {
+  using Ts::operator()...;
+};
+template <class... Ts>
+ParseParamTypeMethods(Ts...) -> ParseParamTypeMethods<Ts...>;
+
+bool RootSignatureParser::parseParam(ParamType Ref) {
+  return std::visit(
+      ParseParamTypeMethods{
+          [this](Register *X) -> bool { return parseRegister(X); },
+          [this](uint32_t *X) -> bool {
+            return consumeExpectedToken(TokenKind::pu_equal,
+                                        diag::err_expected_after,
+                                        CurToken.TokKind) ||
+                   parseUIntParam(X);
+          },
+      },
+      Ref);
+}
+
+bool RootSignatureParser::parseParams(
+    llvm::SmallDenseMap<TokenKind, ParamType> &Params,
+    llvm::SmallDenseSet<TokenKind> &Mandatory) {
+
+  // Initialize a vector of possible keywords
+  SmallVector<TokenKind> Keywords;
+  for (auto Pair : Params)
+    Keywords.push_back(Pair.first);
+
+  // Keep track of which keywords have been seen to report duplicates
+  llvm::SmallDenseSet<TokenKind> Seen;
+
+  while (tryConsumeExpectedToken(Keywords)) {
+    if (Seen.contains(CurToken.TokKind)) {
+      getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param)
+          << CurToken.TokKind;
+      return true;
+    }
+    Seen.insert(CurToken.TokKind);
+
+    if (parseParam(Params[CurToken.TokKind]))
+      return true;
+
+    if (!tryConsumeExpectedToken(TokenKind::pu_comma))
+      break;
+  }
+
+  bool AllMandatoryDefined = true;
+  for (auto Kind : Mandatory) {
+    bool SeenParam = Seen.contains(Kind);
+    if (!SeenParam) {
+      getDiags().Report(CurToken.TokLoc, diag::err_hlsl_rootsig_missing_param)
+          << Kind;
+    }
+    AllMandatoryDefined &= SeenParam;
+  }
+
+  return !AllMandatoryDefined;
+}
+
+bool RootSignatureParser::parseUIntParam(uint32_t *X) {
+  assert(CurToken.TokKind == TokenKind::pu_equal &&
----------------
joaosaffran wrote:

This made me confused. The only place this is called is parsing 
`TokenKind::pu_equal` before calling it, so it seems confusing, IMHO, that this 
assert is here.

https://github.com/llvm/llvm-project/pull/133800
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to