Skip to content

Commit c6a2f4a

Browse files
committed
improve diagnostics for descriptor table clauses
1 parent 019e50e commit c6a2f4a

File tree

4 files changed

+59
-25
lines changed

4 files changed

+59
-25
lines changed

clang/include/clang/Parse/ParseHLSLRootSignature.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ class RootSignatureParser {
111111
std::optional<llvm::dxbc::DescriptorRangeFlags> Flags;
112112
};
113113
std::optional<ParsedClauseParams>
114-
parseDescriptorTableClauseParams(RootSignatureToken::Kind RegType);
114+
parseDescriptorTableClauseParams(RootSignatureToken::Kind DescType,
115+
RootSignatureToken::Kind RegType);
115116

116117
struct ParsedStaticSamplerParams {
117118
std::optional<llvm::hlsl::rootsig::Register> Reg;

clang/lib/Parse/ParseHLSLRootSignature.cpp

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -330,10 +330,13 @@ RootSignatureParser::parseDescriptorTableClause() {
330330
}
331331
Clause.setDefaultFlags(Version);
332332

333-
auto Params = parseDescriptorTableClauseParams(ExpectedReg);
333+
auto Params = parseDescriptorTableClauseParams(ParamKind, ExpectedReg);
334334
if (!Params.has_value())
335335
return std::nullopt;
336336

337+
if (consumeExpectedToken(TokenKind::pu_r_paren))
338+
return std::nullopt;
339+
337340
// Check mandatory parameters were provided
338341
if (!Params->Reg.has_value()) {
339342
reportDiag(diag::err_hlsl_rootsig_missing_param) << ExpectedReg;
@@ -355,9 +358,6 @@ RootSignatureParser::parseDescriptorTableClause() {
355358
if (Params->Flags.has_value())
356359
Clause.Flags = Params->Flags.value();
357360

358-
if (consumeExpectedToken(TokenKind::pu_r_paren))
359-
return std::nullopt;
360-
361361
return Clause;
362362
}
363363

@@ -577,14 +577,15 @@ RootSignatureParser::parseRootDescriptorParams(TokenKind DescType,
577577
}
578578

579579
std::optional<RootSignatureParser::ParsedClauseParams>
580-
RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
580+
RootSignatureParser::parseDescriptorTableClauseParams(TokenKind DescType,
581+
TokenKind RegType) {
581582
assert(CurToken.TokKind == TokenKind::pu_l_paren &&
582583
"Expects to only be invoked starting at given token");
583584

584585
ParsedClauseParams Params;
585-
do {
586-
// ( `b` | `t` | `u` | `s`) POS_INT
586+
while (!peekExpectedToken(TokenKind::pu_r_paren)) {
587587
if (tryConsumeExpectedToken(RegType)) {
588+
// ( `b` | `t` | `u` | `s`) POS_INT
588589
if (Params.Reg.has_value()) {
589590
reportDiag(diag::err_hlsl_rootsig_repeat_param) << CurToken.TokKind;
590591
return std::nullopt;
@@ -593,10 +594,8 @@ RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
593594
if (!Reg.has_value())
594595
return std::nullopt;
595596
Params.Reg = Reg;
596-
}
597-
598-
// `numDescriptors` `=` POS_INT | unbounded
599-
if (tryConsumeExpectedToken(TokenKind::kw_numDescriptors)) {
597+
} else if (tryConsumeExpectedToken(TokenKind::kw_numDescriptors)) {
598+
// `numDescriptors` `=` POS_INT | unbounded
600599
if (Params.NumDescriptors.has_value()) {
601600
reportDiag(diag::err_hlsl_rootsig_repeat_param) << CurToken.TokKind;
602601
return std::nullopt;
@@ -615,10 +614,8 @@ RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
615614
}
616615

617616
Params.NumDescriptors = NumDescriptors;
618-
}
619-
620-
// `space` `=` POS_INT
621-
if (tryConsumeExpectedToken(TokenKind::kw_space)) {
617+
} else if (tryConsumeExpectedToken(TokenKind::kw_space)) {
618+
// `space` `=` POS_INT
622619
if (Params.Space.has_value()) {
623620
reportDiag(diag::err_hlsl_rootsig_repeat_param) << CurToken.TokKind;
624621
return std::nullopt;
@@ -631,10 +628,8 @@ RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
631628
if (!Space.has_value())
632629
return std::nullopt;
633630
Params.Space = Space;
634-
}
635-
636-
// `offset` `=` POS_INT | DESCRIPTOR_RANGE_OFFSET_APPEND
637-
if (tryConsumeExpectedToken(TokenKind::kw_offset)) {
631+
} else if (tryConsumeExpectedToken(TokenKind::kw_offset)) {
632+
// `offset` `=` POS_INT | DESCRIPTOR_RANGE_OFFSET_APPEND
638633
if (Params.Offset.has_value()) {
639634
reportDiag(diag::err_hlsl_rootsig_repeat_param) << CurToken.TokKind;
640635
return std::nullopt;
@@ -653,10 +648,8 @@ RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
653648
}
654649

655650
Params.Offset = Offset;
656-
}
657-
658-
// `flags` `=` DESCRIPTOR_RANGE_FLAGS
659-
if (tryConsumeExpectedToken(TokenKind::kw_flags)) {
651+
} else if (tryConsumeExpectedToken(TokenKind::kw_flags)) {
652+
// `flags` `=` DESCRIPTOR_RANGE_FLAGS
660653
if (Params.Flags.has_value()) {
661654
reportDiag(diag::err_hlsl_rootsig_repeat_param) << CurToken.TokKind;
662655
return std::nullopt;
@@ -669,9 +662,16 @@ RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
669662
if (!Flags.has_value())
670663
return std::nullopt;
671664
Params.Flags = Flags;
665+
} else {
666+
consumeNextToken(); // position to start of invalid token
667+
reportDiag(diag::err_hlsl_rootsig_invalid_param) << /*param of=*/DescType;
668+
return std::nullopt;
672669
}
673670

674-
} while (tryConsumeExpectedToken(TokenKind::pu_comma));
671+
// ',' denotes another element, otherwise, expected to be at ')'
672+
if (!tryConsumeExpectedToken(TokenKind::pu_comma))
673+
break;
674+
}
675675

676676
return Params;
677677
}

clang/test/SemaHLSL/RootSignature-err.hlsl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,7 @@ void bad_root_signature_6() {}
3838
// expected-error@+1 {{invalid parameter of SRV}}
3939
[RootSignature("SRV(invalid)")]
4040
void bad_root_signature_7() {}
41+
42+
// expected-error@+1 {{invalid parameter of Sampler}}
43+
[RootSignature("DescriptorTable(Sampler(invalid))")]
44+
void bad_root_signature_8() {}

clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,4 +1345,33 @@ TEST_F(ParseHLSLRootSignatureTest, InvalidRootDescriptorParamsCommaTest) {
13451345
ASSERT_TRUE(Consumer->isSatisfied());
13461346
}
13471347

1348+
TEST_F(ParseHLSLRootSignatureTest, InvalidDescriptorClauseParamsCommaTest) {
1349+
// This test will check that an error is produced when there is a missing
1350+
// comma between parameters
1351+
const llvm::StringLiteral Source = R"cc(
1352+
DescriptorTable(
1353+
UAV(
1354+
u0
1355+
flags = 0
1356+
)
1357+
)
1358+
)cc";
1359+
1360+
auto Ctx = createMinimalASTContext();
1361+
StringLiteral *Signature = wrapSource(Ctx, Source);
1362+
1363+
TrivialModuleLoader ModLoader;
1364+
auto PP = createPP(Source, ModLoader);
1365+
1366+
SmallVector<RootSignatureElement> Elements;
1367+
hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1368+
Signature, *PP);
1369+
1370+
// Test correct diagnostic produced
1371+
Consumer->setExpected(diag::err_expected);
1372+
ASSERT_TRUE(Parser.parse());
1373+
1374+
ASSERT_TRUE(Consumer->isSatisfied());
1375+
}
1376+
13481377
} // anonymous namespace

0 commit comments

Comments
 (0)