ast: Have all decorations derive from base class

This is the first step in unifying the way decorations are parsed - i.e. instead of parsing decorations in different ways based on the predicted grammar that follows, we can parse decorations blocks in a unified way, then later verify what we have is as expected.

`StructDecoration` has been transformed from an `enum class` to a proper class so it can derive from `Decoration`.

Bug: tint:282
Bug: tint:291
Change-Id: Iaf12d266068d03edf695acdf2cd21e6cc3ea8eb3
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/31663
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
Ben Clayton
2020-11-03 21:40:20 +00:00
committed by Commit Bot service account
parent 4735f01193
commit 35298800a6
34 changed files with 386 additions and 88 deletions

View File

@@ -48,6 +48,7 @@
#include "src/ast/sint_literal.h"
#include "src/ast/stride_decoration.h"
#include "src/ast/struct.h"
#include "src/ast/struct_block_decoration.h"
#include "src/ast/struct_decoration.h"
#include "src/ast/struct_member.h"
#include "src/ast/struct_member_decoration.h"
@@ -802,9 +803,11 @@ ast::type::Type* ParserImpl::ConvertType(
if (struct_decorations.size() == 1) {
const auto decoration = struct_decorations[0][0];
if (decoration == SpvDecorationBlock) {
ast_struct_decorations.push_back(ast::StructDecoration::kBlock);
ast_struct_decorations.push_back(
std::make_unique<ast::StructBlockDecoration>());
} else if (decoration == SpvDecorationBufferBlock) {
ast_struct_decorations.push_back(ast::StructDecoration::kBlock);
ast_struct_decorations.push_back(
std::make_unique<ast::StructBlockDecoration>());
remap_buffer_block_type_.insert(type_id);
} else {
Fail() << "struct with ID " << type_id

View File

@@ -42,6 +42,7 @@
#include "src/ast/sint_literal.h"
#include "src/ast/stage_decoration.h"
#include "src/ast/stride_decoration.h"
#include "src/ast/struct_block_decoration.h"
#include "src/ast/struct_member_offset_decoration.h"
#include "src/ast/switch_statement.h"
#include "src/ast/type/alias_type.h"
@@ -1524,10 +1525,10 @@ bool ParserImpl::struct_decoration_decl(ast::StructDecorationList& decos) {
if (has_error()) {
return false;
}
if (deco == ast::StructDecoration::kNone) {
if (deco == nullptr) {
return true;
}
decos.push_back(deco);
decos.emplace_back(std::move(deco));
next(); // Consume the peek of [[
next(); // Consume the peek from the struct_decoration
@@ -1543,11 +1544,11 @@ bool ParserImpl::struct_decoration_decl(ast::StructDecorationList& decos) {
// struct_decoration
// : BLOCK
ast::StructDecoration ParserImpl::struct_decoration(Token t) {
std::unique_ptr<ast::StructDecoration> ParserImpl::struct_decoration(Token t) {
if (t.IsBlock()) {
return ast::StructDecoration::kBlock;
return std::make_unique<ast::StructBlockDecoration>();
}
return ast::StructDecoration::kNone;
return nullptr;
}
// struct_body_decl

View File

@@ -189,7 +189,7 @@ class ParserImpl {
/// Parses a `struct_decoration` grammar element
/// @param t the current token
/// @returns the struct decoration or StructDecoraton::kNone if none matched
ast::StructDecoration struct_decoration(Token t);
std::unique_ptr<ast::StructDecoration> struct_decoration(Token t);
/// Parses a `struct_body_decl` grammar element
/// @returns the struct members
ast::StructMemberList struct_body_decl();

View File

@@ -51,7 +51,7 @@ TEST_F(ParserImplTest, StructDecl_ParsesWithDecoration) {
EXPECT_EQ(s->impl()->members()[0]->name(), "a");
EXPECT_EQ(s->impl()->members()[1]->name(), "b");
ASSERT_EQ(s->impl()->decorations().size(), 1u);
EXPECT_EQ(s->impl()->decorations()[0], ast::StructDecoration::kBlock);
EXPECT_TRUE(s->impl()->decorations()[0]->IsBlock());
}
TEST_F(ParserImplTest, StructDecl_ParsesWithMultipleDecoration) {
@@ -69,8 +69,8 @@ TEST_F(ParserImplTest, StructDecl_ParsesWithMultipleDecoration) {
EXPECT_EQ(s->impl()->members()[0]->name(), "a");
EXPECT_EQ(s->impl()->members()[1]->name(), "b");
ASSERT_EQ(s->impl()->decorations().size(), 2u);
EXPECT_EQ(s->impl()->decorations()[0], ast::StructDecoration::kBlock);
EXPECT_EQ(s->impl()->decorations()[1], ast::StructDecoration::kBlock);
EXPECT_TRUE(s->impl()->decorations()[0]->IsBlock());
EXPECT_TRUE(s->impl()->decorations()[1]->IsBlock());
}
TEST_F(ParserImplTest, StructDecl_EmptyMembers) {

View File

@@ -27,7 +27,7 @@ TEST_F(ParserImplTest, StructDecorationDecl_Parses) {
ASSERT_TRUE(p->struct_decoration_decl(decos));
ASSERT_FALSE(p->has_error());
EXPECT_EQ(decos.size(), 1u);
EXPECT_EQ(decos[0], ast::StructDecoration::kBlock);
EXPECT_TRUE(decos[0]->IsBlock());
}
TEST_F(ParserImplTest, StructDecorationDecl_MissingAttrRight) {

View File

@@ -24,7 +24,7 @@ namespace {
struct StructDecorationData {
const char* input;
ast::StructDecoration result;
bool is_block;
};
inline std::ostream& operator<<(std::ostream& out, StructDecorationData data) {
out << std::string(data.input);
@@ -40,17 +40,16 @@ TEST_P(StructDecorationTest, Parses) {
auto deco = p->struct_decoration(p->peek());
ASSERT_FALSE(p->has_error());
EXPECT_EQ(deco, params.result);
EXPECT_EQ(deco->IsBlock(), params.is_block);
}
INSTANTIATE_TEST_SUITE_P(ParserImplTest,
StructDecorationTest,
testing::Values(StructDecorationData{
"block", ast::StructDecoration::kBlock}));
testing::Values(StructDecorationData{"block", true}));
TEST_F(ParserImplTest, StructDecoration_NoMatch) {
auto* p = parser("not-a-stage");
auto deco = p->struct_decoration(p->peek());
ASSERT_EQ(deco, ast::StructDecoration::kNone);
ASSERT_EQ(deco, nullptr);
auto t = p->next();
EXPECT_TRUE(t.IsIdentifier());