@@ -57,6 +57,27 @@ std::optional<RootConstants> RootSignatureParser::parseRootConstants() {
5757
5858 RootConstants Constants;
5959
60+ auto Params = parseRootConstantParams ();
61+ if (!Params.has_value ())
62+ return std::nullopt ;
63+
64+ // Check mandatory parameters were provided
65+ if (!Params->Num32BitConstants .has_value ()) {
66+ getDiags ().Report (CurToken.TokLoc , diag::err_hlsl_rootsig_missing_param)
67+ << TokenKind::kw_num32BitConstants;
68+ return std::nullopt ;
69+ }
70+
71+ Constants.Num32BitConstants = Params->Num32BitConstants .value ();
72+
73+ if (!Params->Reg .has_value ()) {
74+ getDiags ().Report (CurToken.TokLoc , diag::err_hlsl_rootsig_missing_param)
75+ << TokenKind::bReg;
76+ return std::nullopt ;
77+ }
78+
79+ Constants.Reg = Params->Reg .value ();
80+
6081 if (consumeExpectedToken (TokenKind::pu_r_paren,
6182 diag::err_hlsl_unexpected_end_of_params,
6283 /* param of=*/ TokenKind::kw_RootConstants))
@@ -187,14 +208,55 @@ RootSignatureParser::parseDescriptorTableClause() {
187208 return Clause;
188209}
189210
211+ // Parameter arguments (eg. `bReg`, `space`, ...) can be specified in any
212+ // order and only exactly once. The following methods will parse through as
213+ // many arguments as possible reporting an error if a duplicate is seen.
214+ std::optional<RootSignatureParser::ParsedConstantParams>
215+ RootSignatureParser::parseRootConstantParams () {
216+ assert (CurToken.TokKind == TokenKind::pu_l_paren &&
217+ " Expects to only be invoked starting at given token" );
218+
219+ ParsedConstantParams Params;
220+ do {
221+ // `num32BitConstants` `=` POS_INT
222+ if (tryConsumeExpectedToken (TokenKind::kw_num32BitConstants)) {
223+ if (Params.Num32BitConstants .has_value ()) {
224+ getDiags ().Report (CurToken.TokLoc , diag::err_hlsl_rootsig_repeat_param)
225+ << CurToken.TokKind ;
226+ return std::nullopt ;
227+ }
228+
229+ if (consumeExpectedToken (TokenKind::pu_equal))
230+ return std::nullopt ;
231+
232+ auto Num32BitConstants = parseUIntParam ();
233+ if (!Num32BitConstants.has_value ())
234+ return std::nullopt ;
235+ Params.Num32BitConstants = Num32BitConstants;
236+ }
237+
238+ // `b` POS_INT
239+ if (tryConsumeExpectedToken (TokenKind::bReg)) {
240+ if (Params.Reg .has_value ()) {
241+ getDiags ().Report (CurToken.TokLoc , diag::err_hlsl_rootsig_repeat_param)
242+ << CurToken.TokKind ;
243+ return std::nullopt ;
244+ }
245+ auto Reg = parseRegister ();
246+ if (!Reg.has_value ())
247+ return std::nullopt ;
248+ Params.Reg = Reg;
249+ }
250+ } while (tryConsumeExpectedToken (TokenKind::pu_comma));
251+
252+ return Params;
253+ }
254+
190255std::optional<RootSignatureParser::ParsedClauseParams>
191256RootSignatureParser::parseDescriptorTableClauseParams (TokenKind RegType) {
192257 assert (CurToken.TokKind == TokenKind::pu_l_paren &&
193258 " Expects to only be invoked starting at given token" );
194259
195- // Parameter arguments (eg. `bReg`, `space`, ...) can be specified in any
196- // order and only exactly once. Parse through as many arguments as possible
197- // reporting an error if a duplicate is seen.
198260 ParsedClauseParams Params;
199261 do {
200262 // ( `b` | `t` | `u` | `s`) POS_INT
0 commit comments