@@ -88,50 +88,52 @@ bool RootSignatureParser::parseDescriptorTableClause() {
88
88
CurToken.TokKind == TokenKind::kw_UAV ||
89
89
CurToken.TokKind == TokenKind::kw_Sampler) &&
90
90
" Expects to only be invoked starting at given keyword" );
91
- TokenKind ParamKind = CurToken.TokKind ; // retain for diagnostics
91
+
92
+ TokenKind ParamKind = CurToken.TokKind ;
93
+
94
+ if (consumeExpectedToken (TokenKind::pu_l_paren, diag::err_expected_after,
95
+ CurToken.TokKind ))
96
+ return true ;
92
97
93
98
DescriptorTableClause Clause;
94
- TokenKind ExpectedRegister ;
99
+ TokenKind ExpectedReg ;
95
100
switch (ParamKind) {
96
101
default :
97
102
llvm_unreachable (" Switch for consumed token was not provided" );
98
103
case TokenKind::kw_CBV:
99
104
Clause.Type = ClauseType::CBuffer;
100
- ExpectedRegister = TokenKind::bReg;
105
+ ExpectedReg = TokenKind::bReg;
101
106
break ;
102
107
case TokenKind::kw_SRV:
103
108
Clause.Type = ClauseType::SRV;
104
- ExpectedRegister = TokenKind::tReg;
109
+ ExpectedReg = TokenKind::tReg;
105
110
break ;
106
111
case TokenKind::kw_UAV:
107
112
Clause.Type = ClauseType::UAV;
108
- ExpectedRegister = TokenKind::uReg;
113
+ ExpectedReg = TokenKind::uReg;
109
114
break ;
110
115
case TokenKind::kw_Sampler:
111
116
Clause.Type = ClauseType::Sampler;
112
- ExpectedRegister = TokenKind::sReg ;
117
+ ExpectedReg = TokenKind::sReg ;
113
118
break ;
114
119
}
115
120
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))
121
+ auto Params = parseDescriptorTableClauseParams (ExpectedReg);
122
+ if (!Params.has_value ())
122
123
return true ;
123
124
124
125
// Check mandatory parameters were provided
125
- if (!Result. Register .has_value ()) {
126
+ if (!Params-> Register .has_value ()) {
126
127
getDiags ().Report (CurToken.TokLoc , diag::err_hlsl_rootsig_missing_param)
127
- << ExpectedRegister ;
128
+ << ExpectedReg ;
128
129
return true ;
129
130
}
130
131
131
- Clause.Register = *Result. Register ;
132
+ Clause.Register = Params-> Register . value () ;
132
133
133
- if (Result.Space )
134
- Clause.Space = *Result.Space ;
134
+ // Fill in optional values
135
+ if (Params->Space .has_value ())
136
+ Clause.Space = Params->Space .value ();
135
137
136
138
if (consumeExpectedToken (TokenKind::pu_r_paren,
137
139
diag::err_hlsl_unexpected_end_of_params,
@@ -142,56 +144,68 @@ bool RootSignatureParser::parseDescriptorTableClause() {
142
144
return false ;
143
145
}
144
146
145
- bool RootSignatureParser::parseDescriptorTableClauseParams (ParsedParams &Params, TokenKind RegType) {
147
+ std::optional<RootSignatureParser::ParsedClauseParams>
148
+ RootSignatureParser::parseDescriptorTableClauseParams (TokenKind RegType) {
146
149
assert (CurToken.TokKind == TokenKind::pu_l_paren &&
147
150
" Expects to only be invoked starting at given token" );
148
151
152
+ // Parameter arguments (eg. `bReg`, `space`, ...) can be specified in any
153
+ // order and only exactly once. Parse through as many arguments as possible
154
+ // reporting an error if a duplicate is seen.
155
+ ParsedClauseParams Params;
149
156
do {
157
+ // ( `b` | `t` | `u` | `s`) POS_INT
150
158
if (tryConsumeExpectedToken (RegType)) {
151
159
if (Params.Register .has_value ()) {
152
160
getDiags ().Report (CurToken.TokLoc , diag::err_hlsl_rootsig_repeat_param)
153
- << CurToken.TokKind ;
154
- return true ;
161
+ << CurToken.TokKind ;
162
+ return std::nullopt ;
155
163
}
156
- Register Reg;
157
- if (parseRegister ( Reg))
158
- return true ;
164
+ auto Reg = parseRegister () ;
165
+ if (! Reg. has_value ( ))
166
+ return std::nullopt ;
159
167
Params.Register = Reg;
160
168
}
169
+
170
+ // `space` `=` POS_INT
161
171
if (tryConsumeExpectedToken (TokenKind::kw_space)) {
162
172
if (Params.Space .has_value ()) {
163
173
getDiags ().Report (CurToken.TokLoc , diag::err_hlsl_rootsig_repeat_param)
164
- << CurToken.TokKind ;
165
- return true ;
174
+ << CurToken.TokKind ;
175
+ return std::nullopt ;
166
176
}
177
+
167
178
if (consumeExpectedToken (TokenKind::pu_equal))
168
- return true ;
169
- uint32_t Space;
170
- if (parseUIntParam (Space))
171
- return true ;
179
+ return std::nullopt;
180
+
181
+ auto Space = parseUIntParam ();
182
+ if (!Space.has_value ())
183
+ return std::nullopt;
172
184
Params.Space = Space;
173
185
}
174
186
} while (tryConsumeExpectedToken (TokenKind::pu_comma));
175
187
176
- return false ;
188
+ return Params ;
177
189
}
178
190
179
- bool RootSignatureParser::parseUIntParam (uint32_t &X ) {
191
+ std::optional< uint32_t > RootSignatureParser::parseUIntParam () {
180
192
assert (CurToken.TokKind == TokenKind::pu_equal &&
181
193
" Expects to only be invoked starting at given keyword" );
182
194
tryConsumeExpectedToken (TokenKind::pu_plus);
183
- return consumeExpectedToken (TokenKind::int_literal, diag::err_expected_after,
184
- CurToken.TokKind ) ||
185
- handleUIntLiteral (X);
195
+ if (consumeExpectedToken (TokenKind::int_literal, diag::err_expected_after,
196
+ CurToken.TokKind ))
197
+ return std::nullopt;
198
+ return handleUIntLiteral ();
186
199
}
187
200
188
- bool RootSignatureParser::parseRegister (Register &Register ) {
201
+ std::optional<Register> RootSignatureParser::parseRegister () {
189
202
assert ((CurToken.TokKind == TokenKind::bReg ||
190
203
CurToken.TokKind == TokenKind::tReg ||
191
204
CurToken.TokKind == TokenKind::uReg ||
192
205
CurToken.TokKind == TokenKind::sReg ) &&
193
206
" Expects to only be invoked starting at given keyword" );
194
207
208
+ Register Register;
195
209
switch (CurToken.TokKind ) {
196
210
default :
197
211
llvm_unreachable (" Switch for consumed token was not provided" );
@@ -209,13 +223,15 @@ bool RootSignatureParser::parseRegister(Register &Register) {
209
223
break ;
210
224
}
211
225
212
- if (handleUIntLiteral (Register.Number ))
213
- return true ; // propogate NumericLiteralParser error
226
+ auto Number = handleUIntLiteral ();
227
+ if (!Number.has_value ())
228
+ return std::nullopt; // propogate NumericLiteralParser error
214
229
215
- return false ;
230
+ Register.Number = *Number;
231
+ return Register;
216
232
}
217
233
218
- bool RootSignatureParser::handleUIntLiteral (uint32_t &X ) {
234
+ std::optional< uint32_t > RootSignatureParser::handleUIntLiteral () {
219
235
// Parse the numeric value and do semantic checks on its specification
220
236
clang::NumericLiteralParser Literal (CurToken.NumSpelling , CurToken.TokLoc ,
221
237
PP.getSourceManager (), PP.getLangOpts (),
@@ -231,11 +247,10 @@ bool RootSignatureParser::handleUIntLiteral(uint32_t &X) {
231
247
PP.getDiagnostics ().Report (CurToken.TokLoc ,
232
248
diag::err_hlsl_number_literal_overflow)
233
249
<< 0 << CurToken.NumSpelling ;
234
- return true ;
250
+ return std::nullopt ;
235
251
}
236
252
237
- X = Val.getExtValue ();
238
- return false ;
253
+ return Val.getExtValue ();
239
254
}
240
255
241
256
bool RootSignatureParser::peekExpectedToken (TokenKind Expected) {
0 commit comments