Skip to content

Commit 019e50e

Browse files
committed
improve diagnostics for root descriptors
1 parent 3a89542 commit 019e50e

File tree

4 files changed

+56
-21
lines changed

4 files changed

+56
-21
lines changed

clang/include/clang/Parse/ParseHLSLRootSignature.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,8 @@ class RootSignatureParser {
100100
std::optional<llvm::dxbc::RootDescriptorFlags> Flags;
101101
};
102102
std::optional<ParsedRootDescriptorParams>
103-
parseRootDescriptorParams(RootSignatureToken::Kind RegType);
103+
parseRootDescriptorParams(RootSignatureToken::Kind DescType,
104+
RootSignatureToken::Kind RegType);
104105

105106
struct ParsedClauseParams {
106107
std::optional<llvm::hlsl::rootsig::Register> Reg;

clang/lib/Parse/ParseHLSLRootSignature.cpp

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -209,10 +209,13 @@ std::optional<RootDescriptor> RootSignatureParser::parseRootDescriptor() {
209209
}
210210
Descriptor.setDefaultFlags(Version);
211211

212-
auto Params = parseRootDescriptorParams(ExpectedReg);
212+
auto Params = parseRootDescriptorParams(DescriptorKind, ExpectedReg);
213213
if (!Params.has_value())
214214
return std::nullopt;
215215

216+
if (consumeExpectedToken(TokenKind::pu_r_paren))
217+
return std::nullopt;
218+
216219
// Check mandatory parameters were provided
217220
if (!Params->Reg.has_value()) {
218221
reportDiag(diag::err_hlsl_rootsig_missing_param) << ExpectedReg;
@@ -231,9 +234,6 @@ std::optional<RootDescriptor> RootSignatureParser::parseRootDescriptor() {
231234
if (Params->Flags.has_value())
232235
Descriptor.Flags = Params->Flags.value();
233236

234-
if (consumeExpectedToken(TokenKind::pu_r_paren))
235-
return std::nullopt;
236-
237237
return Descriptor;
238238
}
239239

@@ -503,14 +503,15 @@ RootSignatureParser::parseRootConstantParams() {
503503
}
504504

505505
std::optional<RootSignatureParser::ParsedRootDescriptorParams>
506-
RootSignatureParser::parseRootDescriptorParams(TokenKind RegType) {
506+
RootSignatureParser::parseRootDescriptorParams(TokenKind DescType,
507+
TokenKind RegType) {
507508
assert(CurToken.TokKind == TokenKind::pu_l_paren &&
508509
"Expects to only be invoked starting at given token");
509510

510511
ParsedRootDescriptorParams Params;
511-
do {
512-
// ( `b` | `t` | `u`) POS_INT
512+
while (!peekExpectedToken(TokenKind::pu_r_paren)) {
513513
if (tryConsumeExpectedToken(RegType)) {
514+
// ( `b` | `t` | `u`) POS_INT
514515
if (Params.Reg.has_value()) {
515516
reportDiag(diag::err_hlsl_rootsig_repeat_param) << CurToken.TokKind;
516517
return std::nullopt;
@@ -519,10 +520,8 @@ RootSignatureParser::parseRootDescriptorParams(TokenKind RegType) {
519520
if (!Reg.has_value())
520521
return std::nullopt;
521522
Params.Reg = Reg;
522-
}
523-
524-
// `space` `=` POS_INT
525-
if (tryConsumeExpectedToken(TokenKind::kw_space)) {
523+
} else if (tryConsumeExpectedToken(TokenKind::kw_space)) {
524+
// `space` `=` POS_INT
526525
if (Params.Space.has_value()) {
527526
reportDiag(diag::err_hlsl_rootsig_repeat_param) << CurToken.TokKind;
528527
return std::nullopt;
@@ -535,10 +534,8 @@ RootSignatureParser::parseRootDescriptorParams(TokenKind RegType) {
535534
if (!Space.has_value())
536535
return std::nullopt;
537536
Params.Space = Space;
538-
}
539-
540-
// `visibility` `=` SHADER_VISIBILITY
541-
if (tryConsumeExpectedToken(TokenKind::kw_visibility)) {
537+
} else if (tryConsumeExpectedToken(TokenKind::kw_visibility)) {
538+
// `visibility` `=` SHADER_VISIBILITY
542539
if (Params.Visibility.has_value()) {
543540
reportDiag(diag::err_hlsl_rootsig_repeat_param) << CurToken.TokKind;
544541
return std::nullopt;
@@ -551,10 +548,8 @@ RootSignatureParser::parseRootDescriptorParams(TokenKind RegType) {
551548
if (!Visibility.has_value())
552549
return std::nullopt;
553550
Params.Visibility = Visibility;
554-
}
555-
556-
// `flags` `=` ROOT_DESCRIPTOR_FLAGS
557-
if (tryConsumeExpectedToken(TokenKind::kw_flags)) {
551+
} else if (tryConsumeExpectedToken(TokenKind::kw_flags)) {
552+
// `flags` `=` ROOT_DESCRIPTOR_FLAGS
558553
if (Params.Flags.has_value()) {
559554
reportDiag(diag::err_hlsl_rootsig_repeat_param) << CurToken.TokKind;
560555
return std::nullopt;
@@ -567,8 +562,16 @@ RootSignatureParser::parseRootDescriptorParams(TokenKind RegType) {
567562
if (!Flags.has_value())
568563
return std::nullopt;
569564
Params.Flags = Flags;
565+
} else {
566+
consumeNextToken(); // position to start of invalid token
567+
reportDiag(diag::err_hlsl_rootsig_invalid_param) << /*param of=*/DescType;
568+
return std::nullopt;
570569
}
571-
} while (tryConsumeExpectedToken(TokenKind::pu_comma));
570+
571+
// ',' denotes another element, otherwise, expected to be at ')'
572+
if (!tryConsumeExpectedToken(TokenKind::pu_comma))
573+
break;
574+
}
572575

573576
return Params;
574577
}

clang/test/SemaHLSL/RootSignature-err.hlsl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,7 @@ void bad_root_signature_5() {}
3434
// expected-error@+1 {{invalid parameter of RootConstants}}
3535
[RootSignature(MultiLineRootSignature)]
3636
void bad_root_signature_6() {}
37+
38+
// expected-error@+1 {{invalid parameter of SRV}}
39+
[RootSignature("SRV(invalid)")]
40+
void bad_root_signature_7() {}

clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,4 +1318,31 @@ TEST_F(ParseHLSLRootSignatureTest, InvalidRootConstantParamsCommaTest) {
13181318
ASSERT_TRUE(Consumer->isSatisfied());
13191319
}
13201320

1321+
TEST_F(ParseHLSLRootSignatureTest, InvalidRootDescriptorParamsCommaTest) {
1322+
// This test will check that an error is produced when there is a missing
1323+
// comma between parameters
1324+
const llvm::StringLiteral Source = R"cc(
1325+
CBV(
1326+
b0
1327+
flags = 0
1328+
)
1329+
)cc";
1330+
1331+
auto Ctx = createMinimalASTContext();
1332+
StringLiteral *Signature = wrapSource(Ctx, Source);
1333+
1334+
TrivialModuleLoader ModLoader;
1335+
auto PP = createPP(Source, ModLoader);
1336+
1337+
SmallVector<RootSignatureElement> Elements;
1338+
hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1339+
Signature, *PP);
1340+
1341+
// Test correct diagnostic produced
1342+
Consumer->setExpected(diag::err_expected);
1343+
ASSERT_TRUE(Parser.parse());
1344+
1345+
ASSERT_TRUE(Consumer->isSatisfied());
1346+
}
1347+
13211348
} // anonymous namespace

0 commit comments

Comments
 (0)