================ @@ -0,0 +1,417 @@ +#include "clang/Parse/ParseHLSLRootSignature.h" + +#include "clang/Lex/LiteralSupport.h" + +#include "llvm/Support/raw_ostream.h" + +using namespace llvm::hlsl::rootsig; + +namespace clang { +namespace hlsl { + +static std::string FormatTokenKinds(ArrayRef<TokenKind> Kinds) { + std::string TokenString; + llvm::raw_string_ostream Out(TokenString); + bool First = true; + for (auto Kind : Kinds) { + if (!First) + Out << ", "; + switch (Kind) { +#define TOK(X, SPELLING) \ + case TokenKind::X: \ + Out << SPELLING; \ + break; +#include "clang/Lex/HLSLRootSignatureTokenKinds.def" + } + First = false; + } + + return TokenString; +} + +// Parser Definitions + +RootSignatureParser::RootSignatureParser(SmallVector<RootElement> &Elements, + RootSignatureLexer &Lexer, + Preprocessor &PP) + : Elements(Elements), Lexer(Lexer), PP(PP), CurToken(SourceLocation()) {} + +bool RootSignatureParser::Parse() { + // Handle edge-case of empty RootSignature() + if (Lexer.EndOfBuffer()) + return false; + + // Iterate as many RootElements as possible + while (!ParseRootElement()) { + if (Lexer.EndOfBuffer()) + return false; + if (ConsumeExpectedToken(TokenKind::pu_comma)) + return true; + } + + return true; +} + +bool RootSignatureParser::ParseRootElement() { + if (ConsumeExpectedToken(TokenKind::kw_DescriptorTable)) + return true; + + // Dispatch onto the correct parse method + switch (CurToken.Kind) { + case TokenKind::kw_DescriptorTable: + return ParseDescriptorTable(); + default: + break; + } + llvm_unreachable("Switch for an expected token was not provided"); +} + +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(CurToken.TokLoc, diag::err_hlsl_rootsig_repeat_param) + << FormatTokenKinds(CurToken.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 (CurToken.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"); ---------------- inbelic wrote:
Forwarding this for visibility: https://github.com/llvm/llvm-project/pull/122982#discussion_r1953996279 https://github.com/llvm/llvm-project/pull/122982 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits