Skip to content

Commit 55517f5

Browse files
authored
[HLSL][RootSignature] Add parsing for empty RootConstants (#137999)
- defines the empty RootConstants in-memory struct - adds test harness for testing it - adds missing parameter keywords to the lexer (`RootConstants`, `num32BitConstants`) First part of implementing: #126576
1 parent cb0b961 commit 55517f5

File tree

6 files changed

+66
-7
lines changed

6 files changed

+66
-7
lines changed

clang/include/clang/Lex/HLSLRootSignatureTokenKinds.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ PUNCTUATOR(minus, '-')
7575
// RootElement Keywords:
7676
KEYWORD(RootSignature) // used only for diagnostic messaging
7777
KEYWORD(DescriptorTable)
78+
KEYWORD(RootConstants)
79+
80+
// RootConstants Keywords:
81+
KEYWORD(num32BitConstants)
7882

7983
// DescriptorTable Keywords:
8084
KEYWORD(CBV)

clang/include/clang/Parse/ParseHLSLRootSignature.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class RootSignatureParser {
7171
// expected, or, there is a lexing error
7272

7373
/// Root Element parse methods:
74+
std::optional<llvm::hlsl::rootsig::RootConstants> parseRootConstants();
7475
std::optional<llvm::hlsl::rootsig::DescriptorTable> parseDescriptorTable();
7576
std::optional<llvm::hlsl::rootsig::DescriptorTableClause>
7677
parseDescriptorTableClause();

clang/lib/Parse/ParseHLSLRootSignature.cpp

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ RootSignatureParser::RootSignatureParser(SmallVector<RootElement> &Elements,
2727
bool RootSignatureParser::parse() {
2828
// Iterate as many RootElements as possible
2929
do {
30+
if (tryConsumeExpectedToken(TokenKind::kw_RootConstants)) {
31+
auto Constants = parseRootConstants();
32+
if (!Constants.has_value())
33+
return true;
34+
Elements.push_back(*Constants);
35+
}
36+
3037
if (tryConsumeExpectedToken(TokenKind::kw_DescriptorTable)) {
3138
auto Table = parseDescriptorTable();
3239
if (!Table.has_value())
@@ -35,12 +42,27 @@ bool RootSignatureParser::parse() {
3542
}
3643
} while (tryConsumeExpectedToken(TokenKind::pu_comma));
3744

38-
if (consumeExpectedToken(TokenKind::end_of_stream,
45+
return consumeExpectedToken(TokenKind::end_of_stream,
46+
diag::err_hlsl_unexpected_end_of_params,
47+
/*param of=*/TokenKind::kw_RootSignature);
48+
}
49+
50+
std::optional<RootConstants> RootSignatureParser::parseRootConstants() {
51+
assert(CurToken.TokKind == TokenKind::kw_RootConstants &&
52+
"Expects to only be invoked starting at given keyword");
53+
54+
if (consumeExpectedToken(TokenKind::pu_l_paren, diag::err_expected_after,
55+
CurToken.TokKind))
56+
return std::nullopt;
57+
58+
RootConstants Constants;
59+
60+
if (consumeExpectedToken(TokenKind::pu_r_paren,
3961
diag::err_hlsl_unexpected_end_of_params,
40-
/*param of=*/TokenKind::kw_RootSignature))
41-
return true;
62+
/*param of=*/TokenKind::kw_RootConstants))
63+
return std::nullopt;
4264

43-
return false;
65+
return Constants;
4466
}
4567

4668
std::optional<DescriptorTable> RootSignatureParser::parseDescriptorTable() {

clang/unittests/Lex/LexHLSLRootSignatureTest.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ TEST_F(LexHLSLRootSignatureTest, ValidLexAllTokensTest) {
128128
129129
RootSignature
130130
131-
DescriptorTable
131+
DescriptorTable RootConstants
132+
133+
num32BitConstants
132134
133135
CBV SRV UAV Sampler
134136
space visibility flags

clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,32 @@ TEST_F(ParseHLSLRootSignatureTest, ValidSamplerFlagsTest) {
252252
ASSERT_TRUE(Consumer->isSatisfied());
253253
}
254254

255+
TEST_F(ParseHLSLRootSignatureTest, ValidParseRootConsantsTest) {
256+
const llvm::StringLiteral Source = R"cc(
257+
RootConstants()
258+
)cc";
259+
260+
TrivialModuleLoader ModLoader;
261+
auto PP = createPP(Source, ModLoader);
262+
auto TokLoc = SourceLocation();
263+
264+
hlsl::RootSignatureLexer Lexer(Source, TokLoc);
265+
SmallVector<RootElement> Elements;
266+
hlsl::RootSignatureParser Parser(Elements, Lexer, *PP);
267+
268+
// Test no diagnostics produced
269+
Consumer->setNoDiag();
270+
271+
ASSERT_FALSE(Parser.parse());
272+
273+
ASSERT_EQ(Elements.size(), 1u);
274+
275+
RootElement Elem = Elements[0];
276+
ASSERT_TRUE(std::holds_alternative<RootConstants>(Elem));
277+
278+
ASSERT_TRUE(Consumer->isSatisfied());
279+
}
280+
255281
TEST_F(ParseHLSLRootSignatureTest, ValidTrailingCommaTest) {
256282
// This test will checks we can handling trailing commas ','
257283
const llvm::StringLiteral Source = R"cc(

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ struct Register {
5454
uint32_t Number;
5555
};
5656

57+
// Models the parameter values of root constants
58+
struct RootConstants {};
59+
5760
// Models the end of a descriptor table and stores its visibility
5861
struct DescriptorTable {
5962
ShaderVisibility Visibility = ShaderVisibility::All;
@@ -88,8 +91,9 @@ struct DescriptorTableClause {
8891
}
8992
};
9093

91-
// Models RootElement : DescriptorTable | DescriptorTableClause
92-
using RootElement = std::variant<DescriptorTable, DescriptorTableClause>;
94+
// Models RootElement : RootConstants | DescriptorTable | DescriptorTableClause
95+
using RootElement =
96+
std::variant<RootConstants, DescriptorTable, DescriptorTableClause>;
9397

9498
} // namespace rootsig
9599
} // namespace hlsl

0 commit comments

Comments
 (0)