Skip to content

Commit 24a2bea

Browse files
committed
add invalid_param diagnostic to differentiate between missing comma vs invalid token
1 parent 95166f5 commit 24a2bea

File tree

5 files changed

+63
-13
lines changed

5 files changed

+63
-13
lines changed

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1860,6 +1860,7 @@ def err_hlsl_virtual_inheritance
18601860
: Error<"virtual inheritance is unsupported in HLSL">;
18611861

18621862
// HLSL Root Signature Parser Diagnostics
1863+
def err_hlsl_invalid_param : Error<"invalid parameter of %0">;
18631864
def err_hlsl_rootsig_repeat_param : Error<"specified the same parameter '%0' multiple times">;
18641865
def err_hlsl_rootsig_missing_param : Error<"did not specify mandatory parameter '%0'">;
18651866
def err_hlsl_number_literal_overflow : Error<

clang/include/clang/Parse/ParseHLSLRootSignature.h

Lines changed: 4 additions & 2 deletions
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 DescKind,
104+
RootSignatureToken::Kind RegType);
104105

105106
struct ParsedClauseParams {
106107
std::optional<llvm::hlsl::rootsig::Register> Reg;
@@ -110,7 +111,8 @@ class RootSignatureParser {
110111
std::optional<llvm::dxbc::DescriptorRangeFlags> Flags;
111112
};
112113
std::optional<ParsedClauseParams>
113-
parseDescriptorTableClauseParams(RootSignatureToken::Kind RegType);
114+
parseDescriptorTableClauseParams(RootSignatureToken::Kind ClauseKind,
115+
RootSignatureToken::Kind RegType);
114116

115117
struct ParsedStaticSamplerParams {
116118
std::optional<llvm::hlsl::rootsig::Register> Reg;

clang/lib/Parse/ParseHLSLRootSignature.cpp

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ bool RootSignatureParser::parse() {
5959
if (!Sampler.has_value())
6060
return true;
6161
Elements.emplace_back(RootSignatureElement(ElementLoc, *Sampler));
62+
} else {
63+
consumeNextToken(); // let diagnostic be at the start of invalid token
64+
reportDiag(diag::err_hlsl_invalid_param)
65+
<< /*param of*/ TokenKind::kw_RootSignature;
66+
return true;
6267
}
6368

6469
// ',' denotes another element, otherwise, expected to be at end of stream
@@ -198,7 +203,7 @@ std::optional<RootDescriptor> RootSignatureParser::parseRootDescriptor() {
198203
}
199204
Descriptor.setDefaultFlags(Version);
200205

201-
auto Params = parseRootDescriptorParams(ExpectedReg);
206+
auto Params = parseRootDescriptorParams(DescriptorKind, ExpectedReg);
202207
if (!Params.has_value())
203208
return std::nullopt;
204209

@@ -261,6 +266,11 @@ std::optional<DescriptorTable> RootSignatureParser::parseDescriptorTable() {
261266
Visibility = parseShaderVisibility();
262267
if (!Visibility.has_value())
263268
return std::nullopt;
269+
} else {
270+
consumeNextToken(); // let diagnostic be at the start of invalid token
271+
reportDiag(diag::err_hlsl_invalid_param)
272+
<< /*param of*/ TokenKind::kw_DescriptorTable;
273+
return std::nullopt;
264274
}
265275

266276
// ',' denotes another element, otherwise, expected to be at ')'
@@ -316,7 +326,7 @@ RootSignatureParser::parseDescriptorTableClause() {
316326
}
317327
Clause.setDefaultFlags(Version);
318328

319-
auto Params = parseDescriptorTableClauseParams(ExpectedReg);
329+
auto Params = parseDescriptorTableClauseParams(ParamKind, ExpectedReg);
320330
if (!Params.has_value())
321331
return std::nullopt;
322332

@@ -474,6 +484,11 @@ RootSignatureParser::parseRootConstantParams() {
474484
if (!Visibility.has_value())
475485
return std::nullopt;
476486
Params.Visibility = Visibility;
487+
} else {
488+
consumeNextToken(); // let diagnostic be at the start of invalid token
489+
reportDiag(diag::err_hlsl_invalid_param)
490+
<< /*param of*/ TokenKind::kw_RootConstants;
491+
return std::nullopt;
477492
}
478493

479494
// ',' denotes another element, otherwise, expected to be at ')'
@@ -485,7 +500,8 @@ RootSignatureParser::parseRootConstantParams() {
485500
}
486501

487502
std::optional<RootSignatureParser::ParsedRootDescriptorParams>
488-
RootSignatureParser::parseRootDescriptorParams(TokenKind RegType) {
503+
RootSignatureParser::parseRootDescriptorParams(TokenKind DescKind,
504+
TokenKind RegType) {
489505
assert(CurToken.TokKind == TokenKind::pu_l_paren &&
490506
"Expects to only be invoked starting at given token");
491507

@@ -543,6 +559,10 @@ RootSignatureParser::parseRootDescriptorParams(TokenKind RegType) {
543559
if (!Flags.has_value())
544560
return std::nullopt;
545561
Params.Flags = Flags;
562+
} else {
563+
consumeNextToken(); // let diagnostic be at the start of invalid token
564+
reportDiag(diag::err_hlsl_invalid_param) << /*param of*/ DescKind;
565+
return std::nullopt;
546566
}
547567

548568
// ',' denotes another element, otherwise, expected to be at ')'
@@ -554,7 +574,8 @@ RootSignatureParser::parseRootDescriptorParams(TokenKind RegType) {
554574
}
555575

556576
std::optional<RootSignatureParser::ParsedClauseParams>
557-
RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
577+
RootSignatureParser::parseDescriptorTableClauseParams(TokenKind ClauseKind,
578+
TokenKind RegType) {
558579
assert(CurToken.TokKind == TokenKind::pu_l_paren &&
559580
"Expects to only be invoked starting at given token");
560581

@@ -638,6 +659,10 @@ RootSignatureParser::parseDescriptorTableClauseParams(TokenKind RegType) {
638659
if (!Flags.has_value())
639660
return std::nullopt;
640661
Params.Flags = Flags;
662+
} else {
663+
consumeNextToken(); // let diagnostic be at the start of invalid token
664+
reportDiag(diag::err_hlsl_invalid_param) << /*param of*/ ClauseKind;
665+
return std::nullopt;
641666
}
642667

643668
// ',' denotes another element, otherwise, expected to be at ')'
@@ -833,6 +858,11 @@ RootSignatureParser::parseStaticSamplerParams() {
833858
if (!Visibility.has_value())
834859
return std::nullopt;
835860
Params.Visibility = Visibility;
861+
} else {
862+
consumeNextToken(); // let diagnostic be at the start of invalid token
863+
reportDiag(diag::err_hlsl_invalid_param)
864+
<< /*param of*/ TokenKind::kw_StaticSampler;
865+
return std::nullopt;
836866
}
837867

838868
// ',' denotes another element, otherwise, expected to be at ')'

clang/test/SemaHLSL/RootSignature-err.hlsl

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,41 @@ void bad_root_signature_2() {}
1717
[RootSignature(""), RootSignature("")] // expected-warning {{attribute 'RootSignature' is already applied}}
1818
void bad_root_signature_3() {}
1919

20-
[RootSignature("DescriptorTable(), invalid")] // expected-error {{expected end of stream}}
20+
// expected-error@+1 {{invalid parameter of RootSignature}}
21+
[RootSignature("DescriptorTable(), invalid")]
2122
void bad_root_signature_4() {}
2223

23-
// expected-error@+1 {{expected ')'}}
24+
// expected-error@+1 {{invalid parameter of RootConstants}}
2425
[RootSignature("RootConstants(b0, num32BitConstants = 1, invalid)")]
2526
void bad_root_signature_5() {}
2627

2728
#define MultiLineRootSignature \
2829
"CBV(b0)," \
2930
"RootConstants(num32BitConstants = 3, b0, invalid)"
3031

31-
// CHECK: [[@LINE-2]]:42: note: expanded from macro 'MultiLineRootSignature'
32+
// CHECK: [[@LINE-2]]:44: note: expanded from macro 'MultiLineRootSignature'
3233
// CHECK-NEXT: [[@LINE-3]] | "RootConstants(num32BitConstants = 3, b0, invalid)"
33-
// CHECK-NEXT: | ^
34-
// expected-error@+1 {{expected ')'}}
34+
// CHECK-NEXT: | ^
35+
// expected-error@+1 {{invalid parameter of RootConstants}}
3536
[RootSignature(MultiLineRootSignature)]
3637
void bad_root_signature_6() {}
3738

3839
// expected-error@+1 {{expected end of stream}}
3940
[RootSignature("RootFlags() RootConstants(b0, num32BitConstants = 1))")]
4041
void bad_root_signature_7() {}
42+
43+
// expected-error@+1 {{invalid parameter of RootConstants}}
44+
[RootSignature("RootConstants(b0, num32BitConstantsTypo = 1))")]
45+
void bad_root_signature_8() {}
46+
47+
// expected-error@+1 {{invalid parameter of UAV}}
48+
[RootSignature("UAV(b3")]
49+
void bad_root_signature_9() {}
50+
51+
// expected-error@+1 {{invalid parameter of SRV}}
52+
[RootSignature("DescriptorTable(SRV(s1, invalid))")]
53+
void bad_root_signature_10() {}
54+
55+
// expected-error@+1 {{invalid parameter of DescriptorTable}}
56+
[RootSignature("DescriptorTable(invalid))")]
57+
void bad_root_signature_11() {}

clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@ TEST_F(ParseHLSLRootSignatureTest, InvalidParseInvalidTokenTest) {
865865
Signature, *PP);
866866

867867
// Test correct diagnostic produced - invalid token
868-
Consumer->setExpected(diag::err_expected);
868+
Consumer->setExpected(diag::err_hlsl_invalid_param);
869869
ASSERT_TRUE(Parser.parse());
870870

871871
ASSERT_TRUE(Consumer->isSatisfied());
@@ -886,7 +886,7 @@ TEST_F(ParseHLSLRootSignatureTest, InvalidParseUnexpectedEndOfStreamTest) {
886886
hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
887887
Signature, *PP);
888888

889-
// Test correct diagnostic produced - end of stream
889+
// Test correct diagnostic produced - expected '(' after DescriptorTable
890890
Consumer->setExpected(diag::err_expected_after);
891891

892892
ASSERT_TRUE(Parser.parse());

0 commit comments

Comments
 (0)