[tint] Add constant::Invalid
Similar to type::Invalid, can be used as a placeholder constant in a failed parse / resolve.
Change-Id: I880642a4a9e4c2a9b7d48d418dc636761711e2e0
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/189704
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/tint/lang/core/constant/BUILD.bazel b/src/tint/lang/core/constant/BUILD.bazel
index b092c56..c58c65c 100644
--- a/src/tint/lang/core/constant/BUILD.bazel
+++ b/src/tint/lang/core/constant/BUILD.bazel
@@ -41,6 +41,7 @@
srcs = [
"composite.cc",
"eval.cc",
+ "invalid.cc",
"manager.cc",
"node.cc",
"scalar.cc",
@@ -51,6 +52,7 @@
"clone_context.h",
"composite.h",
"eval.h",
+ "invalid.h",
"manager.h",
"node.h",
"scalar.h",
@@ -93,6 +95,7 @@
"eval_test.h",
"eval_unary_op_test.cc",
"helper_test.h",
+ "invalid_test.cc",
"manager_test.cc",
"scalar_test.cc",
"splat_test.cc",
diff --git a/src/tint/lang/core/constant/BUILD.cmake b/src/tint/lang/core/constant/BUILD.cmake
index b7dbca1..c4f4558 100644
--- a/src/tint/lang/core/constant/BUILD.cmake
+++ b/src/tint/lang/core/constant/BUILD.cmake
@@ -44,6 +44,8 @@
lang/core/constant/composite.h
lang/core/constant/eval.cc
lang/core/constant/eval.h
+ lang/core/constant/invalid.cc
+ lang/core/constant/invalid.h
lang/core/constant/manager.cc
lang/core/constant/manager.h
lang/core/constant/node.cc
@@ -91,6 +93,7 @@
lang/core/constant/eval_test.h
lang/core/constant/eval_unary_op_test.cc
lang/core/constant/helper_test.h
+ lang/core/constant/invalid_test.cc
lang/core/constant/manager_test.cc
lang/core/constant/scalar_test.cc
lang/core/constant/splat_test.cc
diff --git a/src/tint/lang/core/constant/BUILD.gn b/src/tint/lang/core/constant/BUILD.gn
index 8549c0b..2a343e5 100644
--- a/src/tint/lang/core/constant/BUILD.gn
+++ b/src/tint/lang/core/constant/BUILD.gn
@@ -49,6 +49,8 @@
"composite.h",
"eval.cc",
"eval.h",
+ "invalid.cc",
+ "invalid.h",
"manager.cc",
"manager.h",
"node.cc",
@@ -93,6 +95,7 @@
"eval_test.h",
"eval_unary_op_test.cc",
"helper_test.h",
+ "invalid_test.cc",
"manager_test.cc",
"scalar_test.cc",
"splat_test.cc",
diff --git a/src/tint/lang/core/constant/invalid.cc b/src/tint/lang/core/constant/invalid.cc
new file mode 100644
index 0000000..ecf434a
--- /dev/null
+++ b/src/tint/lang/core/constant/invalid.cc
@@ -0,0 +1,45 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/core/constant/invalid.h"
+
+#include "src/tint/lang/core/constant/manager.h"
+#include "src/tint/lang/core/type/invalid.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::core::constant::Invalid);
+
+namespace tint::core::constant {
+
+Invalid::Invalid(const core::type::Invalid* ty) : type(ty) {}
+
+Invalid::~Invalid() = default;
+
+const Invalid* Invalid::Clone(CloneContext& ctx) const {
+ return ctx.dst.Invalid();
+}
+
+} // namespace tint::core::constant
diff --git a/src/tint/lang/core/constant/invalid.h b/src/tint/lang/core/constant/invalid.h
new file mode 100644
index 0000000..e767172
--- /dev/null
+++ b/src/tint/lang/core/constant/invalid.h
@@ -0,0 +1,79 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_TINT_LANG_CORE_CONSTANT_INVALID_H_
+#define SRC_TINT_LANG_CORE_CONSTANT_INVALID_H_
+
+#include "src/tint/lang/core/constant/value.h"
+#include "src/tint/lang/core/type/invalid.h"
+#include "src/tint/utils/rtti/castable.h"
+
+namespace tint::core::constant {
+
+/// Invalid represents an invalid constant, used as a placeholder in a failed parse / resolve.
+class Invalid : public Castable<Invalid, Value> {
+ public:
+ /// Constructor
+ /// @param ty the Invalid type
+ explicit Invalid(const core::type::Invalid* ty);
+ ~Invalid() override;
+
+ /// @returns the type of the Invalid
+ const core::type::Type* Type() const override { return type; }
+
+ /// Retrieve item at index @p i
+ /// @param i the index to retrieve
+ /// @returns the element, or nullptr if out of bounds
+ const Value* Index([[maybe_unused]] size_t i) const override { return nullptr; }
+
+ /// @copydoc Value::NumElements()
+ size_t NumElements() const override { return 0; }
+
+ /// @returns true if the element is zero
+ bool AllZero() const override { return false; }
+ /// @returns true if the element is zero
+ bool AnyZero() const override { return false; }
+
+ /// @returns the hash for the Invalid
+ HashCode Hash() const override { return tint::Hash(type); }
+
+ /// Clones the constant into the provided context
+ /// @param ctx the clone context
+ /// @returns the cloned node
+ const Invalid* Clone(CloneContext& ctx) const override;
+
+ /// The Invalid type
+ core::type::Invalid const* const type;
+
+ protected:
+ /// @returns a monostate variant.
+ std::variant<std::monostate, AInt, AFloat> InternalValue() const override { return {}; }
+};
+
+} // namespace tint::core::constant
+
+#endif // SRC_TINT_LANG_CORE_CONSTANT_INVALID_H_
diff --git a/src/tint/lang/core/constant/invalid_test.cc b/src/tint/lang/core/constant/invalid_test.cc
new file mode 100644
index 0000000..bcbcb7a5
--- /dev/null
+++ b/src/tint/lang/core/constant/invalid_test.cc
@@ -0,0 +1,73 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/core/constant/invalid.h"
+
+#include "src/tint/lang/core/constant/helper_test.h"
+#include "src/tint/lang/core/constant/scalar.h"
+#include "src/tint/lang/core/fluent_types.h"
+
+using namespace tint::core::number_suffixes; // NOLINT
+using namespace tint::core::fluent_types; // NOLINT
+
+namespace tint::core::constant {
+namespace {
+
+using ConstantTest_Invalid = TestHelper;
+
+TEST_F(ConstantTest_Invalid, AllZero) {
+ auto* invalid = constants.Invalid();
+ EXPECT_FALSE(invalid->AllZero());
+}
+
+TEST_F(ConstantTest_Invalid, AnyZero) {
+ auto* invalid = constants.Invalid();
+ EXPECT_FALSE(invalid->AnyZero());
+}
+
+TEST_F(ConstantTest_Invalid, Index) {
+ auto* invalid = constants.Invalid();
+ EXPECT_EQ(invalid->Index(0), nullptr);
+ EXPECT_EQ(invalid->Index(1), nullptr);
+ EXPECT_EQ(invalid->Index(2), nullptr);
+}
+
+TEST_F(ConstantTest_Invalid, Clone) {
+ auto* invalid = constants.Invalid();
+
+ constant::Manager mgr;
+ constant::CloneContext ctx{core::type::CloneContext{{nullptr}, {nullptr, &mgr.types}}, mgr};
+
+ auto* cloned = invalid->Clone(ctx);
+ EXPECT_NE(cloned, invalid);
+ ASSERT_NE(cloned, nullptr);
+ EXPECT_TRUE(cloned->type->Is<core::type::Invalid>());
+ EXPECT_TRUE(cloned->Is<core::constant::Invalid>());
+}
+
+} // namespace
+} // namespace tint::core::constant
diff --git a/src/tint/lang/core/constant/manager.cc b/src/tint/lang/core/constant/manager.cc
index ecd4a38..bf8a822 100644
--- a/src/tint/lang/core/constant/manager.cc
+++ b/src/tint/lang/core/constant/manager.cc
@@ -28,6 +28,7 @@
#include "src/tint/lang/core/constant/manager.h"
#include "src/tint/lang/core/constant/composite.h"
+#include "src/tint/lang/core/constant/invalid.h"
#include "src/tint/lang/core/constant/scalar.h"
#include "src/tint/lang/core/constant/splat.h"
#include "src/tint/lang/core/type/abstract_float.h"
@@ -162,7 +163,12 @@
[&](const core::type::F32*) { return Get(f32(0)); }, //
[&](const core::type::F16*) { return Get(f16(0)); }, //
[&](const core::type::Bool*) { return Get(false); }, //
+ [&](const core::type::Invalid*) { return Invalid(); }, //
TINT_ICE_ON_NO_MATCH);
}
+const constant::Invalid* Manager::Invalid() {
+ return values_.Get<constant::Invalid>(types.invalid());
+}
+
} // namespace tint::core::constant
diff --git a/src/tint/lang/core/constant/manager.h b/src/tint/lang/core/constant/manager.h
index 43497db..7105996 100644
--- a/src/tint/lang/core/constant/manager.h
+++ b/src/tint/lang/core/constant/manager.h
@@ -30,6 +30,7 @@
#include <utility>
+#include "src/tint/lang/core/constant/invalid.h"
#include "src/tint/lang/core/constant/value.h"
#include "src/tint/lang/core/number.h"
#include "src/tint/lang/core/type/manager.h"
@@ -144,6 +145,10 @@
/// @returns a constant zero-value for the type
const Value* Zero(const core::type::Type* type);
+ /// Constructs an invalid constant
+ /// @returns an invalid constant
+ const constant::Invalid* Invalid();
+
/// The type manager
core::type::Manager types;
diff --git a/src/tint/lang/core/constant/value.cc b/src/tint/lang/core/constant/value.cc
index f426010..97a64f1 100644
--- a/src/tint/lang/core/constant/value.cc
+++ b/src/tint/lang/core/constant/value.cc
@@ -29,6 +29,7 @@
#include "src/tint/lang/core/constant/splat.h"
#include "src/tint/lang/core/type/array.h"
+#include "src/tint/lang/core/type/invalid.h"
#include "src/tint/lang/core/type/matrix.h"
#include "src/tint/lang/core/type/struct.h"
#include "src/tint/lang/core/type/vector.h"
@@ -106,13 +107,8 @@
}
return false;
},
- [&](Default) {
- auto va = InternalValue();
- auto vb = b->InternalValue();
- TINT_ASSERT(!std::holds_alternative<std::monostate>(va));
- TINT_ASSERT(!std::holds_alternative<std::monostate>(vb));
- return va == vb;
- });
+ [&](const core::type::Invalid*) { return true; },
+ [&](Default) { return InternalValue() == b->InternalValue(); });
}
} // namespace tint::core::constant
diff --git a/src/tint/lang/core/ir/builder.h b/src/tint/lang/core/ir/builder.h
index e3b797b..48cad54 100644
--- a/src/tint/lang/core/ir/builder.h
+++ b/src/tint/lang/core/ir/builder.h
@@ -361,6 +361,10 @@
return Constant(ConstantValue(v));
}
+ /// Creates a new invalid ir::Constant
+ /// @returns the new constant
+ ir::Constant* InvalidConstant() { return Constant(ir.constant_values.Invalid()); }
+
/// Retrieves the inner constant from an ir::Constant
/// @param constant the ir constant
/// @returns the core::constant::Value inside the constant