@@ -26,22 +26,14 @@ RootSignatureParser::RootSignatureParser(SmallVector<RootElement> &Elements,
26
26
27
27
bool RootSignatureParser::parse () {
28
28
// Iterate as many RootElements as possible
29
- while (tryConsumeExpectedToken (TokenKind::kw_DescriptorTable)) {
30
- // Dispatch onto parser method.
31
- // We guard against the unreachable here as we just ensured that CurToken
32
- // will be one of the kinds in the while condition
33
- switch (CurToken.TokKind ) {
34
- case TokenKind::kw_DescriptorTable:
35
- if (parseDescriptorTable ())
29
+ do {
30
+ if (tryConsumeExpectedToken (TokenKind::kw_DescriptorTable)) {
31
+ auto Table = parseDescriptorTable ();
32
+ if (!Table.has_value ())
36
33
return true ;
37
- break ;
38
- default :
39
- llvm_unreachable (" Switch for consumed token was not provided" );
34
+ Elements.push_back (*Table);
40
35
}
41
-
42
- if (!tryConsumeExpectedToken (TokenKind::pu_comma))
43
- break ;
44
- }
36
+ } while (tryConsumeExpectedToken (TokenKind::pu_comma));
45
37
46
38
if (consumeExpectedToken (TokenKind::end_of_stream,
47
39
diag::err_hlsl_unexpected_end_of_params,
@@ -51,147 +43,153 @@ bool RootSignatureParser::parse() {
51
43
return false ;
52
44
}
53
45
54
- bool RootSignatureParser::parseDescriptorTable () {
46
+ std::optional<DescriptorTable> RootSignatureParser::parseDescriptorTable () {
55
47
assert (CurToken.TokKind == TokenKind::kw_DescriptorTable &&
56
48
" Expects to only be invoked starting at given keyword" );
57
49
58
- DescriptorTable Table;
59
-
60
50
if (consumeExpectedToken (TokenKind::pu_l_paren, diag::err_expected_after,
61
51
CurToken.TokKind ))
62
- return true ;
52
+ return std::nullopt ;
63
53
64
- // Iterate as many Clauses as possible
65
- while (tryConsumeExpectedToken ({TokenKind::kw_CBV, TokenKind::kw_SRV,
66
- TokenKind::kw_UAV, TokenKind::kw_Sampler})) {
67
- if (parseDescriptorTableClause ())
68
- return true ;
69
-
70
- Table.NumClauses ++;
54
+ DescriptorTable Table;
71
55
72
- if (!tryConsumeExpectedToken (TokenKind::pu_comma))
73
- break ;
74
- }
56
+ // Iterate as many Clauses as possible
57
+ do {
58
+ if (tryConsumeExpectedToken ({TokenKind::kw_CBV, TokenKind::kw_SRV,
59
+ TokenKind::kw_UAV, TokenKind::kw_Sampler})) {
60
+ auto Clause = parseDescriptorTableClause ();
61
+ if (!Clause.has_value ())
62
+ return std::nullopt;
63
+ Elements.push_back (*Clause);
64
+ Table.NumClauses ++;
65
+ }
66
+ } while (tryConsumeExpectedToken (TokenKind::pu_comma));
75
67
76
68
if (consumeExpectedToken (TokenKind::pu_r_paren,
77
69
diag::err_hlsl_unexpected_end_of_params,
78
70
/* param of=*/ TokenKind::kw_DescriptorTable))
79
- return true ;
71
+ return std::nullopt ;
80
72
81
- Elements.push_back (Table);
82
- return false ;
73
+ return Table;
83
74
}
84
75
85
- bool RootSignatureParser::parseDescriptorTableClause () {
76
+ std::optional<DescriptorTableClause>
77
+ RootSignatureParser::parseDescriptorTableClause () {
86
78
assert ((CurToken.TokKind == TokenKind::kw_CBV ||
87
79
CurToken.TokKind == TokenKind::kw_SRV ||
88
80
CurToken.TokKind == TokenKind::kw_UAV ||
89
81
CurToken.TokKind == TokenKind::kw_Sampler) &&
90
82
" Expects to only be invoked starting at given keyword" );
91
- TokenKind ParamKind = CurToken.TokKind ; // retain for diagnostics
83
+
84
+ TokenKind ParamKind = CurToken.TokKind ;
85
+
86
+ if (consumeExpectedToken (TokenKind::pu_l_paren, diag::err_expected_after,
87
+ CurToken.TokKind ))
88
+ return std::nullopt;
92
89
93
90
DescriptorTableClause Clause;
94
- TokenKind ExpectedRegister ;
91
+ TokenKind ExpectedReg ;
95
92
switch (ParamKind) {
96
93
default :
97
94
llvm_unreachable (" Switch for consumed token was not provided" );
98
95
case TokenKind::kw_CBV:
99
96
Clause.Type = ClauseType::CBuffer;
100
- ExpectedRegister = TokenKind::bReg;
97
+ ExpectedReg = TokenKind::bReg;
101
98
break ;
102
99
case TokenKind::kw_SRV:
103
100
Clause.Type = ClauseType::SRV;
104
- ExpectedRegister = TokenKind::tReg;
101
+ ExpectedReg = TokenKind::tReg;
105
102
break ;
106
103
case TokenKind::kw_UAV:
107
104
Clause.Type = ClauseType::UAV;
108
- ExpectedRegister = TokenKind::uReg;
105
+ ExpectedReg = TokenKind::uReg;
109
106
break ;
110
107
case TokenKind::kw_Sampler:
111
108
Clause.Type = ClauseType::Sampler;
112
- ExpectedRegister = TokenKind::sReg ;
109
+ ExpectedReg = TokenKind::sReg ;
113
110
break ;
114
111
}
115
112
116
- if (consumeExpectedToken (TokenKind::pu_l_paren, diag::err_expected_after,
117
- ParamKind))
118
- return true ;
119
-
120
- ParsedParams Result;
121
- if (parseDescriptorTableClauseParams (Result, ExpectedRegister))
122
- return true ;
113
+ auto Params = parseDescriptorTableClauseParams (ExpectedReg);
114
+ if (!Params.has_value ())
115
+ return std::nullopt;
123
116
124
117
// Check mandatory parameters were provided
125
- if (!Result. Register .has_value ()) {
118
+ if (!Params-> Register .has_value ()) {
126
119
getDiags ().Report (CurToken.TokLoc , diag::err_hlsl_rootsig_missing_param)
127
- << ExpectedRegister ;
128
- return true ;
120
+ << ExpectedReg ;
121
+ return std::nullopt ;
129
122
}
130
123
131
- Clause.Register = *Result. Register ;
124
+ Clause.Register = Params-> Register . value () ;
132
125
133
- if (Result.Space )
134
- Clause.Space = *Result.Space ;
126
+ // Fill in optional values
127
+ if (Params->Space .has_value ())
128
+ Clause.Space = Params->Space .value ();
135
129
136
130
if (consumeExpectedToken (TokenKind::pu_r_paren,
137
131
diag::err_hlsl_unexpected_end_of_params,
138
132
/* param of=*/ ParamKind))
139
- return true ;
133
+ return std::nullopt ;
140
134
141
- Elements.push_back (Clause);
142
- return false ;
135
+ return Clause;
143
136
}
144
137
145
- bool RootSignatureParser::parseDescriptorTableClauseParams (ParsedParams &Params, TokenKind RegType) {
138
+ std::optional<RootSignatureParser::ParsedParams>
139
+ RootSignatureParser::parseDescriptorTableClauseParams (TokenKind RegType) {
146
140
assert (CurToken.TokKind == TokenKind::pu_l_paren &&
147
141
" Expects to only be invoked starting at given token" );
148
142
143
+ ParsedParams Params;
149
144
do {
150
145
if (tryConsumeExpectedToken (RegType)) {
151
146
if (Params.Register .has_value ()) {
152
147
getDiags ().Report (CurToken.TokLoc , diag::err_hlsl_rootsig_repeat_param)
153
- << CurToken.TokKind ;
154
- return true ;
148
+ << CurToken.TokKind ;
149
+ return std::nullopt ;
155
150
}
156
- Register Reg;
157
- if (parseRegister ( Reg))
158
- return true ;
151
+ auto Reg = parseRegister () ;
152
+ if (! Reg. has_value ( ))
153
+ return std::nullopt ;
159
154
Params.Register = Reg;
160
155
}
156
+
161
157
if (tryConsumeExpectedToken (TokenKind::kw_space)) {
162
158
if (Params.Space .has_value ()) {
163
159
getDiags ().Report (CurToken.TokLoc , diag::err_hlsl_rootsig_repeat_param)
164
- << CurToken.TokKind ;
165
- return true ;
160
+ << CurToken.TokKind ;
161
+ return std::nullopt ;
166
162
}
167
163
if (consumeExpectedToken (TokenKind::pu_equal))
168
- return true ;
169
- uint32_t Space;
170
- if (parseUIntParam ( Space))
171
- return true ;
164
+ return std::nullopt ;
165
+ auto Space = parseUIntParam () ;
166
+ if (! Space. has_value ( ))
167
+ return std::nullopt ;
172
168
Params.Space = Space;
173
169
}
174
170
} while (tryConsumeExpectedToken (TokenKind::pu_comma));
175
171
176
- return false ;
172
+ return Params ;
177
173
}
178
174
179
- bool RootSignatureParser::parseUIntParam (uint32_t &X ) {
175
+ std::optional< uint32_t > RootSignatureParser::parseUIntParam () {
180
176
assert (CurToken.TokKind == TokenKind::pu_equal &&
181
177
" Expects to only be invoked starting at given keyword" );
182
178
tryConsumeExpectedToken (TokenKind::pu_plus);
183
- return consumeExpectedToken (TokenKind::int_literal, diag::err_expected_after,
184
- CurToken.TokKind ) ||
185
- handleUIntLiteral (X);
179
+ if (consumeExpectedToken (TokenKind::int_literal, diag::err_expected_after,
180
+ CurToken.TokKind ))
181
+ return std::nullopt;
182
+ return handleUIntLiteral ();
186
183
}
187
184
188
- bool RootSignatureParser::parseRegister (Register &Register ) {
185
+ std::optional<Register> RootSignatureParser::parseRegister () {
189
186
assert ((CurToken.TokKind == TokenKind::bReg ||
190
187
CurToken.TokKind == TokenKind::tReg ||
191
188
CurToken.TokKind == TokenKind::uReg ||
192
189
CurToken.TokKind == TokenKind::sReg ) &&
193
190
" Expects to only be invoked starting at given keyword" );
194
191
192
+ Register Register;
195
193
switch (CurToken.TokKind ) {
196
194
default :
197
195
llvm_unreachable (" Switch for consumed token was not provided" );
@@ -209,13 +207,15 @@ bool RootSignatureParser::parseRegister(Register &Register) {
209
207
break ;
210
208
}
211
209
212
- if (handleUIntLiteral (Register.Number ))
213
- return true ; // propogate NumericLiteralParser error
210
+ auto Number = handleUIntLiteral ();
211
+ if (!Number.has_value ())
212
+ return std::nullopt; // propogate NumericLiteralParser error
214
213
215
- return false ;
214
+ Register.Number = *Number;
215
+ return Register;
216
216
}
217
217
218
- bool RootSignatureParser::handleUIntLiteral (uint32_t &X ) {
218
+ std::optional< uint32_t > RootSignatureParser::handleUIntLiteral () {
219
219
// Parse the numeric value and do semantic checks on its specification
220
220
clang::NumericLiteralParser Literal (CurToken.NumSpelling , CurToken.TokLoc ,
221
221
PP.getSourceManager (), PP.getLangOpts (),
@@ -231,11 +231,10 @@ bool RootSignatureParser::handleUIntLiteral(uint32_t &X) {
231
231
PP.getDiagnostics ().Report (CurToken.TokLoc ,
232
232
diag::err_hlsl_number_literal_overflow)
233
233
<< 0 << CurToken.NumSpelling ;
234
- return true ;
234
+ return std::nullopt ;
235
235
}
236
236
237
- X = Val.getExtValue ();
238
- return false ;
237
+ return Val.getExtValue ();
239
238
}
240
239
241
240
bool RootSignatureParser::peekExpectedToken (TokenKind Expected) {
0 commit comments