Skip to content

Commit 519e4d8

Browse files
committed
improve diagnostics for descriptor table
1 parent ca854e2 commit 519e4d8

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

clang/lib/Parse/ParseHLSLRootSignature.cpp

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -247,17 +247,19 @@ std::optional<DescriptorTable> RootSignatureParser::parseDescriptorTable() {
247247
DescriptorTable Table;
248248
std::optional<llvm::dxbc::ShaderVisibility> Visibility;
249249

250-
// Iterate as many Clauses as possible
251-
do {
250+
// Iterate as many Clauses as possible, until we hit ')'
251+
while (!peekExpectedToken(TokenKind::pu_r_paren)) {
252252
if (tryConsumeExpectedToken({TokenKind::kw_CBV, TokenKind::kw_SRV,
253253
TokenKind::kw_UAV, TokenKind::kw_Sampler})) {
254+
// DescriptorTableClause - CBV, SRV, UAV, or Sampler
254255
SourceLocation ElementLoc = getTokenLocation(CurToken);
255256
auto Clause = parseDescriptorTableClause();
256257
if (!Clause.has_value())
257258
return std::nullopt;
258259
Elements.push_back(RootSignatureElement(ElementLoc, *Clause));
259260
Table.NumClauses++;
260261
} else if (tryConsumeExpectedToken(TokenKind::kw_visibility)) {
262+
// visibility = SHADER_VISIBILITY
261263
if (Visibility.has_value()) {
262264
reportDiag(diag::err_hlsl_rootsig_repeat_param) << CurToken.TokKind;
263265
return std::nullopt;
@@ -269,16 +271,25 @@ std::optional<DescriptorTable> RootSignatureParser::parseDescriptorTable() {
269271
Visibility = parseShaderVisibility();
270272
if (!Visibility.has_value())
271273
return std::nullopt;
274+
} else {
275+
consumeNextToken(); // position to start of invalid token
276+
reportDiag(diag::err_hlsl_rootsig_invalid_param)
277+
<< /*param of=*/TokenKind::kw_DescriptorTable;
278+
return std::nullopt;
272279
}
273-
} while (tryConsumeExpectedToken(TokenKind::pu_comma));
274280

275-
// Fill in optional visibility
276-
if (Visibility.has_value())
277-
Table.Visibility = Visibility.value();
281+
// ',' denotes another element, otherwise, expected to be at ')'
282+
if (!tryConsumeExpectedToken(TokenKind::pu_comma))
283+
break;
284+
}
278285

279286
if (consumeExpectedToken(TokenKind::pu_r_paren))
280287
return std::nullopt;
281288

289+
// Fill in optional visibility
290+
if (Visibility.has_value())
291+
Table.Visibility = Visibility.value();
292+
282293
return Table;
283294
}
284295

clang/unittests/Parse/ParseHLSLRootSignatureTest.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,4 +1264,31 @@ TEST_F(ParseHLSLRootSignatureTest, InvalidRootElementMissingCommaTest) {
12641264
ASSERT_TRUE(Consumer->isSatisfied());
12651265
}
12661266

1267+
TEST_F(ParseHLSLRootSignatureTest, InvalidDescriptorTableMissingCommaTest) {
1268+
// This test will check that an error is produced when there is a missing
1269+
// comma between parameters
1270+
const llvm::StringLiteral Source = R"cc(
1271+
DescriptorTable(
1272+
CBV(b0)
1273+
visibility = SHADER_VISIBILITY_ALL
1274+
)
1275+
)cc";
1276+
1277+
auto Ctx = createMinimalASTContext();
1278+
StringLiteral *Signature = wrapSource(Ctx, Source);
1279+
1280+
TrivialModuleLoader ModLoader;
1281+
auto PP = createPP(Source, ModLoader);
1282+
1283+
SmallVector<RootSignatureElement> Elements;
1284+
hlsl::RootSignatureParser Parser(RootSignatureVersion::V1_1, Elements,
1285+
Signature, *PP);
1286+
1287+
// Test correct diagnostic produced
1288+
Consumer->setExpected(diag::err_expected);
1289+
ASSERT_TRUE(Parser.parse());
1290+
1291+
ASSERT_TRUE(Consumer->isSatisfied());
1292+
}
1293+
12671294
} // anonymous namespace

0 commit comments

Comments
 (0)