From 35298800a6089c3ceec83d092e237a8162251f92 Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Tue, 3 Nov 2020 21:40:20 +0000 Subject: [PATCH] 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 Commit-Queue: Ben Clayton --- BUILD.gn | 5 ++ src/CMakeLists.txt | 5 ++ src/ast/array_decoration.cc | 2 +- src/ast/array_decoration.h | 10 ++- src/ast/decoration.cc | 39 +++++++++ src/ast/decoration.h | 82 +++++++++++++++++++ src/ast/decoration_test.cc | 53 ++++++++++++ src/ast/function_decoration.cc | 2 +- src/ast/function_decoration.h | 12 ++- src/ast/struct.cc | 23 +++--- src/ast/struct_block_decoration.cc | 33 ++++++++ src/ast/struct_block_decoration.h | 48 +++++++++++ src/ast/struct_decoration.cc | 16 +--- src/ast/struct_decoration.h | 24 +++++- src/ast/struct_member_decoration.cc | 3 +- src/ast/struct_member_decoration.h | 10 ++- src/ast/struct_test.cc | 26 ++---- src/ast/type/access_control_type_test.cc | 3 + src/ast/type/alias_type_test.cc | 3 + src/ast/variable_decoration.cc | 2 +- src/ast/variable_decoration.h | 12 ++- src/inspector/inspector_test.cc | 3 +- src/reader/spirv/parser_impl.cc | 7 +- src/reader/wgsl/parser_impl.cc | 11 +-- src/reader/wgsl/parser_impl.h | 2 +- .../wgsl/parser_impl_struct_decl_test.cc | 6 +- ...parser_impl_struct_decoration_decl_test.cc | 2 +- .../parser_impl_struct_decoration_test.cc | 9 +- src/transform/vertex_pulling_transform.cc | 3 +- src/writer/hlsl/generator_impl_type_test.cc | 3 +- src/writer/msl/generator_impl_type_test.cc | 3 +- src/writer/spirv/builder_type_test.cc | 3 +- src/writer/wgsl/generator_impl.cc | 6 +- src/writer/wgsl/generator_impl_type_test.cc | 3 +- 34 files changed, 386 insertions(+), 88 deletions(-) create mode 100644 src/ast/decoration.cc create mode 100644 src/ast/decoration.h create mode 100644 src/ast/decoration_test.cc create mode 100644 src/ast/struct_block_decoration.cc create mode 100644 src/ast/struct_block_decoration.h diff --git a/BUILD.gn b/BUILD.gn index 2165569747..1a1aae1e05 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -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", diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0eff8bd059..f5e1945cd2 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 diff --git a/src/ast/array_decoration.cc b/src/ast/array_decoration.cc index 8402439fbb..96da686660 100644 --- a/src/ast/array_decoration.cc +++ b/src/ast/array_decoration.cc @@ -21,7 +21,7 @@ namespace tint { namespace ast { -ArrayDecoration::ArrayDecoration() = default; +ArrayDecoration::ArrayDecoration() : Decoration(Kind) {} ArrayDecoration::~ArrayDecoration() = default; diff --git a/src/ast/array_decoration.h b/src/ast/array_decoration.h index 579668b0c7..a86a4df89e 100644 --- a/src/ast/array_decoration.h +++ b/src/ast/array_decoration.h @@ -19,15 +19,20 @@ #include #include +#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(); }; diff --git a/src/ast/decoration.cc b/src/ast/decoration.cc new file mode 100644 index 0000000000..c4abc90ad2 --- /dev/null +++ b/src/ast/decoration.cc @@ -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 << ""; +} + +} // namespace ast +} // namespace tint diff --git a/src/ast/decoration.h b/src/ast/decoration.h new file mode 100644 index 0000000000..9c58cca375 --- /dev/null +++ b/src/ast/decoration.h @@ -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 +#include +#include + +#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 + 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 +std::unique_ptr As(std::unique_ptr&& deco) { + if (deco == nullptr) { + return nullptr; + } + if (deco->Is()) { + auto ptr = static_cast(deco.release()); + return std::unique_ptr(ptr); + } + return nullptr; +} + +/// A list of unique decorations +using DecorationList = std::vector>; + +} // namespace ast +} // namespace tint + +#endif // SRC_AST_DECORATION_H_ diff --git a/src/ast/decoration_test.cc b/src/ast/decoration_test.cc new file mode 100644 index 0000000000..a800494155 --- /dev/null +++ b/src/ast/decoration_test.cc @@ -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 +#include + +#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); + auto downcast = As(std::move(upcast)); + EXPECT_EQ(decoration, downcast.get()); +} + +TEST_F(DecorationTest, AsIncorrectType) { + auto* decoration = new ConstantIdDecoration(1); + auto upcast = std::unique_ptr(decoration); + auto downcast = As(std::move(upcast)); + EXPECT_EQ(nullptr, downcast.get()); +} + +TEST_F(DecorationTest, Is) { + auto decoration = std::make_unique(1); + EXPECT_TRUE(decoration->Is()); + EXPECT_FALSE(decoration->Is()); +} + +} // namespace +} // namespace ast +} // namespace tint diff --git a/src/ast/function_decoration.cc b/src/ast/function_decoration.cc index d94c2c1ebc..15d7eaa5e8 100644 --- a/src/ast/function_decoration.cc +++ b/src/ast/function_decoration.cc @@ -22,7 +22,7 @@ namespace tint { namespace ast { -FunctionDecoration::FunctionDecoration() = default; +FunctionDecoration::FunctionDecoration() : Decoration(Kind) {} FunctionDecoration::~FunctionDecoration() = default; diff --git a/src/ast/function_decoration.h b/src/ast/function_decoration.h index d7671382c0..101f3a9551 100644 --- a/src/ast/function_decoration.h +++ b/src/ast/function_decoration.h @@ -19,6 +19,8 @@ #include #include +#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(); }; diff --git a/src/ast/struct.cc b/src/ast/struct.cc index cf3a02c4fd..8f1e23b72e 100644 --- a/src/ast/struct.cc +++ b/src/ast/struct.cc @@ -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); diff --git a/src/ast/struct_block_decoration.cc b/src/ast/struct_block_decoration.cc new file mode 100644 index 0000000000..aac4c2113e --- /dev/null +++ b/src/ast/struct_block_decoration.cc @@ -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 diff --git a/src/ast/struct_block_decoration.h b/src/ast/struct_block_decoration.h new file mode 100644 index 0000000000..e5f4eafa3d --- /dev/null +++ b/src/ast/struct_block_decoration.h @@ -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 +#include +#include + +#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>; + +} // namespace ast +} // namespace tint + +#endif // SRC_AST_STRUCT_BLOCK_DECORATION_H_ diff --git a/src/ast/struct_decoration.cc b/src/ast/struct_decoration.cc index 10ee4850f4..f75e16be0b 100644 --- a/src/ast/struct_decoration.cc +++ b/src/ast/struct_decoration.cc @@ -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 diff --git a/src/ast/struct_decoration.h b/src/ast/struct_decoration.h index 20139ac874..9386e42f11 100644 --- a/src/ast/struct_decoration.h +++ b/src/ast/struct_decoration.h @@ -15,19 +15,37 @@ #ifndef SRC_AST_STRUCT_DECORATION_H_ #define SRC_AST_STRUCT_DECORATION_H_ +#include #include #include +#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; +using StructDecorationList = std::vector>; } // namespace ast } // namespace tint diff --git a/src/ast/struct_member_decoration.cc b/src/ast/struct_member_decoration.cc index 1c4d15478e..1e35fd4bce 100644 --- a/src/ast/struct_member_decoration.cc +++ b/src/ast/struct_member_decoration.cc @@ -21,7 +21,8 @@ namespace tint { namespace ast { -StructMemberDecoration::StructMemberDecoration() = default; +StructMemberDecoration::StructMemberDecoration() + : Decoration(DecorationKind::kStructMember) {} StructMemberDecoration::~StructMemberDecoration() = default; diff --git a/src/ast/struct_member_decoration.h b/src/ast/struct_member_decoration.h index b54f3ebd60..b8cbb8ab3c 100644 --- a/src/ast/struct_member_decoration.h +++ b/src/ast/struct_member_decoration.h @@ -19,15 +19,20 @@ #include #include +#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(); }; diff --git a/src/ast/struct_test.cc b/src/ast/struct_test.cc index 55abf23d11..95f8adb938 100644 --- a/src/ast/struct_test.cc +++ b/src/ast/struct_test.cc @@ -19,7 +19,7 @@ #include #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("a", &i32, StructMemberDecorationList())); StructDecorationList decos; - decos.push_back(StructDecoration::kBlock); + decos.push_back(std::make_unique()); 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("a", &i32, StructMemberDecorationList())); StructDecorationList decos; - decos.push_back(StructDecoration::kBlock); + decos.push_back(std::make_unique()); 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("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("a", &i32, StructMemberDecorationList())); StructDecorationList decos; - decos.push_back(StructDecoration::kBlock); + decos.push_back(std::make_unique()); Struct s{std::move(decos), std::move(members)}; diff --git a/src/ast/type/access_control_type_test.cc b/src/ast/type/access_control_type_test.cc index cfb3eb0d62..6dc716e37d 100644 --- a/src/ast/type/access_control_type_test.cc +++ b/src/ast/type/access_control_type_test.cc @@ -14,6 +14,9 @@ #include "src/ast/type/access_control_type.h" +#include +#include + #include "gtest/gtest.h" #include "src/ast/storage_class.h" #include "src/ast/stride_decoration.h" diff --git a/src/ast/type/alias_type_test.cc b/src/ast/type/alias_type_test.cc index 1b5dbc0a94..6266cfb3aa 100644 --- a/src/ast/type/alias_type_test.cc +++ b/src/ast/type/alias_type_test.cc @@ -14,6 +14,9 @@ #include "src/ast/type/alias_type.h" +#include +#include + #include "gtest/gtest.h" #include "src/ast/storage_class.h" #include "src/ast/stride_decoration.h" diff --git a/src/ast/variable_decoration.cc b/src/ast/variable_decoration.cc index fff88bee38..2087e68efd 100644 --- a/src/ast/variable_decoration.cc +++ b/src/ast/variable_decoration.cc @@ -25,7 +25,7 @@ namespace tint { namespace ast { -VariableDecoration::VariableDecoration() = default; +VariableDecoration::VariableDecoration() : Decoration(Kind) {} VariableDecoration::~VariableDecoration() = default; diff --git a/src/ast/variable_decoration.h b/src/ast/variable_decoration.h index 8cc5f70dc3..3a13b68ccc 100644 --- a/src/ast/variable_decoration.h +++ b/src/ast/variable_decoration.h @@ -20,6 +20,8 @@ #include #include +#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(); }; diff --git a/src/inspector/inspector_test.cc b/src/inspector/inspector_test.cc index f3665e7798..97d04f7b43 100644 --- a/src/inspector/inspector_test.cc +++ b/src/inspector/inspector_test.cc @@ -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()); } auto str = diff --git a/src/reader/spirv/parser_impl.cc b/src/reader/spirv/parser_impl.cc index d38e96caab..ab77baf68c 100644 --- a/src/reader/spirv/parser_impl.cc +++ b/src/reader/spirv/parser_impl.cc @@ -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()); } else if (decoration == SpvDecorationBufferBlock) { - ast_struct_decorations.push_back(ast::StructDecoration::kBlock); + ast_struct_decorations.push_back( + std::make_unique()); remap_buffer_block_type_.insert(type_id); } else { Fail() << "struct with ID " << type_id diff --git a/src/reader/wgsl/parser_impl.cc b/src/reader/wgsl/parser_impl.cc index eb4322194a..a938eca57d 100644 --- a/src/reader/wgsl/parser_impl.cc +++ b/src/reader/wgsl/parser_impl.cc @@ -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 ParserImpl::struct_decoration(Token t) { if (t.IsBlock()) { - return ast::StructDecoration::kBlock; + return std::make_unique(); } - return ast::StructDecoration::kNone; + return nullptr; } // struct_body_decl diff --git a/src/reader/wgsl/parser_impl.h b/src/reader/wgsl/parser_impl.h index 467b6ee209..4133f4b150 100644 --- a/src/reader/wgsl/parser_impl.h +++ b/src/reader/wgsl/parser_impl.h @@ -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 struct_decoration(Token t); /// Parses a `struct_body_decl` grammar element /// @returns the struct members ast::StructMemberList struct_body_decl(); diff --git a/src/reader/wgsl/parser_impl_struct_decl_test.cc b/src/reader/wgsl/parser_impl_struct_decl_test.cc index 3222117dde..c217341239 100644 --- a/src/reader/wgsl/parser_impl_struct_decl_test.cc +++ b/src/reader/wgsl/parser_impl_struct_decl_test.cc @@ -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) { diff --git a/src/reader/wgsl/parser_impl_struct_decoration_decl_test.cc b/src/reader/wgsl/parser_impl_struct_decoration_decl_test.cc index 5c0ef8eba3..3ff9674269 100644 --- a/src/reader/wgsl/parser_impl_struct_decoration_decl_test.cc +++ b/src/reader/wgsl/parser_impl_struct_decoration_decl_test.cc @@ -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) { diff --git a/src/reader/wgsl/parser_impl_struct_decoration_test.cc b/src/reader/wgsl/parser_impl_struct_decoration_test.cc index 4d07af480e..a8da5b252b 100644 --- a/src/reader/wgsl/parser_impl_struct_decoration_test.cc +++ b/src/reader/wgsl/parser_impl_struct_decoration_test.cc @@ -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()); diff --git a/src/transform/vertex_pulling_transform.cc b/src/transform/vertex_pulling_transform.cc index 3ab074d362..e8390d793b 100644 --- a/src/transform/vertex_pulling_transform.cc +++ b/src/transform/vertex_pulling_transform.cc @@ -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()); auto* struct_type = ctx_->type_mgr().Get(std::make_unique( diff --git a/src/writer/hlsl/generator_impl_type_test.cc b/src/writer/hlsl/generator_impl_type_test.cc index 62c7bae718..274a6bea07 100644 --- a/src/writer/hlsl/generator_impl_type_test.cc +++ b/src/writer/hlsl/generator_impl_type_test.cc @@ -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("b", &f32, std::move(b_deco))); ast::StructDecorationList decos; - decos.push_back(ast::StructDecoration::kBlock); + decos.push_back(std::make_unique()); auto str = std::make_unique(std::move(decos), std::move(members)); diff --git a/src/writer/msl/generator_impl_type_test.cc b/src/writer/msl/generator_impl_type_test.cc index d49714e5a8..c3a12056a8 100644 --- a/src/writer/msl/generator_impl_type_test.cc +++ b/src/writer/msl/generator_impl_type_test.cc @@ -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("b", &f32, std::move(b_deco))); ast::StructDecorationList decos; - decos.push_back(ast::StructDecoration::kBlock); + decos.push_back(std::make_unique()); auto str = std::make_unique(std::move(decos), std::move(members)); diff --git a/src/writer/spirv/builder_type_test.cc b/src/writer/spirv/builder_type_test.cc index fe8710e7a4..aef87ed385 100644 --- a/src/writer/spirv/builder_type_test.cc +++ b/src/writer/spirv/builder_type_test.cc @@ -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("a", &f32, std::move(decos))); ast::StructDecorationList struct_decos; - struct_decos.push_back(ast::StructDecoration::kBlock); + struct_decos.push_back(std::make_unique()); auto s = std::make_unique(std::move(struct_decos), std::move(members)); diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc index 205df74340..50c378b3c3 100644 --- a/src/writer/wgsl/generator_impl.cc +++ b/src/writer/wgsl/generator_impl.cc @@ -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; diff --git a/src/writer/wgsl/generator_impl_type_test.cc b/src/writer/wgsl/generator_impl_type_test.cc index a8b507046e..2fc6542466 100644 --- a/src/writer/wgsl/generator_impl_type_test.cc +++ b/src/writer/wgsl/generator_impl_type_test.cc @@ -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("b", &f32, std::move(b_deco))); ast::StructDecorationList decos; - decos.push_back(ast::StructDecoration::kBlock); + decos.push_back(std::make_unique()); auto str = std::make_unique(std::move(decos), std::move(members));