Skip to content

Commit a0999c7

Browse files
author
Finn Plummer
committed
implement parsing of empty DescriptorTableClause
1 parent d744cd1 commit a0999c7

File tree

4 files changed

+89
-2
lines changed

4 files changed

+89
-2
lines changed

clang/include/clang/Parse/ParseHLSLRootSignature.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class RootSignatureParser {
4242

4343
/// Root Element parse methods:
4444
bool ParseDescriptorTable();
45+
bool ParseDescriptorTableClause();
4546

4647
/// Invoke the Lexer to consume a token and update CurToken with the result
4748
void ConsumeNextToken() { CurToken = Lexer.ConsumeToken(); }

clang/lib/Parse/ParseHLSLRootSignature.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,27 @@ bool RootSignatureParser::Parse() {
5959
}
6060

6161
bool RootSignatureParser::ParseDescriptorTable() {
62+
assert(CurToken.Kind == TokenKind::kw_DescriptorTable &&
63+
"Expects to only be invoked starting at given keyword");
64+
6265
DescriptorTable Table;
6366

6467
if (ConsumeExpectedToken(TokenKind::pu_l_paren, diag::err_expected_after,
6568
CurToken.Kind))
6669
return true;
6770

71+
// Iterate as many Clauses as possible
72+
while (TryConsumeExpectedToken({TokenKind::kw_CBV, TokenKind::kw_SRV,
73+
TokenKind::kw_UAV, TokenKind::kw_Sampler})) {
74+
if (ParseDescriptorTableClause())
75+
return true;
76+
77+
Table.NumClauses++;
78+
79+
if (!TryConsumeExpectedToken(TokenKind::pu_comma))
80+
break;
81+
}
82+
6883
if (ConsumeExpectedToken(TokenKind::pu_r_paren, diag::err_expected_after,
6984
CurToken.Kind))
7085
return true;
@@ -73,6 +88,43 @@ bool RootSignatureParser::ParseDescriptorTable() {
7388
return false;
7489
}
7590

91+
bool RootSignatureParser::ParseDescriptorTableClause() {
92+
assert((CurToken.Kind == TokenKind::kw_CBV ||
93+
CurToken.Kind == TokenKind::kw_SRV ||
94+
CurToken.Kind == TokenKind::kw_UAV ||
95+
CurToken.Kind == TokenKind::kw_Sampler)
96+
&& "Expects to only be invoked starting at given keyword");
97+
98+
DescriptorTableClause Clause;
99+
switch (CurToken.Kind) {
100+
default: break; // Unreachable given Try + assert pattern
101+
case TokenKind::kw_CBV:
102+
Clause.Type = ClauseType::CBuffer;
103+
break;
104+
case TokenKind::kw_SRV:
105+
Clause.Type = ClauseType::SRV;
106+
break;
107+
case TokenKind::kw_UAV:
108+
Clause.Type = ClauseType::UAV;
109+
break;
110+
case TokenKind::kw_Sampler:
111+
Clause.Type = ClauseType::Sampler;
112+
break;
113+
}
114+
115+
if (ConsumeExpectedToken(TokenKind::pu_l_paren, diag::err_expected_after,
116+
CurToken.Kind))
117+
return true;
118+
119+
120+
if (ConsumeExpectedToken(TokenKind::pu_r_paren, diag::err_expected_after,
121+
CurToken.Kind))
122+
return true;
123+
124+
Elements.push_back(Clause);
125+
return false;
126+
}
127+
76128
// Returns true when given token is one of the expected kinds
77129
static bool IsExpectedToken(TokenKind Kind, ArrayRef<TokenKind> AnyExpected) {
78130
for (auto Expected : AnyExpected)

clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,12 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseEmptyTest) {
128128

129129
TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) {
130130
const llvm::StringLiteral Source = R"cc(
131+
DescriptorTable(
132+
CBV(),
133+
SRV(),
134+
Sampler(),
135+
UAV()
136+
),
131137
DescriptorTable()
132138
)cc";
133139

@@ -143,9 +149,30 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) {
143149
Consumer->SetNoDiag();
144150

145151
ASSERT_FALSE(Parser.Parse());
152+
153+
// First Descriptor Table with 4 elements
146154
RootElement Elem = Elements[0];
155+
ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
156+
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::CBuffer);
157+
158+
Elem = Elements[1];
159+
ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
160+
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::SRV);
161+
162+
Elem = Elements[2];
163+
ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
164+
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::Sampler);
165+
166+
Elem = Elements[3];
167+
ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
168+
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::UAV);
169+
170+
Elem = Elements[4];
171+
ASSERT_TRUE(std::holds_alternative<DescriptorTable>(Elem));
172+
ASSERT_EQ(std::get<DescriptorTable>(Elem).NumClauses, (uint32_t)4);
147173

148174
// Empty Descriptor Table
175+
Elem = Elements[5];
149176
ASSERT_TRUE(std::holds_alternative<DescriptorTable>(Elem));
150177
ASSERT_EQ(std::get<DescriptorTable>(Elem).NumClauses, 0u);
151178
ASSERT_TRUE(Consumer->IsSatisfied());

llvm/include/llvm/Frontend/HLSL/HLSLRootSignature.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#ifndef LLVM_FRONTEND_HLSL_HLSLROOTSIGNATURE_H
1515
#define LLVM_FRONTEND_HLSL_HLSLROOTSIGNATURE_H
1616

17+
#include "llvm/Support/DXILABI.h"
1718
#include <variant>
1819

1920
namespace llvm {
@@ -27,8 +28,14 @@ struct DescriptorTable {
2728
uint32_t NumClauses = 0; // The number of clauses in the table
2829
};
2930

30-
// Models RootElement : DescriptorTable
31-
using RootElement = std::variant<DescriptorTable>;
31+
// Models DTClause : CBV | SRV | UAV | Sampler, by collecting like parameters
32+
using ClauseType = llvm::dxil::ResourceClass;
33+
struct DescriptorTableClause {
34+
ClauseType Type;
35+
};
36+
37+
// Models RootElement : DescriptorTable | DescriptorTableClause
38+
using RootElement = std::variant<DescriptorTable, DescriptorTableClause>;
3239

3340
} // namespace rootsig
3441
} // namespace hlsl

0 commit comments

Comments
 (0)