================ @@ -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 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits