Skip to content

Commit 7fba04c

Browse files
committed
add support for empty descriptor table clause
1 parent 457acaa commit 7fba04c

File tree

4 files changed

+124
-4
lines changed

4 files changed

+124
-4
lines changed

clang/include/clang/Parse/ParseHLSLRootSignature.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ class RootSignatureParser {
113113
// Root Element helpers
114114
bool ParseRootElement();
115115
bool ParseDescriptorTable();
116+
bool ParseDescriptorTableClause();
116117

117118
/// Invoke the lexer to consume a token and update CurToken with the result
118119
///
@@ -126,10 +127,21 @@ class RootSignatureParser {
126127
return false;
127128
}
128129

130+
// Attempt to retrieve the next token, if TokenKind is invalid then there was
131+
// no next token.
132+
RootSignatureToken PeekNextToken();
133+
129134
// Is the current token one of the expected kinds
130135
bool EnsureExpectedToken(TokenKind AnyExpected);
131136
bool EnsureExpectedToken(ArrayRef<TokenKind> AnyExpected);
132137

138+
// Peek if the next token is of the expected kind.
139+
//
140+
// Return value denotes if it failed to match the expected kind, either it is
141+
// the end of the stream or it didn't match any of the expected kinds.
142+
bool PeekExpectedToken(TokenKind Expected);
143+
bool PeekExpectedToken(ArrayRef<TokenKind> AnyExpected);
144+
133145
/// Consume the next token and report an error if it is not of the expected
134146
/// kind.
135147
///
@@ -138,6 +150,15 @@ class RootSignatureParser {
138150
bool ConsumeExpectedToken(TokenKind Expected);
139151
bool ConsumeExpectedToken(ArrayRef<TokenKind> AnyExpected);
140152

153+
// Peek if the next token is of the expected kind and if it is then consume
154+
// it.
155+
//
156+
// Return value denotes if it failed to match the expected kind, either it is
157+
// the end of the stream or it didn't match any of the expected kinds. It will
158+
// not report an error if there isn't a match.
159+
bool TryConsumeExpectedToken(TokenKind Expected);
160+
bool TryConsumeExpectedToken(ArrayRef<TokenKind> Expected);
161+
141162
private:
142163
SmallVector<llvm::hlsl::rootsig::RootElement> &Elements;
143164
RootSignatureLexer &Lexer;

clang/lib/Parse/ParseHLSLRootSignature.cpp

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,12 +269,55 @@ bool RootSignatureParser::ParseDescriptorTable() {
269269
return true;
270270

271271
// Empty case:
272-
if (!ConsumeExpectedToken(TokenKind::pu_r_paren)) {
272+
if (!TryConsumeExpectedToken(TokenKind::pu_r_paren)) {
273273
Elements.push_back(Table);
274274
return false;
275275
}
276276

277-
return true;
277+
// Iterate through all the defined clauses
278+
do {
279+
if (ParseDescriptorTableClause())
280+
return true;
281+
Table.NumClauses++;
282+
} while (!TryConsumeExpectedToken(TokenKind::pu_comma));
283+
284+
if (ConsumeExpectedToken(TokenKind::pu_r_paren))
285+
return true;
286+
287+
Elements.push_back(Table);
288+
return false;
289+
}
290+
291+
bool RootSignatureParser::ParseDescriptorTableClause() {
292+
if (ConsumeExpectedToken({TokenKind::kw_CBV, TokenKind::kw_SRV,
293+
TokenKind::kw_UAV, TokenKind::kw_Sampler}))
294+
return true;
295+
296+
DescriptorTableClause Clause;
297+
switch (CurToken.Kind) {
298+
case TokenKind::kw_CBV:
299+
Clause.Type = ClauseType::CBuffer;
300+
break;
301+
case TokenKind::kw_SRV:
302+
Clause.Type = ClauseType::SRV;
303+
break;
304+
case TokenKind::kw_UAV:
305+
Clause.Type = ClauseType::UAV;
306+
break;
307+
case TokenKind::kw_Sampler:
308+
Clause.Type = ClauseType::Sampler;
309+
break;
310+
default:
311+
llvm_unreachable("Switch for an expected token was not provided");
312+
}
313+
if (ConsumeExpectedToken(TokenKind::pu_l_paren))
314+
return true;
315+
316+
if (ConsumeExpectedToken(TokenKind::pu_r_paren))
317+
return true;
318+
319+
Elements.push_back(Clause);
320+
return false;
278321
}
279322

280323
// Is given token one of the expected kinds
@@ -299,6 +342,19 @@ bool RootSignatureParser::EnsureExpectedToken(ArrayRef<TokenKind> AnyExpected) {
299342
return true;
300343
}
301344

345+
bool RootSignatureParser::PeekExpectedToken(TokenKind Expected) {
346+
return PeekExpectedToken(ArrayRef{Expected});
347+
}
348+
349+
bool RootSignatureParser::PeekExpectedToken(ArrayRef<TokenKind> AnyExpected) {
350+
auto Result = Lexer.PeekNextToken();
351+
if (!Result)
352+
return true;
353+
if (IsExpectedToken(Result->Kind, AnyExpected))
354+
return false;
355+
return true;
356+
}
357+
302358
bool RootSignatureParser::ConsumeExpectedToken(TokenKind Expected) {
303359
return ConsumeExpectedToken(ArrayRef{Expected});
304360
}
@@ -311,5 +367,16 @@ bool RootSignatureParser::ConsumeExpectedToken(
311367
return EnsureExpectedToken(AnyExpected);
312368
}
313369

370+
bool RootSignatureParser::TryConsumeExpectedToken(TokenKind Expected) {
371+
return TryConsumeExpectedToken(ArrayRef{Expected});
372+
}
373+
374+
bool RootSignatureParser::TryConsumeExpectedToken(
375+
ArrayRef<TokenKind> AnyExpected) {
376+
if (PeekExpectedToken(AnyExpected))
377+
return true;
378+
return ConsumeNextToken();
379+
}
380+
314381
} // namespace hlsl
315382
} // namespace clang

clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp

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

338338
TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) {
339339
const llvm::StringLiteral Source = R"cc(
340+
DescriptorTable(
341+
CBV(),
342+
SRV(),
343+
Sampler(),
344+
UAV()
345+
),
340346
DescriptorTable()
341347
)cc";
342348

@@ -353,7 +359,26 @@ TEST_F(ParseHLSLRootSignatureTest, ValidParseDTClausesTest) {
353359

354360
ASSERT_FALSE(Parser.Parse());
355361
RootElement Elem = Elements[0];
362+
ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
363+
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::CBuffer);
364+
365+
Elem = Elements[1];
366+
ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
367+
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::SRV);
368+
369+
Elem = Elements[2];
370+
ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
371+
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::Sampler);
372+
373+
Elem = Elements[3];
374+
ASSERT_TRUE(std::holds_alternative<DescriptorTableClause>(Elem));
375+
ASSERT_EQ(std::get<DescriptorTableClause>(Elem).Type, ClauseType::UAV);
376+
377+
Elem = Elements[4];
378+
ASSERT_TRUE(std::holds_alternative<DescriptorTable>(Elem));
379+
ASSERT_EQ(std::get<DescriptorTable>(Elem).NumClauses, (uint32_t)4);
356380

381+
Elem = Elements[5];
357382
// Test generated DescriptorTable start has correct default values
358383
ASSERT_TRUE(std::holds_alternative<DescriptorTable>(Elem));
359384
ASSERT_EQ(std::get<DescriptorTable>(Elem).NumClauses, (uint32_t)0);

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)