@@ -17,6 +17,15 @@ namespace hlsl {
17
17
18
18
using TokenKind = RootSignatureToken::Kind;
19
19
20
+ static const TokenKind RootElementKeywords[] = {
21
+ TokenKind::kw_RootFlags,
22
+ TokenKind::kw_CBV,
23
+ TokenKind::kw_UAV,
24
+ TokenKind::kw_SRV,
25
+ TokenKind::kw_DescriptorTable,
26
+ TokenKind::kw_StaticSampler,
27
+ };
28
+
20
29
RootSignatureParser::RootSignatureParser (
21
30
llvm::dxbc::RootSignatureVersion Version,
22
31
SmallVector<RootSignatureElement> &Elements, StringLiteral *Signature,
@@ -27,51 +36,63 @@ RootSignatureParser::RootSignatureParser(
27
36
bool RootSignatureParser::parse () {
28
37
// Iterate as many RootSignatureElements as possible, until we hit the
29
38
// end of the stream
39
+ bool HadError = false ;
30
40
while (!peekExpectedToken (TokenKind::end_of_stream)) {
41
+ bool HadLocalError = false ;
31
42
if (tryConsumeExpectedToken (TokenKind::kw_RootFlags)) {
32
43
SourceLocation ElementLoc = getTokenLocation (CurToken);
33
44
auto Flags = parseRootFlags ();
34
- if (!Flags.has_value ())
35
- return true ;
36
- Elements.emplace_back (RootSignatureElement (ElementLoc, *Flags));
45
+ if (Flags.has_value ())
46
+ Elements.emplace_back (RootSignatureElement (ElementLoc, *Flags));
47
+ else
48
+ HadLocalError = true ;
37
49
} else if (tryConsumeExpectedToken (TokenKind::kw_RootConstants)) {
38
50
SourceLocation ElementLoc = getTokenLocation (CurToken);
39
51
auto Constants = parseRootConstants ();
40
- if (!Constants.has_value ())
41
- return true ;
42
- Elements.emplace_back (RootSignatureElement (ElementLoc, *Constants));
52
+ if (Constants.has_value ())
53
+ Elements.emplace_back (RootSignatureElement (ElementLoc, *Constants));
54
+ else
55
+ HadLocalError = true ;
43
56
} else if (tryConsumeExpectedToken (TokenKind::kw_DescriptorTable)) {
44
57
SourceLocation ElementLoc = getTokenLocation (CurToken);
45
58
auto Table = parseDescriptorTable ();
46
- if (!Table.has_value ())
47
- return true ;
48
- Elements.emplace_back (RootSignatureElement (ElementLoc, *Table));
59
+ if (Table.has_value ())
60
+ Elements.emplace_back (RootSignatureElement (ElementLoc, *Table));
61
+ else
62
+ HadLocalError = true ;
49
63
} else if (tryConsumeExpectedToken (
50
64
{TokenKind::kw_CBV, TokenKind::kw_SRV, TokenKind::kw_UAV})) {
51
65
SourceLocation ElementLoc = getTokenLocation (CurToken);
52
66
auto Descriptor = parseRootDescriptor ();
53
- if (!Descriptor.has_value ())
54
- return true ;
55
- Elements.emplace_back (RootSignatureElement (ElementLoc, *Descriptor));
67
+ if (Descriptor.has_value ())
68
+ Elements.emplace_back (RootSignatureElement (ElementLoc, *Descriptor));
69
+ else
70
+ HadLocalError = true ;
56
71
} else if (tryConsumeExpectedToken (TokenKind::kw_StaticSampler)) {
57
72
SourceLocation ElementLoc = getTokenLocation (CurToken);
58
73
auto Sampler = parseStaticSampler ();
59
- if (!Sampler.has_value ())
60
- return true ;
61
- Elements.emplace_back (RootSignatureElement (ElementLoc, *Sampler));
74
+ if (Sampler.has_value ())
75
+ Elements.emplace_back (RootSignatureElement (ElementLoc, *Sampler));
76
+ else
77
+ HadLocalError = true ;
62
78
} else {
79
+ HadLocalError = true ;
63
80
consumeNextToken (); // let diagnostic be at the start of invalid token
64
81
reportDiag (diag::err_hlsl_invalid_token)
65
82
<< /* parameter=*/ 0 << /* param of*/ TokenKind::kw_RootSignature;
66
- return true ;
67
83
}
68
84
69
- // ',' denotes another element, otherwise, expected to be at end of stream
70
- if (!tryConsumeExpectedToken (TokenKind::pu_comma))
85
+ if (HadLocalError) {
86
+ HadError = true ;
87
+ skipUntilExpectedToken (RootElementKeywords);
88
+ } else if (!tryConsumeExpectedToken (TokenKind::pu_comma)) {
89
+ // ',' denotes another element, otherwise, expected to be at end of stream
71
90
break ;
91
+ }
72
92
}
73
93
74
- return consumeExpectedToken (TokenKind::end_of_stream,
94
+ return HadError ||
95
+ consumeExpectedToken (TokenKind::end_of_stream,
75
96
diag::err_expected_either, TokenKind::pu_comma);
76
97
}
77
98
@@ -1371,6 +1392,18 @@ bool RootSignatureParser::tryConsumeExpectedToken(
1371
1392
return true ;
1372
1393
}
1373
1394
1395
+ bool RootSignatureParser::skipUntilExpectedToken (
1396
+ ArrayRef<TokenKind> AnyExpected) {
1397
+
1398
+ while (!peekExpectedToken (AnyExpected)) {
1399
+ if (peekExpectedToken (TokenKind::end_of_stream))
1400
+ return false ;
1401
+ consumeNextToken ();
1402
+ }
1403
+
1404
+ return true ;
1405
+ }
1406
+
1374
1407
SourceLocation RootSignatureParser::getTokenLocation (RootSignatureToken Tok) {
1375
1408
return Signature->getLocationOfByte (Tok.LocOffset , PP.getSourceManager (),
1376
1409
PP.getLangOpts (), PP.getTargetInfo ());
0 commit comments