================
@@ -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 = {
----------------
llvm-beanz wrote:

> Hm, okay. I think that is where we disagree then: whether it is worthwhile to 
> make this generic or not.
> 
> I will make the (opinionated) argument for having it implemented generically:
> 
> * There isn't much of a difference in how we will parse the different root 
> parameter types, `RootSBV(...), CBV(...), StaticSampler(...), 
> RootConstants(...), etc`, so, adding their respective parse methods in future 
> prs will just be something like:

I don't think what you've described int he code example here is where the 
genericness becomes a problem.

>  * We can contrast that with DXC, 
> [here](https://github.com/microsoft/DirectXShaderCompiler/blob/c940161bb3398ff988fafc343ed1623d4a3fad6c/tools/clang/lib/Parse/HLSLRootSignature.cpp#L1301),
>  where it needs to redefine the same "seen" and "mandatory" functionality 
> over and over again.
> * I assume that if we don't want to have a generic method in clang then the 
> code flow would follow a similar pattern as DXC (maybe I don't understand the 
> struct approach correctly and that is a wrong assumption?).

I think you draw a false equivalence. You seem to be saying we either do this 
generically, or we do this like DXC... That's not what I'm saying. The approach 
that Clang takes generally in parsing is to parse things out, and from the 
parsed information construct a declaration or statement, which then gets 
validated during construction.

That is not how DXC's parser for root signatures works, nor is it what you're 
proposing, but maybe it's the better approach.

> * Therefore, using a generic way to parse the parameters of root parameter 
> types will be clearer in its intent (it is declarative) and easier to extend 
> (instead of copying functionality over) when we add the other parts of the 
> RootSignatureParser

I think the bigger question is at what layer of abstraction does being generic 
help and at what layer of abstraction is it a hinderance.

Having a `parseRootParam` function that "generically" parses a root-level 
parameter seems like a good idea, but should it remain generic based on the 
type of the parameter? Should we have a single "parseArgument" function? 
Maybe... Should these functions produce the same structural result for every 
parameter? These things are less clear to me.

> These reasons are why I went with the current generic implementation.
> 
> Regarding scalability, the struct of arrays or the map will have a statically 
> known `N` elements (or pairs), where `N` is the number of parameters for a 
> given root parameter type. (`N` is not equal to the total number of token 
> kinds). The largest `N` would be is for `StaticSamplers` with 13, and then 
> for example `DescriptorTableClause` it is 5. And we could make 
> `Mandatory/Seen` just be two `uint32_t` bitfields.

The reasons that led you to a generic solution, might be reasons why following 
existing patterns that Clang uses for order-independent parsing (like 
attributes), might be the better architectural decision. Maybe we should borrow 
more from Clang's AST design and have polymorphic returned objects rather than 
variants.

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