ast: Support decoration kind hierarchies
Instead of just having a single `DecorationKind` for the first
derivation from `Decoration`, have a `DecorationKind` for every
decoration type.
Add `Decoration::IsKind()` to test whether the decoration is of, or
derives from the given kind.
Note, this change is originally by bclayton@ from
https://dawn-review.googlesource.com/c/tint/+/33201
R=bclayton@google.com
Bug: tint:287
Change-Id: I69b51dfaa3f82ef4d61cda383b2f98f401013429
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/33280
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@google.com>
Auto-Submit: dan sinclair <dsinclair@chromium.org>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/ast/array_decoration.cc b/src/ast/array_decoration.cc
index 8a0753d..d7f22f3 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 473dc5b..77b6164 100644
--- a/src/ast/array_decoration.h
+++ b/src/ast/array_decoration.h
@@ -30,10 +30,15 @@
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 @@
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 64632a6..d0c5063 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 b6633c2..4f65eab 100644
--- a/src/ast/binding_decoration.h
+++ b/src/ast/binding_decoration.h
@@ -25,12 +25,20 @@
/// 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 6dc0bbd..7cb49c7 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 b8169cb..75d40a5 100644
--- a/src/ast/builtin_decoration.h
+++ b/src/ast/builtin_decoration.h
@@ -24,12 +24,20 @@
/// 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 9be39fd..145b80d 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 fbd8ba0..3fb8ef8 100644
--- a/src/ast/constant_id_decoration.h
+++ b/src/ast/constant_id_decoration.h
@@ -24,12 +24,20 @@
/// 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 1b17eb8..2ce8037 100644
--- a/src/ast/decoration.cc
+++ b/src/ast/decoration.cc
@@ -23,14 +23,30 @@
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 << "<unknown>";
}
diff --git a/src/ast/decoration.h b/src/ast/decoration.h
index 9b43a08..a07c0bf 100644
--- a/src/ast/decoration.h
+++ b/src/ast/decoration.h
@@ -28,10 +28,18 @@
/// 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 @@
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 <typename TO>
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 104dbb7..3548654 100644
--- a/src/ast/decoration_test.cc
+++ b/src/ast/decoration_test.cc
@@ -15,11 +15,24 @@
#include "src/ast/decoration.h"
#include <sstream>
+#include <unordered_map>
+#include <unordered_set>
#include <utility>
#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 @@
EXPECT_FALSE(decoration->Is<ArrayDecoration>());
}
+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<DecorationKind> 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<DecorationKind> expect_true;
+ };
+
+ // kArray
+ // | kStride
+ // kFunction
+ // | kStage
+ // | kWorkgroup
+ // kStruct
+ // kStructMember
+ // | kStructMemberOffset
+ // kVariable
+ // | kBinding
+ // | kBuiltin
+ // | kConstantId
+ // | kLocation
+ std::unordered_map<DecorationKind, std::unordered_set<DecorationKind>>
+ 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 f414c9d..fc1409a 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 360991d..1d778fa 100644
--- a/src/ast/function_decoration.h
+++ b/src/ast/function_decoration.h
@@ -31,10 +31,15 @@
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 @@
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 948fc8e..0aa7f1a 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 d5474da..abbfefe 100644
--- a/src/ast/location_decoration.h
+++ b/src/ast/location_decoration.h
@@ -25,12 +25,20 @@
/// 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 08d5312..9d1d502 100644
--- a/src/ast/set_decoration.cc
+++ b/src/ast/set_decoration.cc
@@ -18,7 +18,7 @@
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 838042d..d1f20a2 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 188170b..b7aa3b8 100644
--- a/src/ast/stage_decoration.h
+++ b/src/ast/stage_decoration.h
@@ -24,12 +24,20 @@
/// 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 879fd5d..58ac1a5 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 f6ee3ff..9b00563 100644
--- a/src/ast/stride_decoration.h
+++ b/src/ast/stride_decoration.h
@@ -27,12 +27,20 @@
/// 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 585646d..b95299e 100644
--- a/src/ast/struct_block_decoration.cc
+++ b/src/ast/struct_block_decoration.cc
@@ -18,7 +18,7 @@
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 99c5cc1..340ac14 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 0b889c2..26b1901 100644
--- a/src/ast/struct_decoration.h
+++ b/src/ast/struct_decoration.h
@@ -28,17 +28,23 @@
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 aaf8d34..efbae62 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 f31e6d6..188c777 100644
--- a/src/ast/struct_member_decoration.h
+++ b/src/ast/struct_member_decoration.h
@@ -30,10 +30,15 @@
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 @@
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 b3dec36..b2ad2b4 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 8e679fb..6e5a5a6 100644
--- a/src/ast/struct_member_offset_decoration.h
+++ b/src/ast/struct_member_offset_decoration.h
@@ -27,12 +27,21 @@
/// 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 da68d27..e37d5bd 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 b1c1fa0..6c44242 100644
--- a/src/ast/variable_decoration.h
+++ b/src/ast/variable_decoration.h
@@ -35,10 +35,15 @@
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 @@
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 7f6b38c..e9ecab6 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 d5e6226..cbfb5aa 100644
--- a/src/ast/workgroup_decoration.h
+++ b/src/ast/workgroup_decoration.h
@@ -27,6 +27,9 @@
/// 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 @@
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;