wsgl parser: expect for storage_class

All the call sites of `storage_class()` add their own error handling, so transform this into `expect_storage_class()`.

Also makes error messages more consistent.

Bug: tint:282
Change-Id: I5131acd84f91fc7494ed6b90965853b7d0fc37f0
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/32104
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
This commit is contained in:
Ben Clayton 2020-11-09 18:45:53 +00:00 committed by Commit Bot service account
parent b8df12042a
commit d60f0feee4
5 changed files with 36 additions and 46 deletions

View File

@ -773,13 +773,11 @@ ast::StorageClass ParserImpl::variable_storage_decoration() {
if (!match(Token::Type::kLessThan)) if (!match(Token::Type::kLessThan))
return ast::StorageClass::kNone; return ast::StorageClass::kNone;
auto sc = storage_class(); const char* use = "variable decoration";
auto sc = expect_storage_class(use);
if (has_error()) if (has_error())
return sc; return sc;
if (sc == ast::StorageClass::kNone) {
add_error(peek(), "invalid storage class for variable decoration");
return sc;
}
auto t = next(); auto t = next();
if (!t.IsGreaterThan()) { if (!t.IsGreaterThan()) {
@ -912,19 +910,17 @@ ast::type::Type* ParserImpl::type_decl() {
ast::type::Type* ParserImpl::expect_type_decl_pointer(Token t) { ast::type::Type* ParserImpl::expect_type_decl_pointer(Token t) {
next(); // Consume the peek next(); // Consume the peek
const char* use = "ptr declaration";
t = next(); t = next();
if (!t.IsLessThan()) { if (!t.IsLessThan()) {
add_error(t, "missing < for ptr declaration"); add_error(t, "missing < for ptr declaration");
return nullptr; return nullptr;
} }
auto sc = storage_class(); auto sc = expect_storage_class(use);
if (has_error()) if (has_error())
return nullptr; return nullptr;
if (sc == ast::StorageClass::kNone) {
add_error(peek(), "missing storage class for ptr declaration");
return nullptr;
}
t = next(); t = next();
if (!t.IsComma()) { if (!t.IsComma()) {
@ -1062,44 +1058,35 @@ ast::type::Type* ParserImpl::expect_type_decl_matrix(Token t) {
// | IMAGE // | IMAGE
// | PRIVATE // | PRIVATE
// | FUNCTION // | FUNCTION
ast::StorageClass ParserImpl::storage_class() { ast::StorageClass ParserImpl::expect_storage_class(const std::string& use) {
auto t = peek(); if (match(Token::Type::kIn))
if (t.IsIn()) {
next(); // consume the peek
return ast::StorageClass::kInput; return ast::StorageClass::kInput;
}
if (t.IsOut()) { if (match(Token::Type::kOut))
next(); // consume the peek
return ast::StorageClass::kOutput; return ast::StorageClass::kOutput;
}
if (t.IsUniform()) { if (match(Token::Type::kUniform))
next(); // consume the peek
return ast::StorageClass::kUniform; return ast::StorageClass::kUniform;
}
if (t.IsWorkgroup()) { if (match(Token::Type::kWorkgroup))
next(); // consume the peek
return ast::StorageClass::kWorkgroup; return ast::StorageClass::kWorkgroup;
}
if (t.IsUniformConstant()) { if (match(Token::Type::kUniformConstant))
next(); // consume the peek
return ast::StorageClass::kUniformConstant; return ast::StorageClass::kUniformConstant;
}
if (t.IsStorageBuffer()) { if (match(Token::Type::kStorageBuffer))
next(); // consume the peek
return ast::StorageClass::kStorageBuffer; return ast::StorageClass::kStorageBuffer;
}
if (t.IsImage()) { if (match(Token::Type::kImage))
next(); // consume the peek
return ast::StorageClass::kImage; return ast::StorageClass::kImage;
}
if (t.IsPrivate()) { if (match(Token::Type::kPrivate))
next(); // consume the peek
return ast::StorageClass::kPrivate; return ast::StorageClass::kPrivate;
}
if (t.IsFunction()) { if (match(Token::Type::kFunction))
next(); // consume the peek
return ast::StorageClass::kFunction; return ast::StorageClass::kFunction;
}
add_error(peek().source(), "invalid storage class", use);
return ast::StorageClass::kNone; return ast::StorageClass::kNone;
} }

View File

@ -184,8 +184,9 @@ class ParserImpl {
/// @returns the parsed Type or nullptr if none matched. /// @returns the parsed Type or nullptr if none matched.
ast::type::Type* type_decl(); ast::type::Type* type_decl();
/// Parses a `storage_class` grammar element /// Parses a `storage_class` grammar element
/// @param use a description of what was being parsed if an error was raised
/// @returns the storage class or StorageClass::kNone if none matched /// @returns the storage class or StorageClass::kNone if none matched
ast::StorageClass storage_class(); ast::StorageClass expect_storage_class(const std::string& use);
/// Parses a `struct_decl` grammar element with the initial /// Parses a `struct_decl` grammar element with the initial
/// `struct_decoration_decl*` provided as |decos|. /// `struct_decoration_decl*` provided as |decos|.
/// @returns the struct type or nullptr on error /// @returns the struct type or nullptr on error

View File

@ -1044,7 +1044,7 @@ TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingComma) {
TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingStorageClass) { TEST_F(ParserImplErrorTest, GlobalDeclVarPtrMissingStorageClass) {
EXPECT("var i : ptr<meow, u32>;", EXPECT("var i : ptr<meow, u32>;",
"test.wgsl:1:13 error: missing storage class for ptr declaration\n" "test.wgsl:1:13 error: invalid storage class for ptr declaration\n"
"var i : ptr<meow, u32>;\n" "var i : ptr<meow, u32>;\n"
" ^^^^\n"); " ^^^^\n");
} }

View File

@ -37,7 +37,7 @@ TEST_P(StorageClassTest, Parses) {
auto params = GetParam(); auto params = GetParam();
auto* p = parser(params.input); auto* p = parser(params.input);
auto sc = p->storage_class(); auto sc = p->expect_storage_class("test");
ASSERT_FALSE(p->has_error()); ASSERT_FALSE(p->has_error());
EXPECT_EQ(sc, params.result); EXPECT_EQ(sc, params.result);
@ -61,8 +61,10 @@ INSTANTIATE_TEST_SUITE_P(
TEST_F(ParserImplTest, StorageClass_NoMatch) { TEST_F(ParserImplTest, StorageClass_NoMatch) {
auto* p = parser("not-a-storage-class"); auto* p = parser("not-a-storage-class");
auto sc = p->storage_class(); auto sc = p->expect_storage_class("test");
ASSERT_EQ(sc, ast::StorageClass::kNone); ASSERT_EQ(sc, ast::StorageClass::kNone);
ASSERT_TRUE(p->has_error());
EXPECT_EQ(p->error(), "1:1: invalid storage class for test");
auto t = p->next(); auto t = p->next();
EXPECT_TRUE(t.IsIdentifier()); EXPECT_TRUE(t.IsIdentifier());

View File

@ -262,7 +262,7 @@ TEST_F(ParserImplTest, TypeDecl_Ptr_MissingStorageClass) {
auto* t = p->type_decl(); auto* t = p->type_decl();
ASSERT_EQ(t, nullptr); ASSERT_EQ(t, nullptr);
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:5: missing storage class for ptr declaration"); ASSERT_EQ(p->error(), "1:5: invalid storage class for ptr declaration");
} }
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingParams) { TEST_F(ParserImplTest, TypeDecl_Ptr_MissingParams) {
@ -270,7 +270,7 @@ TEST_F(ParserImplTest, TypeDecl_Ptr_MissingParams) {
auto* t = p->type_decl(); auto* t = p->type_decl();
ASSERT_EQ(t, nullptr); ASSERT_EQ(t, nullptr);
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:5: missing storage class for ptr declaration"); ASSERT_EQ(p->error(), "1:5: invalid storage class for ptr declaration");
} }
TEST_F(ParserImplTest, TypeDecl_Ptr_MissingType) { TEST_F(ParserImplTest, TypeDecl_Ptr_MissingType) {
@ -286,7 +286,7 @@ TEST_F(ParserImplTest, TypeDecl_Ptr_BadStorageClass) {
auto* t = p->type_decl(); auto* t = p->type_decl();
ASSERT_EQ(t, nullptr); ASSERT_EQ(t, nullptr);
ASSERT_TRUE(p->has_error()); ASSERT_TRUE(p->has_error());
ASSERT_EQ(p->error(), "1:5: missing storage class for ptr declaration"); ASSERT_EQ(p->error(), "1:5: invalid storage class for ptr declaration");
} }
TEST_F(ParserImplTest, TypeDecl_Ptr_BadType) { TEST_F(ParserImplTest, TypeDecl_Ptr_BadType) {