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

@ -255,6 +255,8 @@ source_set("libtint_core_src") {
"src/ast/continue_statement.h",
"src/ast/decorated_variable.cc",
"src/ast/decorated_variable.h",
"src/ast/decoration.cc",
"src/ast/decoration.h",
"src/ast/discard_statement.cc",
"src/ast/discard_statement.h",
"src/ast/else_statement.cc",
@ -311,6 +313,8 @@ source_set("libtint_core_src") {
"src/ast/stride_decoration.h",
"src/ast/struct.cc",
"src/ast/struct.h",
"src/ast/struct_block_decoration.cc",
"src/ast/struct_block_decoration.h",
"src/ast/struct_decoration.cc",
"src/ast/struct_decoration.h",
"src/ast/struct_member.cc",
@ -734,6 +738,7 @@ source_set("tint_unittests_core_src") {
"src/ast/case_statement_test.cc",
"src/ast/constant_id_decoration_test.cc",
"src/ast/continue_statement_test.cc",
"src/ast/decoration_test.cc",
"src/ast/decorated_variable_test.cc",
"src/ast/discard_statement_test.cc",
"src/ast/else_statement_test.cc",

View File

@ -76,6 +76,8 @@ set(TINT_LIB_SRCS
ast/continue_statement.h
ast/decorated_variable.cc
ast/decorated_variable.h
ast/decoration.cc
ast/decoration.h
ast/discard_statement.cc
ast/discard_statement.h
ast/else_statement.cc
@ -132,6 +134,8 @@ set(TINT_LIB_SRCS
ast/stride_decoration.h
ast/struct.cc
ast/struct.h
ast/struct_block_decoration.cc
ast/struct_block_decoration.h
ast/struct_decoration.cc
ast/struct_decoration.h
ast/struct_member.cc
@ -344,6 +348,7 @@ set(TINT_TEST_SRCS
ast/constant_id_decoration_test.cc
ast/continue_statement_test.cc
ast/discard_statement_test.cc
ast/decoration_test.cc
ast/decorated_variable_test.cc
ast/else_statement_test.cc
ast/expression_test.cc

View File

@ -21,7 +21,7 @@
namespace tint {
namespace ast {
ArrayDecoration::ArrayDecoration() = default;
ArrayDecoration::ArrayDecoration() : Decoration(Kind) {}
ArrayDecoration::~ArrayDecoration() = default;

View File

@ -19,15 +19,20 @@
#include <string>
#include <vector>
#include "src/ast/decoration.h"
namespace tint {
namespace ast {
class StrideDecoration;
/// A decoration attached to an array
class ArrayDecoration {
class ArrayDecoration : public Decoration {
public:
virtual ~ArrayDecoration();
/// The kind of decoration that this type represents
static constexpr DecorationKind Kind = DecorationKind::kArray;
~ArrayDecoration() override;
/// @returns true if this is a stride decoration
virtual bool IsStride() const;
@ -39,6 +44,7 @@ class ArrayDecoration {
virtual std::string to_str() const = 0;
protected:
/// Constructor
ArrayDecoration();
};

39
src/ast/decoration.cc Normal file
View File

@ -0,0 +1,39 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/decoration.h"
namespace tint {
namespace ast {
Decoration::~Decoration() = default;
std::ostream& operator<<(std::ostream& out, DecorationKind data) {
switch (data) {
case DecorationKind::kArray:
return out << "array";
case DecorationKind::kFunction:
return out << "function";
case DecorationKind::kStruct:
return out << "struct";
case DecorationKind::kStructMember:
return out << "struct member";
case DecorationKind::kVariable:
return out << "variable";
}
return out << "<unknown>";
}
} // namespace ast
} // namespace tint

82
src/ast/decoration.h Normal file
View File

@ -0,0 +1,82 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_DECORATION_H_
#define SRC_AST_DECORATION_H_
#include <memory>
#include <ostream>
#include <vector>
#include "src/source.h"
namespace tint {
namespace ast {
/// The decoration kind enumerator
enum class DecorationKind {
kArray,
kFunction,
kStruct,
kStructMember,
kVariable
};
std::ostream& operator<<(std::ostream& out, DecorationKind data);
/// The base class for all decorations
class Decoration {
public:
virtual ~Decoration();
/// @return the decoration kind
DecorationKind GetKind() const { return kind_; }
/// @return true if this decoration is of (or derives from) type |TO|
template <typename TO>
bool Is() const {
return GetKind() == TO::Kind;
}
protected:
/// Constructor
/// @param kind represents the derived type
explicit Decoration(DecorationKind kind) : kind_(kind) {}
private:
DecorationKind const kind_;
};
/// As dynamically casts |deco| to the target type |TO|.
/// @return the dynamically cast decoration, or nullptr if |deco| is not of the
/// type |TO|.
template <typename TO>
std::unique_ptr<TO> As(std::unique_ptr<Decoration>&& deco) {
if (deco == nullptr) {
return nullptr;
}
if (deco->Is<TO>()) {
auto ptr = static_cast<TO*>(deco.release());
return std::unique_ptr<TO>(ptr);
}
return nullptr;
}
/// A list of unique decorations
using DecorationList = std::vector<std::unique_ptr<Decoration>>;
} // namespace ast
} // namespace tint
#endif // SRC_AST_DECORATION_H_

View File

@ -0,0 +1,53 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/decoration.h"
#include <sstream>
#include <utility>
#include "gtest/gtest.h"
#include "src/ast/array_decoration.h"
#include "src/ast/constant_id_decoration.h"
namespace tint {
namespace ast {
namespace {
using DecorationTest = testing::Test;
TEST_F(DecorationTest, AsCorrectType) {
auto* decoration = new ConstantIdDecoration(1);
auto upcast = std::unique_ptr<Decoration>(decoration);
auto downcast = As<VariableDecoration>(std::move(upcast));
EXPECT_EQ(decoration, downcast.get());
}
TEST_F(DecorationTest, AsIncorrectType) {
auto* decoration = new ConstantIdDecoration(1);
auto upcast = std::unique_ptr<Decoration>(decoration);
auto downcast = As<ArrayDecoration>(std::move(upcast));
EXPECT_EQ(nullptr, downcast.get());
}
TEST_F(DecorationTest, Is) {
auto decoration = std::make_unique<ConstantIdDecoration>(1);
EXPECT_TRUE(decoration->Is<VariableDecoration>());
EXPECT_FALSE(decoration->Is<ArrayDecoration>());
}
} // namespace
} // namespace ast
} // namespace tint

View File

@ -22,7 +22,7 @@
namespace tint {
namespace ast {
FunctionDecoration::FunctionDecoration() = default;
FunctionDecoration::FunctionDecoration() : Decoration(Kind) {}
FunctionDecoration::~FunctionDecoration() = default;

View File

@ -19,6 +19,8 @@
#include <ostream>
#include <vector>
#include "src/ast/decoration.h"
namespace tint {
namespace ast {
@ -26,9 +28,12 @@ class StageDecoration;
class WorkgroupDecoration;
/// A decoration attached to a function
class FunctionDecoration {
class FunctionDecoration : public Decoration {
public:
virtual ~FunctionDecoration();
/// The kind of decoration that this type represents
static constexpr DecorationKind Kind = DecorationKind::kFunction;
~FunctionDecoration() override;
/// @returns true if this is a stage decoration
virtual bool IsStage() const;
@ -42,11 +47,10 @@ class FunctionDecoration {
/// Outputs the function decoration to the given stream
/// @param out the stream to output too
//! @cond Doxygen_Suppress
virtual void to_str(std::ostream& out) const = 0;
//! @endcond
protected:
/// Constructor
FunctionDecoration();
};

View File

@ -23,7 +23,9 @@ Struct::Struct(StructMemberList members)
: Node(), members_(std::move(members)) {}
Struct::Struct(StructDecorationList decorations, StructMemberList members)
: Node(), decorations_(decorations), members_(std::move(members)) {}
: Node(),
decorations_(std::move(decorations)),
members_(std::move(members)) {}
Struct::Struct(const Source& source, StructMemberList members)
: Node(source), members_(std::move(members)) {}
@ -31,7 +33,9 @@ Struct::Struct(const Source& source, StructMemberList members)
Struct::Struct(const Source& source,
StructDecorationList decorations,
StructMemberList members)
: Node(source), decorations_(decorations), members_(std::move(members)) {}
: Node(source),
decorations_(std::move(decorations)),
members_(std::move(members)) {}
Struct::Struct(Struct&&) = default;
@ -47,8 +51,8 @@ StructMember* Struct::get_member(const std::string& name) const {
}
bool Struct::IsBlockDecorated() const {
for (auto deco : decorations_) {
if (deco == StructDecoration::kBlock) {
for (auto& deco : decorations_) {
if (deco->IsBlock()) {
return true;
}
}
@ -56,11 +60,6 @@ bool Struct::IsBlockDecorated() const {
}
bool Struct::IsValid() const {
for (auto deco : decorations_) {
if (deco == StructDecoration::kNone) {
return false;
}
}
for (const auto& mem : members_) {
if (mem == nullptr || !mem->IsValid()) {
return false;
@ -71,9 +70,11 @@ bool Struct::IsValid() const {
void Struct::to_str(std::ostream& out, size_t indent) const {
out << "Struct{" << std::endl;
for (auto deco : decorations_) {
for (auto& deco : decorations_) {
make_indent(out, indent + 2);
out << "[[" << deco << "]]" << std::endl;
out << "[[";
deco->to_str(out);
out << "]]" << std::endl;
}
for (const auto& member : members_) {
member->to_str(out, indent + 2);

View File

@ -0,0 +1,33 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/struct_block_decoration.h"
namespace tint {
namespace ast {
StructBlockDecoration::StructBlockDecoration() = default;
StructBlockDecoration::~StructBlockDecoration() = default;
bool StructBlockDecoration::IsBlock() const {
return true;
}
void StructBlockDecoration::to_str(std::ostream& out) const {
out << "block";
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,48 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_STRUCT_BLOCK_DECORATION_H_
#define SRC_AST_STRUCT_BLOCK_DECORATION_H_
#include <memory>
#include <ostream>
#include <vector>
#include "src/ast/struct_decoration.h"
namespace tint {
namespace ast {
/// The struct decorations
class StructBlockDecoration : public StructDecoration {
public:
/// constructor
StructBlockDecoration();
~StructBlockDecoration() override;
/// @returns true if this is a block struct
bool IsBlock() const override;
/// Outputs the decoration to the given stream
/// @param out the stream to output too
void to_str(std::ostream& out) const override;
};
/// List of struct decorations
using StructDecorationList = std::vector<std::unique_ptr<StructDecoration>>;
} // namespace ast
} // namespace tint
#endif // SRC_AST_STRUCT_BLOCK_DECORATION_H_

View File

@ -17,19 +17,9 @@
namespace tint {
namespace ast {
std::ostream& operator<<(std::ostream& out, StructDecoration stage) {
switch (stage) {
case StructDecoration::kNone: {
out << "none";
break;
}
case StructDecoration::kBlock: {
out << "block";
break;
}
}
return out;
}
StructDecoration::StructDecoration() : Decoration(Kind) {}
StructDecoration::~StructDecoration() = default;
} // namespace ast
} // namespace tint

View File

@ -15,19 +15,37 @@
#ifndef SRC_AST_STRUCT_DECORATION_H_
#define SRC_AST_STRUCT_DECORATION_H_
#include <memory>
#include <ostream>
#include <vector>
#include "src/ast/decoration.h"
namespace tint {
namespace ast {
/// The struct decorations
enum class StructDecoration { kNone = -1, kBlock };
class StructDecoration : public Decoration {
public:
/// The kind of decoration that this type represents
static constexpr DecorationKind Kind = DecorationKind::kStruct;
std::ostream& operator<<(std::ostream& out, StructDecoration stage);
~StructDecoration() override;
/// @returns true if this is a block struct
virtual bool IsBlock() const = 0;
/// Outputs the decoration to the given stream
/// @param out the stream to output too
virtual void to_str(std::ostream& out) const = 0;
protected:
/// Constructor
StructDecoration();
};
/// List of struct decorations
using StructDecorationList = std::vector<StructDecoration>;
using StructDecorationList = std::vector<std::unique_ptr<StructDecoration>>;
} // namespace ast
} // namespace tint

View File

@ -21,7 +21,8 @@
namespace tint {
namespace ast {
StructMemberDecoration::StructMemberDecoration() = default;
StructMemberDecoration::StructMemberDecoration()
: Decoration(DecorationKind::kStructMember) {}
StructMemberDecoration::~StructMemberDecoration() = default;

View File

@ -19,15 +19,20 @@
#include <string>
#include <vector>
#include "src/ast/decoration.h"
namespace tint {
namespace ast {
class StructMemberOffsetDecoration;
/// A decoration attached to a struct member
class StructMemberDecoration {
class StructMemberDecoration : public Decoration {
public:
virtual ~StructMemberDecoration();
/// The kind of decoration that this type represents
static constexpr DecorationKind Kind = DecorationKind::kStructMember;
~StructMemberDecoration() override;
/// @returns true if this is an offset decoration
virtual bool IsOffset() const;
@ -39,6 +44,7 @@ class StructMemberDecoration {
virtual std::string to_str() const = 0;
protected:
/// Constructor
StructMemberDecoration();
};

View File

@ -19,7 +19,7 @@
#include <utility>
#include "gtest/gtest.h"
#include "src/ast/struct_decoration.h"
#include "src/ast/struct_block_decoration.h"
#include "src/ast/struct_member.h"
#include "src/ast/type/i32_type.h"
@ -52,12 +52,12 @@ TEST_F(StructTest, Creation_WithDecorations) {
std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
StructDecorationList decos;
decos.push_back(StructDecoration::kBlock);
decos.push_back(std::make_unique<StructBlockDecoration>());
Struct s{std::move(decos), std::move(members)};
EXPECT_EQ(s.members().size(), 1u);
ASSERT_EQ(s.decorations().size(), 1u);
EXPECT_EQ(s.decorations()[0], StructDecoration::kBlock);
EXPECT_TRUE(s.decorations()[0]->IsBlock());
EXPECT_EQ(s.source().range.begin.line, 0u);
EXPECT_EQ(s.source().range.begin.column, 0u);
EXPECT_EQ(s.source().range.end.line, 0u);
@ -72,14 +72,14 @@ TEST_F(StructTest, CreationWithSourceAndDecorations) {
std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
StructDecorationList decos;
decos.push_back(StructDecoration::kBlock);
decos.push_back(std::make_unique<StructBlockDecoration>());
Struct s{
Source{Source::Range{Source::Location{27, 4}, Source::Location{27, 8}}},
std::move(decos), std::move(members)};
EXPECT_EQ(s.members().size(), 1u);
ASSERT_EQ(s.decorations().size(), 1u);
EXPECT_EQ(s.decorations()[0], StructDecoration::kBlock);
EXPECT_TRUE(s.decorations()[0]->IsBlock());
EXPECT_EQ(s.source().range.begin.line, 27u);
EXPECT_EQ(s.source().range.begin.column, 4u);
EXPECT_EQ(s.source().range.end.line, 27u);
@ -114,20 +114,6 @@ TEST_F(StructTest, IsValid_Invalid_StructMember) {
EXPECT_FALSE(s.IsValid());
}
TEST_F(StructTest, IsValid_NoneDecoration) {
type::I32Type i32;
StructMemberList members;
members.push_back(
std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
StructDecorationList decos;
decos.push_back(StructDecoration::kNone);
Struct s{std::move(decos), std::move(members)};
EXPECT_FALSE(s.IsValid());
}
TEST_F(StructTest, ToStr) {
type::I32Type i32;
@ -136,7 +122,7 @@ TEST_F(StructTest, ToStr) {
std::make_unique<StructMember>("a", &i32, StructMemberDecorationList()));
StructDecorationList decos;
decos.push_back(StructDecoration::kBlock);
decos.push_back(std::make_unique<StructBlockDecoration>());
Struct s{std::move(decos), std::move(members)};

View File

@ -14,6 +14,9 @@
#include "src/ast/type/access_control_type.h"
#include <memory>
#include <utility>
#include "gtest/gtest.h"
#include "src/ast/storage_class.h"
#include "src/ast/stride_decoration.h"

View File

@ -14,6 +14,9 @@
#include "src/ast/type/alias_type.h"
#include <memory>
#include <utility>
#include "gtest/gtest.h"
#include "src/ast/storage_class.h"
#include "src/ast/stride_decoration.h"

View File

@ -25,7 +25,7 @@
namespace tint {
namespace ast {
VariableDecoration::VariableDecoration() = default;
VariableDecoration::VariableDecoration() : Decoration(Kind) {}
VariableDecoration::~VariableDecoration() = default;

View File

@ -20,6 +20,8 @@
#include <string>
#include <vector>
#include "src/ast/decoration.h"
namespace tint {
namespace ast {
@ -30,9 +32,12 @@ class LocationDecoration;
class SetDecoration;
/// A decoration attached to a variable
class VariableDecoration {
class VariableDecoration : public Decoration {
public:
virtual ~VariableDecoration();
/// The kind of decoration that this type represents
static constexpr DecorationKind Kind = DecorationKind::kVariable;
~VariableDecoration() override;
/// @returns true if this is a binding decoration
virtual bool IsBinding() const;
@ -58,11 +63,10 @@ class VariableDecoration {
/// Outputs the variable decoration to the given stream
/// @param out the stream to output too
//! @cond Doxygen_Suppress
virtual void to_str(std::ostream& out) const = 0;
//! @endcond
protected:
/// Constructor
VariableDecoration();
};

View File

@ -34,6 +34,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_decoration.h"
#include "src/ast/struct_member.h"
#include "src/ast/struct_member_decoration.h"
@ -268,7 +269,7 @@ class InspectorHelper {
ast::StructDecorationList decos;
if (is_block) {
decos.push_back(ast::StructDecoration::kBlock);
decos.push_back(std::make_unique<ast::StructBlockDecoration>());
}
auto str =

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());

View File

@ -25,6 +25,7 @@
#include "src/ast/scalar_constructor_expression.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_offset_decoration.h"
@ -234,7 +235,7 @@ void VertexPullingTransform::AddVertexStorageBuffers() {
kStructBufferName, internal_array_type, std::move(member_dec)));
ast::StructDecorationList decos;
decos.push_back(ast::StructDecoration::kBlock);
decos.push_back(std::make_unique<ast::StructBlockDecoration>());
auto* struct_type =
ctx_->type_mgr().Get(std::make_unique<ast::type::StructType>(

View File

@ -14,6 +14,7 @@
#include "src/ast/module.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"
@ -286,7 +287,7 @@ TEST_F(HlslGeneratorImplTest_Type, DISABLED_EmitType_Struct_WithDecoration) {
std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
ast::StructDecorationList decos;
decos.push_back(ast::StructDecoration::kBlock);
decos.push_back(std::make_unique<ast::StructBlockDecoration>());
auto str =
std::make_unique<ast::Struct>(std::move(decos), std::move(members));

View File

@ -15,6 +15,7 @@
#include "gtest/gtest.h"
#include "src/ast/module.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"
@ -324,7 +325,7 @@ TEST_F(MslGeneratorImplTest, DISABLED_EmitType_Struct_WithDecoration) {
std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
ast::StructDecorationList decos;
decos.push_back(ast::StructDecoration::kBlock);
decos.push_back(std::make_unique<ast::StructBlockDecoration>());
auto str =
std::make_unique<ast::Struct>(std::move(decos), std::move(members));

View File

@ -18,6 +18,7 @@
#include "src/ast/identifier_expression.h"
#include "src/ast/stride_decoration.h"
#include "src/ast/struct.h"
#include "src/ast/struct_block_decoration.h"
#include "src/ast/struct_member.h"
#include "src/ast/struct_member_offset_decoration.h"
#include "src/ast/type/access_control_type.h"
@ -361,7 +362,7 @@ TEST_F(BuilderTest_Type, GenerateStruct_Decorated) {
std::make_unique<ast::StructMember>("a", &f32, std::move(decos)));
ast::StructDecorationList struct_decos;
struct_decos.push_back(ast::StructDecoration::kBlock);
struct_decos.push_back(std::make_unique<ast::StructBlockDecoration>());
auto s = std::make_unique<ast::Struct>(std::move(struct_decos),
std::move(members));

View File

@ -552,8 +552,10 @@ bool GeneratorImpl::EmitType(ast::type::Type* type) {
bool GeneratorImpl::EmitStructType(const ast::type::StructType* str) {
auto* impl = str->impl();
for (auto deco : impl->decorations()) {
out_ << "[[" << deco << "]]" << std::endl;
for (auto& deco : impl->decorations()) {
out_ << "[[";
deco->to_str(out_);
out_ << "]]" << std::endl;
}
out_ << "struct " << str->name() << " {" << std::endl;

View File

@ -15,6 +15,7 @@
#include "gtest/gtest.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"
@ -204,7 +205,7 @@ TEST_F(WgslGeneratorImplTest, EmitType_Struct_WithDecoration) {
std::make_unique<ast::StructMember>("b", &f32, std::move(b_deco)));
ast::StructDecorationList decos;
decos.push_back(ast::StructDecoration::kBlock);
decos.push_back(std::make_unique<ast::StructBlockDecoration>());
auto str =
std::make_unique<ast::Struct>(std::move(decos), std::move(members));