8
8
9
9
#include " clang/Parse/ParseHLSLRootSignature.h"
10
10
11
- #include " clang/Lex/LiteralSupport.h"
12
-
13
11
#include " llvm/Support/raw_ostream.h"
14
12
15
13
using namespace llvm ::hlsl::rootsig;
@@ -43,11 +41,12 @@ bool RootSignatureParser::parse() {
43
41
break ;
44
42
}
45
43
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;
49
48
return true ;
50
-
49
+ }
51
50
return false ;
52
51
}
53
52
@@ -73,10 +72,12 @@ bool RootSignatureParser::parseDescriptorTable() {
73
72
break ;
74
73
}
75
74
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;
79
79
return true ;
80
+ }
80
81
81
82
Elements.push_back (Table);
82
83
return false ;
@@ -89,170 +90,36 @@ bool RootSignatureParser::parseDescriptorTableClause() {
89
90
CurToken.TokKind == TokenKind::kw_Sampler) &&
90
91
" Expects to only be invoked starting at given keyword" );
91
92
92
- TokenKind ParamKind = CurToken.TokKind ;
93
-
94
- if (consumeExpectedToken (TokenKind::pu_l_paren, diag::err_expected_after,
95
- CurToken.TokKind ))
96
- return true ;
97
-
98
93
DescriptorTableClause Clause;
99
- TokenKind ExpectedReg;
100
- switch (ParamKind) {
94
+ switch (CurToken.TokKind ) {
101
95
default :
102
96
llvm_unreachable (" Switch for consumed token was not provided" );
103
97
case TokenKind::kw_CBV:
104
98
Clause.Type = ClauseType::CBuffer;
105
- ExpectedReg = TokenKind::bReg;
106
99
break ;
107
100
case TokenKind::kw_SRV:
108
101
Clause.Type = ClauseType::SRV;
109
- ExpectedReg = TokenKind::tReg;
110
102
break ;
111
103
case TokenKind::kw_UAV:
112
104
Clause.Type = ClauseType::UAV;
113
- ExpectedReg = TokenKind::uReg;
114
105
break ;
115
106
case TokenKind::kw_Sampler:
116
107
Clause.Type = ClauseType::Sampler;
117
- ExpectedReg = TokenKind::sReg ;
118
108
break ;
119
109
}
120
110
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 ))
129
113
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 ();
137
114
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 ))
141
117
return true ;
142
118
143
119
Elements.push_back (Clause);
144
120
return false ;
145
121
}
146
122
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
-
256
123
bool RootSignatureParser::peekExpectedToken (TokenKind Expected) {
257
124
return peekExpectedToken (ArrayRef{Expected});
258
125
}
@@ -274,7 +141,6 @@ bool RootSignatureParser::consumeExpectedToken(TokenKind Expected,
274
141
case diag::err_expected:
275
142
DB << Expected;
276
143
break ;
277
- case diag::err_hlsl_unexpected_end_of_params:
278
144
case diag::err_expected_either:
279
145
case diag::err_expected_after:
280
146
DB << Expected << Context;
0 commit comments