Skip to content

Commit 421ed96

Browse files
committed
add diag context when incorrectly given value to parameter
1 parent 86036e1 commit 421ed96

File tree

3 files changed

+34
-29
lines changed

3 files changed

+34
-29
lines changed

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1820,6 +1820,7 @@ def err_hlsl_packoffset_invalid_reg : Error<"invalid resource class specifier '%
18201820

18211821
// HLSL Root Signature Parser Diagnostics
18221822
def err_hlsl_expected_param : Error<"expected parameter in %1(%0)">;
1823+
def err_hlsl_expected_value : Error<"expected value for %1 = %0">;
18231824
def err_hlsl_number_literal_overflow : Error<"integer literal is too large to be represented as a 32-bit %select{signed |}0 integer type">;
18241825
def err_hlsl_rootsig_repeat_param : Error<"specified the same parameter '%0' multiple times">;
18251826
def err_hlsl_rootsig_non_zero_flag : Error<"specified a non-zero integer as a flag">;

clang/include/clang/Parse/ParseHLSLRootSignature.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,19 +62,19 @@ class RootSignatureParser {
6262
/// Each unique ParamType is expected to define a custom Parse method. This
6363
/// function will switch on the ParamType using std::visit and dispatch onto
6464
/// the corresponding Parse method
65-
bool ParseParam(llvm::hlsl::rootsig::ParamType Ref);
65+
bool ParseParam(llvm::hlsl::rootsig::ParamType Ref, TokenKind Context);
6666

6767
/// Parses as many optional parameters as possible in any order
6868
bool ParseOptionalParams(
69-
llvm::SmallDenseMap<TokenKind, llvm::hlsl::rootsig::ParamType> &RefMap);
69+
llvm::SmallDenseMap<TokenKind, llvm::hlsl::rootsig::ParamType> &RefMap, TokenKind Context);
7070

7171
/// Use NumericLiteralParser to convert CurToken.NumSpelling into a unsigned
7272
/// 32-bit integer
7373
bool HandleUIntLiteral(uint32_t &X);
74-
bool ParseUInt(uint32_t *X);
7574
bool ParseRegister(llvm::hlsl::rootsig::Register *Reg, TokenKind Context);
75+
bool ParseUInt(uint32_t *X, TokenKind Context);
7676
bool
77-
ParseDescriptorRangeOffset(llvm::hlsl::rootsig::DescriptorRangeOffset *X);
77+
ParseDescriptorRangeOffset(llvm::hlsl::rootsig::DescriptorRangeOffset *X, TokenKind Context);
7878

7979
/// Method for parsing any type of the ENUM defined token kinds (from
8080
/// HLSLRootSignatureTokenKinds.def)
@@ -86,22 +86,22 @@ class RootSignatureParser {
8686
/// the value of '0' to denote no flag
8787
template <bool AllowZero = false, typename EnumType>
8888
bool ParseEnum(llvm::SmallDenseMap<TokenKind, EnumType> &EnumMap,
89-
EnumType *Enum);
89+
EnumType *Enum, TokenKind Context);
9090

9191
/// Helper methods that define the mappings and invoke ParseEnum for
9292
/// different enum types
93-
bool ParseShaderVisibility(llvm::hlsl::rootsig::ShaderVisibility *Enum);
93+
bool ParseShaderVisibility(llvm::hlsl::rootsig::ShaderVisibility *Enum, TokenKind Context);
9494

9595
/// A wrapper method around ParseEnum that will parse an 'or' chain of
9696
/// enums, with AllowZero = true
9797
template <typename FlagType>
9898
bool ParseFlags(llvm::SmallDenseMap<TokenKind, FlagType> &EnumMap,
99-
FlagType *Enum);
99+
FlagType *Enum, TokenKind Context);
100100

101101
/// Helper methods that define the mappings and invoke ParseFlags for
102102
/// different enum types
103103
bool
104-
ParseDescriptorRangeFlags(llvm::hlsl::rootsig::DescriptorRangeFlags *Enum);
104+
ParseDescriptorRangeFlags(llvm::hlsl::rootsig::DescriptorRangeFlags *Enum, TokenKind Context);
105105

106106
/// Invoke the Lexer to consume a token and update CurToken with the result
107107
void ConsumeNextToken() { CurToken = Lexer.ConsumeToken(); }

clang/lib/Parse/ParseHLSLRootSignature.cpp

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ bool RootSignatureParser::ParseDescriptorTable() {
9797
return true;
9898
}
9999
SeenVisibility = true;
100-
if (ParseParam(&Table.Visibility))
100+
if (ParseParam(&Table.Visibility, TokenKind::kw_visibility))
101101
return true;
102102
continue;
103103
}
@@ -158,7 +158,7 @@ bool RootSignatureParser::ParseDescriptorTableClause() {
158158
{TokenKind::kw_offset, &Clause.Offset},
159159
{TokenKind::kw_flags, &Clause.Flags},
160160
};
161-
if (ParseOptionalParams({RefMap}))
161+
if (ParseOptionalParams({RefMap}, Context))
162162
return true;
163163

164164
if (ConsumeExpectedToken(TokenKind::pu_r_paren, diag::err_expected_after, CurToken.Kind))
@@ -172,20 +172,20 @@ bool RootSignatureParser::ParseDescriptorTableClause() {
172172
template <class... Ts> struct ParseMethods : Ts... { using Ts::operator()...; };
173173
template <class... Ts> ParseMethods(Ts...) -> ParseMethods<Ts...>;
174174

175-
bool RootSignatureParser::ParseParam(ParamType Ref) {
175+
bool RootSignatureParser::ParseParam(ParamType Ref, TokenKind Context) {
176176
if (ConsumeExpectedToken(TokenKind::pu_equal, diag::err_expected_after, CurToken.Kind))
177177
return true;
178178

179179
bool Error;
180180
std::visit(
181181
ParseMethods{
182-
[&](uint32_t *X) { Error = ParseUInt(X); },
182+
[&](uint32_t *X) { Error = ParseUInt(X, Context); },
183183
[&](DescriptorRangeOffset *X) {
184-
Error = ParseDescriptorRangeOffset(X);
184+
Error = ParseDescriptorRangeOffset(X, Context);
185185
},
186-
[&](ShaderVisibility *Enum) { Error = ParseShaderVisibility(Enum); },
186+
[&](ShaderVisibility *Enum) { Error = ParseShaderVisibility(Enum, Context); },
187187
[&](DescriptorRangeFlags *Flags) {
188-
Error = ParseDescriptorRangeFlags(Flags);
188+
Error = ParseDescriptorRangeFlags(Flags, Context);
189189
},
190190
},
191191
Ref);
@@ -194,7 +194,7 @@ bool RootSignatureParser::ParseParam(ParamType Ref) {
194194
}
195195

196196
bool RootSignatureParser::ParseOptionalParams(
197-
llvm::SmallDenseMap<TokenKind, ParamType> &RefMap) {
197+
llvm::SmallDenseMap<TokenKind, ParamType> &RefMap, TokenKind Context) {
198198
SmallVector<TokenKind> ParamKeywords;
199199
for (auto RefPair : RefMap)
200200
ParamKeywords.push_back(RefPair.first);
@@ -214,7 +214,7 @@ bool RootSignatureParser::ParseOptionalParams(
214214
}
215215
Seen.insert(ParamKind);
216216

217-
if (ParseParam(RefMap[ParamKind]))
217+
if (ParseParam(RefMap[ParamKind], ParamKind))
218218
return true;
219219
}
220220

@@ -274,10 +274,10 @@ bool RootSignatureParser::ParseRegister(Register *Register, TokenKind Context) {
274274
return false;
275275
}
276276

277-
bool RootSignatureParser::ParseUInt(uint32_t *X) {
277+
bool RootSignatureParser::ParseUInt(uint32_t *X, TokenKind Context) {
278278
// Treat a postively signed integer as though it is unsigned to match DXC
279279
TryConsumeExpectedToken(TokenKind::pu_plus);
280-
if (ConsumeExpectedToken(TokenKind::int_literal))
280+
if (ConsumeExpectedToken(TokenKind::int_literal, diag::err_hlsl_expected_value, Context))
281281
return true;
282282

283283
if (HandleUIntLiteral(*X))
@@ -286,9 +286,12 @@ bool RootSignatureParser::ParseUInt(uint32_t *X) {
286286
return false;
287287
}
288288

289-
bool RootSignatureParser::ParseDescriptorRangeOffset(DescriptorRangeOffset *X) {
289+
bool RootSignatureParser::ParseDescriptorRangeOffset(DescriptorRangeOffset *X, TokenKind Context) {
290290
if (ConsumeExpectedToken(
291-
{TokenKind::int_literal, TokenKind::en_DescriptorRangeOffsetAppend}))
291+
{TokenKind::int_literal, TokenKind::en_DescriptorRangeOffsetAppend},
292+
diag::err_hlsl_expected_value,
293+
Context
294+
))
292295
return true;
293296

294297
// Edge case for the offset enum -> static value
@@ -306,15 +309,15 @@ bool RootSignatureParser::ParseDescriptorRangeOffset(DescriptorRangeOffset *X) {
306309

307310
template <bool AllowZero, typename EnumType>
308311
bool RootSignatureParser::ParseEnum(
309-
llvm::SmallDenseMap<TokenKind, EnumType> &EnumMap, EnumType *Enum) {
312+
llvm::SmallDenseMap<TokenKind, EnumType> &EnumMap, EnumType *Enum, TokenKind Context) {
310313
SmallVector<TokenKind> EnumToks;
311314
if (AllowZero)
312315
EnumToks.push_back(TokenKind::int_literal); // '0' is a valid flag value
313316
for (auto EnumPair : EnumMap)
314317
EnumToks.push_back(EnumPair.first);
315318

316319
// If invoked we expect to have an enum
317-
if (ConsumeExpectedToken(EnumToks))
320+
if (ConsumeExpectedToken(EnumToks, diag::err_hlsl_expected_value, Context))
318321
return true;
319322

320323
// Handle the edge case when '0' is used to specify None
@@ -341,26 +344,26 @@ bool RootSignatureParser::ParseEnum(
341344
llvm_unreachable("Switch for an expected token was not provided");
342345
}
343346

344-
bool RootSignatureParser::ParseShaderVisibility(ShaderVisibility *Enum) {
347+
bool RootSignatureParser::ParseShaderVisibility(ShaderVisibility *Enum, TokenKind Context) {
345348
// Define the possible flag kinds
346349
llvm::SmallDenseMap<TokenKind, ShaderVisibility> EnumMap = {
347350
#define SHADER_VISIBILITY_ENUM(NAME, LIT) \
348351
{TokenKind::en_##NAME, ShaderVisibility::NAME},
349352
#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
350353
};
351354

352-
return ParseEnum(EnumMap, Enum);
355+
return ParseEnum(EnumMap, Enum, Context);
353356
}
354357

355358
template <typename FlagType>
356359
bool RootSignatureParser::ParseFlags(
357-
llvm::SmallDenseMap<TokenKind, FlagType> &FlagMap, FlagType *Flags) {
360+
llvm::SmallDenseMap<TokenKind, FlagType> &FlagMap, FlagType *Flags, TokenKind Context) {
358361
// Override the default value to 0 so that we can correctly 'or' the values
359362
*Flags = FlagType(0);
360363

361364
do {
362365
FlagType Flag;
363-
if (ParseEnum<true>(FlagMap, &Flag))
366+
if (ParseEnum<true>(FlagMap, &Flag, Context))
364367
return true;
365368
// Store the 'or'
366369
*Flags |= Flag;
@@ -370,15 +373,15 @@ bool RootSignatureParser::ParseFlags(
370373
}
371374

372375
bool RootSignatureParser::ParseDescriptorRangeFlags(
373-
DescriptorRangeFlags *Flags) {
376+
DescriptorRangeFlags *Flags, TokenKind Context) {
374377
// Define the possible flag kinds
375378
llvm::SmallDenseMap<TokenKind, DescriptorRangeFlags> FlagMap = {
376379
#define DESCRIPTOR_RANGE_FLAG_ENUM(NAME, LIT, ON) \
377380
{TokenKind::en_##NAME, DescriptorRangeFlags::NAME},
378381
#include "clang/Lex/HLSLRootSignatureTokenKinds.def"
379382
};
380383

381-
return ParseFlags(FlagMap, Flags);
384+
return ParseFlags(FlagMap, Flags, Context);
382385
}
383386

384387
// Is given token one of the expected kinds
@@ -419,6 +422,7 @@ bool RootSignatureParser::ConsumeExpectedToken(ArrayRef<TokenKind> AnyExpected,
419422
case diag::err_expected_either:
420423
case diag::err_expected_after:
421424
case diag::err_hlsl_expected_param:
425+
case diag::err_hlsl_expected_value:
422426
DB << FormatTokenKinds(AnyExpected) << FormatTokenKinds({Context});
423427
break;
424428
default: break;

0 commit comments

Comments
 (0)