diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn index cb735b86ed..d74eaac120 100644 --- a/src/tint/BUILD.gn +++ b/src/tint/BUILD.gn @@ -367,6 +367,7 @@ libtint_source_set("libtint_core_all_src") { "clone_context.cc", "clone_context.h", "constant/constant.h", + "constant/node.h", "debug.cc", "debug.h", "demangler.cc", @@ -760,6 +761,8 @@ libtint_source_set("libtint_constant_src") { sources = [ "constant/constant.cc", "constant/constant.h", + "constant/node.cc", + "constant/node.h", ] public_deps = [ ":libtint_core_all_src" ] } diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt index 3148070991..d32da21856 100644 --- a/src/tint/CMakeLists.txt +++ b/src/tint/CMakeLists.txt @@ -256,6 +256,8 @@ list(APPEND TINT_LIB_SRCS clone_context.h constant/constant.cc constant/constant.h + constant/node.cc + constant/node.h demangler.cc demangler.h inspector/entry_point.cc diff --git a/src/tint/constant/constant.cc b/src/tint/constant/constant.cc index 4dba6ab830..a5b0caf16a 100644 --- a/src/tint/constant/constant.cc +++ b/src/tint/constant/constant.cc @@ -14,6 +14,8 @@ #include "src/tint/constant/constant.h" +TINT_INSTANTIATE_TYPEINFO(tint::constant::Constant); + namespace tint::constant { Constant::Constant() = default; diff --git a/src/tint/constant/constant.h b/src/tint/constant/constant.h index 62cc3c6cca..bd60f49a01 100644 --- a/src/tint/constant/constant.h +++ b/src/tint/constant/constant.h @@ -17,19 +17,21 @@ #include +#include "src/tint/castable.h" +#include "src/tint/constant/node.h" #include "src/tint/number.h" #include "src/tint/type/type.h" namespace tint::constant { /// Constant is the interface to a compile-time evaluated expression value. -class Constant { +class Constant : public Castable { public: /// Constructor Constant(); /// Destructor - virtual ~Constant(); + ~Constant() override; /// @returns the type of the constant virtual const type::Type* Type() const = 0; diff --git a/src/tint/constant/node.cc b/src/tint/constant/node.cc new file mode 100644 index 0000000000..8f18ba6195 --- /dev/null +++ b/src/tint/constant/node.cc @@ -0,0 +1,27 @@ +// Copyright 2022 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/tint/constant/node.h" + +TINT_INSTANTIATE_TYPEINFO(tint::constant::Node); + +namespace tint::constant { + +Node::Node() = default; + +Node::Node(const Node&) = default; + +Node::~Node() = default; + +} // namespace tint::constant diff --git a/src/tint/constant/node.h b/src/tint/constant/node.h new file mode 100644 index 0000000000..41d00e09e7 --- /dev/null +++ b/src/tint/constant/node.h @@ -0,0 +1,37 @@ +// Copyright 2022 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_TINT_CONSTANT_NODE_H_ +#define SRC_TINT_CONSTANT_NODE_H_ + +#include "src/tint/castable.h" + +namespace tint::constant { + +/// Node is the base class for all constant nodes +class Node : public Castable { + public: + /// Constructor + Node(); + + /// Copy constructor + Node(const Node&); + + /// Destructor + ~Node() override; +}; + +} // namespace tint::constant + +#endif // SRC_TINT_CONSTANT_NODE_H_ diff --git a/src/tint/resolver/const_eval.cc b/src/tint/resolver/const_eval.cc index 558564388b..115082c2f5 100644 --- a/src/tint/resolver/const_eval.cc +++ b/src/tint/resolver/const_eval.cc @@ -23,6 +23,7 @@ #include #include "src/tint/constant/constant.h" +#include "src/tint/number.h" #include "src/tint/program_builder.h" #include "src/tint/sem/member_accessor_expression.h" #include "src/tint/sem/type_initializer.h" @@ -248,7 +249,11 @@ std::make_unsigned_t CountTrailingBits(T e, T bit_value_to_count) { /// ImplConstant inherits from constant::Constant to add an private implementation method for /// conversion. -struct ImplConstant : public constant::Constant { +class ImplConstant : public Castable { + public: + ImplConstant() = default; + ~ImplConstant() override = default; + /// Convert attempts to convert the constant value to the given type. On error, Convert() /// creates a new diagnostic message and returns a Failure. virtual utils::Result Convert(ProgramBuilder& builder, @@ -267,7 +272,8 @@ const ImplConstant* CreateComposite(ProgramBuilder& builder, /// Element holds a single scalar or abstract-numeric value. /// Element implements the Constant interface. template -struct Element : ImplConstant { +class Element : public Castable, ImplConstant> { + public: static_assert(!std::is_same_v, T> || std::is_same_v, "T must be a Number or bool"); @@ -355,7 +361,8 @@ struct Element : ImplConstant { /// Splat is used for zero-initializers, 'splat' initializers, or initializers where each element is /// identical. Splat may be of a vector, matrix or array type. /// Splat implements the Constant interface. -struct Splat : ImplConstant { +class Splat : public Castable { + public: Splat(const type::Type* t, const constant::Constant* e, size_t n) : type(t), el(e), count(n) {} ~Splat() override = default; const type::Type* Type() const override { return type; } @@ -393,7 +400,8 @@ struct Splat : ImplConstant { /// If each element is the same type and value, then a Splat would be a more efficient constant /// implementation. Use CreateComposite() to create the appropriate Constant type. /// Composite implements the Constant interface. -struct Composite : ImplConstant { +class Composite : public Castable { + public: Composite(const type::Type* t, utils::VectorRef els, bool all_0, @@ -460,6 +468,23 @@ struct Composite : ImplConstant { const size_t hash; }; +} // namespace +} // namespace tint::resolver + +TINT_INSTANTIATE_TYPEINFO(tint::resolver::ImplConstant); +TINT_INSTANTIATE_TYPEINFO(tint::resolver::Element); +TINT_INSTANTIATE_TYPEINFO(tint::resolver::Element); +TINT_INSTANTIATE_TYPEINFO(tint::resolver::Element); +TINT_INSTANTIATE_TYPEINFO(tint::resolver::Element); +TINT_INSTANTIATE_TYPEINFO(tint::resolver::Element); +TINT_INSTANTIATE_TYPEINFO(tint::resolver::Element); +TINT_INSTANTIATE_TYPEINFO(tint::resolver::Element); +TINT_INSTANTIATE_TYPEINFO(tint::resolver::Splat); +TINT_INSTANTIATE_TYPEINFO(tint::resolver::Composite); + +namespace tint::resolver { +namespace { + /// CreateElement constructs and returns an Element. template ImplResult CreateElement(ProgramBuilder& builder, const Source& source, const type::Type* t, T v) {