Split concrete constant classes into own files.

This Cl splits the concrete constant implementations out of the
const_eval.cc file and into individual files. The classes are left in
the resolver namespace and will have a namespace update in a followup
CL.

Bug: tint:1718
Change-Id: I54539b6aa06f09aff39a1b1331d89f67a3594791
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/114160
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index 5ac2ea9..af37a52 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -366,8 +366,11 @@
     "castable.h",
     "clone_context.cc",
     "clone_context.h",
+    "constant/composite.h",
     "constant/constant.h",
     "constant/node.h",
+    "constant/scalar.h",
+    "constant/splat.h",
     "debug.cc",
     "debug.h",
     "demangler.cc",
@@ -762,10 +765,16 @@
 
 libtint_source_set("libtint_constant_src") {
   sources = [
+    "constant/composite.cc",
+    "constant/composite.h",
     "constant/constant.cc",
     "constant/constant.h",
     "constant/node.cc",
     "constant/node.h",
+    "constant/scalar.cc",
+    "constant/scalar.h",
+    "constant/splat.cc",
+    "constant/splat.h",
   ]
   public_deps = [ ":libtint_core_all_src" ]
 }
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index d2f2a19..e0248b7 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -254,8 +254,14 @@
   castable.h
   clone_context.cc
   clone_context.h
+  constant/composite.cc
+  constant/composite.h
   constant/constant.cc
   constant/constant.h
+  constant/scalar.cc
+  constant/scalar.h
+  constant/splat.cc
+  constant/splat.h
   constant/node.cc
   constant/node.h
   demangler.cc
diff --git a/src/tint/constant/composite.cc b/src/tint/constant/composite.cc
new file mode 100644
index 0000000..40bcc3c
--- /dev/null
+++ b/src/tint/constant/composite.cc
@@ -0,0 +1,31 @@
+// 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/composite.h"
+
+#include <utility>
+
+TINT_INSTANTIATE_TYPEINFO(tint::resolver::Composite);
+
+namespace tint::resolver {
+
+Composite::Composite(const type::Type* t,
+                     utils::VectorRef<const constant::Constant*> els,
+                     bool all_0,
+                     bool any_0)
+    : type(t), elements(std::move(els)), all_zero(all_0), any_zero(any_0), hash(CalcHash()) {}
+
+Composite::~Composite() = default;
+
+}  // namespace tint::resolver
diff --git a/src/tint/constant/composite.h b/src/tint/constant/composite.h
new file mode 100644
index 0000000..5facc56
--- /dev/null
+++ b/src/tint/constant/composite.h
@@ -0,0 +1,80 @@
+// 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_COMPOSITE_H_
+#define SRC_TINT_CONSTANT_COMPOSITE_H_
+
+#include "src/tint/castable.h"
+#include "src/tint/constant/constant.h"
+#include "src/tint/number.h"
+#include "src/tint/type/type.h"
+#include "src/tint/utils/hash.h"
+#include "src/tint/utils/vector.h"
+
+namespace tint::resolver {
+
+/// Composite holds a number of mixed child Constant values.
+/// Composite may be of a vector, matrix or array type.
+/// 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.
+class Composite : public Castable<Composite, constant::Constant> {
+  public:
+    /// Constructor
+    /// @param t the compsite type
+    /// @param els the composite elements
+    /// @param all_0 true if all elements are 0
+    /// @param any_0 true if any element is 0
+    Composite(const type::Type* t,
+              utils::VectorRef<const constant::Constant*> els,
+              bool all_0,
+              bool any_0);
+    ~Composite() override;
+
+    const type::Type* Type() const override { return type; }
+
+    std::variant<std::monostate, AInt, AFloat> Value() const override { return {}; }
+    const constant::Constant* Index(size_t i) const override {
+        return i < elements.Length() ? elements[i] : nullptr;
+    }
+
+    bool AllZero() const override { return all_zero; }
+    bool AnyZero() const override { return any_zero; }
+    bool AllEqual() const override { return false; }
+    size_t Hash() const override { return hash; }
+
+    /// The composite type
+    type::Type const* const type;
+    /// The composite elements
+    const utils::Vector<const constant::Constant*, 8> elements;
+    /// True if all elements are zero
+    const bool all_zero;
+    /// True if any element is zero
+    const bool any_zero;
+    /// The hash of the composite
+    const size_t hash;
+
+  private:
+    size_t CalcHash() {
+        auto h = utils::Hash(type, all_zero, any_zero);
+        for (auto* el : elements) {
+            h = utils::HashCombine(h, el->Hash());
+        }
+        return h;
+    }
+};
+
+}  // namespace tint::resolver
+
+#endif  // SRC_TINT_CONSTANT_COMPOSITE_H_
diff --git a/src/tint/constant/scalar.cc b/src/tint/constant/scalar.cc
new file mode 100644
index 0000000..2f7de7f
--- /dev/null
+++ b/src/tint/constant/scalar.cc
@@ -0,0 +1,23 @@
+// 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/scalar.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::resolver::Scalar<tint::AInt>);
+TINT_INSTANTIATE_TYPEINFO(tint::resolver::Scalar<tint::AFloat>);
+TINT_INSTANTIATE_TYPEINFO(tint::resolver::Scalar<tint::i32>);
+TINT_INSTANTIATE_TYPEINFO(tint::resolver::Scalar<tint::u32>);
+TINT_INSTANTIATE_TYPEINFO(tint::resolver::Scalar<tint::f16>);
+TINT_INSTANTIATE_TYPEINFO(tint::resolver::Scalar<tint::f32>);
+TINT_INSTANTIATE_TYPEINFO(tint::resolver::Scalar<bool>);
diff --git a/src/tint/constant/scalar.h b/src/tint/constant/scalar.h
new file mode 100644
index 0000000..b159563
--- /dev/null
+++ b/src/tint/constant/scalar.h
@@ -0,0 +1,84 @@
+// 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_SCALAR_H_
+#define SRC_TINT_CONSTANT_SCALAR_H_
+
+#include "src/tint/castable.h"
+#include "src/tint/constant/constant.h"
+#include "src/tint/number.h"
+#include "src/tint/type/type.h"
+#include "src/tint/utils/hash.h"
+
+namespace tint::resolver {
+
+/// Scalar holds a single scalar or abstract-numeric value.
+/// Scalar implements the Constant interface.
+template <typename T>
+class Scalar : public Castable<Scalar<T>, constant::Constant> {
+  public:
+    static_assert(!std::is_same_v<UnwrapNumber<T>, T> || std::is_same_v<T, bool>,
+                  "T must be a Number or bool");
+
+    /// Constructor
+    /// @param t the scalar type
+    /// @param v the scalar value
+    Scalar(const type::Type* t, T v) : type(t), value(v) {
+        if constexpr (IsFloatingPoint<T>) {
+            TINT_ASSERT(Resolver, std::isfinite(v.value));
+        }
+    }
+    ~Scalar() override = default;
+
+    const type::Type* Type() const override { return type; }
+
+    std::variant<std::monostate, AInt, AFloat> Value() const override {
+        if constexpr (IsFloatingPoint<UnwrapNumber<T>>) {
+            return static_cast<AFloat>(value);
+        } else {
+            return static_cast<AInt>(value);
+        }
+    }
+    const constant::Constant* Index(size_t) const override { return nullptr; }
+
+    bool AllZero() const override { return IsPositiveZero(); }
+    bool AnyZero() const override { return IsPositiveZero(); }
+    bool AllEqual() const override { return true; }
+    size_t Hash() const override { return utils::Hash(type, ValueOf()); }
+
+    /// @returns `value` if `T` is not a Number, otherwise ValueOf returns the inner value of the
+    /// Number.
+    inline auto ValueOf() const {
+        if constexpr (std::is_same_v<UnwrapNumber<T>, T>) {
+            return value;
+        } else {
+            return value.value;
+        }
+    }
+
+    /// @returns true if `value` is a positive zero.
+    inline bool IsPositiveZero() const {
+        using N = UnwrapNumber<T>;
+        return Number<N>(value) == Number<N>(0);  // Considers sign bit
+    }
+
+    /// The scalar type
+    type::Type const* const type;
+    /// The scalar value
+    const T value;
+};
+
+}  // namespace tint::resolver
+
+#endif  // SRC_TINT_CONSTANT_SCALAR_H_
diff --git a/src/tint/constant/splat.cc b/src/tint/constant/splat.cc
new file mode 100644
index 0000000..04ae249
--- /dev/null
+++ b/src/tint/constant/splat.cc
@@ -0,0 +1,26 @@
+// 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/splat.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::resolver::Splat);
+
+namespace tint::resolver {
+
+Splat::Splat(const type::Type* t, const constant::Constant* e, size_t n)
+    : type(t), el(e), count(n) {}
+
+Splat::~Splat() = default;
+
+}  // namespace tint::resolver
diff --git a/src/tint/constant/splat.h b/src/tint/constant/splat.h
new file mode 100644
index 0000000..1b7c999
--- /dev/null
+++ b/src/tint/constant/splat.h
@@ -0,0 +1,69 @@
+// 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_SPLAT_H_
+#define SRC_TINT_CONSTANT_SPLAT_H_
+
+#include "src/tint/castable.h"
+#include "src/tint/constant/composite.h"
+#include "src/tint/type/type.h"
+#include "src/tint/utils/vector.h"
+
+namespace tint::resolver {
+
+/// Splat holds a single Constant value, duplicated as all children.
+/// 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.
+class Splat : public Castable<Splat, constant::Constant> {
+  public:
+    /// Constructor
+    /// @param t the splat type
+    /// @param e the splat element
+    /// @param n the number of items in the splat
+    Splat(const type::Type* t, const constant::Constant* e, size_t n);
+    ~Splat() override;
+
+    /// @returns the type of the splat
+    const type::Type* Type() const override { return type; }
+
+    /// @returns a monostate variant.
+    std::variant<std::monostate, AInt, AFloat> Value() const override { return {}; }
+
+    /// Retrieve item at index @p i
+    /// @param i the index to retrieve
+    /// @returns the element, or nullptr if out of bounds
+    const constant::Constant* Index(size_t i) const override { return i < count ? el : nullptr; }
+
+    /// @returns true if the element is zero
+    bool AllZero() const override { return el->AllZero(); }
+    /// @returns true if the element is zero
+    bool AnyZero() const override { return el->AnyZero(); }
+    /// @returns true
+    bool AllEqual() const override { return true; }
+
+    /// @returns the hash for the splat
+    size_t Hash() const override { return utils::Hash(type, el->Hash(), count); }
+
+    /// The type of the splat element
+    type::Type const* const type;
+    /// The element stored in the splat
+    const constant::Constant* el;
+    /// The number of items in the splat
+    const size_t count;
+};
+
+}  // namespace tint::resolver
+
+#endif  // SRC_TINT_CONSTANT_SPLAT_H_
diff --git a/src/tint/resolver/const_eval.cc b/src/tint/resolver/const_eval.cc
index a035849..295b00a 100644
--- a/src/tint/resolver/const_eval.cc
+++ b/src/tint/resolver/const_eval.cc
@@ -22,7 +22,10 @@
 #include <type_traits>
 #include <utility>
 
+#include "src/tint/constant/composite.h"
 #include "src/tint/constant/constant.h"
+#include "src/tint/constant/scalar.h"
+#include "src/tint/constant/splat.h"
 #include "src/tint/number.h"
 #include "src/tint/program_builder.h"
 #include "src/tint/sem/member_accessor_expression.h"
@@ -237,115 +240,6 @@
                                           const type::Type* type,
                                           utils::VectorRef<const constant::Constant*> elements);
 
-/// Scalar holds a single scalar or abstract-numeric value.
-/// Scalar implements the Constant interface.
-template <typename T>
-class Scalar : public Castable<Scalar<T>, constant::Constant> {
-  public:
-    static_assert(!std::is_same_v<UnwrapNumber<T>, T> || std::is_same_v<T, bool>,
-                  "T must be a Number or bool");
-
-    Scalar(const type::Type* t, T v) : type(t), value(v) {
-        if constexpr (IsFloatingPoint<T>) {
-            TINT_ASSERT(Resolver, std::isfinite(v.value));
-        }
-    }
-    ~Scalar() override = default;
-    const type::Type* Type() const override { return type; }
-    std::variant<std::monostate, AInt, AFloat> Value() const override {
-        if constexpr (IsFloatingPoint<UnwrapNumber<T>>) {
-            return static_cast<AFloat>(value);
-        } else {
-            return static_cast<AInt>(value);
-        }
-    }
-    const constant::Constant* Index(size_t) const override { return nullptr; }
-
-    bool AllZero() const override { return IsPositiveZero(); }
-    bool AnyZero() const override { return IsPositiveZero(); }
-
-    bool AllEqual() const override { return true; }
-    size_t Hash() const override { return utils::Hash(type, ValueOf()); }
-
-    /// @returns `value` if `T` is not a Number, otherwise ValueOf returns the inner value of the
-    /// Number.
-    inline auto ValueOf() const {
-        if constexpr (std::is_same_v<UnwrapNumber<T>, T>) {
-            return value;
-        } else {
-            return value.value;
-        }
-    }
-
-    /// @returns true if `value` is a positive zero.
-    inline bool IsPositiveZero() const {
-        using N = UnwrapNumber<T>;
-        return Number<N>(value) == Number<N>(0);  // Considers sign bit
-    }
-
-    type::Type const* const type;
-    const T value;
-};
-
-/// Splat holds a single Constant value, duplicated as all children.
-/// 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.
-class Splat : public Castable<Splat, constant::Constant> {
-  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; }
-    std::variant<std::monostate, AInt, AFloat> Value() const override { return {}; }
-    const constant::Constant* Index(size_t i) const override { return i < count ? el : nullptr; }
-    bool AllZero() const override { return el->AllZero(); }
-    bool AnyZero() const override { return el->AnyZero(); }
-    bool AllEqual() const override { return true; }
-    size_t Hash() const override { return utils::Hash(type, el->Hash(), count); }
-
-    type::Type const* const type;
-    const constant::Constant* el;
-    const size_t count;
-};
-
-/// Composite holds a number of mixed child Constant values.
-/// Composite may be of a vector, matrix or array type.
-/// 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.
-class Composite : public Castable<Composite, constant::Constant> {
-  public:
-    Composite(const type::Type* t,
-              utils::VectorRef<const constant::Constant*> els,
-              bool all_0,
-              bool any_0)
-        : type(t), elements(std::move(els)), all_zero(all_0), any_zero(any_0), hash(CalcHash()) {}
-    ~Composite() override = default;
-    const type::Type* Type() const override { return type; }
-    std::variant<std::monostate, AInt, AFloat> Value() const override { return {}; }
-    const constant::Constant* Index(size_t i) const override {
-        return i < elements.Length() ? elements[i] : nullptr;
-    }
-    bool AllZero() const override { return all_zero; }
-    bool AnyZero() const override { return any_zero; }
-    bool AllEqual() const override { return false; /* otherwise this should be a Splat */ }
-    size_t Hash() const override { return hash; }
-
-    size_t CalcHash() {
-        auto h = utils::Hash(type, all_zero, any_zero);
-        for (auto* el : elements) {
-            h = utils::HashCombine(h, el->Hash());
-        }
-        return h;
-    }
-
-    type::Type const* const type;
-    const utils::Vector<const constant::Constant*, 8> elements;
-    const bool all_zero;
-    const bool any_zero;
-    const size_t hash;
-};
-
 template <typename T>
 ImplResult ScalarConvert(const Scalar<T>* scalar,
                          ProgramBuilder& builder,
@@ -488,22 +382,6 @@
         [&](const Composite* val) { return CompositeConvert(val, builder, target_ty, source); });
 }
 
-}  // namespace
-}  // namespace tint::resolver
-
-TINT_INSTANTIATE_TYPEINFO(tint::resolver::Scalar<tint::AInt>);
-TINT_INSTANTIATE_TYPEINFO(tint::resolver::Scalar<tint::AFloat>);
-TINT_INSTANTIATE_TYPEINFO(tint::resolver::Scalar<tint::i32>);
-TINT_INSTANTIATE_TYPEINFO(tint::resolver::Scalar<tint::u32>);
-TINT_INSTANTIATE_TYPEINFO(tint::resolver::Scalar<tint::f16>);
-TINT_INSTANTIATE_TYPEINFO(tint::resolver::Scalar<tint::f32>);
-TINT_INSTANTIATE_TYPEINFO(tint::resolver::Scalar<bool>);
-TINT_INSTANTIATE_TYPEINFO(tint::resolver::Splat);
-TINT_INSTANTIATE_TYPEINFO(tint::resolver::Composite);
-
-namespace tint::resolver {
-namespace {
-
 /// CreateScalar constructs and returns an Scalar<T>.
 template <typename T>
 ImplResult CreateScalar(ProgramBuilder& builder, const Source& source, const type::Type* t, T v) {