Skip to content

Commit 3a89542

Browse files
committed
improve diagnostics for root constants
1 parent 519e4d8 commit 3a89542

File tree

3 files changed

+50
-20
lines changed

3 files changed

+50
-20
lines changed

clang/lib/Parse/ParseHLSLRootSignature.cpp

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ std::optional<RootConstants> RootSignatureParser::parseRootConstants() {
149149
if (!Params.has_value())
150150
return std::nullopt;
151151

152+
if (consumeExpectedToken(TokenKind::pu_r_paren))
153+
return std::nullopt;
154+
152155
// Check mandatory parameters where provided
153156
if (!Params->Num32BitConstants.has_value()) {
154157
reportDiag(diag::err_hlsl_rootsig_missing_param)
@@ -172,9 +175,6 @@ std::optional<RootConstants> RootSignatureParser::parseRootConstants() {
172175
if (Params->Space.has_value())
173176
Constants.Space = Params->Space.value();
174177

175-
if (consumeExpectedToken(TokenKind::pu_r_paren))
176-
return std::nullopt;
177-
178178
return Constants;
179179
}
180180

@@ -434,9 +434,9 @@ RootSignatureParser::parseRootConstantParams() {
434434
"Expects to only be invoked starting at given token");
435435

436436
ParsedConstantParams Params;
437-
do {
438-
// `num32BitConstants` `=` POS_INT
437+
while (!peekExpectedToken(TokenKind::pu_r_paren)) {
439438
if (tryConsumeExpectedToken(TokenKind::kw_num32BitConstants)) {
439+
// `num32BitConstants` `=` POS_INT
440440
if (Params.Num32BitConstants.has_value()) {
441441
reportDiag(diag::err_hlsl_rootsig_repeat_param) << CurToken.TokKind;
442442
return std::nullopt;
@@ -449,10 +449,8 @@ RootSignatureParser::parseRootConstantParams() {
449449
if (!Num32BitConstants.has_value())
450450
return std::nullopt;
451451
Params.Num32BitConstants = Num32BitConstants;
452-
}
453-
454-
// `b` POS_INT
455-
if (tryConsumeExpectedToken(TokenKind::bReg)) {
452+
} else if (tryConsumeExpectedToken(TokenKind::bReg)) {
453+
// `b` POS_INT
456454
if (Params.Reg.has_value()) {
457455
reportDiag(diag::err_hlsl_rootsig_repeat_param) << CurToken.TokKind;
458456
return std::nullopt;
@@ -461,10 +459,8 @@ RootSignatureParser::parseRootConstantParams() {
461459
if (!Reg.has_value())
462460
return std::nullopt;
463461
Params.Reg = Reg;
464-
}
465-
466-
// `space` `=` POS_INT
467-
if (tryConsumeExpectedToken(TokenKind::kw_space)) {
462+
} else if (tryConsumeExpectedToken(TokenKind::kw_space)) {
463+
// `space` `=` POS_INT
468464
if (Params.Space.has_value()) {
469465
reportDiag(diag::err_hlsl_rootsig_repeat_param) << CurToken.TokKind;
470466
return std::nullopt;
@@ -477,10 +473,8 @@ RootSignatureParser::parseRootConstantParams() {
477473
if (!Space.has_value())
478474
return std::nullopt;
479475
Params.Space = Space;
480-
}
481-
482-
// `visibility` `=` SHADER_VISIBILITY
483-
if (tryConsumeExpectedToken(TokenKind::kw_visibility)) {
476+
} else if (tryConsumeExpectedToken(TokenKind::kw_visibility)) {
477+
// `visibility` `=` SHADER_VISIBILITY
484478
if (Params.Visibility.has_value()) {
485479
reportDiag(diag::err_hlsl_rootsig_repeat_param) << CurToken.TokKind;
486480
return std::nullopt;
@@ -493,8 +487,17 @@ RootSignatureParser::parseRootConstantParams() {
493487
if (!Visibility.has_value())
494488
return std::nullopt;
495489
Params.Visibility = Visibility;
490+
} else {
491+
consumeNextToken(); // position to start of invalid token
492+
reportDiag(diag::err_hlsl_rootsig_invalid_param)
493+
<< /*param of=*/TokenKind::kw_RootConstants;
494+
return std::nullopt;
496495
}
497-
} while (tryConsumeExpectedToken(TokenKind::pu_comma));
496+
497+
// ',' denotes another element, otherwise, expected to be at ')'
498+
if (!tryConsumeExpectedToken(TokenKind::pu_comma))
499+
break;
500+
}
498501

499502
return Params;
500503
}

clang/test/SemaHLSL/RootSignature-err.hlsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ void bad_root_signature_5() {}
3030

3131
// CHECK: note: expanded from macro 'MultiLineRootSignature'
3232
// CHECK-NEXT: [[@LINE-3]] | "RootConstants(num32BitConstants = 3, b0, invalid)"
33-
// CHECK-NEXT: | ^
34-
// expected-error@+1 {{expected ')'}}
33+
// CHECK-NEXT: | ^
34+
// expected-error@+1 {{invalid parameter of RootConstants}}
3535
[RootSignature(MultiLineRootSignature)]
3636
void bad_root_signature_6() {}

clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1291,4 +1291,31 @@ TEST_F(ParseHLSLRootSignatureTest, InvalidDescriptorTableMissingCommaTest) {
12911291
ASSERT_TRUE(Consumer->isSatisfied());
12921292
}
12931293

1294+
TEST_F(ParseHLSLRootSignatureTest, InvalidRootConstantParamsCommaTest) {
1295+
// This test will check that an error is produced when there is a missing
1296+
// comma between parameters
1297+
const llvm::StringLiteral Source = R"cc(
1298+
RootConstants(
1299+
num32BitConstants = 1
1300+
b0
1301+
)
1302+
)cc";
1303+
1304+
auto Ctx = createMinimalASTContext();
1305+
StringLiteral *Signature = wrapSource(Ctx, Source);
1306+
1307+
TrivialModuleLoader ModLoader;
1308+
auto PP = createPP(Source, ModLoader);
1309+
1310+
SmallVector<RootSignatureElement> Elements;
1311+
hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1312+
Signature, *PP);
1313+
1314+
// Test correct diagnostic produced
1315+
Consumer->setExpected(diag::err_expected);
1316+
ASSERT_TRUE(Parser.parse());
1317+
1318+
ASSERT_TRUE(Consumer->isSatisfied());
1319+
}
1320+
12941321
} // anonymous namespace

0 commit comments

Comments
 (0)