88
99#include " clang/Parse/ParseHLSLRootSignature.h"
1010
11- #include " clang/Lex/LiteralSupport.h"
12-
1311#include " llvm/Support/raw_ostream.h"
1412
1513using namespace llvm ::hlsl::rootsig;
@@ -43,11 +41,12 @@ bool RootSignatureParser::parse() {
4341 break ;
4442 }
4543
46- if (consumeExpectedToken (TokenKind::end_of_stream,
47- diag::err_hlsl_unexpected_end_of_params,
48- /* param of=*/ TokenKind::kw_RootSignature))
44+ if (!tryConsumeExpectedToken (TokenKind::end_of_stream)) {
45+ getDiags ().Report (CurToken.TokLoc , diag::err_hlsl_unexpected_end_of_params)
46+ << /* expected=*/ TokenKind::end_of_stream
47+ << /* param of=*/ TokenKind::kw_RootSignature;
4948 return true ;
50-
49+ }
5150 return false ;
5251}
5352
@@ -73,10 +72,12 @@ bool RootSignatureParser::parseDescriptorTable() {
7372 break ;
7473 }
7574
76- if (consumeExpectedToken (TokenKind::pu_r_paren,
77- diag::err_hlsl_unexpected_end_of_params,
78- /* param of=*/ TokenKind::kw_DescriptorTable))
75+ if (!tryConsumeExpectedToken (TokenKind::pu_r_paren)) {
76+ getDiags ().Report (CurToken.TokLoc , diag::err_hlsl_unexpected_end_of_params)
77+ << /* expected=*/ TokenKind::pu_r_paren
78+ << /* param of=*/ TokenKind::kw_DescriptorTable;
7979 return true ;
80+ }
8081
8182 Elements.push_back (Table);
8283 return false ;
@@ -89,170 +90,36 @@ bool RootSignatureParser::parseDescriptorTableClause() {
8990 CurToken.TokKind == TokenKind::kw_Sampler) &&
9091 " Expects to only be invoked starting at given keyword" );
9192
92- TokenKind ParamKind = CurToken.TokKind ;
93-
94- if (consumeExpectedToken (TokenKind::pu_l_paren, diag::err_expected_after,
95- CurToken.TokKind ))
96- return true ;
97-
9893 DescriptorTableClause Clause;
99- TokenKind ExpectedReg;
100- switch (ParamKind) {
94+ switch (CurToken.TokKind ) {
10195 default :
10296 llvm_unreachable (" Switch for consumed token was not provided" );
10397 case TokenKind::kw_CBV:
10498 Clause.Type = ClauseType::CBuffer;
105- ExpectedReg = TokenKind::bReg;
10699 break ;
107100 case TokenKind::kw_SRV:
108101 Clause.Type = ClauseType::SRV;
109- ExpectedReg = TokenKind::tReg;
110102 break ;
111103 case TokenKind::kw_UAV:
112104 Clause.Type = ClauseType::UAV;
113- ExpectedReg = TokenKind::uReg;
114105 break ;
115106 case TokenKind::kw_Sampler:
116107 Clause.Type = ClauseType::Sampler;
117- ExpectedReg = TokenKind::sReg ;
118108 break ;
119109 }
120110
121- auto Params = parseDescriptorTableClauseParams (ExpectedReg);
122- if (!Params.has_value ())
123- return true ;
124-
125- // Check mandatory parameters were provided
126- if (!Params->Register .has_value ()) {
127- getDiags ().Report (CurToken.TokLoc , diag::err_hlsl_rootsig_missing_param)
128- << ExpectedReg;
111+ if (consumeExpectedToken (TokenKind::pu_l_paren, diag::err_expected_after,
112+ CurToken.TokKind ))
129113 return true ;
130- }
131-
132- Clause.Register = Params->Register .value ();
133-
134- // Fill in optional values
135- if (Params->Space .has_value ())
136- Clause.Space = Params->Space .value ();
137114
138- if (consumeExpectedToken (TokenKind::pu_r_paren,
139- diag::err_hlsl_unexpected_end_of_params,
140- /* param of=*/ ParamKind))
115+ if (consumeExpectedToken (TokenKind::pu_r_paren, diag::err_expected_after,
116+ CurToken.TokKind ))
141117 return true ;
142118
143119 Elements.push_back (Clause);
144120 return false ;
145121}
146122
147- std::optional<RootSignatureParser::ParsedClauseParams>
148- RootSignatureParser::parseDescriptorTableClauseParams (TokenKind RegType) {
149- assert (CurToken.TokKind == TokenKind::pu_l_paren &&
150- " Expects to only be invoked starting at given token" );
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;
156- do {
157- // ( `b` | `t` | `u` | `s`) POS_INT
158- if (tryConsumeExpectedToken (RegType)) {
159- if (Params.Register .has_value ()) {
160- getDiags ().Report (CurToken.TokLoc , diag::err_hlsl_rootsig_repeat_param)
161- << CurToken.TokKind ;
162- return std::nullopt ;
163- }
164- auto Reg = parseRegister ();
165- if (!Reg.has_value ())
166- return std::nullopt ;
167- Params.Register = Reg;
168- }
169-
170- // `space` `=` POS_INT
171- if (tryConsumeExpectedToken (TokenKind::kw_space)) {
172- if (Params.Space .has_value ()) {
173- getDiags ().Report (CurToken.TokLoc , diag::err_hlsl_rootsig_repeat_param)
174- << CurToken.TokKind ;
175- return std::nullopt ;
176- }
177-
178- if (consumeExpectedToken (TokenKind::pu_equal))
179- return std::nullopt ;
180-
181- auto Space = parseUIntParam ();
182- if (!Space.has_value ())
183- return std::nullopt ;
184- Params.Space = Space;
185- }
186- } while (tryConsumeExpectedToken (TokenKind::pu_comma));
187-
188- return Params;
189- }
190-
191- std::optional<uint32_t > RootSignatureParser::parseUIntParam () {
192- assert (CurToken.TokKind == TokenKind::pu_equal &&
193- " Expects to only be invoked starting at given keyword" );
194- tryConsumeExpectedToken (TokenKind::pu_plus);
195- if (consumeExpectedToken (TokenKind::int_literal, diag::err_expected_after,
196- CurToken.TokKind ))
197- return std::nullopt ;
198- return handleUIntLiteral ();
199- }
200-
201- std::optional<Register> RootSignatureParser::parseRegister () {
202- assert ((CurToken.TokKind == TokenKind::bReg ||
203- CurToken.TokKind == TokenKind::tReg ||
204- CurToken.TokKind == TokenKind::uReg ||
205- CurToken.TokKind == TokenKind::sReg ) &&
206- " Expects to only be invoked starting at given keyword" );
207-
208- Register Register;
209- switch (CurToken.TokKind ) {
210- default :
211- llvm_unreachable (" Switch for consumed token was not provided" );
212- case TokenKind::bReg:
213- Register.ViewType = RegisterType::BReg;
214- break ;
215- case TokenKind::tReg:
216- Register.ViewType = RegisterType::TReg;
217- break ;
218- case TokenKind::uReg:
219- Register.ViewType = RegisterType::UReg;
220- break ;
221- case TokenKind::sReg :
222- Register.ViewType = RegisterType::SReg;
223- break ;
224- }
225-
226- auto Number = handleUIntLiteral ();
227- if (!Number.has_value ())
228- return std::nullopt ; // propogate NumericLiteralParser error
229-
230- Register.Number = *Number;
231- return Register;
232- }
233-
234- std::optional<uint32_t > RootSignatureParser::handleUIntLiteral () {
235- // Parse the numeric value and do semantic checks on its specification
236- clang::NumericLiteralParser Literal (CurToken.NumSpelling , CurToken.TokLoc ,
237- PP.getSourceManager (), PP.getLangOpts (),
238- PP.getTargetInfo (), PP.getDiagnostics ());
239- if (Literal.hadError )
240- return true ; // Error has already been reported so just return
241-
242- assert (Literal.isIntegerLiteral () && " IsNumberChar will only support digits" );
243-
244- llvm::APSInt Val = llvm::APSInt (32 , false );
245- if (Literal.GetIntegerValue (Val)) {
246- // Report that the value has overflowed
247- PP.getDiagnostics ().Report (CurToken.TokLoc ,
248- diag::err_hlsl_number_literal_overflow)
249- << 0 << CurToken.NumSpelling ;
250- return std::nullopt ;
251- }
252-
253- return Val.getExtValue ();
254- }
255-
256123bool RootSignatureParser::peekExpectedToken (TokenKind Expected) {
257124 return peekExpectedToken (ArrayRef{Expected});
258125}
@@ -274,7 +141,6 @@ bool RootSignatureParser::consumeExpectedToken(TokenKind Expected,
274141 case diag::err_expected:
275142 DB << Expected;
276143 break ;
277- case diag::err_hlsl_unexpected_end_of_params:
278144 case diag::err_expected_either:
279145 case diag::err_expected_after:
280146 DB << Expected << Context;
0 commit comments