diff --git a/src/ast/array_decoration.cc b/src/ast/array_decoration.cc index 8a0753dd8a..d7f22f3935 100644 --- a/src/ast/array_decoration.cc +++ b/src/ast/array_decoration.cc @@ -21,11 +21,17 @@ namespace tint { namespace ast { -ArrayDecoration::ArrayDecoration(const Source& source) - : Decoration(Kind, source) {} +constexpr const DecorationKind ArrayDecoration::Kind; + +ArrayDecoration::ArrayDecoration(DecorationKind kind, const Source& source) + : Decoration(kind, source) {} ArrayDecoration::~ArrayDecoration() = default; +bool ArrayDecoration::IsKind(DecorationKind kind) const { + return kind == Kind; +} + bool ArrayDecoration::IsStride() const { return false; } diff --git a/src/ast/array_decoration.h b/src/ast/array_decoration.h index 473dc5b23e..77b616459c 100644 --- a/src/ast/array_decoration.h +++ b/src/ast/array_decoration.h @@ -30,10 +30,15 @@ class StrideDecoration; class ArrayDecoration : public Decoration { public: /// The kind of decoration that this type represents - static constexpr DecorationKind Kind = DecorationKind::kArray; + static constexpr const DecorationKind Kind = DecorationKind::kArray; ~ArrayDecoration() override; + /// @param kind the decoration kind + /// @return true if this Decoration is of the (or derives from) the given + /// kind. + bool IsKind(DecorationKind kind) const override; + /// @returns true if this is a stride decoration virtual bool IsStride() const; @@ -42,8 +47,9 @@ class ArrayDecoration : public Decoration { protected: /// Constructor + /// @param kind the decoration kind /// @param source the source of this decoration - explicit ArrayDecoration(const Source& source); + ArrayDecoration(DecorationKind kind, const Source& source); }; /// A list of array decorations diff --git a/src/ast/binding_decoration.cc b/src/ast/binding_decoration.cc index 64632a611b..d0c5063886 100644 --- a/src/ast/binding_decoration.cc +++ b/src/ast/binding_decoration.cc @@ -17,11 +17,17 @@ namespace tint { namespace ast { +constexpr const DecorationKind BindingDecoration::Kind; + BindingDecoration::BindingDecoration(uint32_t val, const Source& source) - : VariableDecoration(source), value_(val) {} + : VariableDecoration(Kind, source), value_(val) {} BindingDecoration::~BindingDecoration() = default; +bool BindingDecoration::IsKind(DecorationKind kind) const { + return kind == Kind || VariableDecoration::IsKind(kind); +} + bool BindingDecoration::IsBinding() const { return true; } diff --git a/src/ast/binding_decoration.h b/src/ast/binding_decoration.h index b6633c200e..4f65eabfd0 100644 --- a/src/ast/binding_decoration.h +++ b/src/ast/binding_decoration.h @@ -25,12 +25,20 @@ namespace ast { /// A binding decoration class BindingDecoration : public VariableDecoration { public: + /// The kind of decoration that this type represents + static constexpr const DecorationKind Kind = DecorationKind::kBinding; + /// constructor /// @param value the binding value /// @param source the source of this decoration BindingDecoration(uint32_t value, const Source& source); ~BindingDecoration() override; + /// @param kind the decoration kind + /// @return true if this Decoration is of the (or derives from) the given + /// kind. + bool IsKind(DecorationKind kind) const override; + /// @returns true if this is a binding decoration bool IsBinding() const override; diff --git a/src/ast/builtin_decoration.cc b/src/ast/builtin_decoration.cc index 6dc0bbd42b..7cb49c73f3 100644 --- a/src/ast/builtin_decoration.cc +++ b/src/ast/builtin_decoration.cc @@ -17,11 +17,17 @@ namespace tint { namespace ast { +constexpr const DecorationKind BuiltinDecoration::Kind; + BuiltinDecoration::BuiltinDecoration(Builtin builtin, const Source& source) - : VariableDecoration(source), builtin_(builtin) {} + : VariableDecoration(Kind, source), builtin_(builtin) {} BuiltinDecoration::~BuiltinDecoration() = default; +bool BuiltinDecoration::IsKind(DecorationKind kind) const { + return kind == Kind || VariableDecoration::IsKind(kind); +} + bool BuiltinDecoration::IsBuiltin() const { return true; } diff --git a/src/ast/builtin_decoration.h b/src/ast/builtin_decoration.h index b8169cbddf..75d40a5c95 100644 --- a/src/ast/builtin_decoration.h +++ b/src/ast/builtin_decoration.h @@ -24,12 +24,20 @@ namespace ast { /// A builtin decoration class BuiltinDecoration : public VariableDecoration { public: + /// The kind of decoration that this type represents + static constexpr const DecorationKind Kind = DecorationKind::kBuiltin; + /// constructor /// @param builtin the builtin value /// @param source the source of this decoration BuiltinDecoration(Builtin builtin, const Source& source); ~BuiltinDecoration() override; + /// @param kind the decoration kind + /// @return true if this Decoration is of the (or derives from) the given + /// kind. + bool IsKind(DecorationKind kind) const override; + /// @returns true if this is a builtin decoration bool IsBuiltin() const override; diff --git a/src/ast/constant_id_decoration.cc b/src/ast/constant_id_decoration.cc index 9be39fd4d4..145b80d572 100644 --- a/src/ast/constant_id_decoration.cc +++ b/src/ast/constant_id_decoration.cc @@ -17,11 +17,17 @@ namespace tint { namespace ast { +constexpr const DecorationKind ConstantIdDecoration::Kind; + ConstantIdDecoration::ConstantIdDecoration(uint32_t val, const Source& source) - : VariableDecoration(source), value_(val) {} + : VariableDecoration(Kind, source), value_(val) {} ConstantIdDecoration::~ConstantIdDecoration() = default; +bool ConstantIdDecoration::IsKind(DecorationKind kind) const { + return kind == Kind || VariableDecoration::IsKind(kind); +} + bool ConstantIdDecoration::IsConstantId() const { return true; } diff --git a/src/ast/constant_id_decoration.h b/src/ast/constant_id_decoration.h index fbd8ba07d3..3fb8ef8fb6 100644 --- a/src/ast/constant_id_decoration.h +++ b/src/ast/constant_id_decoration.h @@ -24,12 +24,20 @@ namespace ast { /// A constant id decoration class ConstantIdDecoration : public VariableDecoration { public: + /// The kind of decoration that this type represents + static constexpr const DecorationKind Kind = DecorationKind::kConstantId; + /// constructor /// @param val the constant_id value /// @param source the source of this decoration ConstantIdDecoration(uint32_t val, const Source& source); ~ConstantIdDecoration() override; + /// @param kind the decoration kind + /// @return true if this Decoration is of the (or derives from) the given + /// kind. + bool IsKind(DecorationKind kind) const override; + /// @returns true if this is a constant_id decoration bool IsConstantId() const override; diff --git a/src/ast/decoration.cc b/src/ast/decoration.cc index 1b17eb8ddd..2ce8037ab0 100644 --- a/src/ast/decoration.cc +++ b/src/ast/decoration.cc @@ -23,14 +23,30 @@ std::ostream& operator<<(std::ostream& out, DecorationKind data) { switch (data) { case DecorationKind::kArray: return out << "array"; + case DecorationKind::kStride: + return out << "stride"; case DecorationKind::kFunction: return out << "function"; + case DecorationKind::kStage: + return out << "stage"; + case DecorationKind::kWorkgroup: + return out << "workgroup"; case DecorationKind::kStruct: return out << "struct"; case DecorationKind::kStructMember: return out << "struct member"; + case DecorationKind::kStructMemberOffset: + return out << "offset"; case DecorationKind::kVariable: return out << "variable"; + case DecorationKind::kBinding: + return out << "binding"; + case DecorationKind::kBuiltin: + return out << "builtin"; + case DecorationKind::kConstantId: + return out << "constant_id"; + case DecorationKind::kLocation: + return out << "location"; } return out << ""; } diff --git a/src/ast/decoration.h b/src/ast/decoration.h index 9b43a087e9..a07c0bf9fc 100644 --- a/src/ast/decoration.h +++ b/src/ast/decoration.h @@ -28,10 +28,18 @@ namespace ast { /// The decoration kind enumerator enum class DecorationKind { kArray, + /*|*/ kStride, kFunction, + /*|*/ kStage, + /*|*/ kWorkgroup, kStruct, kStructMember, - kVariable + /*|*/ kStructMemberOffset, + kVariable, + /*|*/ kBinding, + /*|*/ kBuiltin, + /*|*/ kConstantId, + /*|*/ kLocation, }; std::ostream& operator<<(std::ostream& out, DecorationKind data); @@ -41,15 +49,20 @@ class Decoration : public Node { public: ~Decoration() override; - /// @return the decoration kind - DecorationKind GetKind() const { return kind_; } + /// @param kind the decoration kind + /// @return true if this Decoration is of the (or derives from) the given + /// kind. + virtual bool IsKind(DecorationKind kind) const = 0; /// @return true if this decoration is of (or derives from) type |TO| template bool Is() const { - return GetKind() == TO::Kind; + return IsKind(TO::Kind); } + /// @return the decoration kind + DecorationKind GetKind() const { return kind_; } + /// @returns true if the node is valid bool IsValid() const override; diff --git a/src/ast/decoration_test.cc b/src/ast/decoration_test.cc index 104dbb743e..3548654dc1 100644 --- a/src/ast/decoration_test.cc +++ b/src/ast/decoration_test.cc @@ -15,11 +15,24 @@ #include "src/ast/decoration.h" #include +#include +#include #include #include "src/ast/array_decoration.h" +#include "src/ast/binding_decoration.h" +#include "src/ast/builtin_decoration.h" #include "src/ast/constant_id_decoration.h" +#include "src/ast/function_decoration.h" +#include "src/ast/location_decoration.h" +#include "src/ast/stage_decoration.h" +#include "src/ast/stride_decoration.h" +#include "src/ast/struct_decoration.h" +#include "src/ast/struct_member_decoration.h" +#include "src/ast/struct_member_offset_decoration.h" #include "src/ast/test_helper.h" +#include "src/ast/variable_decoration.h" +#include "src/ast/workgroup_decoration.h" namespace tint { namespace ast { @@ -47,6 +60,120 @@ TEST_F(DecorationTest, Is) { EXPECT_FALSE(decoration->Is()); } +TEST_F(DecorationTest, Kinds) { + EXPECT_EQ(ArrayDecoration::Kind, DecorationKind::kArray); + EXPECT_EQ(StrideDecoration::Kind, DecorationKind::kStride); + EXPECT_EQ(FunctionDecoration::Kind, DecorationKind::kFunction); + EXPECT_EQ(StageDecoration::Kind, DecorationKind::kStage); + EXPECT_EQ(WorkgroupDecoration::Kind, DecorationKind::kWorkgroup); + EXPECT_EQ(StructDecoration::Kind, DecorationKind::kStruct); + EXPECT_EQ(StructMemberDecoration::Kind, DecorationKind::kStructMember); + EXPECT_EQ(StructMemberOffsetDecoration::Kind, + DecorationKind::kStructMemberOffset); + EXPECT_EQ(VariableDecoration::Kind, DecorationKind::kVariable); + EXPECT_EQ(BindingDecoration::Kind, DecorationKind::kBinding); + EXPECT_EQ(BuiltinDecoration::Kind, DecorationKind::kBuiltin); + EXPECT_EQ(ConstantIdDecoration::Kind, DecorationKind::kConstantId); + EXPECT_EQ(LocationDecoration::Kind, DecorationKind::kLocation); +} + +TEST_F(DecorationTest, IsKind) { + std::vector all_kinds{ + DecorationKind::kArray, DecorationKind::kStride, + DecorationKind::kFunction, DecorationKind::kStage, + DecorationKind::kWorkgroup, DecorationKind::kStruct, + DecorationKind::kStructMember, DecorationKind::kStructMemberOffset, + DecorationKind::kVariable, DecorationKind::kBinding, + DecorationKind::kBuiltin, DecorationKind::kConstantId, + DecorationKind::kLocation, + }; + + struct ExpectedKinds { + DecorationKind kind; + std::unordered_set expect_true; + }; + + // kArray + // | kStride + // kFunction + // | kStage + // | kWorkgroup + // kStruct + // kStructMember + // | kStructMemberOffset + // kVariable + // | kBinding + // | kBuiltin + // | kConstantId + // | kLocation + std::unordered_map> + kind_is{ + { + DecorationKind::kStride, + {DecorationKind::kArray, DecorationKind::kStride}, + }, + { + DecorationKind::kStage, + {DecorationKind::kFunction, DecorationKind::kStage}, + }, + { + DecorationKind::kWorkgroup, + {DecorationKind::kFunction, DecorationKind::kWorkgroup}, + }, + { + DecorationKind::kStruct, + {DecorationKind::kStruct}, + }, + { + DecorationKind::kStructMemberOffset, + {DecorationKind::kStructMember, + DecorationKind::kStructMemberOffset}, + }, + { + DecorationKind::kBinding, + {DecorationKind::kVariable, DecorationKind::kBinding}, + }, + { + DecorationKind::kBuiltin, + {DecorationKind::kVariable, DecorationKind::kBuiltin}, + }, + { + DecorationKind::kConstantId, + {DecorationKind::kVariable, DecorationKind::kConstantId}, + }, + { + DecorationKind::kLocation, + {DecorationKind::kVariable, DecorationKind::kLocation}, + }, + }; + + auto check = [&](Decoration* d) { + auto& is_set = kind_is[d->GetKind()]; + for (auto test : all_kinds) { + bool is_kind = is_set.find(test) != is_set.end(); + EXPECT_EQ(d->IsKind(test), is_kind) + << "decoration: " << d->GetKind() << " IsKind(" << test << ")"; + } + }; + StrideDecoration stride(0, {}); + StageDecoration stage(PipelineStage::kNone, {}); + WorkgroupDecoration workgroup(0, {}); + StructMemberOffsetDecoration struct_member_offset(0, {}); + BindingDecoration binding(0, {}); + BuiltinDecoration builtin(Builtin::kNone, {}); + ConstantIdDecoration constant_id(0, {}); + LocationDecoration location(0, {}); + + check(&stride); + check(&stage); + check(&workgroup); + check(&struct_member_offset); + check(&binding); + check(&builtin); + check(&constant_id); + check(&location); +} + } // namespace } // namespace ast } // namespace tint diff --git a/src/ast/function_decoration.cc b/src/ast/function_decoration.cc index f414c9dad0..fc1409ab32 100644 --- a/src/ast/function_decoration.cc +++ b/src/ast/function_decoration.cc @@ -22,11 +22,18 @@ namespace tint { namespace ast { -FunctionDecoration::FunctionDecoration(const Source& source) - : Decoration(Kind, source) {} +constexpr const DecorationKind FunctionDecoration::Kind; + +FunctionDecoration::FunctionDecoration(DecorationKind kind, + const Source& source) + : Decoration(kind, source) {} FunctionDecoration::~FunctionDecoration() = default; +bool FunctionDecoration::IsKind(DecorationKind kind) const { + return kind == Kind; +} + bool FunctionDecoration::IsStage() const { return false; } diff --git a/src/ast/function_decoration.h b/src/ast/function_decoration.h index 360991db97..1d778faaf5 100644 --- a/src/ast/function_decoration.h +++ b/src/ast/function_decoration.h @@ -31,10 +31,15 @@ class WorkgroupDecoration; class FunctionDecoration : public Decoration { public: /// The kind of decoration that this type represents - static constexpr DecorationKind Kind = DecorationKind::kFunction; + static constexpr const DecorationKind Kind = DecorationKind::kFunction; ~FunctionDecoration() override; + /// @param kind the decoration kind + /// @return true if this Decoration is of the (or derives from) the given + /// kind. + bool IsKind(DecorationKind kind) const override; + /// @returns true if this is a stage decoration virtual bool IsStage() const; /// @returns true if this is a workgroup decoration @@ -47,8 +52,9 @@ class FunctionDecoration : public Decoration { protected: /// Constructor + /// @param kind the decoration kind /// @param source the source of this decoration - explicit FunctionDecoration(const Source& source); + FunctionDecoration(DecorationKind kind, const Source& source); }; /// A list of function decorations diff --git a/src/ast/location_decoration.cc b/src/ast/location_decoration.cc index 948fc8e6d5..0aa7f1aa54 100644 --- a/src/ast/location_decoration.cc +++ b/src/ast/location_decoration.cc @@ -17,11 +17,17 @@ namespace tint { namespace ast { +constexpr const DecorationKind LocationDecoration::Kind; + LocationDecoration::LocationDecoration(uint32_t val, const Source& source) - : VariableDecoration(source), value_(val) {} + : VariableDecoration(Kind, source), value_(val) {} LocationDecoration::~LocationDecoration() = default; +bool LocationDecoration::IsKind(DecorationKind kind) const { + return kind == Kind || VariableDecoration::IsKind(kind); +} + bool LocationDecoration::IsLocation() const { return true; } diff --git a/src/ast/location_decoration.h b/src/ast/location_decoration.h index d5474dab5d..abbfefe0d3 100644 --- a/src/ast/location_decoration.h +++ b/src/ast/location_decoration.h @@ -25,12 +25,20 @@ namespace ast { /// A location decoration class LocationDecoration : public VariableDecoration { public: + /// The kind of decoration that this type represents + static constexpr const DecorationKind Kind = DecorationKind::kLocation; + /// constructor /// @param value the location value /// @param source the source of this decoration explicit LocationDecoration(uint32_t value, const Source& source); ~LocationDecoration() override; + /// @param kind the decoration kind + /// @return true if this Decoration is of the (or derives from) the given + /// kind. + bool IsKind(DecorationKind kind) const override; + /// @returns true if this is a location decoration bool IsLocation() const override; diff --git a/src/ast/set_decoration.cc b/src/ast/set_decoration.cc index 08d5312afc..9d1d502c8c 100644 --- a/src/ast/set_decoration.cc +++ b/src/ast/set_decoration.cc @@ -18,7 +18,7 @@ namespace tint { namespace ast { SetDecoration::SetDecoration(uint32_t val, const Source& source) - : VariableDecoration(source), value_(val) {} + : VariableDecoration(Kind, source), value_(val) {} SetDecoration::~SetDecoration() = default; diff --git a/src/ast/stage_decoration.cc b/src/ast/stage_decoration.cc index 838042dffb..d1f20a2ff4 100644 --- a/src/ast/stage_decoration.cc +++ b/src/ast/stage_decoration.cc @@ -17,11 +17,17 @@ namespace tint { namespace ast { +constexpr const DecorationKind StageDecoration::Kind; + StageDecoration::StageDecoration(ast::PipelineStage stage, const Source& source) - : FunctionDecoration(source), stage_(stage) {} + : FunctionDecoration(Kind, source), stage_(stage) {} StageDecoration::~StageDecoration() = default; +bool StageDecoration::IsKind(DecorationKind kind) const { + return kind == Kind || FunctionDecoration::IsKind(kind); +} + bool StageDecoration::IsStage() const { return true; } diff --git a/src/ast/stage_decoration.h b/src/ast/stage_decoration.h index 188170bf21..b7aa3b85fb 100644 --- a/src/ast/stage_decoration.h +++ b/src/ast/stage_decoration.h @@ -24,12 +24,20 @@ namespace ast { /// A workgroup decoration class StageDecoration : public FunctionDecoration { public: + /// The kind of decoration that this type represents + static constexpr const DecorationKind Kind = DecorationKind::kStage; + /// constructor /// @param stage the pipeline stage /// @param source the source of this decoration StageDecoration(ast::PipelineStage stage, const Source& source); ~StageDecoration() override; + /// @param kind the decoration kind + /// @return true if this Decoration is of the (or derives from) the given + /// kind. + bool IsKind(DecorationKind kind) const override; + /// @returns true if this is a stage decoration bool IsStage() const override; diff --git a/src/ast/stride_decoration.cc b/src/ast/stride_decoration.cc index 879fd5d15a..58ac1a5245 100644 --- a/src/ast/stride_decoration.cc +++ b/src/ast/stride_decoration.cc @@ -17,8 +17,14 @@ namespace tint { namespace ast { +constexpr const DecorationKind StrideDecoration::Kind; + StrideDecoration::StrideDecoration(uint32_t stride, const Source& source) - : ArrayDecoration(source), stride_(stride) {} + : ArrayDecoration(Kind, source), stride_(stride) {} + +bool StrideDecoration::IsKind(DecorationKind kind) const { + return kind == Kind || ArrayDecoration::IsKind(kind); +} bool StrideDecoration::IsStride() const { return true; diff --git a/src/ast/stride_decoration.h b/src/ast/stride_decoration.h index f6ee3ff56e..9b00563919 100644 --- a/src/ast/stride_decoration.h +++ b/src/ast/stride_decoration.h @@ -27,12 +27,20 @@ namespace ast { /// A stride decoration class StrideDecoration : public ArrayDecoration { public: + /// The kind of decoration that this type represents + static constexpr const DecorationKind Kind = DecorationKind::kStride; + /// constructor /// @param stride the stride value /// @param source the source of this decoration StrideDecoration(uint32_t stride, const Source& source); ~StrideDecoration() override; + /// @param kind the decoration kind + /// @return true if this Decoration is of the (or derives from) the given + /// kind. + bool IsKind(DecorationKind kind) const override; + /// @returns true if this is a stride decoration bool IsStride() const override; diff --git a/src/ast/struct_block_decoration.cc b/src/ast/struct_block_decoration.cc index 585646d0c4..b95299e3ae 100644 --- a/src/ast/struct_block_decoration.cc +++ b/src/ast/struct_block_decoration.cc @@ -18,7 +18,7 @@ namespace tint { namespace ast { StructBlockDecoration::StructBlockDecoration(const Source& source) - : StructDecoration(source) {} + : StructDecoration(Kind, source) {} StructBlockDecoration::~StructBlockDecoration() = default; diff --git a/src/ast/struct_decoration.cc b/src/ast/struct_decoration.cc index 99c5cc1e1d..340ac1447f 100644 --- a/src/ast/struct_decoration.cc +++ b/src/ast/struct_decoration.cc @@ -17,10 +17,16 @@ namespace tint { namespace ast { -StructDecoration::StructDecoration(const Source& source) - : Decoration(Kind, source) {} +constexpr const DecorationKind StructDecoration::Kind; + +StructDecoration::StructDecoration(DecorationKind kind, const Source& source) + : Decoration(kind, source) {} StructDecoration::~StructDecoration() = default; +bool StructDecoration::IsKind(DecorationKind kind) const { + return kind == Kind; +} + } // namespace ast } // namespace tint diff --git a/src/ast/struct_decoration.h b/src/ast/struct_decoration.h index 0b889c265a..26b1901106 100644 --- a/src/ast/struct_decoration.h +++ b/src/ast/struct_decoration.h @@ -28,17 +28,23 @@ namespace ast { class StructDecoration : public Decoration { public: /// The kind of decoration that this type represents - static constexpr DecorationKind Kind = DecorationKind::kStruct; + static constexpr const DecorationKind Kind = DecorationKind::kStruct; ~StructDecoration() override; + /// @param kind the decoration kind + /// @return true if this Decoration is of the (or derives from) the given + /// kind. + bool IsKind(DecorationKind kind) const override; + /// @returns true if this is a block struct virtual bool IsBlock() const = 0; protected: /// Constructor + /// @param kind the decoration kind /// @param source the source of this decoration - explicit StructDecoration(const Source& source); + explicit StructDecoration(DecorationKind kind, const Source& source); }; /// List of struct decorations diff --git a/src/ast/struct_member_decoration.cc b/src/ast/struct_member_decoration.cc index aaf8d34510..efbae62db9 100644 --- a/src/ast/struct_member_decoration.cc +++ b/src/ast/struct_member_decoration.cc @@ -21,11 +21,18 @@ namespace tint { namespace ast { -StructMemberDecoration::StructMemberDecoration(const Source& source) - : Decoration(DecorationKind::kStructMember, source) {} +constexpr const DecorationKind StructMemberDecoration::Kind; + +StructMemberDecoration::StructMemberDecoration(DecorationKind kind, + const Source& source) + : Decoration(kind, source) {} StructMemberDecoration::~StructMemberDecoration() = default; +bool StructMemberDecoration::IsKind(DecorationKind kind) const { + return kind == Kind; +} + bool StructMemberDecoration::IsOffset() const { return false; } diff --git a/src/ast/struct_member_decoration.h b/src/ast/struct_member_decoration.h index f31e6d6c70..188c77751f 100644 --- a/src/ast/struct_member_decoration.h +++ b/src/ast/struct_member_decoration.h @@ -30,10 +30,15 @@ class StructMemberOffsetDecoration; class StructMemberDecoration : public Decoration { public: /// The kind of decoration that this type represents - static constexpr DecorationKind Kind = DecorationKind::kStructMember; + static constexpr const DecorationKind Kind = DecorationKind::kStructMember; ~StructMemberDecoration() override; + /// @param kind the decoration kind + /// @return true if this Decoration is of the (or derives from) the given + /// kind. + bool IsKind(DecorationKind kind) const override; + /// @returns true if this is an offset decoration virtual bool IsOffset() const; @@ -42,8 +47,9 @@ class StructMemberDecoration : public Decoration { protected: /// Constructor + /// @param kind the decoration kind /// @param source the source of this decoration - explicit StructMemberDecoration(const Source& source); + explicit StructMemberDecoration(DecorationKind kind, const Source& source); }; /// A list of struct member decorations diff --git a/src/ast/struct_member_offset_decoration.cc b/src/ast/struct_member_offset_decoration.cc index b3dec36300..b2ad2b494f 100644 --- a/src/ast/struct_member_offset_decoration.cc +++ b/src/ast/struct_member_offset_decoration.cc @@ -17,9 +17,15 @@ namespace tint { namespace ast { +constexpr const DecorationKind StructMemberOffsetDecoration::Kind; + StructMemberOffsetDecoration::StructMemberOffsetDecoration(uint32_t offset, const Source& source) - : StructMemberDecoration(source), offset_(offset) {} + : StructMemberDecoration(Kind, source), offset_(offset) {} + +bool StructMemberOffsetDecoration::IsKind(DecorationKind kind) const { + return kind == Kind || StructMemberDecoration::IsKind(kind); +} bool StructMemberOffsetDecoration::IsOffset() const { return true; diff --git a/src/ast/struct_member_offset_decoration.h b/src/ast/struct_member_offset_decoration.h index 8e679fb75e..6e5a5a690d 100644 --- a/src/ast/struct_member_offset_decoration.h +++ b/src/ast/struct_member_offset_decoration.h @@ -27,12 +27,21 @@ namespace ast { /// A struct member offset decoration class StructMemberOffsetDecoration : public StructMemberDecoration { public: + /// The kind of decoration that this type represents + static constexpr const DecorationKind Kind = + DecorationKind::kStructMemberOffset; + /// constructor /// @param offset the offset value /// @param source the source of this decoration StructMemberOffsetDecoration(uint32_t offset, const Source& source); ~StructMemberOffsetDecoration() override; + /// @param kind the decoration kind + /// @return true if this Decoration is of the (or derives from) the given + /// kind. + bool IsKind(DecorationKind kind) const override; + /// @returns true if this is an offset decoration bool IsOffset() const override; diff --git a/src/ast/variable_decoration.cc b/src/ast/variable_decoration.cc index da68d27e15..e37d5bde46 100644 --- a/src/ast/variable_decoration.cc +++ b/src/ast/variable_decoration.cc @@ -25,11 +25,18 @@ namespace tint { namespace ast { -VariableDecoration::VariableDecoration(const Source& source) - : Decoration(Kind, source) {} +constexpr const DecorationKind VariableDecoration::Kind; + +VariableDecoration::VariableDecoration(DecorationKind kind, + const Source& source) + : Decoration(kind, source) {} VariableDecoration::~VariableDecoration() = default; +bool VariableDecoration::IsKind(DecorationKind kind) const { + return kind == Kind; +} + bool VariableDecoration::IsBinding() const { return false; } diff --git a/src/ast/variable_decoration.h b/src/ast/variable_decoration.h index b1c1fa0f39..6c44242903 100644 --- a/src/ast/variable_decoration.h +++ b/src/ast/variable_decoration.h @@ -35,10 +35,15 @@ class SetDecoration; class VariableDecoration : public Decoration { public: /// The kind of decoration that this type represents - static constexpr DecorationKind Kind = DecorationKind::kVariable; + static constexpr const DecorationKind Kind = DecorationKind::kVariable; ~VariableDecoration() override; + /// @param kind the decoration kind + /// @return true if this Decoration is of the (or derives from) the given + /// kind. + bool IsKind(DecorationKind kind) const override; + /// @returns true if this is a binding decoration virtual bool IsBinding() const; /// @returns true if this is a builtin decoration @@ -63,8 +68,9 @@ class VariableDecoration : public Decoration { protected: /// Constructor + /// @param kind the decoration kind /// @param source the source of this decoration - explicit VariableDecoration(const Source& source); + VariableDecoration(DecorationKind kind, const Source& source); }; /// A list of variable decorations diff --git a/src/ast/workgroup_decoration.cc b/src/ast/workgroup_decoration.cc index 7f6b38c828..e9ecab6ccf 100644 --- a/src/ast/workgroup_decoration.cc +++ b/src/ast/workgroup_decoration.cc @@ -17,22 +17,28 @@ namespace tint { namespace ast { +constexpr const DecorationKind WorkgroupDecoration::Kind; + WorkgroupDecoration::WorkgroupDecoration(uint32_t x, const Source& source) - : FunctionDecoration(source), x_(x) {} + : FunctionDecoration(Kind, source), x_(x) {} WorkgroupDecoration::WorkgroupDecoration(uint32_t x, uint32_t y, const Source& source) - : FunctionDecoration(source), x_(x), y_(y) {} + : FunctionDecoration(Kind, source), x_(x), y_(y) {} WorkgroupDecoration::WorkgroupDecoration(uint32_t x, uint32_t y, uint32_t z, const Source& source) - : FunctionDecoration(source), x_(x), y_(y), z_(z) {} + : FunctionDecoration(Kind, source), x_(x), y_(y), z_(z) {} WorkgroupDecoration::~WorkgroupDecoration() = default; +bool WorkgroupDecoration::IsKind(DecorationKind kind) const { + return kind == Kind || FunctionDecoration::IsKind(kind); +} + bool WorkgroupDecoration::IsWorkgroup() const { return true; } diff --git a/src/ast/workgroup_decoration.h b/src/ast/workgroup_decoration.h index d5e6226723..cbfb5aafcb 100644 --- a/src/ast/workgroup_decoration.h +++ b/src/ast/workgroup_decoration.h @@ -27,6 +27,9 @@ namespace ast { /// A workgroup decoration class WorkgroupDecoration : public FunctionDecoration { public: + /// The kind of decoration that this type represents + static constexpr const DecorationKind Kind = DecorationKind::kWorkgroup; + /// constructor /// @param x the workgroup x dimension size /// @param source the source of this decoration @@ -44,6 +47,11 @@ class WorkgroupDecoration : public FunctionDecoration { WorkgroupDecoration(uint32_t x, uint32_t y, uint32_t z, const Source& source); ~WorkgroupDecoration() override; + /// @param kind the decoration kind + /// @return true if this Decoration is of the (or derives from) the given + /// kind. + bool IsKind(DecorationKind kind) const override; + /// @returns true if this is a workgroup decoration bool IsWorkgroup() const override;