[tint] Begin decoupling intrinsic table data from table.cc
Change-Id: I123733c34808957f37da7b7dd964727d2f069c46
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/144128
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index 794d8ab..b1e6daa 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -289,11 +289,12 @@
sources = [
"lang/core/constant/eval.cc",
"lang/core/constant/eval.h",
+ "lang/core/intrinsic/core_table_data.cc",
+ "lang/core/intrinsic/core_table_data.h",
"lang/core/intrinsic/ctor_conv.cc",
"lang/core/intrinsic/ctor_conv.h",
"lang/core/intrinsic/table.cc",
"lang/core/intrinsic/table.h",
- "lang/core/intrinsic/table.inl",
"lang/wgsl/program/clone_context.cc",
"lang/wgsl/program/program.cc",
"lang/wgsl/program/program_builder.cc",
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 52f39e1..157a51e 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -518,9 +518,12 @@
lang/core/constant/eval.h
lang/wgsl/resolver/dependency_graph.cc
lang/wgsl/resolver/dependency_graph.h
+ lang/core/intrinsic/core_table_data.cc
+ lang/core/intrinsic/core_table_data.h
+ lang/core/intrinsic/ctor_conv.cc
+ lang/core/intrinsic/ctor_conv.h
lang/core/intrinsic/table.cc
lang/core/intrinsic/table.h
- lang/core/intrinsic/table.inl
lang/wgsl/resolver/resolve.cc
lang/wgsl/resolver/resolve.h
lang/wgsl/resolver/resolver.cc
diff --git a/src/tint/lang/core/intrinsic/table.inl b/src/tint/lang/core/intrinsic/core_table_data.cc
similarity index 83%
rename from src/tint/lang/core/intrinsic/table.inl
rename to src/tint/lang/core/intrinsic/core_table_data.cc
index 43a8477..c46680b 100644
--- a/src/tint/lang/core/intrinsic/table.inl
+++ b/src/tint/lang/core/intrinsic/core_table_data.cc
@@ -1,4 +1,4 @@
-// Copyright 2021 The Tint Authors.
+// Copyright 2023 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.
@@ -15,2828 +15,1788 @@
////////////////////////////////////////////////////////////////////////////////
// File generated by tools/src/cmd/gen
// using the template:
-// src/tint/lang/core/intrinsic/table.inl.tmpl
+// src/tint/lang/core/intrinsic/core_table_data.cc.tmpl
//
// Do not modify this file directly
////////////////////////////////////////////////////////////////////////////////
+#include <limits>
+#include <string>
+
+#include "src/tint/lang/core/intrinsic/core_table_data.h"
+#include "src/tint/lang/core/intrinsic/core_type_matchers.h"
+#include "src/tint/utils/text/string_stream.h"
+
+namespace tint::core::intrinsic {
+namespace {
+
+using IntrinsicInfo = tint::core::intrinsic::TableData::IntrinsicInfo;
+using MatcherIndex = tint::core::intrinsic::TableData::MatcherIndex;
+using MatchState = tint::core::intrinsic::TableData::MatchState;
+using Number = tint::core::intrinsic::TableData::Number;
+using NumberMatcher = tint::core::intrinsic::TableData::NumberMatcher;
+using OverloadFlag = tint::core::intrinsic::TableData::OverloadFlag;
+using OverloadFlags = tint::core::intrinsic::TableData::OverloadFlags;
+using OverloadInfo = tint::core::intrinsic::TableData::OverloadInfo;
+using ParameterInfo = tint::core::intrinsic::TableData::ParameterInfo;
+using StringStream = tint::StringStream;
+using TemplateNumberInfo = tint::core::intrinsic::TableData::TemplateNumberInfo;
+using TemplateTypeInfo = tint::core::intrinsic::TableData::TemplateTypeInfo;
+using Type = tint::type::Type;
+using TypeMatcher = tint::core::intrinsic::TableData::TypeMatcher;
+
+template <size_t N>
+using TemplateNumberMatcher = tint::core::intrinsic::TableData::TemplateNumberMatcher<N>;
+
+template <size_t N>
+using TemplateTypeMatcher = tint::core::intrinsic::TableData::TemplateTypeMatcher<N>;
+
+static constexpr auto kNoMatcher = tint::core::intrinsic::TableData::kNoMatcher;
+
// clang-format off
/// TypeMatcher for 'type bool'
-class Bool : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kBoolMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (!match_bool(state, ty)) {
+ return nullptr;
+ }
+ return build_bool(state);
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "bool";
+ }
};
-const type::Type* Bool::Match(MatchState& state, const type::Type* ty) const {
- if (!match_bool(state, ty)) {
- return nullptr;
- }
- return build_bool(state);
-}
-
-std::string Bool::String(MatchState*) const {
- return "bool";
-}
/// TypeMatcher for 'type ia'
-class Ia : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kIaMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (!match_ia(state, ty)) {
+ return nullptr;
+ }
+ return build_ia(state);
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ ss << "abstract-int";
+ return ss.str();
+ }
};
-const type::Type* Ia::Match(MatchState& state, const type::Type* ty) const {
- if (!match_ia(state, ty)) {
- return nullptr;
- }
- return build_ia(state);
-}
-
-std::string Ia::String(MatchState*) const {
- StringStream ss;
- ss << "abstract-int";
- return ss.str();
-}
/// TypeMatcher for 'type fa'
-class Fa : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kFaMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (!match_fa(state, ty)) {
+ return nullptr;
+ }
+ return build_fa(state);
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ ss << "abstract-float";
+ return ss.str();
+ }
};
-const type::Type* Fa::Match(MatchState& state, const type::Type* ty) const {
- if (!match_fa(state, ty)) {
- return nullptr;
- }
- return build_fa(state);
-}
-
-std::string Fa::String(MatchState*) const {
- StringStream ss;
- ss << "abstract-float";
- return ss.str();
-}
/// TypeMatcher for 'type i32'
-class I32 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kI32Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (!match_i32(state, ty)) {
+ return nullptr;
+ }
+ return build_i32(state);
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "i32";
+ }
};
-const type::Type* I32::Match(MatchState& state, const type::Type* ty) const {
- if (!match_i32(state, ty)) {
- return nullptr;
- }
- return build_i32(state);
-}
-
-std::string I32::String(MatchState*) const {
- return "i32";
-}
/// TypeMatcher for 'type u32'
-class U32 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kU32Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (!match_u32(state, ty)) {
+ return nullptr;
+ }
+ return build_u32(state);
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "u32";
+ }
};
-const type::Type* U32::Match(MatchState& state, const type::Type* ty) const {
- if (!match_u32(state, ty)) {
- return nullptr;
- }
- return build_u32(state);
-}
-
-std::string U32::String(MatchState*) const {
- return "u32";
-}
/// TypeMatcher for 'type f32'
-class F32 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kF32Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (!match_f32(state, ty)) {
+ return nullptr;
+ }
+ return build_f32(state);
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "f32";
+ }
};
-const type::Type* F32::Match(MatchState& state, const type::Type* ty) const {
- if (!match_f32(state, ty)) {
- return nullptr;
- }
- return build_f32(state);
-}
-
-std::string F32::String(MatchState*) const {
- return "f32";
-}
/// TypeMatcher for 'type f16'
-class F16 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kF16Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (!match_f16(state, ty)) {
+ return nullptr;
+ }
+ return build_f16(state);
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "f16";
+ }
};
-const type::Type* F16::Match(MatchState& state, const type::Type* ty) const {
- if (!match_f16(state, ty)) {
- return nullptr;
- }
- return build_f16(state);
-}
-
-std::string F16::String(MatchState*) const {
- return "f16";
-}
/// TypeMatcher for 'type vec2'
-class Vec2 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kVec2Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_vec2(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_vec2(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "vec2<" + T + ">";
+ }
};
-const type::Type* Vec2::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_vec2(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_vec2(state, T);
-}
-
-std::string Vec2::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "vec2<" + T + ">";
-}
/// TypeMatcher for 'type vec3'
-class Vec3 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kVec3Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_vec3(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_vec3(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "vec3<" + T + ">";
+ }
};
-const type::Type* Vec3::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_vec3(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_vec3(state, T);
-}
-
-std::string Vec3::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "vec3<" + T + ">";
-}
/// TypeMatcher for 'type vec4'
-class Vec4 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kVec4Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_vec4(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_vec4(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "vec4<" + T + ">";
+ }
};
-const type::Type* Vec4::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_vec4(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_vec4(state, T);
-}
-
-std::string Vec4::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "vec4<" + T + ">";
-}
/// TypeMatcher for 'type mat2x2'
-class Mat2X2 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kMat2X2Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_mat2x2(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat2x2(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "mat2x2<" + T + ">";
+ }
};
-const type::Type* Mat2X2::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_mat2x2(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_mat2x2(state, T);
-}
-
-std::string Mat2X2::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "mat2x2<" + T + ">";
-}
/// TypeMatcher for 'type mat2x3'
-class Mat2X3 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kMat2X3Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_mat2x3(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat2x3(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "mat2x3<" + T + ">";
+ }
};
-const type::Type* Mat2X3::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_mat2x3(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_mat2x3(state, T);
-}
-
-std::string Mat2X3::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "mat2x3<" + T + ">";
-}
/// TypeMatcher for 'type mat2x4'
-class Mat2X4 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kMat2X4Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_mat2x4(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat2x4(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "mat2x4<" + T + ">";
+ }
};
-const type::Type* Mat2X4::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_mat2x4(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_mat2x4(state, T);
-}
-
-std::string Mat2X4::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "mat2x4<" + T + ">";
-}
/// TypeMatcher for 'type mat3x2'
-class Mat3X2 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kMat3X2Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_mat3x2(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat3x2(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "mat3x2<" + T + ">";
+ }
};
-const type::Type* Mat3X2::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_mat3x2(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_mat3x2(state, T);
-}
-
-std::string Mat3X2::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "mat3x2<" + T + ">";
-}
/// TypeMatcher for 'type mat3x3'
-class Mat3X3 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kMat3X3Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_mat3x3(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat3x3(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "mat3x3<" + T + ">";
+ }
};
-const type::Type* Mat3X3::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_mat3x3(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_mat3x3(state, T);
-}
-
-std::string Mat3X3::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "mat3x3<" + T + ">";
-}
/// TypeMatcher for 'type mat3x4'
-class Mat3X4 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kMat3X4Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_mat3x4(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat3x4(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "mat3x4<" + T + ">";
+ }
};
-const type::Type* Mat3X4::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_mat3x4(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_mat3x4(state, T);
-}
-
-std::string Mat3X4::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "mat3x4<" + T + ">";
-}
/// TypeMatcher for 'type mat4x2'
-class Mat4X2 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kMat4X2Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_mat4x2(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat4x2(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "mat4x2<" + T + ">";
+ }
};
-const type::Type* Mat4X2::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_mat4x2(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_mat4x2(state, T);
-}
-
-std::string Mat4X2::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "mat4x2<" + T + ">";
-}
/// TypeMatcher for 'type mat4x3'
-class Mat4X3 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kMat4X3Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_mat4x3(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat4x3(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "mat4x3<" + T + ">";
+ }
};
-const type::Type* Mat4X3::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_mat4x3(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_mat4x3(state, T);
-}
-
-std::string Mat4X3::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "mat4x3<" + T + ">";
-}
/// TypeMatcher for 'type mat4x4'
-class Mat4X4 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kMat4X4Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_mat4x4(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat4x4(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "mat4x4<" + T + ">";
+ }
};
-const type::Type* Mat4X4::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_mat4x4(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_mat4x4(state, T);
-}
-
-std::string Mat4X4::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "mat4x4<" + T + ">";
-}
/// TypeMatcher for 'type vec'
-class Vec : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-const type::Type* Vec::Match(MatchState& state, const type::Type* ty) const {
+constexpr TypeMatcher kVecMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
Number N = Number::invalid;
- const type::Type* T = nullptr;
- if (!match_vec(state, ty, N, T)) {
- return nullptr;
- }
- N = state.Num(N);
- if (!N.IsValid()) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_vec(state, N, T);
-}
-
-std::string Vec::String(MatchState* state) const {
+ const Type* T = nullptr;
+ if (!match_vec(state, ty, N, T)) {
+ return nullptr;
+ }
+ N = state.Num(N);
+ if (!N.IsValid()) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_vec(state, N, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
const std::string N = state->NumName();
const std::string T = state->TypeName();
- StringStream ss;
- ss << "vec" << N << "<" << T << ">";
- return ss.str();
-}
-
-/// TypeMatcher for 'type mat'
-class Mat : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+ StringStream ss;
+ ss << "vec" << N << "<" << T << ">";
+ return ss.str();
+ }
};
-const type::Type* Mat::Match(MatchState& state, const type::Type* ty) const {
+
+/// TypeMatcher for 'type mat'
+constexpr TypeMatcher kMatMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
Number N = Number::invalid;
Number M = Number::invalid;
- const type::Type* T = nullptr;
- if (!match_mat(state, ty, N, M, T)) {
- return nullptr;
- }
- N = state.Num(N);
- if (!N.IsValid()) {
- return nullptr;
- }
- M = state.Num(M);
- if (!M.IsValid()) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_mat(state, N, M, T);
-}
-
-std::string Mat::String(MatchState* state) const {
+ const Type* T = nullptr;
+ if (!match_mat(state, ty, N, M, T)) {
+ return nullptr;
+ }
+ N = state.Num(N);
+ if (!N.IsValid()) {
+ return nullptr;
+ }
+ M = state.Num(M);
+ if (!M.IsValid()) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_mat(state, N, M, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
const std::string N = state->NumName();
const std::string M = state->NumName();
const std::string T = state->TypeName();
- StringStream ss;
- ss << "mat" << N << "x" << M << "<" << T << ">";
- return ss.str();
-}
-
-/// TypeMatcher for 'type ptr'
-class Ptr : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+ StringStream ss;
+ ss << "mat" << N << "x" << M << "<" << T << ">";
+ return ss.str();
+ }
};
-const type::Type* Ptr::Match(MatchState& state, const type::Type* ty) const {
- Number S = Number::invalid;
- const type::Type* T = nullptr;
- Number A = Number::invalid;
- if (!match_ptr(state, ty, S, T, A)) {
- return nullptr;
- }
- S = state.Num(S);
- if (!S.IsValid()) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- A = state.Num(A);
- if (!A.IsValid()) {
- return nullptr;
- }
- return build_ptr(state, S, T, A);
-}
-std::string Ptr::String(MatchState* state) const {
+/// TypeMatcher for 'type ptr'
+constexpr TypeMatcher kPtrMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ Number S = Number::invalid;
+ const Type* T = nullptr;
+ Number A = Number::invalid;
+ if (!match_ptr(state, ty, S, T, A)) {
+ return nullptr;
+ }
+ S = state.Num(S);
+ if (!S.IsValid()) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ A = state.Num(A);
+ if (!A.IsValid()) {
+ return nullptr;
+ }
+ return build_ptr(state, S, T, A);
+ },
+/* string */ [](MatchState* state) -> std::string {
const std::string S = state->NumName();
const std::string T = state->TypeName();
const std::string A = state->NumName();
- return "ptr<" + S + ", " + T + ", " + A + ">";
-}
+ return "ptr<" + S + ", " + T + ", " + A + ">";
+ }
+};
+
/// TypeMatcher for 'type atomic'
-class Atomic : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kAtomicMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_atomic(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_atomic(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "atomic<" + T + ">";
+ }
};
-const type::Type* Atomic::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_atomic(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_atomic(state, T);
-}
-
-std::string Atomic::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "atomic<" + T + ">";
-}
/// TypeMatcher for 'type array'
-class Array : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kArrayMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_array(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_array(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "array<" + T + ">";
+ }
};
-const type::Type* Array::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_array(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_array(state, T);
-}
-
-std::string Array::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "array<" + T + ">";
-}
/// TypeMatcher for 'type sampler'
-class Sampler : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kSamplerMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (!match_sampler(state, ty)) {
+ return nullptr;
+ }
+ return build_sampler(state);
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "sampler";
+ }
};
-const type::Type* Sampler::Match(MatchState& state, const type::Type* ty) const {
- if (!match_sampler(state, ty)) {
- return nullptr;
- }
- return build_sampler(state);
-}
-
-std::string Sampler::String(MatchState*) const {
- return "sampler";
-}
/// TypeMatcher for 'type sampler_comparison'
-class SamplerComparison : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kSamplerComparisonMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (!match_sampler_comparison(state, ty)) {
+ return nullptr;
+ }
+ return build_sampler_comparison(state);
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "sampler_comparison";
+ }
};
-const type::Type* SamplerComparison::Match(MatchState& state, const type::Type* ty) const {
- if (!match_sampler_comparison(state, ty)) {
- return nullptr;
- }
- return build_sampler_comparison(state);
-}
-
-std::string SamplerComparison::String(MatchState*) const {
- return "sampler_comparison";
-}
/// TypeMatcher for 'type texture_1d'
-class Texture1D : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kTexture1DMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_texture_1d(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_texture_1d(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "texture_1d<" + T + ">";
+ }
};
-const type::Type* Texture1D::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_texture_1d(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_texture_1d(state, T);
-}
-
-std::string Texture1D::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "texture_1d<" + T + ">";
-}
/// TypeMatcher for 'type texture_2d'
-class Texture2D : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kTexture2DMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_texture_2d(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_texture_2d(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "texture_2d<" + T + ">";
+ }
};
-const type::Type* Texture2D::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_texture_2d(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_texture_2d(state, T);
-}
-
-std::string Texture2D::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "texture_2d<" + T + ">";
-}
/// TypeMatcher for 'type texture_2d_array'
-class Texture2DArray : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kTexture2DArrayMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_texture_2d_array(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_texture_2d_array(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "texture_2d_array<" + T + ">";
+ }
};
-const type::Type* Texture2DArray::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_texture_2d_array(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_texture_2d_array(state, T);
-}
-
-std::string Texture2DArray::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "texture_2d_array<" + T + ">";
-}
/// TypeMatcher for 'type texture_3d'
-class Texture3D : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kTexture3DMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_texture_3d(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_texture_3d(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "texture_3d<" + T + ">";
+ }
};
-const type::Type* Texture3D::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_texture_3d(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_texture_3d(state, T);
-}
-
-std::string Texture3D::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "texture_3d<" + T + ">";
-}
/// TypeMatcher for 'type texture_cube'
-class TextureCube : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kTextureCubeMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_texture_cube(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_texture_cube(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "texture_cube<" + T + ">";
+ }
};
-const type::Type* TextureCube::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_texture_cube(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_texture_cube(state, T);
-}
-
-std::string TextureCube::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "texture_cube<" + T + ">";
-}
/// TypeMatcher for 'type texture_cube_array'
-class TextureCubeArray : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kTextureCubeArrayMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_texture_cube_array(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_texture_cube_array(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "texture_cube_array<" + T + ">";
+ }
};
-const type::Type* TextureCubeArray::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_texture_cube_array(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_texture_cube_array(state, T);
-}
-
-std::string TextureCubeArray::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "texture_cube_array<" + T + ">";
-}
/// TypeMatcher for 'type texture_multisampled_2d'
-class TextureMultisampled2D : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kTextureMultisampled2DMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_texture_multisampled_2d(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_texture_multisampled_2d(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "texture_multisampled_2d<" + T + ">";
+ }
};
-const type::Type* TextureMultisampled2D::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_texture_multisampled_2d(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_texture_multisampled_2d(state, T);
-}
-
-std::string TextureMultisampled2D::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "texture_multisampled_2d<" + T + ">";
-}
/// TypeMatcher for 'type texture_depth_2d'
-class TextureDepth2D : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kTextureDepth2DMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (!match_texture_depth_2d(state, ty)) {
+ return nullptr;
+ }
+ return build_texture_depth_2d(state);
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "texture_depth_2d";
+ }
};
-const type::Type* TextureDepth2D::Match(MatchState& state, const type::Type* ty) const {
- if (!match_texture_depth_2d(state, ty)) {
- return nullptr;
- }
- return build_texture_depth_2d(state);
-}
-
-std::string TextureDepth2D::String(MatchState*) const {
- return "texture_depth_2d";
-}
/// TypeMatcher for 'type texture_depth_2d_array'
-class TextureDepth2DArray : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kTextureDepth2DArrayMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (!match_texture_depth_2d_array(state, ty)) {
+ return nullptr;
+ }
+ return build_texture_depth_2d_array(state);
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "texture_depth_2d_array";
+ }
};
-const type::Type* TextureDepth2DArray::Match(MatchState& state, const type::Type* ty) const {
- if (!match_texture_depth_2d_array(state, ty)) {
- return nullptr;
- }
- return build_texture_depth_2d_array(state);
-}
-
-std::string TextureDepth2DArray::String(MatchState*) const {
- return "texture_depth_2d_array";
-}
/// TypeMatcher for 'type texture_depth_cube'
-class TextureDepthCube : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kTextureDepthCubeMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (!match_texture_depth_cube(state, ty)) {
+ return nullptr;
+ }
+ return build_texture_depth_cube(state);
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "texture_depth_cube";
+ }
};
-const type::Type* TextureDepthCube::Match(MatchState& state, const type::Type* ty) const {
- if (!match_texture_depth_cube(state, ty)) {
- return nullptr;
- }
- return build_texture_depth_cube(state);
-}
-
-std::string TextureDepthCube::String(MatchState*) const {
- return "texture_depth_cube";
-}
/// TypeMatcher for 'type texture_depth_cube_array'
-class TextureDepthCubeArray : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kTextureDepthCubeArrayMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (!match_texture_depth_cube_array(state, ty)) {
+ return nullptr;
+ }
+ return build_texture_depth_cube_array(state);
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "texture_depth_cube_array";
+ }
};
-const type::Type* TextureDepthCubeArray::Match(MatchState& state, const type::Type* ty) const {
- if (!match_texture_depth_cube_array(state, ty)) {
- return nullptr;
- }
- return build_texture_depth_cube_array(state);
-}
-
-std::string TextureDepthCubeArray::String(MatchState*) const {
- return "texture_depth_cube_array";
-}
/// TypeMatcher for 'type texture_depth_multisampled_2d'
-class TextureDepthMultisampled2D : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kTextureDepthMultisampled2DMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (!match_texture_depth_multisampled_2d(state, ty)) {
+ return nullptr;
+ }
+ return build_texture_depth_multisampled_2d(state);
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "texture_depth_multisampled_2d";
+ }
};
-const type::Type* TextureDepthMultisampled2D::Match(MatchState& state, const type::Type* ty) const {
- if (!match_texture_depth_multisampled_2d(state, ty)) {
- return nullptr;
- }
- return build_texture_depth_multisampled_2d(state);
-}
-
-std::string TextureDepthMultisampled2D::String(MatchState*) const {
- return "texture_depth_multisampled_2d";
-}
/// TypeMatcher for 'type texture_storage_1d'
-class TextureStorage1D : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-const type::Type* TextureStorage1D::Match(MatchState& state, const type::Type* ty) const {
+constexpr TypeMatcher kTextureStorage1DMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
Number F = Number::invalid;
Number A = Number::invalid;
- if (!match_texture_storage_1d(state, ty, F, A)) {
- return nullptr;
- }
- F = state.Num(F);
- if (!F.IsValid()) {
- return nullptr;
- }
- A = state.Num(A);
- if (!A.IsValid()) {
- return nullptr;
- }
- return build_texture_storage_1d(state, F, A);
-}
-
-std::string TextureStorage1D::String(MatchState* state) const {
+ if (!match_texture_storage_1d(state, ty, F, A)) {
+ return nullptr;
+ }
+ F = state.Num(F);
+ if (!F.IsValid()) {
+ return nullptr;
+ }
+ A = state.Num(A);
+ if (!A.IsValid()) {
+ return nullptr;
+ }
+ return build_texture_storage_1d(state, F, A);
+ },
+/* string */ [](MatchState* state) -> std::string {
const std::string F = state->NumName();
const std::string A = state->NumName();
- return "texture_storage_1d<" + F + ", " + A + ">";
-}
+ return "texture_storage_1d<" + F + ", " + A + ">";
+ }
+};
+
/// TypeMatcher for 'type texture_storage_2d'
-class TextureStorage2D : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-const type::Type* TextureStorage2D::Match(MatchState& state, const type::Type* ty) const {
+constexpr TypeMatcher kTextureStorage2DMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
Number F = Number::invalid;
Number A = Number::invalid;
- if (!match_texture_storage_2d(state, ty, F, A)) {
- return nullptr;
- }
- F = state.Num(F);
- if (!F.IsValid()) {
- return nullptr;
- }
- A = state.Num(A);
- if (!A.IsValid()) {
- return nullptr;
- }
- return build_texture_storage_2d(state, F, A);
-}
-
-std::string TextureStorage2D::String(MatchState* state) const {
+ if (!match_texture_storage_2d(state, ty, F, A)) {
+ return nullptr;
+ }
+ F = state.Num(F);
+ if (!F.IsValid()) {
+ return nullptr;
+ }
+ A = state.Num(A);
+ if (!A.IsValid()) {
+ return nullptr;
+ }
+ return build_texture_storage_2d(state, F, A);
+ },
+/* string */ [](MatchState* state) -> std::string {
const std::string F = state->NumName();
const std::string A = state->NumName();
- return "texture_storage_2d<" + F + ", " + A + ">";
-}
+ return "texture_storage_2d<" + F + ", " + A + ">";
+ }
+};
+
/// TypeMatcher for 'type texture_storage_2d_array'
-class TextureStorage2DArray : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-const type::Type* TextureStorage2DArray::Match(MatchState& state, const type::Type* ty) const {
+constexpr TypeMatcher kTextureStorage2DArrayMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
Number F = Number::invalid;
Number A = Number::invalid;
- if (!match_texture_storage_2d_array(state, ty, F, A)) {
- return nullptr;
- }
- F = state.Num(F);
- if (!F.IsValid()) {
- return nullptr;
- }
- A = state.Num(A);
- if (!A.IsValid()) {
- return nullptr;
- }
- return build_texture_storage_2d_array(state, F, A);
-}
-
-std::string TextureStorage2DArray::String(MatchState* state) const {
+ if (!match_texture_storage_2d_array(state, ty, F, A)) {
+ return nullptr;
+ }
+ F = state.Num(F);
+ if (!F.IsValid()) {
+ return nullptr;
+ }
+ A = state.Num(A);
+ if (!A.IsValid()) {
+ return nullptr;
+ }
+ return build_texture_storage_2d_array(state, F, A);
+ },
+/* string */ [](MatchState* state) -> std::string {
const std::string F = state->NumName();
const std::string A = state->NumName();
- return "texture_storage_2d_array<" + F + ", " + A + ">";
-}
+ return "texture_storage_2d_array<" + F + ", " + A + ">";
+ }
+};
+
/// TypeMatcher for 'type texture_storage_3d'
-class TextureStorage3D : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-const type::Type* TextureStorage3D::Match(MatchState& state, const type::Type* ty) const {
+constexpr TypeMatcher kTextureStorage3DMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
Number F = Number::invalid;
Number A = Number::invalid;
- if (!match_texture_storage_3d(state, ty, F, A)) {
- return nullptr;
- }
- F = state.Num(F);
- if (!F.IsValid()) {
- return nullptr;
- }
- A = state.Num(A);
- if (!A.IsValid()) {
- return nullptr;
- }
- return build_texture_storage_3d(state, F, A);
-}
-
-std::string TextureStorage3D::String(MatchState* state) const {
+ if (!match_texture_storage_3d(state, ty, F, A)) {
+ return nullptr;
+ }
+ F = state.Num(F);
+ if (!F.IsValid()) {
+ return nullptr;
+ }
+ A = state.Num(A);
+ if (!A.IsValid()) {
+ return nullptr;
+ }
+ return build_texture_storage_3d(state, F, A);
+ },
+/* string */ [](MatchState* state) -> std::string {
const std::string F = state->NumName();
const std::string A = state->NumName();
- return "texture_storage_3d<" + F + ", " + A + ">";
-}
+ return "texture_storage_3d<" + F + ", " + A + ">";
+ }
+};
+
/// TypeMatcher for 'type texture_external'
-class TextureExternal : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kTextureExternalMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (!match_texture_external(state, ty)) {
+ return nullptr;
+ }
+ return build_texture_external(state);
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "texture_external";
+ }
};
-const type::Type* TextureExternal::Match(MatchState& state, const type::Type* ty) const {
- if (!match_texture_external(state, ty)) {
- return nullptr;
- }
- return build_texture_external(state);
-}
-
-std::string TextureExternal::String(MatchState*) const {
- return "texture_external";
-}
/// TypeMatcher for 'type packedVec3'
-class PackedVec3 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kPackedVec3Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_packedVec3(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_packedVec3(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "packedVec3<" + T + ">";
+ }
};
-const type::Type* PackedVec3::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_packedVec3(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_packedVec3(state, T);
-}
-
-std::string PackedVec3::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "packedVec3<" + T + ">";
-}
/// TypeMatcher for 'type __modf_result'
-class ModfResult : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kModfResultMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_modf_result(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_modf_result(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ StringStream ss;
+ ss << "__modf_result_" << T;
+ return ss.str();
+ }
};
-const type::Type* ModfResult::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_modf_result(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_modf_result(state, T);
-}
-
-std::string ModfResult::String(MatchState* state) const {
- const std::string T = state->TypeName();
- StringStream ss;
- ss << "__modf_result_" << T;
- return ss.str();
-}
/// TypeMatcher for 'type __modf_result_vec'
-class ModfResultVec : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-const type::Type* ModfResultVec::Match(MatchState& state, const type::Type* ty) const {
+constexpr TypeMatcher kModfResultVecMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
Number N = Number::invalid;
- const type::Type* T = nullptr;
- if (!match_modf_result_vec(state, ty, N, T)) {
- return nullptr;
- }
- N = state.Num(N);
- if (!N.IsValid()) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_modf_result_vec(state, N, T);
-}
-
-std::string ModfResultVec::String(MatchState* state) const {
+ const Type* T = nullptr;
+ if (!match_modf_result_vec(state, ty, N, T)) {
+ return nullptr;
+ }
+ N = state.Num(N);
+ if (!N.IsValid()) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_modf_result_vec(state, N, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
const std::string N = state->NumName();
const std::string T = state->TypeName();
- StringStream ss;
- ss << "__modf_result_vec" << N << "_" << T;
- return ss.str();
-}
+ StringStream ss;
+ ss << "__modf_result_vec" << N << "_" << T;
+ return ss.str();
+ }
+};
+
/// TypeMatcher for 'type __frexp_result'
-class FrexpResult : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kFrexpResultMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_frexp_result(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_frexp_result(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ StringStream ss;
+ ss << "__frexp_result_" << T;
+ return ss.str();
+ }
};
-const type::Type* FrexpResult::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_frexp_result(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_frexp_result(state, T);
-}
-
-std::string FrexpResult::String(MatchState* state) const {
- const std::string T = state->TypeName();
- StringStream ss;
- ss << "__frexp_result_" << T;
- return ss.str();
-}
/// TypeMatcher for 'type __frexp_result_vec'
-class FrexpResultVec : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-const type::Type* FrexpResultVec::Match(MatchState& state, const type::Type* ty) const {
+constexpr TypeMatcher kFrexpResultVecMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
Number N = Number::invalid;
- const type::Type* T = nullptr;
- if (!match_frexp_result_vec(state, ty, N, T)) {
- return nullptr;
- }
- N = state.Num(N);
- if (!N.IsValid()) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_frexp_result_vec(state, N, T);
-}
-
-std::string FrexpResultVec::String(MatchState* state) const {
+ const Type* T = nullptr;
+ if (!match_frexp_result_vec(state, ty, N, T)) {
+ return nullptr;
+ }
+ N = state.Num(N);
+ if (!N.IsValid()) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_frexp_result_vec(state, N, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
const std::string N = state->NumName();
const std::string T = state->TypeName();
- StringStream ss;
- ss << "__frexp_result_vec" << N << "_" << T;
- return ss.str();
-}
+ StringStream ss;
+ ss << "__frexp_result_vec" << N << "_" << T;
+ return ss.str();
+ }
+};
+
/// TypeMatcher for 'type __atomic_compare_exchange_result'
-class AtomicCompareExchangeResult : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kAtomicCompareExchangeResultMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ const Type* T = nullptr;
+ if (!match_atomic_compare_exchange_result(state, ty, T)) {
+ return nullptr;
+ }
+ T = state.Type(T);
+ if (T == nullptr) {
+ return nullptr;
+ }
+ return build_atomic_compare_exchange_result(state, T);
+ },
+/* string */ [](MatchState* state) -> std::string {
+ const std::string T = state->TypeName();
+ return "__atomic_compare_exchange_result<" + T + ">";
+ }
};
-const type::Type* AtomicCompareExchangeResult::Match(MatchState& state, const type::Type* ty) const {
- const type::Type* T = nullptr;
- if (!match_atomic_compare_exchange_result(state, ty, T)) {
- return nullptr;
- }
- T = state.Type(T);
- if (T == nullptr) {
- return nullptr;
- }
- return build_atomic_compare_exchange_result(state, T);
-}
-
-std::string AtomicCompareExchangeResult::String(MatchState* state) const {
- const std::string T = state->TypeName();
- return "__atomic_compare_exchange_result<" + T + ">";
-}
/// TypeMatcher for 'match scalar'
-class Scalar : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kScalarMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_ia(state, ty)) {
+ return build_ia(state);
+ }
+ if (match_fa(state, ty)) {
+ return build_fa(state);
+ }
+ if (match_i32(state, ty)) {
+ return build_i32(state);
+ }
+ if (match_u32(state, ty)) {
+ return build_u32(state);
+ }
+ if (match_f32(state, ty)) {
+ return build_f32(state);
+ }
+ if (match_f16(state, ty)) {
+ return build_f16(state);
+ }
+ if (match_bool(state, ty)) {
+ return build_bool(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kIaMatcher.string(nullptr) << ", " << kFaMatcher.string(nullptr) << ", " << kF32Matcher.string(nullptr) << ", " << kF16Matcher.string(nullptr) << ", " << kI32Matcher.string(nullptr) << ", " << kU32Matcher.string(nullptr) << " or " << kBoolMatcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* Scalar::Match(MatchState& state, const type::Type* ty) const {
- if (match_ia(state, ty)) {
- return build_ia(state);
- }
- if (match_fa(state, ty)) {
- return build_fa(state);
- }
- if (match_i32(state, ty)) {
- return build_i32(state);
- }
- if (match_u32(state, ty)) {
- return build_u32(state);
- }
- if (match_f32(state, ty)) {
- return build_f32(state);
- }
- if (match_f16(state, ty)) {
- return build_f16(state);
- }
- if (match_bool(state, ty)) {
- return build_bool(state);
- }
- return nullptr;
-}
-
-std::string Scalar::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << Ia().String(nullptr) << ", " << Fa().String(nullptr) << ", " << F32().String(nullptr) << ", " << F16().String(nullptr) << ", " << I32().String(nullptr) << ", " << U32().String(nullptr) << " or " << Bool().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match concrete_scalar'
-class ConcreteScalar : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kConcreteScalarMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_i32(state, ty)) {
+ return build_i32(state);
+ }
+ if (match_u32(state, ty)) {
+ return build_u32(state);
+ }
+ if (match_f32(state, ty)) {
+ return build_f32(state);
+ }
+ if (match_f16(state, ty)) {
+ return build_f16(state);
+ }
+ if (match_bool(state, ty)) {
+ return build_bool(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kF32Matcher.string(nullptr) << ", " << kF16Matcher.string(nullptr) << ", " << kI32Matcher.string(nullptr) << ", " << kU32Matcher.string(nullptr) << " or " << kBoolMatcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* ConcreteScalar::Match(MatchState& state, const type::Type* ty) const {
- if (match_i32(state, ty)) {
- return build_i32(state);
- }
- if (match_u32(state, ty)) {
- return build_u32(state);
- }
- if (match_f32(state, ty)) {
- return build_f32(state);
- }
- if (match_f16(state, ty)) {
- return build_f16(state);
- }
- if (match_bool(state, ty)) {
- return build_bool(state);
- }
- return nullptr;
-}
-
-std::string ConcreteScalar::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << F32().String(nullptr) << ", " << F16().String(nullptr) << ", " << I32().String(nullptr) << ", " << U32().String(nullptr) << " or " << Bool().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match scalar_no_f32'
-class ScalarNoF32 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kScalarNoF32Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_ia(state, ty)) {
+ return build_ia(state);
+ }
+ if (match_fa(state, ty)) {
+ return build_fa(state);
+ }
+ if (match_i32(state, ty)) {
+ return build_i32(state);
+ }
+ if (match_u32(state, ty)) {
+ return build_u32(state);
+ }
+ if (match_f16(state, ty)) {
+ return build_f16(state);
+ }
+ if (match_bool(state, ty)) {
+ return build_bool(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kIaMatcher.string(nullptr) << ", " << kFaMatcher.string(nullptr) << ", " << kI32Matcher.string(nullptr) << ", " << kF16Matcher.string(nullptr) << ", " << kU32Matcher.string(nullptr) << " or " << kBoolMatcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* ScalarNoF32::Match(MatchState& state, const type::Type* ty) const {
- if (match_ia(state, ty)) {
- return build_ia(state);
- }
- if (match_fa(state, ty)) {
- return build_fa(state);
- }
- if (match_i32(state, ty)) {
- return build_i32(state);
- }
- if (match_u32(state, ty)) {
- return build_u32(state);
- }
- if (match_f16(state, ty)) {
- return build_f16(state);
- }
- if (match_bool(state, ty)) {
- return build_bool(state);
- }
- return nullptr;
-}
-
-std::string ScalarNoF32::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << Ia().String(nullptr) << ", " << Fa().String(nullptr) << ", " << I32().String(nullptr) << ", " << F16().String(nullptr) << ", " << U32().String(nullptr) << " or " << Bool().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match scalar_no_f16'
-class ScalarNoF16 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kScalarNoF16Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_ia(state, ty)) {
+ return build_ia(state);
+ }
+ if (match_fa(state, ty)) {
+ return build_fa(state);
+ }
+ if (match_i32(state, ty)) {
+ return build_i32(state);
+ }
+ if (match_u32(state, ty)) {
+ return build_u32(state);
+ }
+ if (match_f32(state, ty)) {
+ return build_f32(state);
+ }
+ if (match_bool(state, ty)) {
+ return build_bool(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kIaMatcher.string(nullptr) << ", " << kFaMatcher.string(nullptr) << ", " << kF32Matcher.string(nullptr) << ", " << kI32Matcher.string(nullptr) << ", " << kU32Matcher.string(nullptr) << " or " << kBoolMatcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* ScalarNoF16::Match(MatchState& state, const type::Type* ty) const {
- if (match_ia(state, ty)) {
- return build_ia(state);
- }
- if (match_fa(state, ty)) {
- return build_fa(state);
- }
- if (match_i32(state, ty)) {
- return build_i32(state);
- }
- if (match_u32(state, ty)) {
- return build_u32(state);
- }
- if (match_f32(state, ty)) {
- return build_f32(state);
- }
- if (match_bool(state, ty)) {
- return build_bool(state);
- }
- return nullptr;
-}
-
-std::string ScalarNoF16::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << Ia().String(nullptr) << ", " << Fa().String(nullptr) << ", " << F32().String(nullptr) << ", " << I32().String(nullptr) << ", " << U32().String(nullptr) << " or " << Bool().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match scalar_no_i32'
-class ScalarNoI32 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kScalarNoI32Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_ia(state, ty)) {
+ return build_ia(state);
+ }
+ if (match_fa(state, ty)) {
+ return build_fa(state);
+ }
+ if (match_u32(state, ty)) {
+ return build_u32(state);
+ }
+ if (match_f32(state, ty)) {
+ return build_f32(state);
+ }
+ if (match_f16(state, ty)) {
+ return build_f16(state);
+ }
+ if (match_bool(state, ty)) {
+ return build_bool(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kIaMatcher.string(nullptr) << ", " << kFaMatcher.string(nullptr) << ", " << kF32Matcher.string(nullptr) << ", " << kF16Matcher.string(nullptr) << ", " << kU32Matcher.string(nullptr) << " or " << kBoolMatcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* ScalarNoI32::Match(MatchState& state, const type::Type* ty) const {
- if (match_ia(state, ty)) {
- return build_ia(state);
- }
- if (match_fa(state, ty)) {
- return build_fa(state);
- }
- if (match_u32(state, ty)) {
- return build_u32(state);
- }
- if (match_f32(state, ty)) {
- return build_f32(state);
- }
- if (match_f16(state, ty)) {
- return build_f16(state);
- }
- if (match_bool(state, ty)) {
- return build_bool(state);
- }
- return nullptr;
-}
-
-std::string ScalarNoI32::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << Ia().String(nullptr) << ", " << Fa().String(nullptr) << ", " << F32().String(nullptr) << ", " << F16().String(nullptr) << ", " << U32().String(nullptr) << " or " << Bool().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match scalar_no_u32'
-class ScalarNoU32 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kScalarNoU32Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_ia(state, ty)) {
+ return build_ia(state);
+ }
+ if (match_fa(state, ty)) {
+ return build_fa(state);
+ }
+ if (match_i32(state, ty)) {
+ return build_i32(state);
+ }
+ if (match_f32(state, ty)) {
+ return build_f32(state);
+ }
+ if (match_f16(state, ty)) {
+ return build_f16(state);
+ }
+ if (match_bool(state, ty)) {
+ return build_bool(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kIaMatcher.string(nullptr) << ", " << kFaMatcher.string(nullptr) << ", " << kF32Matcher.string(nullptr) << ", " << kF16Matcher.string(nullptr) << ", " << kI32Matcher.string(nullptr) << " or " << kBoolMatcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* ScalarNoU32::Match(MatchState& state, const type::Type* ty) const {
- if (match_ia(state, ty)) {
- return build_ia(state);
- }
- if (match_fa(state, ty)) {
- return build_fa(state);
- }
- if (match_i32(state, ty)) {
- return build_i32(state);
- }
- if (match_f32(state, ty)) {
- return build_f32(state);
- }
- if (match_f16(state, ty)) {
- return build_f16(state);
- }
- if (match_bool(state, ty)) {
- return build_bool(state);
- }
- return nullptr;
-}
-
-std::string ScalarNoU32::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << Ia().String(nullptr) << ", " << Fa().String(nullptr) << ", " << F32().String(nullptr) << ", " << F16().String(nullptr) << ", " << I32().String(nullptr) << " or " << Bool().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match scalar_no_bool'
-class ScalarNoBool : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kScalarNoBoolMatcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_ia(state, ty)) {
+ return build_ia(state);
+ }
+ if (match_fa(state, ty)) {
+ return build_fa(state);
+ }
+ if (match_i32(state, ty)) {
+ return build_i32(state);
+ }
+ if (match_u32(state, ty)) {
+ return build_u32(state);
+ }
+ if (match_f32(state, ty)) {
+ return build_f32(state);
+ }
+ if (match_f16(state, ty)) {
+ return build_f16(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kIaMatcher.string(nullptr) << ", " << kFaMatcher.string(nullptr) << ", " << kF32Matcher.string(nullptr) << ", " << kF16Matcher.string(nullptr) << ", " << kI32Matcher.string(nullptr) << " or " << kU32Matcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* ScalarNoBool::Match(MatchState& state, const type::Type* ty) const {
- if (match_ia(state, ty)) {
- return build_ia(state);
- }
- if (match_fa(state, ty)) {
- return build_fa(state);
- }
- if (match_i32(state, ty)) {
- return build_i32(state);
- }
- if (match_u32(state, ty)) {
- return build_u32(state);
- }
- if (match_f32(state, ty)) {
- return build_f32(state);
- }
- if (match_f16(state, ty)) {
- return build_f16(state);
- }
- return nullptr;
-}
-
-std::string ScalarNoBool::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << Ia().String(nullptr) << ", " << Fa().String(nullptr) << ", " << F32().String(nullptr) << ", " << F16().String(nullptr) << ", " << I32().String(nullptr) << " or " << U32().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match fia_fiu32_f16'
-class FiaFiu32F16 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kFiaFiu32F16Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_ia(state, ty)) {
+ return build_ia(state);
+ }
+ if (match_fa(state, ty)) {
+ return build_fa(state);
+ }
+ if (match_i32(state, ty)) {
+ return build_i32(state);
+ }
+ if (match_u32(state, ty)) {
+ return build_u32(state);
+ }
+ if (match_f32(state, ty)) {
+ return build_f32(state);
+ }
+ if (match_f16(state, ty)) {
+ return build_f16(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kFaMatcher.string(nullptr) << ", " << kIaMatcher.string(nullptr) << ", " << kF32Matcher.string(nullptr) << ", " << kI32Matcher.string(nullptr) << ", " << kU32Matcher.string(nullptr) << " or " << kF16Matcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* FiaFiu32F16::Match(MatchState& state, const type::Type* ty) const {
- if (match_ia(state, ty)) {
- return build_ia(state);
- }
- if (match_fa(state, ty)) {
- return build_fa(state);
- }
- if (match_i32(state, ty)) {
- return build_i32(state);
- }
- if (match_u32(state, ty)) {
- return build_u32(state);
- }
- if (match_f32(state, ty)) {
- return build_f32(state);
- }
- if (match_f16(state, ty)) {
- return build_f16(state);
- }
- return nullptr;
-}
-
-std::string FiaFiu32F16::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << Fa().String(nullptr) << ", " << Ia().String(nullptr) << ", " << F32().String(nullptr) << ", " << I32().String(nullptr) << ", " << U32().String(nullptr) << " or " << F16().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match fia_fi32_f16'
-class FiaFi32F16 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kFiaFi32F16Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_ia(state, ty)) {
+ return build_ia(state);
+ }
+ if (match_fa(state, ty)) {
+ return build_fa(state);
+ }
+ if (match_i32(state, ty)) {
+ return build_i32(state);
+ }
+ if (match_f32(state, ty)) {
+ return build_f32(state);
+ }
+ if (match_f16(state, ty)) {
+ return build_f16(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kFaMatcher.string(nullptr) << ", " << kIaMatcher.string(nullptr) << ", " << kF32Matcher.string(nullptr) << ", " << kI32Matcher.string(nullptr) << " or " << kF16Matcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* FiaFi32F16::Match(MatchState& state, const type::Type* ty) const {
- if (match_ia(state, ty)) {
- return build_ia(state);
- }
- if (match_fa(state, ty)) {
- return build_fa(state);
- }
- if (match_i32(state, ty)) {
- return build_i32(state);
- }
- if (match_f32(state, ty)) {
- return build_f32(state);
- }
- if (match_f16(state, ty)) {
- return build_f16(state);
- }
- return nullptr;
-}
-
-std::string FiaFi32F16::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << Fa().String(nullptr) << ", " << Ia().String(nullptr) << ", " << F32().String(nullptr) << ", " << I32().String(nullptr) << " or " << F16().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match fia_fiu32'
-class FiaFiu32 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kFiaFiu32Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_ia(state, ty)) {
+ return build_ia(state);
+ }
+ if (match_fa(state, ty)) {
+ return build_fa(state);
+ }
+ if (match_i32(state, ty)) {
+ return build_i32(state);
+ }
+ if (match_u32(state, ty)) {
+ return build_u32(state);
+ }
+ if (match_f32(state, ty)) {
+ return build_f32(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kFaMatcher.string(nullptr) << ", " << kIaMatcher.string(nullptr) << ", " << kF32Matcher.string(nullptr) << ", " << kI32Matcher.string(nullptr) << " or " << kU32Matcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* FiaFiu32::Match(MatchState& state, const type::Type* ty) const {
- if (match_ia(state, ty)) {
- return build_ia(state);
- }
- if (match_fa(state, ty)) {
- return build_fa(state);
- }
- if (match_i32(state, ty)) {
- return build_i32(state);
- }
- if (match_u32(state, ty)) {
- return build_u32(state);
- }
- if (match_f32(state, ty)) {
- return build_f32(state);
- }
- return nullptr;
-}
-
-std::string FiaFiu32::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << Fa().String(nullptr) << ", " << Ia().String(nullptr) << ", " << F32().String(nullptr) << ", " << I32().String(nullptr) << " or " << U32().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match fa_f32'
-class FaF32 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kFaF32Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_fa(state, ty)) {
+ return build_fa(state);
+ }
+ if (match_f32(state, ty)) {
+ return build_f32(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kFaMatcher.string(nullptr) << " or " << kF32Matcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* FaF32::Match(MatchState& state, const type::Type* ty) const {
- if (match_fa(state, ty)) {
- return build_fa(state);
- }
- if (match_f32(state, ty)) {
- return build_f32(state);
- }
- return nullptr;
-}
-
-std::string FaF32::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << Fa().String(nullptr) << " or " << F32().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match fa_f32_f16'
-class FaF32F16 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kFaF32F16Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_fa(state, ty)) {
+ return build_fa(state);
+ }
+ if (match_f32(state, ty)) {
+ return build_f32(state);
+ }
+ if (match_f16(state, ty)) {
+ return build_f16(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kFaMatcher.string(nullptr) << ", " << kF32Matcher.string(nullptr) << " or " << kF16Matcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* FaF32F16::Match(MatchState& state, const type::Type* ty) const {
- if (match_fa(state, ty)) {
- return build_fa(state);
- }
- if (match_f32(state, ty)) {
- return build_f32(state);
- }
- if (match_f16(state, ty)) {
- return build_f16(state);
- }
- return nullptr;
-}
-
-std::string FaF32F16::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << Fa().String(nullptr) << ", " << F32().String(nullptr) << " or " << F16().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match ia_iu32'
-class IaIu32 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kIaIu32Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_ia(state, ty)) {
+ return build_ia(state);
+ }
+ if (match_i32(state, ty)) {
+ return build_i32(state);
+ }
+ if (match_u32(state, ty)) {
+ return build_u32(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kIaMatcher.string(nullptr) << ", " << kI32Matcher.string(nullptr) << " or " << kU32Matcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* IaIu32::Match(MatchState& state, const type::Type* ty) const {
- if (match_ia(state, ty)) {
- return build_ia(state);
- }
- if (match_i32(state, ty)) {
- return build_i32(state);
- }
- if (match_u32(state, ty)) {
- return build_u32(state);
- }
- return nullptr;
-}
-
-std::string IaIu32::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << Ia().String(nullptr) << ", " << I32().String(nullptr) << " or " << U32().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match ia_i32'
-class IaI32 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kIaI32Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_ia(state, ty)) {
+ return build_ia(state);
+ }
+ if (match_i32(state, ty)) {
+ return build_i32(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kIaMatcher.string(nullptr) << " or " << kI32Matcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* IaI32::Match(MatchState& state, const type::Type* ty) const {
- if (match_ia(state, ty)) {
- return build_ia(state);
- }
- if (match_i32(state, ty)) {
- return build_i32(state);
- }
- return nullptr;
-}
-
-std::string IaI32::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << Ia().String(nullptr) << " or " << I32().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match fiu32_f16'
-class Fiu32F16 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kFiu32F16Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_i32(state, ty)) {
+ return build_i32(state);
+ }
+ if (match_u32(state, ty)) {
+ return build_u32(state);
+ }
+ if (match_f32(state, ty)) {
+ return build_f32(state);
+ }
+ if (match_f16(state, ty)) {
+ return build_f16(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kF32Matcher.string(nullptr) << ", " << kI32Matcher.string(nullptr) << ", " << kU32Matcher.string(nullptr) << " or " << kF16Matcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* Fiu32F16::Match(MatchState& state, const type::Type* ty) const {
- if (match_i32(state, ty)) {
- return build_i32(state);
- }
- if (match_u32(state, ty)) {
- return build_u32(state);
- }
- if (match_f32(state, ty)) {
- return build_f32(state);
- }
- if (match_f16(state, ty)) {
- return build_f16(state);
- }
- return nullptr;
-}
-
-std::string Fiu32F16::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << F32().String(nullptr) << ", " << I32().String(nullptr) << ", " << U32().String(nullptr) << " or " << F16().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match fiu32'
-class Fiu32 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kFiu32Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_i32(state, ty)) {
+ return build_i32(state);
+ }
+ if (match_u32(state, ty)) {
+ return build_u32(state);
+ }
+ if (match_f32(state, ty)) {
+ return build_f32(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kF32Matcher.string(nullptr) << ", " << kI32Matcher.string(nullptr) << " or " << kU32Matcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* Fiu32::Match(MatchState& state, const type::Type* ty) const {
- if (match_i32(state, ty)) {
- return build_i32(state);
- }
- if (match_u32(state, ty)) {
- return build_u32(state);
- }
- if (match_f32(state, ty)) {
- return build_f32(state);
- }
- return nullptr;
-}
-
-std::string Fiu32::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << F32().String(nullptr) << ", " << I32().String(nullptr) << " or " << U32().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match fi32_f16'
-class Fi32F16 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kFi32F16Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_i32(state, ty)) {
+ return build_i32(state);
+ }
+ if (match_f32(state, ty)) {
+ return build_f32(state);
+ }
+ if (match_f16(state, ty)) {
+ return build_f16(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kF32Matcher.string(nullptr) << ", " << kI32Matcher.string(nullptr) << " or " << kF16Matcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* Fi32F16::Match(MatchState& state, const type::Type* ty) const {
- if (match_i32(state, ty)) {
- return build_i32(state);
- }
- if (match_f32(state, ty)) {
- return build_f32(state);
- }
- if (match_f16(state, ty)) {
- return build_f16(state);
- }
- return nullptr;
-}
-
-std::string Fi32F16::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << F32().String(nullptr) << ", " << I32().String(nullptr) << " or " << F16().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match fi32'
-class Fi32 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kFi32Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_i32(state, ty)) {
+ return build_i32(state);
+ }
+ if (match_f32(state, ty)) {
+ return build_f32(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kF32Matcher.string(nullptr) << " or " << kI32Matcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* Fi32::Match(MatchState& state, const type::Type* ty) const {
- if (match_i32(state, ty)) {
- return build_i32(state);
- }
- if (match_f32(state, ty)) {
- return build_f32(state);
- }
- return nullptr;
-}
-
-std::string Fi32::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << F32().String(nullptr) << " or " << I32().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match f32_f16'
-class F32F16 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kF32F16Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_f32(state, ty)) {
+ return build_f32(state);
+ }
+ if (match_f16(state, ty)) {
+ return build_f16(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kF32Matcher.string(nullptr) << " or " << kF16Matcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* F32F16::Match(MatchState& state, const type::Type* ty) const {
- if (match_f32(state, ty)) {
- return build_f32(state);
- }
- if (match_f16(state, ty)) {
- return build_f16(state);
- }
- return nullptr;
-}
-
-std::string F32F16::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << F32().String(nullptr) << " or " << F16().String(nullptr);
- return ss.str();
-}
-
/// TypeMatcher for 'match iu32'
-class Iu32 : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
+constexpr TypeMatcher kIu32Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
+ if (match_i32(state, ty)) {
+ return build_i32(state);
+ }
+ if (match_u32(state, ty)) {
+ return build_u32(state);
+ }
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss << kI32Matcher.string(nullptr) << " or " << kU32Matcher.string(nullptr);
+ return ss.str();
+ }
};
-const type::Type* Iu32::Match(MatchState& state, const type::Type* ty) const {
- if (match_i32(state, ty)) {
- return build_i32(state);
- }
- if (match_u32(state, ty)) {
- return build_u32(state);
- }
- return nullptr;
-}
-
-std::string Iu32::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss << I32().String(nullptr) << " or " << U32().String(nullptr);
- return ss.str();
-}
-
/// EnumMatcher for 'match f32_texel_format'
-class F32TexelFormat : public NumberMatcher {
- public:
- /// Checks whether the given number matches the enum matcher rules.
- /// Match may define template numbers in state.
- /// @param state the MatchState
- /// @param number the enum value as a Number
- /// @return true if the enum value matches the set
- Number Match(MatchState& state, Number number) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-Number F32TexelFormat::Match(MatchState&, Number number) const {
- switch (static_cast<TexelFormat>(number.Value())) {
- case TexelFormat::kBgra8Unorm:
- case TexelFormat::kRgba8Unorm:
- case TexelFormat::kRgba8Snorm:
- case TexelFormat::kRgba16Float:
- case TexelFormat::kR32Float:
- case TexelFormat::kRg32Float:
- case TexelFormat::kRgba32Float:
- return number;
- default:
- return Number::invalid;
+constexpr NumberMatcher kF32TexelFormatMatcher {
+/* match */ [](MatchState&, Number number) -> Number {
+ switch (static_cast<TexelFormat>(number.Value())) {
+ case TexelFormat::kBgra8Unorm:
+ case TexelFormat::kRgba8Unorm:
+ case TexelFormat::kRgba8Snorm:
+ case TexelFormat::kRgba16Float:
+ case TexelFormat::kR32Float:
+ case TexelFormat::kRg32Float:
+ case TexelFormat::kRgba32Float:
+ return number;
+ default:
+ return Number::invalid;
+ }
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "bgra8unorm, rgba8unorm, rgba8snorm, rgba16float, r32float, rg32float or rgba32float";
}
-}
-
-std::string F32TexelFormat::String(MatchState*) const {
- return "bgra8unorm, rgba8unorm, rgba8snorm, rgba16float, r32float, rg32float or rgba32float";
-}
+};
/// EnumMatcher for 'match i32_texel_format'
-class I32TexelFormat : public NumberMatcher {
- public:
- /// Checks whether the given number matches the enum matcher rules.
- /// Match may define template numbers in state.
- /// @param state the MatchState
- /// @param number the enum value as a Number
- /// @return true if the enum value matches the set
- Number Match(MatchState& state, Number number) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-Number I32TexelFormat::Match(MatchState&, Number number) const {
- switch (static_cast<TexelFormat>(number.Value())) {
- case TexelFormat::kRgba8Sint:
- case TexelFormat::kRgba16Sint:
- case TexelFormat::kR32Sint:
- case TexelFormat::kRg32Sint:
- case TexelFormat::kRgba32Sint:
- return number;
- default:
- return Number::invalid;
+constexpr NumberMatcher kI32TexelFormatMatcher {
+/* match */ [](MatchState&, Number number) -> Number {
+ switch (static_cast<TexelFormat>(number.Value())) {
+ case TexelFormat::kRgba8Sint:
+ case TexelFormat::kRgba16Sint:
+ case TexelFormat::kR32Sint:
+ case TexelFormat::kRg32Sint:
+ case TexelFormat::kRgba32Sint:
+ return number;
+ default:
+ return Number::invalid;
+ }
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "rgba8sint, rgba16sint, r32sint, rg32sint or rgba32sint";
}
-}
-
-std::string I32TexelFormat::String(MatchState*) const {
- return "rgba8sint, rgba16sint, r32sint, rg32sint or rgba32sint";
-}
+};
/// EnumMatcher for 'match u32_texel_format'
-class U32TexelFormat : public NumberMatcher {
- public:
- /// Checks whether the given number matches the enum matcher rules.
- /// Match may define template numbers in state.
- /// @param state the MatchState
- /// @param number the enum value as a Number
- /// @return true if the enum value matches the set
- Number Match(MatchState& state, Number number) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-Number U32TexelFormat::Match(MatchState&, Number number) const {
- switch (static_cast<TexelFormat>(number.Value())) {
- case TexelFormat::kRgba8Uint:
- case TexelFormat::kRgba16Uint:
- case TexelFormat::kR32Uint:
- case TexelFormat::kRg32Uint:
- case TexelFormat::kRgba32Uint:
- return number;
- default:
- return Number::invalid;
+constexpr NumberMatcher kU32TexelFormatMatcher {
+/* match */ [](MatchState&, Number number) -> Number {
+ switch (static_cast<TexelFormat>(number.Value())) {
+ case TexelFormat::kRgba8Uint:
+ case TexelFormat::kRgba16Uint:
+ case TexelFormat::kR32Uint:
+ case TexelFormat::kRg32Uint:
+ case TexelFormat::kRgba32Uint:
+ return number;
+ default:
+ return Number::invalid;
+ }
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "rgba8uint, rgba16uint, r32uint, rg32uint or rgba32uint";
}
-}
-
-std::string U32TexelFormat::String(MatchState*) const {
- return "rgba8uint, rgba16uint, r32uint, rg32uint or rgba32uint";
-}
+};
/// EnumMatcher for 'match write'
-class Write : public NumberMatcher {
- public:
- /// Checks whether the given number matches the enum matcher rules.
- /// Match may define template numbers in state.
- /// @param state the MatchState
- /// @param number the enum value as a Number
- /// @return true if the enum value matches the set
- Number Match(MatchState& state, Number number) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-Number Write::Match(MatchState&, Number number) const {
- if (number.IsAny() || number.Value() == static_cast<uint32_t>(Access::kWrite)) {
- return Number(static_cast<uint32_t>(Access::kWrite));
+constexpr NumberMatcher kWriteMatcher {
+/* match */ [](MatchState&, Number number) -> Number {
+ if (number.IsAny() || number.Value() == static_cast<uint32_t>(Access::kWrite)) {
+ return Number(static_cast<uint32_t>(Access::kWrite));
+ }
+ return Number::invalid;
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "write";
}
- return Number::invalid;
-}
-
-std::string Write::String(MatchState*) const {
- return "write";
-}
+};
/// EnumMatcher for 'match read_write'
-class ReadWrite : public NumberMatcher {
- public:
- /// Checks whether the given number matches the enum matcher rules.
- /// Match may define template numbers in state.
- /// @param state the MatchState
- /// @param number the enum value as a Number
- /// @return true if the enum value matches the set
- Number Match(MatchState& state, Number number) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-Number ReadWrite::Match(MatchState&, Number number) const {
- if (number.IsAny() || number.Value() == static_cast<uint32_t>(Access::kReadWrite)) {
- return Number(static_cast<uint32_t>(Access::kReadWrite));
+constexpr NumberMatcher kReadWriteMatcher {
+/* match */ [](MatchState&, Number number) -> Number {
+ if (number.IsAny() || number.Value() == static_cast<uint32_t>(Access::kReadWrite)) {
+ return Number(static_cast<uint32_t>(Access::kReadWrite));
+ }
+ return Number::invalid;
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "read_write";
}
- return Number::invalid;
-}
-
-std::string ReadWrite::String(MatchState*) const {
- return "read_write";
-}
+};
/// EnumMatcher for 'match function_private_workgroup'
-class FunctionPrivateWorkgroup : public NumberMatcher {
- public:
- /// Checks whether the given number matches the enum matcher rules.
- /// Match may define template numbers in state.
- /// @param state the MatchState
- /// @param number the enum value as a Number
- /// @return true if the enum value matches the set
- Number Match(MatchState& state, Number number) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-Number FunctionPrivateWorkgroup::Match(MatchState&, Number number) const {
- switch (static_cast<AddressSpace>(number.Value())) {
- case AddressSpace::kFunction:
- case AddressSpace::kPrivate:
- case AddressSpace::kWorkgroup:
- return number;
- default:
- return Number::invalid;
+constexpr NumberMatcher kFunctionPrivateWorkgroupMatcher {
+/* match */ [](MatchState&, Number number) -> Number {
+ switch (static_cast<AddressSpace>(number.Value())) {
+ case AddressSpace::kFunction:
+ case AddressSpace::kPrivate:
+ case AddressSpace::kWorkgroup:
+ return number;
+ default:
+ return Number::invalid;
+ }
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "function, private or workgroup";
}
-}
-
-std::string FunctionPrivateWorkgroup::String(MatchState*) const {
- return "function, private or workgroup";
-}
+};
/// EnumMatcher for 'match workgroup_or_storage'
-class WorkgroupOrStorage : public NumberMatcher {
- public:
- /// Checks whether the given number matches the enum matcher rules.
- /// Match may define template numbers in state.
- /// @param state the MatchState
- /// @param number the enum value as a Number
- /// @return true if the enum value matches the set
- Number Match(MatchState& state, Number number) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-Number WorkgroupOrStorage::Match(MatchState&, Number number) const {
- switch (static_cast<AddressSpace>(number.Value())) {
- case AddressSpace::kWorkgroup:
- case AddressSpace::kStorage:
- return number;
- default:
- return Number::invalid;
+constexpr NumberMatcher kWorkgroupOrStorageMatcher {
+/* match */ [](MatchState&, Number number) -> Number {
+ switch (static_cast<AddressSpace>(number.Value())) {
+ case AddressSpace::kWorkgroup:
+ case AddressSpace::kStorage:
+ return number;
+ default:
+ return Number::invalid;
+ }
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "workgroup or storage";
}
-}
-
-std::string WorkgroupOrStorage::String(MatchState*) const {
- return "workgroup or storage";
-}
+};
/// EnumMatcher for 'match storage'
-class Storage : public NumberMatcher {
- public:
- /// Checks whether the given number matches the enum matcher rules.
- /// Match may define template numbers in state.
- /// @param state the MatchState
- /// @param number the enum value as a Number
- /// @return true if the enum value matches the set
- Number Match(MatchState& state, Number number) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-Number Storage::Match(MatchState&, Number number) const {
- if (number.IsAny() || number.Value() == static_cast<uint32_t>(AddressSpace::kStorage)) {
- return Number(static_cast<uint32_t>(AddressSpace::kStorage));
+constexpr NumberMatcher kStorageMatcher {
+/* match */ [](MatchState&, Number number) -> Number {
+ if (number.IsAny() || number.Value() == static_cast<uint32_t>(AddressSpace::kStorage)) {
+ return Number(static_cast<uint32_t>(AddressSpace::kStorage));
+ }
+ return Number::invalid;
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "storage";
}
- return Number::invalid;
-}
-
-std::string Storage::String(MatchState*) const {
- return "storage";
-}
+};
/// EnumMatcher for 'match workgroup'
-class Workgroup : public NumberMatcher {
- public:
- /// Checks whether the given number matches the enum matcher rules.
- /// Match may define template numbers in state.
- /// @param state the MatchState
- /// @param number the enum value as a Number
- /// @return true if the enum value matches the set
- Number Match(MatchState& state, Number number) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-Number Workgroup::Match(MatchState&, Number number) const {
- if (number.IsAny() || number.Value() == static_cast<uint32_t>(AddressSpace::kWorkgroup)) {
- return Number(static_cast<uint32_t>(AddressSpace::kWorkgroup));
+constexpr NumberMatcher kWorkgroupMatcher {
+/* match */ [](MatchState&, Number number) -> Number {
+ if (number.IsAny() || number.Value() == static_cast<uint32_t>(AddressSpace::kWorkgroup)) {
+ return Number(static_cast<uint32_t>(AddressSpace::kWorkgroup));
+ }
+ return Number::invalid;
+ },
+/* string */ [](MatchState*) -> std::string {
+ return "workgroup";
}
- return Number::invalid;
-}
-
-std::string Workgroup::String(MatchState*) const {
- return "workgroup";
-}
-
-/// Matchers holds type and number matchers
-class Matchers {
- private:
- TemplateTypeMatcher template_type_0_{0};
- TemplateTypeMatcher template_type_1_{1};
- TemplateTypeMatcher template_type_2_{2};
- TemplateTypeMatcher template_type_3_{3};
- TemplateNumberMatcher template_number_0_{0};
- TemplateNumberMatcher template_number_1_{1};
- TemplateNumberMatcher template_number_2_{2};
- Bool Bool_;
- Ia Ia_;
- Fa Fa_;
- I32 I32_;
- U32 U32_;
- F32 F32_;
- F16 F16_;
- Vec2 Vec2_;
- Vec3 Vec3_;
- Vec4 Vec4_;
- Mat2X2 Mat2X2_;
- Mat2X3 Mat2X3_;
- Mat2X4 Mat2X4_;
- Mat3X2 Mat3X2_;
- Mat3X3 Mat3X3_;
- Mat3X4 Mat3X4_;
- Mat4X2 Mat4X2_;
- Mat4X3 Mat4X3_;
- Mat4X4 Mat4X4_;
- Vec Vec_;
- Mat Mat_;
- Ptr Ptr_;
- Atomic Atomic_;
- Array Array_;
- Sampler Sampler_;
- SamplerComparison SamplerComparison_;
- Texture1D Texture1D_;
- Texture2D Texture2D_;
- Texture2DArray Texture2DArray_;
- Texture3D Texture3D_;
- TextureCube TextureCube_;
- TextureCubeArray TextureCubeArray_;
- TextureMultisampled2D TextureMultisampled2D_;
- TextureDepth2D TextureDepth2D_;
- TextureDepth2DArray TextureDepth2DArray_;
- TextureDepthCube TextureDepthCube_;
- TextureDepthCubeArray TextureDepthCubeArray_;
- TextureDepthMultisampled2D TextureDepthMultisampled2D_;
- TextureStorage1D TextureStorage1D_;
- TextureStorage2D TextureStorage2D_;
- TextureStorage2DArray TextureStorage2DArray_;
- TextureStorage3D TextureStorage3D_;
- TextureExternal TextureExternal_;
- PackedVec3 PackedVec3_;
- ModfResult ModfResult_;
- ModfResultVec ModfResultVec_;
- FrexpResult FrexpResult_;
- FrexpResultVec FrexpResultVec_;
- AtomicCompareExchangeResult AtomicCompareExchangeResult_;
- Scalar Scalar_;
- ConcreteScalar ConcreteScalar_;
- ScalarNoF32 ScalarNoF32_;
- ScalarNoF16 ScalarNoF16_;
- ScalarNoI32 ScalarNoI32_;
- ScalarNoU32 ScalarNoU32_;
- ScalarNoBool ScalarNoBool_;
- FiaFiu32F16 FiaFiu32F16_;
- FiaFi32F16 FiaFi32F16_;
- FiaFiu32 FiaFiu32_;
- FaF32 FaF32_;
- FaF32F16 FaF32F16_;
- IaIu32 IaIu32_;
- IaI32 IaI32_;
- Fiu32F16 Fiu32F16_;
- Fiu32 Fiu32_;
- Fi32F16 Fi32F16_;
- Fi32 Fi32_;
- F32F16 F32F16_;
- Iu32 Iu32_;
- F32TexelFormat F32TexelFormat_;
- I32TexelFormat I32TexelFormat_;
- U32TexelFormat U32TexelFormat_;
- Write Write_;
- ReadWrite ReadWrite_;
- FunctionPrivateWorkgroup FunctionPrivateWorkgroup_;
- WorkgroupOrStorage WorkgroupOrStorage_;
- Storage Storage_;
- Workgroup Workgroup_;
-
- public:
- /// Constructor
- Matchers();
- /// Destructor
- ~Matchers();
-
- /// The template types, types, and type matchers
- TypeMatcher const* const type[73] = {
- /* [0] */ &template_type_0_,
- /* [1] */ &template_type_1_,
- /* [2] */ &template_type_2_,
- /* [3] */ &template_type_3_,
- /* [4] */ &Bool_,
- /* [5] */ &Ia_,
- /* [6] */ &Fa_,
- /* [7] */ &I32_,
- /* [8] */ &U32_,
- /* [9] */ &F32_,
- /* [10] */ &F16_,
- /* [11] */ &Vec2_,
- /* [12] */ &Vec3_,
- /* [13] */ &Vec4_,
- /* [14] */ &Mat2X2_,
- /* [15] */ &Mat2X3_,
- /* [16] */ &Mat2X4_,
- /* [17] */ &Mat3X2_,
- /* [18] */ &Mat3X3_,
- /* [19] */ &Mat3X4_,
- /* [20] */ &Mat4X2_,
- /* [21] */ &Mat4X3_,
- /* [22] */ &Mat4X4_,
- /* [23] */ &Vec_,
- /* [24] */ &Mat_,
- /* [25] */ &Ptr_,
- /* [26] */ &Atomic_,
- /* [27] */ &Array_,
- /* [28] */ &Sampler_,
- /* [29] */ &SamplerComparison_,
- /* [30] */ &Texture1D_,
- /* [31] */ &Texture2D_,
- /* [32] */ &Texture2DArray_,
- /* [33] */ &Texture3D_,
- /* [34] */ &TextureCube_,
- /* [35] */ &TextureCubeArray_,
- /* [36] */ &TextureMultisampled2D_,
- /* [37] */ &TextureDepth2D_,
- /* [38] */ &TextureDepth2DArray_,
- /* [39] */ &TextureDepthCube_,
- /* [40] */ &TextureDepthCubeArray_,
- /* [41] */ &TextureDepthMultisampled2D_,
- /* [42] */ &TextureStorage1D_,
- /* [43] */ &TextureStorage2D_,
- /* [44] */ &TextureStorage2DArray_,
- /* [45] */ &TextureStorage3D_,
- /* [46] */ &TextureExternal_,
- /* [47] */ &PackedVec3_,
- /* [48] */ &ModfResult_,
- /* [49] */ &ModfResultVec_,
- /* [50] */ &FrexpResult_,
- /* [51] */ &FrexpResultVec_,
- /* [52] */ &AtomicCompareExchangeResult_,
- /* [53] */ &Scalar_,
- /* [54] */ &ConcreteScalar_,
- /* [55] */ &ScalarNoF32_,
- /* [56] */ &ScalarNoF16_,
- /* [57] */ &ScalarNoI32_,
- /* [58] */ &ScalarNoU32_,
- /* [59] */ &ScalarNoBool_,
- /* [60] */ &FiaFiu32F16_,
- /* [61] */ &FiaFi32F16_,
- /* [62] */ &FiaFiu32_,
- /* [63] */ &FaF32_,
- /* [64] */ &FaF32F16_,
- /* [65] */ &IaIu32_,
- /* [66] */ &IaI32_,
- /* [67] */ &Fiu32F16_,
- /* [68] */ &Fiu32_,
- /* [69] */ &Fi32F16_,
- /* [70] */ &Fi32_,
- /* [71] */ &F32F16_,
- /* [72] */ &Iu32_,
- };
-
- /// The template numbers, and number matchers
- NumberMatcher const* const number[12] = {
- /* [0] */ &template_number_0_,
- /* [1] */ &template_number_1_,
- /* [2] */ &template_number_2_,
- /* [3] */ &F32TexelFormat_,
- /* [4] */ &I32TexelFormat_,
- /* [5] */ &U32TexelFormat_,
- /* [6] */ &Write_,
- /* [7] */ &ReadWrite_,
- /* [8] */ &FunctionPrivateWorkgroup_,
- /* [9] */ &WorkgroupOrStorage_,
- /* [10] */ &Storage_,
- /* [11] */ &Workgroup_,
- };
};
-Matchers::Matchers() = default;
-Matchers::~Matchers() = default;
+/// Type and number matchers
+
+/// The template types, types, and type matchers
+constexpr TypeMatcher kTypeMatchers[] = {
+ /* [0] */ TemplateTypeMatcher<0>::matcher,
+ /* [1] */ TemplateTypeMatcher<1>::matcher,
+ /* [2] */ TemplateTypeMatcher<2>::matcher,
+ /* [3] */ TemplateTypeMatcher<3>::matcher,
+ /* [4] */ kBoolMatcher,
+ /* [5] */ kIaMatcher,
+ /* [6] */ kFaMatcher,
+ /* [7] */ kI32Matcher,
+ /* [8] */ kU32Matcher,
+ /* [9] */ kF32Matcher,
+ /* [10] */ kF16Matcher,
+ /* [11] */ kVec2Matcher,
+ /* [12] */ kVec3Matcher,
+ /* [13] */ kVec4Matcher,
+ /* [14] */ kMat2X2Matcher,
+ /* [15] */ kMat2X3Matcher,
+ /* [16] */ kMat2X4Matcher,
+ /* [17] */ kMat3X2Matcher,
+ /* [18] */ kMat3X3Matcher,
+ /* [19] */ kMat3X4Matcher,
+ /* [20] */ kMat4X2Matcher,
+ /* [21] */ kMat4X3Matcher,
+ /* [22] */ kMat4X4Matcher,
+ /* [23] */ kVecMatcher,
+ /* [24] */ kMatMatcher,
+ /* [25] */ kPtrMatcher,
+ /* [26] */ kAtomicMatcher,
+ /* [27] */ kArrayMatcher,
+ /* [28] */ kSamplerMatcher,
+ /* [29] */ kSamplerComparisonMatcher,
+ /* [30] */ kTexture1DMatcher,
+ /* [31] */ kTexture2DMatcher,
+ /* [32] */ kTexture2DArrayMatcher,
+ /* [33] */ kTexture3DMatcher,
+ /* [34] */ kTextureCubeMatcher,
+ /* [35] */ kTextureCubeArrayMatcher,
+ /* [36] */ kTextureMultisampled2DMatcher,
+ /* [37] */ kTextureDepth2DMatcher,
+ /* [38] */ kTextureDepth2DArrayMatcher,
+ /* [39] */ kTextureDepthCubeMatcher,
+ /* [40] */ kTextureDepthCubeArrayMatcher,
+ /* [41] */ kTextureDepthMultisampled2DMatcher,
+ /* [42] */ kTextureStorage1DMatcher,
+ /* [43] */ kTextureStorage2DMatcher,
+ /* [44] */ kTextureStorage2DArrayMatcher,
+ /* [45] */ kTextureStorage3DMatcher,
+ /* [46] */ kTextureExternalMatcher,
+ /* [47] */ kPackedVec3Matcher,
+ /* [48] */ kModfResultMatcher,
+ /* [49] */ kModfResultVecMatcher,
+ /* [50] */ kFrexpResultMatcher,
+ /* [51] */ kFrexpResultVecMatcher,
+ /* [52] */ kAtomicCompareExchangeResultMatcher,
+ /* [53] */ kScalarMatcher,
+ /* [54] */ kConcreteScalarMatcher,
+ /* [55] */ kScalarNoF32Matcher,
+ /* [56] */ kScalarNoF16Matcher,
+ /* [57] */ kScalarNoI32Matcher,
+ /* [58] */ kScalarNoU32Matcher,
+ /* [59] */ kScalarNoBoolMatcher,
+ /* [60] */ kFiaFiu32F16Matcher,
+ /* [61] */ kFiaFi32F16Matcher,
+ /* [62] */ kFiaFiu32Matcher,
+ /* [63] */ kFaF32Matcher,
+ /* [64] */ kFaF32F16Matcher,
+ /* [65] */ kIaIu32Matcher,
+ /* [66] */ kIaI32Matcher,
+ /* [67] */ kFiu32F16Matcher,
+ /* [68] */ kFiu32Matcher,
+ /* [69] */ kFi32F16Matcher,
+ /* [70] */ kFi32Matcher,
+ /* [71] */ kF32F16Matcher,
+ /* [72] */ kIu32Matcher,
+};
+
+/// The template numbers, and number matchers
+constexpr NumberMatcher kNumberMatchers[] = {
+ /* [0] */ TemplateNumberMatcher<0>::matcher,
+ /* [1] */ TemplateNumberMatcher<1>::matcher,
+ /* [2] */ TemplateNumberMatcher<2>::matcher,
+ /* [3] */ kF32TexelFormatMatcher,
+ /* [4] */ kI32TexelFormatMatcher,
+ /* [5] */ kU32TexelFormatMatcher,
+ /* [6] */ kWriteMatcher,
+ /* [7] */ kReadWriteMatcher,
+ /* [8] */ kFunctionPrivateWorkgroupMatcher,
+ /* [9] */ kWorkgroupOrStorageMatcher,
+ /* [10] */ kStorageMatcher,
+ /* [11] */ kWorkgroupMatcher,
+};
constexpr MatcherIndex kMatcherIndices[] = {
/* [0] */ 25,
@@ -15404,3 +14364,38 @@
};
// clang-format on
+
+} // anonymous namespace
+
+const TableData& CoreTableData() {
+ static const TableData data{
+ /* type_matchers */ kTypeMatchers,
+ /* number_matchers */ kNumberMatchers,
+ /* ctor_conv */ kConstructorsAndConverters,
+ /* builtins */ kBuiltins,
+ /* binary_plus */ kBinaryOperators[kBinaryOperatorPlus],
+ /* binary_minus */ kBinaryOperators[kBinaryOperatorMinus],
+ /* binary_star */ kBinaryOperators[kBinaryOperatorStar],
+ /* binary_divide */ kBinaryOperators[kBinaryOperatorDivide],
+ /* binary_modulo */ kBinaryOperators[kBinaryOperatorModulo],
+ /* binary_xor */ kBinaryOperators[kBinaryOperatorXor],
+ /* binary_and */ kBinaryOperators[kBinaryOperatorAnd],
+ /* binary_or */ kBinaryOperators[kBinaryOperatorOr],
+ /* binary_logical_and */ kBinaryOperators[kBinaryOperatorLogicalAnd],
+ /* binary_logical_or */ kBinaryOperators[kBinaryOperatorLogicalOr],
+ /* binary_equal */ kBinaryOperators[kBinaryOperatorEqual],
+ /* binary_not_equal */ kBinaryOperators[kBinaryOperatorNotEqual],
+ /* binary_less_than */ kBinaryOperators[kBinaryOperatorLessThan],
+ /* binary_greater_than */ kBinaryOperators[kBinaryOperatorGreaterThan],
+ /* binary_less_than_equal */ kBinaryOperators[kBinaryOperatorLessThanEqual],
+ /* binary_greater_than_equal */ kBinaryOperators[kBinaryOperatorGreaterThanEqual],
+ /* binary_shift_left */ kBinaryOperators[kBinaryOperatorShiftLeft],
+ /* binary_shift_right */ kBinaryOperators[kBinaryOperatorShiftRight],
+ /* unary_not */ kUnaryOperators[kUnaryOperatorNot],
+ /* unary_complement */ kUnaryOperators[kUnaryOperatorComplement],
+ /* unary_minus */ kUnaryOperators[kUnaryOperatorMinus],
+ };
+ return data;
+}
+
+} // namespace tint::core::intrinsic
diff --git a/src/tint/lang/core/intrinsic/core_table_data.cc.tmpl b/src/tint/lang/core/intrinsic/core_table_data.cc.tmpl
new file mode 100644
index 0000000..e0b096b
--- /dev/null
+++ b/src/tint/lang/core/intrinsic/core_table_data.cc.tmpl
@@ -0,0 +1,26 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/src/cmd/gen to generate intrinsic_table.inl
+Used by BuiltinTable.cc for builtin overload resolution.
+
+To update the generated file, run:
+ ./tools/run gen
+
+See:
+* tools/src/cmd/gen for structures used by this template
+* https://golang.org/pkg/text/template/ for documentation on the template syntax
+--------------------------------------------------------------------------------
+*/ -}}
+
+{{- Import "src/tint/utils/templates/intrinsic_table_data.tmpl.inc" -}}
+
+{{- $I := LoadIntrinsics "src/tint/lang/core/core.def" -}}
+
+#include <limits>
+#include <string>
+
+#include "src/tint/lang/core/intrinsic/core_table_data.h"
+#include "src/tint/lang/core/intrinsic/core_type_matchers.h"
+#include "src/tint/utils/text/string_stream.h"
+
+{{ Eval "Data" "Intrinsics" $I "Namespace" "tint::core::intrinsic" "Name" "CoreTableData" -}}
diff --git a/src/tint/lang/core/intrinsic/core_table_data.h b/src/tint/lang/core/intrinsic/core_table_data.h
new file mode 100644
index 0000000..a9a7bd1
--- /dev/null
+++ b/src/tint/lang/core/intrinsic/core_table_data.h
@@ -0,0 +1,26 @@
+// Copyright 2023 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_LANG_CORE_INTRINSIC_CORE_TABLE_DATA_H_
+#define SRC_TINT_LANG_CORE_INTRINSIC_CORE_TABLE_DATA_H_
+
+#include "src/tint/lang/core/intrinsic/table_data.h"
+
+namespace tint::core::intrinsic {
+
+const TableData& CoreTableData();
+
+} // namespace tint::core::intrinsic
+
+#endif // SRC_TINT_LANG_CORE_INTRINSIC_CORE_TABLE_DATA_H_
diff --git a/src/tint/lang/core/intrinsic/core_type_matchers.h b/src/tint/lang/core/intrinsic/core_type_matchers.h
new file mode 100644
index 0000000..b061443
--- /dev/null
+++ b/src/tint/lang/core/intrinsic/core_type_matchers.h
@@ -0,0 +1,570 @@
+// Copyright 2023 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_LANG_CORE_INTRINSIC_CORE_TYPE_MATCHERS_H_
+#define SRC_TINT_LANG_CORE_INTRINSIC_CORE_TYPE_MATCHERS_H_
+
+#include "src/tint/lang/core/evaluation_stage.h"
+#include "src/tint/lang/core/intrinsic/table_data.h"
+#include "src/tint/lang/core/type/abstract_float.h"
+#include "src/tint/lang/core/type/abstract_int.h"
+#include "src/tint/lang/core/type/abstract_numeric.h"
+#include "src/tint/lang/core/type/array.h"
+#include "src/tint/lang/core/type/atomic.h"
+#include "src/tint/lang/core/type/bool.h"
+#include "src/tint/lang/core/type/builtin_structs.h"
+#include "src/tint/lang/core/type/depth_multisampled_texture.h"
+#include "src/tint/lang/core/type/depth_texture.h"
+#include "src/tint/lang/core/type/external_texture.h"
+#include "src/tint/lang/core/type/f16.h"
+#include "src/tint/lang/core/type/f32.h"
+#include "src/tint/lang/core/type/i32.h"
+#include "src/tint/lang/core/type/manager.h"
+#include "src/tint/lang/core/type/matrix.h"
+#include "src/tint/lang/core/type/multisampled_texture.h"
+#include "src/tint/lang/core/type/pointer.h"
+#include "src/tint/lang/core/type/sampled_texture.h"
+#include "src/tint/lang/core/type/storage_texture.h"
+#include "src/tint/lang/core/type/texture_dimension.h"
+#include "src/tint/lang/core/type/u32.h"
+#include "src/tint/lang/core/type/vector.h"
+
+namespace tint::core::intrinsic {
+
+inline bool match_bool(TableData::MatchState&, const type::Type* ty) {
+ return ty->IsAnyOf<TableData::Any, type::Bool>();
+}
+
+inline const type::AbstractFloat* build_fa(TableData::MatchState& state) {
+ return state.types.AFloat();
+}
+
+inline bool match_fa(TableData::MatchState& state, const type::Type* ty) {
+ return (state.earliest_eval_stage <= EvaluationStage::kConstant) &&
+ ty->IsAnyOf<TableData::Any, type::AbstractNumeric>();
+}
+
+inline const type::AbstractInt* build_ia(TableData::MatchState& state) {
+ return state.types.AInt();
+}
+
+inline bool match_ia(TableData::MatchState& state, const type::Type* ty) {
+ return (state.earliest_eval_stage <= EvaluationStage::kConstant) &&
+ ty->IsAnyOf<TableData::Any, type::AbstractInt>();
+}
+
+inline const type::Bool* build_bool(TableData::MatchState& state) {
+ return state.types.bool_();
+}
+
+inline const type::F16* build_f16(TableData::MatchState& state) {
+ return state.types.f16();
+}
+
+inline bool match_f16(TableData::MatchState&, const type::Type* ty) {
+ return ty->IsAnyOf<TableData::Any, type::F16, type::AbstractNumeric>();
+}
+
+inline const type::F32* build_f32(TableData::MatchState& state) {
+ return state.types.f32();
+}
+
+inline bool match_f32(TableData::MatchState&, const type::Type* ty) {
+ return ty->IsAnyOf<TableData::Any, type::F32, type::AbstractNumeric>();
+}
+
+inline const type::I32* build_i32(TableData::MatchState& state) {
+ return state.types.i32();
+}
+
+inline bool match_i32(TableData::MatchState&, const type::Type* ty) {
+ return ty->IsAnyOf<TableData::Any, type::I32, type::AbstractInt>();
+}
+
+inline const type::U32* build_u32(TableData::MatchState& state) {
+ return state.types.u32();
+}
+
+inline bool match_u32(TableData::MatchState&, const type::Type* ty) {
+ return ty->IsAnyOf<TableData::Any, type::U32, type::AbstractInt>();
+}
+
+inline bool match_vec(TableData::MatchState&,
+ const type::Type* ty,
+ TableData::Number& N,
+ const type::Type*& T) {
+ if (ty->Is<TableData::Any>()) {
+ N = TableData::Number::any;
+ T = ty;
+ return true;
+ }
+
+ if (auto* v = ty->As<type::Vector>()) {
+ N = v->Width();
+ T = v->type();
+ return true;
+ }
+ return false;
+}
+
+template <uint32_t N>
+inline bool match_vec(TableData::MatchState&, const type::Type* ty, const type::Type*& T) {
+ if (ty->Is<TableData::Any>()) {
+ T = ty;
+ return true;
+ }
+
+ if (auto* v = ty->As<type::Vector>()) {
+ if (v->Width() == N) {
+ T = v->type();
+ return true;
+ }
+ }
+ return false;
+}
+
+inline const type::Vector* build_vec(TableData::MatchState& state,
+ TableData::Number N,
+ const type::Type* el) {
+ return state.types.vec(el, N.Value());
+}
+
+template <uint32_t N>
+inline const type::Vector* build_vec(TableData::MatchState& state, const type::Type* el) {
+ return state.types.vec(el, N);
+}
+
+constexpr auto match_vec2 = match_vec<2>;
+constexpr auto match_vec3 = match_vec<3>;
+constexpr auto match_vec4 = match_vec<4>;
+
+constexpr auto build_vec2 = build_vec<2>;
+constexpr auto build_vec3 = build_vec<3>;
+constexpr auto build_vec4 = build_vec<4>;
+
+inline bool match_packedVec3(TableData::MatchState&, const type::Type* ty, const type::Type*& T) {
+ if (ty->Is<TableData::Any>()) {
+ T = ty;
+ return true;
+ }
+
+ if (auto* v = ty->As<type::Vector>()) {
+ if (v->Packed()) {
+ T = v->type();
+ return true;
+ }
+ }
+ return false;
+}
+
+inline const type::Vector* build_packedVec3(TableData::MatchState& state, const type::Type* el) {
+ return state.types.Get<type::Vector>(el, 3u, /* packed */ true);
+}
+
+inline bool match_mat(TableData::MatchState&,
+ const type::Type* ty,
+ TableData::Number& M,
+ TableData::Number& N,
+ const type::Type*& T) {
+ if (ty->Is<TableData::Any>()) {
+ M = TableData::Number::any;
+ N = TableData::Number::any;
+ T = ty;
+ return true;
+ }
+ if (auto* m = ty->As<type::Matrix>()) {
+ M = m->columns();
+ N = m->ColumnType()->Width();
+ T = m->type();
+ return true;
+ }
+ return false;
+}
+
+template <uint32_t C, uint32_t R>
+inline bool match_mat(TableData::MatchState&, const type::Type* ty, const type::Type*& T) {
+ if (ty->Is<TableData::Any>()) {
+ T = ty;
+ return true;
+ }
+ if (auto* m = ty->As<type::Matrix>()) {
+ if (m->columns() == C && m->rows() == R) {
+ T = m->type();
+ return true;
+ }
+ }
+ return false;
+}
+
+inline const type::Matrix* build_mat(TableData::MatchState& state,
+ TableData::Number C,
+ TableData::Number R,
+ const type::Type* T) {
+ auto* column_type = state.types.vec(T, R.Value());
+ return state.types.mat(column_type, C.Value());
+}
+
+template <uint32_t C, uint32_t R>
+inline const type::Matrix* build_mat(TableData::MatchState& state, const type::Type* T) {
+ auto* column_type = state.types.vec(T, R);
+ return state.types.mat(column_type, C);
+}
+
+constexpr auto build_mat2x2 = build_mat<2, 2>;
+constexpr auto build_mat2x3 = build_mat<2, 3>;
+constexpr auto build_mat2x4 = build_mat<2, 4>;
+constexpr auto build_mat3x2 = build_mat<3, 2>;
+constexpr auto build_mat3x3 = build_mat<3, 3>;
+constexpr auto build_mat3x4 = build_mat<3, 4>;
+constexpr auto build_mat4x2 = build_mat<4, 2>;
+constexpr auto build_mat4x3 = build_mat<4, 3>;
+constexpr auto build_mat4x4 = build_mat<4, 4>;
+
+constexpr auto match_mat2x2 = match_mat<2, 2>;
+constexpr auto match_mat2x3 = match_mat<2, 3>;
+constexpr auto match_mat2x4 = match_mat<2, 4>;
+constexpr auto match_mat3x2 = match_mat<3, 2>;
+constexpr auto match_mat3x3 = match_mat<3, 3>;
+constexpr auto match_mat3x4 = match_mat<3, 4>;
+constexpr auto match_mat4x2 = match_mat<4, 2>;
+constexpr auto match_mat4x3 = match_mat<4, 3>;
+constexpr auto match_mat4x4 = match_mat<4, 4>;
+
+inline bool match_array(TableData::MatchState&, const type::Type* ty, const type::Type*& T) {
+ if (ty->Is<TableData::Any>()) {
+ T = ty;
+ return true;
+ }
+
+ if (auto* a = ty->As<type::Array>()) {
+ if (a->Count()->Is<type::RuntimeArrayCount>()) {
+ T = a->ElemType();
+ return true;
+ }
+ }
+ return false;
+}
+
+inline const type::Array* build_array(TableData::MatchState& state, const type::Type* el) {
+ return state.types.Get<type::Array>(el,
+ /* count */ state.types.Get<type::RuntimeArrayCount>(),
+ /* align */ 0u,
+ /* size */ 0u,
+ /* stride */ 0u,
+ /* stride_implicit */ 0u);
+}
+
+inline bool match_ptr(TableData::MatchState&,
+ const type::Type* ty,
+ TableData::Number& S,
+ const type::Type*& T,
+ TableData::Number& A) {
+ if (ty->Is<TableData::Any>()) {
+ S = TableData::Number::any;
+ T = ty;
+ A = TableData::Number::any;
+ return true;
+ }
+
+ if (auto* p = ty->As<type::Pointer>()) {
+ S = TableData::Number(static_cast<uint32_t>(p->AddressSpace()));
+ T = p->StoreType();
+ A = TableData::Number(static_cast<uint32_t>(p->Access()));
+ return true;
+ }
+ return false;
+}
+
+inline const type::Pointer* build_ptr(TableData::MatchState& state,
+ TableData::Number S,
+ const type::Type* T,
+ TableData::Number& A) {
+ return state.types.ptr(static_cast<core::AddressSpace>(S.Value()), T,
+ static_cast<core::Access>(A.Value()));
+}
+
+inline bool match_atomic(TableData::MatchState&, const type::Type* ty, const type::Type*& T) {
+ if (ty->Is<TableData::Any>()) {
+ T = ty;
+ return true;
+ }
+
+ if (auto* a = ty->As<type::Atomic>()) {
+ T = a->Type();
+ return true;
+ }
+ return false;
+}
+
+inline const type::Atomic* build_atomic(TableData::MatchState& state, const type::Type* T) {
+ return state.types.atomic(T);
+}
+
+inline bool match_sampler(TableData::MatchState&, const type::Type* ty) {
+ if (ty->Is<TableData::Any>()) {
+ return true;
+ }
+ return ty->Is([](const type::Sampler* s) { return s->kind() == type::SamplerKind::kSampler; });
+}
+
+inline const type::Sampler* build_sampler(TableData::MatchState& state) {
+ return state.types.sampler();
+}
+
+inline bool match_sampler_comparison(TableData::MatchState&, const type::Type* ty) {
+ if (ty->Is<TableData::Any>()) {
+ return true;
+ }
+ return ty->Is(
+ [](const type::Sampler* s) { return s->kind() == type::SamplerKind::kComparisonSampler; });
+}
+
+inline const type::Sampler* build_sampler_comparison(TableData::MatchState& state) {
+ return state.types.comparison_sampler();
+}
+
+inline bool match_texture(TableData::MatchState&,
+ const type::Type* ty,
+ type::TextureDimension dim,
+ const type::Type*& T) {
+ if (ty->Is<TableData::Any>()) {
+ T = ty;
+ return true;
+ }
+ if (auto* v = ty->As<type::SampledTexture>()) {
+ if (v->dim() == dim) {
+ T = v->type();
+ return true;
+ }
+ }
+ return false;
+}
+
+#define JOIN(a, b) a##b
+
+#define DECLARE_SAMPLED_TEXTURE(suffix, dim) \
+ inline bool JOIN(match_texture_, suffix)(TableData::MatchState & state, const type::Type* ty, \
+ const type::Type*& T) { \
+ return match_texture(state, ty, dim, T); \
+ } \
+ inline const type::SampledTexture* JOIN(build_texture_, suffix)(TableData::MatchState & state, \
+ const type::Type* T) { \
+ return state.types.Get<type::SampledTexture>(dim, T); \
+ }
+
+DECLARE_SAMPLED_TEXTURE(1d, type::TextureDimension::k1d)
+DECLARE_SAMPLED_TEXTURE(2d, type::TextureDimension::k2d)
+DECLARE_SAMPLED_TEXTURE(2d_array, type::TextureDimension::k2dArray)
+DECLARE_SAMPLED_TEXTURE(3d, type::TextureDimension::k3d)
+DECLARE_SAMPLED_TEXTURE(cube, type::TextureDimension::kCube)
+DECLARE_SAMPLED_TEXTURE(cube_array, type::TextureDimension::kCubeArray)
+#undef DECLARE_SAMPLED_TEXTURE
+
+inline bool match_texture_multisampled(TableData::MatchState&,
+ const type::Type* ty,
+ type::TextureDimension dim,
+ const type::Type*& T) {
+ if (ty->Is<TableData::Any>()) {
+ T = ty;
+ return true;
+ }
+ if (auto* v = ty->As<type::MultisampledTexture>()) {
+ if (v->dim() == dim) {
+ T = v->type();
+ return true;
+ }
+ }
+ return false;
+}
+
+#define DECLARE_MULTISAMPLED_TEXTURE(suffix, dim) \
+ inline bool JOIN(match_texture_multisampled_, suffix)( \
+ TableData::MatchState & state, const type::Type* ty, const type::Type*& T) { \
+ return match_texture_multisampled(state, ty, dim, T); \
+ } \
+ inline const type::MultisampledTexture* JOIN(build_texture_multisampled_, suffix)( \
+ TableData::MatchState & state, const type::Type* T) { \
+ return state.types.Get<type::MultisampledTexture>(dim, T); \
+ }
+
+DECLARE_MULTISAMPLED_TEXTURE(2d, type::TextureDimension::k2d)
+#undef DECLARE_MULTISAMPLED_TEXTURE
+
+inline bool match_texture_depth(TableData::MatchState&,
+ const type::Type* ty,
+ type::TextureDimension dim) {
+ if (ty->Is<TableData::Any>()) {
+ return true;
+ }
+ return ty->Is([&](const type::DepthTexture* t) { return t->dim() == dim; });
+}
+
+#define DECLARE_DEPTH_TEXTURE(suffix, dim) \
+ inline bool JOIN(match_texture_depth_, suffix)(TableData::MatchState & state, \
+ const type::Type* ty) { \
+ return match_texture_depth(state, ty, dim); \
+ } \
+ inline const type::DepthTexture* JOIN(build_texture_depth_, \
+ suffix)(TableData::MatchState & state) { \
+ return state.types.Get<type::DepthTexture>(dim); \
+ }
+
+DECLARE_DEPTH_TEXTURE(2d, type::TextureDimension::k2d)
+DECLARE_DEPTH_TEXTURE(2d_array, type::TextureDimension::k2dArray)
+DECLARE_DEPTH_TEXTURE(cube, type::TextureDimension::kCube)
+DECLARE_DEPTH_TEXTURE(cube_array, type::TextureDimension::kCubeArray)
+#undef DECLARE_DEPTH_TEXTURE
+
+inline bool match_texture_depth_multisampled_2d(TableData::MatchState&, const type::Type* ty) {
+ if (ty->Is<TableData::Any>()) {
+ return true;
+ }
+ return ty->Is([&](const type::DepthMultisampledTexture* t) {
+ return t->dim() == type::TextureDimension::k2d;
+ });
+}
+
+inline type::DepthMultisampledTexture* build_texture_depth_multisampled_2d(
+ TableData::MatchState& state) {
+ return state.types.Get<type::DepthMultisampledTexture>(type::TextureDimension::k2d);
+}
+
+inline bool match_texture_storage(TableData::MatchState&,
+ const type::Type* ty,
+ type::TextureDimension dim,
+ TableData::Number& F,
+ TableData::Number& A) {
+ if (ty->Is<TableData::Any>()) {
+ F = TableData::Number::any;
+ A = TableData::Number::any;
+ return true;
+ }
+ if (auto* v = ty->As<type::StorageTexture>()) {
+ if (v->dim() == dim) {
+ F = TableData::Number(static_cast<uint32_t>(v->texel_format()));
+ A = TableData::Number(static_cast<uint32_t>(v->access()));
+ return true;
+ }
+ }
+ return false;
+}
+
+#define DECLARE_STORAGE_TEXTURE(suffix, dim) \
+ inline bool JOIN(match_texture_storage_, suffix)(TableData::MatchState & state, \
+ const type::Type* ty, TableData::Number& F, \
+ TableData::Number& A) { \
+ return match_texture_storage(state, ty, dim, F, A); \
+ } \
+ inline const type::StorageTexture* JOIN(build_texture_storage_, suffix)( \
+ TableData::MatchState & state, TableData::Number F, TableData::Number A) { \
+ auto format = static_cast<TexelFormat>(F.Value()); \
+ auto access = static_cast<Access>(A.Value()); \
+ auto* T = type::StorageTexture::SubtypeFor(format, state.types); \
+ return state.types.Get<type::StorageTexture>(dim, format, access, T); \
+ }
+
+DECLARE_STORAGE_TEXTURE(1d, type::TextureDimension::k1d)
+DECLARE_STORAGE_TEXTURE(2d, type::TextureDimension::k2d)
+DECLARE_STORAGE_TEXTURE(2d_array, type::TextureDimension::k2dArray)
+DECLARE_STORAGE_TEXTURE(3d, type::TextureDimension::k3d)
+#undef DECLARE_STORAGE_TEXTURE
+
+inline bool match_texture_external(TableData::MatchState&, const type::Type* ty) {
+ return ty->IsAnyOf<TableData::Any, type::ExternalTexture>();
+}
+
+inline const type::ExternalTexture* build_texture_external(TableData::MatchState& state) {
+ return state.types.Get<type::ExternalTexture>();
+}
+
+// Builtin types starting with a _ prefix cannot be declared in WGSL, so they
+// can only be used as return types. Because of this, they must only match Any,
+// which is used as the return type matcher.
+inline bool match_modf_result(TableData::MatchState&, const type::Type* ty, const type::Type*& T) {
+ if (!ty->Is<TableData::Any>()) {
+ return false;
+ }
+ T = ty;
+ return true;
+}
+inline bool match_modf_result_vec(TableData::MatchState&,
+ const type::Type* ty,
+ TableData::Number& N,
+ const type::Type*& T) {
+ if (!ty->Is<TableData::Any>()) {
+ return false;
+ }
+ N = TableData::Number::any;
+ T = ty;
+ return true;
+}
+inline bool match_frexp_result(TableData::MatchState&, const type::Type* ty, const type::Type*& T) {
+ if (!ty->Is<TableData::Any>()) {
+ return false;
+ }
+ T = ty;
+ return true;
+}
+inline bool match_frexp_result_vec(TableData::MatchState&,
+ const type::Type* ty,
+ TableData::Number& N,
+ const type::Type*& T) {
+ if (!ty->Is<TableData::Any>()) {
+ return false;
+ }
+ N = TableData::Number::any;
+ T = ty;
+ return true;
+}
+
+inline bool match_atomic_compare_exchange_result(TableData::MatchState&,
+ const type::Type* ty,
+ const type::Type*& T) {
+ if (ty->Is<TableData::Any>()) {
+ T = ty;
+ return true;
+ }
+ return false;
+}
+
+inline const type::Struct* build_modf_result(TableData::MatchState& state, const type::Type* el) {
+ return type::CreateModfResult(state.types, state.symbols, el);
+}
+
+inline const type::Struct* build_modf_result_vec(TableData::MatchState& state,
+ TableData::Number& n,
+ const type::Type* el) {
+ auto* vec = state.types.vec(el, n.Value());
+ return type::CreateModfResult(state.types, state.symbols, vec);
+}
+
+inline const type::Struct* build_frexp_result(TableData::MatchState& state, const type::Type* el) {
+ return type::CreateFrexpResult(state.types, state.symbols, el);
+}
+
+inline const type::Struct* build_frexp_result_vec(TableData::MatchState& state,
+ TableData::Number& n,
+ const type::Type* el) {
+ auto* vec = state.types.vec(el, n.Value());
+ return type::CreateFrexpResult(state.types, state.symbols, vec);
+}
+
+inline const type::Struct* build_atomic_compare_exchange_result(TableData::MatchState& state,
+ const type::Type* ty) {
+ return type::CreateAtomicCompareExchangeResult(state.types, state.symbols, ty);
+}
+
+} // namespace tint::core::intrinsic
+
+#endif // SRC_TINT_LANG_CORE_INTRINSIC_CORE_TYPE_MATCHERS_H_
diff --git a/src/tint/lang/core/intrinsic/table.cc b/src/tint/lang/core/intrinsic/table.cc
index 778db1a..b9dbcc8 100644
--- a/src/tint/lang/core/intrinsic/table.cc
+++ b/src/tint/lang/core/intrinsic/table.cc
@@ -19,18 +19,8 @@
#include <utility>
#include "src/tint/lang/core/evaluation_stage.h"
-#include "src/tint/lang/core/type/abstract_float.h"
-#include "src/tint/lang/core/type/abstract_int.h"
-#include "src/tint/lang/core/type/abstract_numeric.h"
-#include "src/tint/lang/core/type/atomic.h"
-#include "src/tint/lang/core/type/builtin_structs.h"
-#include "src/tint/lang/core/type/depth_multisampled_texture.h"
-#include "src/tint/lang/core/type/depth_texture.h"
-#include "src/tint/lang/core/type/external_texture.h"
-#include "src/tint/lang/core/type/multisampled_texture.h"
-#include "src/tint/lang/core/type/sampled_texture.h"
-#include "src/tint/lang/core/type/storage_texture.h"
-#include "src/tint/lang/core/type/texture_dimension.h"
+#include "src/tint/lang/core/intrinsic/core_table_data.h"
+#include "src/tint/lang/core/intrinsic/table_data.h"
#include "src/tint/lang/wgsl/ast/binary_expression.h"
#include "src/tint/lang/wgsl/program/program_builder.h"
#include "src/tint/lang/wgsl/sem/pipeline_stage_set.h"
@@ -44,290 +34,49 @@
#include "src/tint/utils/text/string_stream.h"
namespace tint::core::intrinsic {
+
+const TableData::Number TableData::Number::any{Number::kAny};
+const TableData::Number TableData::Number::invalid{Number::kInvalid};
+
+TableData::Any::Any() : Base(0u, type::Flags{}) {}
+TableData::Any::~Any() = default;
+
+bool TableData::Any::Equals(const type::UniqueNode&) const {
+ return false;
+}
+
+std::string TableData::Any::FriendlyName() const {
+ return "<any>";
+}
+
+type::Type* TableData::Any::Clone(type::CloneContext&) const {
+ return nullptr;
+}
+
namespace {
-// Forward declarations
-struct OverloadInfo;
-class Matchers;
-class NumberMatcher;
-class TypeMatcher;
+// Aliases
+using Any = TableData::Any;
+using Number = TableData::Number;
+using MatcherIndex = TableData::MatcherIndex;
+using TypeMatcher = TableData::TypeMatcher;
+using NumberMatcher = TableData::NumberMatcher;
+using MatchState = TableData::MatchState;
+using TemplateTypeInfo = TableData::TemplateTypeInfo;
+using TemplateNumberInfo = TableData::TemplateNumberInfo;
+using ParameterInfo = TableData::ParameterInfo;
+using IntrinsicInfo = TableData::IntrinsicInfo;
+using OverloadInfo = TableData::OverloadInfo;
+using OverloadFlag = TableData::OverloadFlag;
+using OverloadFlags = TableData::OverloadFlags;
+using TemplateState = TableData::TemplateState;
+constexpr const auto kNoMatcher = TableData::kNoMatcher;
/// The Vector `N` template argument value for arrays of parameters.
-constexpr static const size_t kNumFixedParams = 8;
+constexpr const size_t kNumFixedParams = 8;
/// The Vector `N` template argument value for arrays of overload candidates.
-constexpr static const size_t kNumFixedCandidates = 8;
-
-/// A special type that matches all TypeMatchers
-class Any final : public Castable<Any, type::Type> {
- public:
- Any() : Base(0u, type::Flags{}) {}
- ~Any() override = default;
-
- // Stub implementations for type::Type conformance.
- bool Equals(const type::UniqueNode&) const override { return false; }
- std::string FriendlyName() const override { return "<any>"; }
- type::Type* Clone(type::CloneContext&) const override { return nullptr; }
-};
-
-/// Number is an 32 bit unsigned integer, which can be in one of three states:
-/// * Invalid - Number has not been assigned a value
-/// * Valid - a fixed integer value
-/// * Any - matches any other non-invalid number
-struct Number {
- static const Number any;
- static const Number invalid;
-
- /// Constructed as a valid number with the value v
- explicit Number(uint32_t v) : value_(v), state_(kValid) {}
-
- /// @returns the value of the number
- inline uint32_t Value() const { return value_; }
-
- /// @returns the true if the number is valid
- inline bool IsValid() const { return state_ == kValid; }
-
- /// @returns the true if the number is any
- inline bool IsAny() const { return state_ == kAny; }
-
- /// Assignment operator.
- /// The number becomes valid, with the value n
- inline Number& operator=(uint32_t n) {
- value_ = n;
- state_ = kValid;
- return *this;
- }
-
- private:
- enum State {
- kInvalid,
- kValid,
- kAny,
- };
-
- constexpr explicit Number(State state) : state_(state) {}
-
- uint32_t value_ = 0;
- State state_ = kInvalid;
-};
-
-const Number Number::any{Number::kAny};
-const Number Number::invalid{Number::kInvalid};
-
-/// TemplateState holds the state of the template numbers and types.
-/// Used by the MatchState.
-class TemplateState {
- public:
- /// If the template type with index `idx` is undefined, then it is defined with the `ty` and
- /// Type() returns `ty`.
- /// If the template type is defined, and `ty` can be converted to the template type then the
- /// template type is returned.
- /// If the template type is defined, and the template type can be converted to `ty`, then the
- /// template type is replaced with `ty`, and `ty` is returned.
- /// If none of the above applies, then `ty` is a type mismatch for the template type, and
- /// nullptr is returned.
- const type::Type* Type(size_t idx, const type::Type* ty) {
- if (idx >= types_.Length()) {
- types_.Resize(idx + 1);
- }
- auto& t = types_[idx];
- if (t == nullptr) {
- t = ty;
- return ty;
- }
- ty = type::Type::Common(Vector{t, ty});
- if (ty) {
- t = ty;
- }
- return ty;
- }
-
- /// If the number with index `idx` is undefined, then it is defined with the number `number` and
- /// Num() returns true. If the number is defined, then `Num()` returns true iff it is equal to
- /// `ty`.
- bool Num(size_t idx, Number number) {
- if (idx >= numbers_.Length()) {
- numbers_.Resize(idx + 1, Number::invalid);
- }
- auto& n = numbers_[idx];
- if (!n.IsValid()) {
- n = number.Value();
- return true;
- }
- return n.Value() == number.Value();
- }
-
- /// Type returns the template type with index `idx`, or nullptr if the type was not defined.
- const type::Type* Type(size_t idx) const {
- if (idx >= types_.Length()) {
- return nullptr;
- }
- return types_[idx];
- }
-
- /// SetType replaces the template type with index `idx` with type `ty`.
- void SetType(size_t idx, const type::Type* ty) {
- if (idx >= types_.Length()) {
- types_.Resize(idx + 1);
- }
- types_[idx] = ty;
- }
-
- /// Type returns the number type with index `idx`.
- Number Num(size_t idx) const {
- if (idx >= numbers_.Length()) {
- return Number::invalid;
- }
- return numbers_[idx];
- }
-
- /// @return the total number of type and number templates
- size_t Count() const { return types_.Length() + numbers_.Length(); }
-
- private:
- Vector<const type::Type*, 4> types_;
- Vector<Number, 2> numbers_;
-};
-
-/// Index type used for matcher indices
-using MatcherIndex = uint8_t;
-
-/// Index value used for template types / numbers that do not have a constraint
-constexpr MatcherIndex kNoMatcher = std::numeric_limits<MatcherIndex>::max();
-
-/// MatchState holds the state used to match an overload.
-class MatchState {
- public:
- MatchState(ProgramBuilder& b,
- TemplateState& t,
- const Matchers& m,
- const OverloadInfo* o,
- MatcherIndex const* matcher_indices,
- EvaluationStage s)
- : builder(b),
- templates(t),
- matchers(m),
- overload(o),
- earliest_eval_stage(s),
- matcher_indices_(matcher_indices) {}
-
- /// The program builder
- ProgramBuilder& builder;
- /// The template types and numbers
- TemplateState& templates;
- /// The type and number matchers
- Matchers const& matchers;
- /// The current overload being evaluated
- OverloadInfo const* overload;
- /// The earliest evaluation stage of the builtin call
- EvaluationStage earliest_eval_stage;
-
- /// Type uses the next TypeMatcher from the matcher indices to match the type
- /// `ty`. If the type matches, the canonical expected type is returned. If the
- /// type `ty` does not match, then nullptr is returned.
- /// @note: The matcher indices are progressed on calling.
- const type::Type* Type(const type::Type* ty);
-
- /// Num uses the next NumMatcher from the matcher indices to match the number
- /// `num`. If the number matches, the canonical expected number is returned.
- /// If the number `num` does not match, then an invalid number is returned.
- /// @note: The matcher indices are progressed on calling.
- Number Num(Number num);
-
- /// @returns a string representation of the next TypeMatcher from the matcher
- /// indices.
- /// @note: The matcher indices are progressed on calling.
- std::string TypeName();
-
- /// @returns a string representation of the next NumberMatcher from the
- /// matcher indices.
- /// @note: The matcher indices are progressed on calling.
- std::string NumName();
-
- private:
- MatcherIndex const* matcher_indices_ = nullptr;
-};
-
-/// A TypeMatcher is the interface used to match an type used as part of an
-/// overload's parameter or return type.
-class TypeMatcher {
- public:
- /// Destructor
- virtual ~TypeMatcher() = default;
-
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- virtual const type::Type* Match(MatchState& state, const type::Type* type) const = 0;
-
- /// @return a string representation of the matcher. Used for printing error
- /// messages when no overload is found.
- virtual std::string String(MatchState* state) const = 0;
-};
-
-/// A NumberMatcher is the interface used to match a number or enumerator used
-/// as part of an overload's parameter or return type.
-class NumberMatcher {
- public:
- /// Destructor
- virtual ~NumberMatcher() = default;
-
- /// Checks whether the given number matches the matcher rules.
- /// Match may define template numbers in state.
- /// @param number the number to match
- /// @returns true if the argument type is as expected.
- virtual Number Match(MatchState& state, Number number) const = 0;
-
- /// @return a string representation of the matcher. Used for printing error
- /// messages when no overload is found.
- virtual std::string String(MatchState* state) const = 0;
-};
-
-/// TemplateTypeMatcher is a Matcher for a template type.
-/// The TemplateTypeMatcher will initially match against any type, and then will only be further
-/// constrained based on the conversion rules defined at https://www.w3.org/TR/WGSL/#conversion-rank
-class TemplateTypeMatcher : public TypeMatcher {
- public:
- /// Constructor
- explicit TemplateTypeMatcher(size_t index) : index_(index) {}
-
- const type::Type* Match(MatchState& state, const type::Type* type) const override {
- if (type->Is<Any>()) {
- return state.templates.Type(index_);
- }
- if (auto* templates = state.templates.Type(index_, type)) {
- return templates;
- }
- return nullptr;
- }
-
- std::string String(MatchState* state) const override;
-
- private:
- size_t index_;
-};
-
-/// TemplateNumberMatcher is a Matcher for a template number.
-/// The TemplateNumberMatcher will match against any number (so long as it is
-/// consistent for all uses in the overload)
-class TemplateNumberMatcher : public NumberMatcher {
- public:
- explicit TemplateNumberMatcher(size_t index) : index_(index) {}
-
- Number Match(MatchState& state, Number number) const override {
- if (number.IsAny()) {
- return state.templates.Num(index_);
- }
- return state.templates.Num(index_, number) ? number : Number::invalid;
- }
-
- std::string String(MatchState* state) const override;
-
- private:
- size_t index_;
-};
+constexpr const size_t kNumFixedCandidates = 8;
////////////////////////////////////////////////////////////////////////////////
// Binding functions for use in the generated builtin_table.inl
@@ -336,573 +85,6 @@
////////////////////////////////////////////////////////////////////////////////
using PipelineStage = ast::PipelineStage;
-/// Unique flag bits for overloads
-enum class OverloadFlag {
- kIsBuiltin, // The overload is a builtin ('fn')
- kIsOperator, // The overload is an operator ('op')
- kIsConstructor, // The overload is a value constructor ('ctor')
- kIsConverter, // The overload is a value converter ('conv')
- kSupportsVertexPipeline, // The overload can be used in vertex shaders
- kSupportsFragmentPipeline, // The overload can be used in fragment shaders
- kSupportsComputePipeline, // The overload can be used in compute shaders
- kMustUse, // The overload cannot be called as a statement
- kIsDeprecated, // The overload is deprecated
-};
-
-// An enum set of OverloadFlag, used by OperatorInfo
-using OverloadFlags = tint::EnumSet<OverloadFlag>;
-
-bool match_bool(MatchState&, const type::Type* ty) {
- return ty->IsAnyOf<Any, type::Bool>();
-}
-
-const type::AbstractFloat* build_fa(MatchState& state) {
- return state.builder.create<type::AbstractFloat>();
-}
-
-bool match_fa(MatchState& state, const type::Type* ty) {
- return (state.earliest_eval_stage <= EvaluationStage::kConstant) &&
- ty->IsAnyOf<Any, type::AbstractNumeric>();
-}
-
-const type::AbstractInt* build_ia(MatchState& state) {
- return state.builder.create<type::AbstractInt>();
-}
-
-bool match_ia(MatchState& state, const type::Type* ty) {
- return (state.earliest_eval_stage <= EvaluationStage::kConstant) &&
- ty->IsAnyOf<Any, type::AbstractInt>();
-}
-
-const type::Bool* build_bool(MatchState& state) {
- return state.builder.create<type::Bool>();
-}
-
-const type::F16* build_f16(MatchState& state) {
- return state.builder.create<type::F16>();
-}
-
-bool match_f16(MatchState&, const type::Type* ty) {
- return ty->IsAnyOf<Any, type::F16, type::AbstractNumeric>();
-}
-
-const type::F32* build_f32(MatchState& state) {
- return state.builder.create<type::F32>();
-}
-
-bool match_f32(MatchState&, const type::Type* ty) {
- return ty->IsAnyOf<Any, type::F32, type::AbstractNumeric>();
-}
-
-const type::I32* build_i32(MatchState& state) {
- return state.builder.create<type::I32>();
-}
-
-bool match_i32(MatchState&, const type::Type* ty) {
- return ty->IsAnyOf<Any, type::I32, type::AbstractInt>();
-}
-
-const type::U32* build_u32(MatchState& state) {
- return state.builder.create<type::U32>();
-}
-
-bool match_u32(MatchState&, const type::Type* ty) {
- return ty->IsAnyOf<Any, type::U32, type::AbstractInt>();
-}
-
-bool match_vec(MatchState&, const type::Type* ty, Number& N, const type::Type*& T) {
- if (ty->Is<Any>()) {
- N = Number::any;
- T = ty;
- return true;
- }
-
- if (auto* v = ty->As<type::Vector>()) {
- N = v->Width();
- T = v->type();
- return true;
- }
- return false;
-}
-
-template <uint32_t N>
-bool match_vec(MatchState&, const type::Type* ty, const type::Type*& T) {
- if (ty->Is<Any>()) {
- T = ty;
- return true;
- }
-
- if (auto* v = ty->As<type::Vector>()) {
- if (v->Width() == N) {
- T = v->type();
- return true;
- }
- }
- return false;
-}
-
-const type::Vector* build_vec(MatchState& state, Number N, const type::Type* el) {
- return state.builder.create<type::Vector>(el, N.Value());
-}
-
-template <uint32_t N>
-const type::Vector* build_vec(MatchState& state, const type::Type* el) {
- return state.builder.create<type::Vector>(el, N);
-}
-
-constexpr auto match_vec2 = match_vec<2>;
-constexpr auto match_vec3 = match_vec<3>;
-constexpr auto match_vec4 = match_vec<4>;
-
-constexpr auto build_vec2 = build_vec<2>;
-constexpr auto build_vec3 = build_vec<3>;
-constexpr auto build_vec4 = build_vec<4>;
-
-bool match_packedVec3(MatchState&, const type::Type* ty, const type::Type*& T) {
- if (ty->Is<Any>()) {
- T = ty;
- return true;
- }
-
- if (auto* v = ty->As<type::Vector>()) {
- if (v->Packed()) {
- T = v->type();
- return true;
- }
- }
- return false;
-}
-
-const type::Vector* build_packedVec3(MatchState& state, const type::Type* el) {
- return state.builder.create<type::Vector>(el, 3u, /* packed */ true);
-}
-
-bool match_mat(MatchState&, const type::Type* ty, Number& M, Number& N, const type::Type*& T) {
- if (ty->Is<Any>()) {
- M = Number::any;
- N = Number::any;
- T = ty;
- return true;
- }
- if (auto* m = ty->As<type::Matrix>()) {
- M = m->columns();
- N = m->ColumnType()->Width();
- T = m->type();
- return true;
- }
- return false;
-}
-
-template <uint32_t C, uint32_t R>
-bool match_mat(MatchState&, const type::Type* ty, const type::Type*& T) {
- if (ty->Is<Any>()) {
- T = ty;
- return true;
- }
- if (auto* m = ty->As<type::Matrix>()) {
- if (m->columns() == C && m->rows() == R) {
- T = m->type();
- return true;
- }
- }
- return false;
-}
-
-const type::Matrix* build_mat(MatchState& state, Number C, Number R, const type::Type* T) {
- auto* column_type = state.builder.create<type::Vector>(T, R.Value());
- return state.builder.create<type::Matrix>(column_type, C.Value());
-}
-
-template <uint32_t C, uint32_t R>
-const type::Matrix* build_mat(MatchState& state, const type::Type* T) {
- auto* column_type = state.builder.create<type::Vector>(T, R);
- return state.builder.create<type::Matrix>(column_type, C);
-}
-
-constexpr auto build_mat2x2 = build_mat<2, 2>;
-constexpr auto build_mat2x3 = build_mat<2, 3>;
-constexpr auto build_mat2x4 = build_mat<2, 4>;
-constexpr auto build_mat3x2 = build_mat<3, 2>;
-constexpr auto build_mat3x3 = build_mat<3, 3>;
-constexpr auto build_mat3x4 = build_mat<3, 4>;
-constexpr auto build_mat4x2 = build_mat<4, 2>;
-constexpr auto build_mat4x3 = build_mat<4, 3>;
-constexpr auto build_mat4x4 = build_mat<4, 4>;
-
-constexpr auto match_mat2x2 = match_mat<2, 2>;
-constexpr auto match_mat2x3 = match_mat<2, 3>;
-constexpr auto match_mat2x4 = match_mat<2, 4>;
-constexpr auto match_mat3x2 = match_mat<3, 2>;
-constexpr auto match_mat3x3 = match_mat<3, 3>;
-constexpr auto match_mat3x4 = match_mat<3, 4>;
-constexpr auto match_mat4x2 = match_mat<4, 2>;
-constexpr auto match_mat4x3 = match_mat<4, 3>;
-constexpr auto match_mat4x4 = match_mat<4, 4>;
-
-bool match_array(MatchState&, const type::Type* ty, const type::Type*& T) {
- if (ty->Is<Any>()) {
- T = ty;
- return true;
- }
-
- if (auto* a = ty->As<type::Array>()) {
- if (a->Count()->Is<type::RuntimeArrayCount>()) {
- T = a->ElemType();
- return true;
- }
- }
- return false;
-}
-
-const type::Array* build_array(MatchState& state, const type::Type* el) {
- return state.builder.create<type::Array>(
- el,
- /* count */ state.builder.create<type::RuntimeArrayCount>(),
- /* align */ 0u,
- /* size */ 0u,
- /* stride */ 0u,
- /* stride_implicit */ 0u);
-}
-
-bool match_ptr(MatchState&, const type::Type* ty, Number& S, const type::Type*& T, Number& A) {
- if (ty->Is<Any>()) {
- S = Number::any;
- T = ty;
- A = Number::any;
- return true;
- }
-
- if (auto* p = ty->As<type::Pointer>()) {
- S = Number(static_cast<uint32_t>(p->AddressSpace()));
- T = p->StoreType();
- A = Number(static_cast<uint32_t>(p->Access()));
- return true;
- }
- return false;
-}
-
-const type::Pointer* build_ptr(MatchState& state, Number S, const type::Type* T, Number& A) {
- return state.builder.create<type::Pointer>(static_cast<core::AddressSpace>(S.Value()), T,
- static_cast<core::Access>(A.Value()));
-}
-
-bool match_atomic(MatchState&, const type::Type* ty, const type::Type*& T) {
- if (ty->Is<Any>()) {
- T = ty;
- return true;
- }
-
- if (auto* a = ty->As<type::Atomic>()) {
- T = a->Type();
- return true;
- }
- return false;
-}
-
-const type::Atomic* build_atomic(MatchState& state, const type::Type* T) {
- return state.builder.create<type::Atomic>(T);
-}
-
-bool match_sampler(MatchState&, const type::Type* ty) {
- if (ty->Is<Any>()) {
- return true;
- }
- return ty->Is([](const type::Sampler* s) { return s->kind() == type::SamplerKind::kSampler; });
-}
-
-const type::Sampler* build_sampler(MatchState& state) {
- return state.builder.create<type::Sampler>(type::SamplerKind::kSampler);
-}
-
-bool match_sampler_comparison(MatchState&, const type::Type* ty) {
- if (ty->Is<Any>()) {
- return true;
- }
- return ty->Is(
- [](const type::Sampler* s) { return s->kind() == type::SamplerKind::kComparisonSampler; });
-}
-
-const type::Sampler* build_sampler_comparison(MatchState& state) {
- return state.builder.create<type::Sampler>(type::SamplerKind::kComparisonSampler);
-}
-
-bool match_texture(MatchState&,
- const type::Type* ty,
- type::TextureDimension dim,
- const type::Type*& T) {
- if (ty->Is<Any>()) {
- T = ty;
- return true;
- }
- if (auto* v = ty->As<type::SampledTexture>()) {
- if (v->dim() == dim) {
- T = v->type();
- return true;
- }
- }
- return false;
-}
-
-#define JOIN(a, b) a##b
-
-#define DECLARE_SAMPLED_TEXTURE(suffix, dim) \
- bool JOIN(match_texture_, suffix)(MatchState & state, const type::Type* ty, \
- const type::Type*& T) { \
- return match_texture(state, ty, dim, T); \
- } \
- const type::SampledTexture* JOIN(build_texture_, suffix)(MatchState & state, \
- const type::Type* T) { \
- return state.builder.create<type::SampledTexture>(dim, T); \
- }
-
-DECLARE_SAMPLED_TEXTURE(1d, type::TextureDimension::k1d)
-DECLARE_SAMPLED_TEXTURE(2d, type::TextureDimension::k2d)
-DECLARE_SAMPLED_TEXTURE(2d_array, type::TextureDimension::k2dArray)
-DECLARE_SAMPLED_TEXTURE(3d, type::TextureDimension::k3d)
-DECLARE_SAMPLED_TEXTURE(cube, type::TextureDimension::kCube)
-DECLARE_SAMPLED_TEXTURE(cube_array, type::TextureDimension::kCubeArray)
-#undef DECLARE_SAMPLED_TEXTURE
-
-bool match_texture_multisampled(MatchState&,
- const type::Type* ty,
- type::TextureDimension dim,
- const type::Type*& T) {
- if (ty->Is<Any>()) {
- T = ty;
- return true;
- }
- if (auto* v = ty->As<type::MultisampledTexture>()) {
- if (v->dim() == dim) {
- T = v->type();
- return true;
- }
- }
- return false;
-}
-
-#define DECLARE_MULTISAMPLED_TEXTURE(suffix, dim) \
- bool JOIN(match_texture_multisampled_, suffix)(MatchState & state, const type::Type* ty, \
- const type::Type*& T) { \
- return match_texture_multisampled(state, ty, dim, T); \
- } \
- const type::MultisampledTexture* JOIN(build_texture_multisampled_, suffix)( \
- MatchState & state, const type::Type* T) { \
- return state.builder.create<type::MultisampledTexture>(dim, T); \
- }
-
-DECLARE_MULTISAMPLED_TEXTURE(2d, type::TextureDimension::k2d)
-#undef DECLARE_MULTISAMPLED_TEXTURE
-
-bool match_texture_depth(MatchState&, const type::Type* ty, type::TextureDimension dim) {
- if (ty->Is<Any>()) {
- return true;
- }
- return ty->Is([&](const type::DepthTexture* t) { return t->dim() == dim; });
-}
-
-#define DECLARE_DEPTH_TEXTURE(suffix, dim) \
- bool JOIN(match_texture_depth_, suffix)(MatchState & state, const type::Type* ty) { \
- return match_texture_depth(state, ty, dim); \
- } \
- const type::DepthTexture* JOIN(build_texture_depth_, suffix)(MatchState & state) { \
- return state.builder.create<type::DepthTexture>(dim); \
- }
-
-DECLARE_DEPTH_TEXTURE(2d, type::TextureDimension::k2d)
-DECLARE_DEPTH_TEXTURE(2d_array, type::TextureDimension::k2dArray)
-DECLARE_DEPTH_TEXTURE(cube, type::TextureDimension::kCube)
-DECLARE_DEPTH_TEXTURE(cube_array, type::TextureDimension::kCubeArray)
-#undef DECLARE_DEPTH_TEXTURE
-
-bool match_texture_depth_multisampled_2d(MatchState&, const type::Type* ty) {
- if (ty->Is<Any>()) {
- return true;
- }
- return ty->Is([&](const type::DepthMultisampledTexture* t) {
- return t->dim() == type::TextureDimension::k2d;
- });
-}
-
-type::DepthMultisampledTexture* build_texture_depth_multisampled_2d(MatchState& state) {
- return state.builder.create<type::DepthMultisampledTexture>(type::TextureDimension::k2d);
-}
-
-bool match_texture_storage(MatchState&,
- const type::Type* ty,
- type::TextureDimension dim,
- Number& F,
- Number& A) {
- if (ty->Is<Any>()) {
- F = Number::any;
- A = Number::any;
- return true;
- }
- if (auto* v = ty->As<type::StorageTexture>()) {
- if (v->dim() == dim) {
- F = Number(static_cast<uint32_t>(v->texel_format()));
- A = Number(static_cast<uint32_t>(v->access()));
- return true;
- }
- }
- return false;
-}
-
-#define DECLARE_STORAGE_TEXTURE(suffix, dim) \
- bool JOIN(match_texture_storage_, suffix)(MatchState & state, const type::Type* ty, Number& F, \
- Number& A) { \
- return match_texture_storage(state, ty, dim, F, A); \
- } \
- const type::StorageTexture* JOIN(build_texture_storage_, suffix)(MatchState & state, Number F, \
- Number A) { \
- auto format = static_cast<TexelFormat>(F.Value()); \
- auto access = static_cast<Access>(A.Value()); \
- auto* T = type::StorageTexture::SubtypeFor(format, state.builder.Types()); \
- return state.builder.create<type::StorageTexture>(dim, format, access, T); \
- }
-
-DECLARE_STORAGE_TEXTURE(1d, type::TextureDimension::k1d)
-DECLARE_STORAGE_TEXTURE(2d, type::TextureDimension::k2d)
-DECLARE_STORAGE_TEXTURE(2d_array, type::TextureDimension::k2dArray)
-DECLARE_STORAGE_TEXTURE(3d, type::TextureDimension::k3d)
-#undef DECLARE_STORAGE_TEXTURE
-
-bool match_texture_external(MatchState&, const type::Type* ty) {
- return ty->IsAnyOf<Any, type::ExternalTexture>();
-}
-
-const type::ExternalTexture* build_texture_external(MatchState& state) {
- return state.builder.create<type::ExternalTexture>();
-}
-
-// Builtin types starting with a _ prefix cannot be declared in WGSL, so they
-// can only be used as return types. Because of this, they must only match Any,
-// which is used as the return type matcher.
-bool match_modf_result(MatchState&, const type::Type* ty, const type::Type*& T) {
- if (!ty->Is<Any>()) {
- return false;
- }
- T = ty;
- return true;
-}
-bool match_modf_result_vec(MatchState&, const type::Type* ty, Number& N, const type::Type*& T) {
- if (!ty->Is<Any>()) {
- return false;
- }
- N = Number::any;
- T = ty;
- return true;
-}
-bool match_frexp_result(MatchState&, const type::Type* ty, const type::Type*& T) {
- if (!ty->Is<Any>()) {
- return false;
- }
- T = ty;
- return true;
-}
-bool match_frexp_result_vec(MatchState&, const type::Type* ty, Number& N, const type::Type*& T) {
- if (!ty->Is<Any>()) {
- return false;
- }
- N = Number::any;
- T = ty;
- return true;
-}
-
-bool match_atomic_compare_exchange_result(MatchState&, const type::Type* ty, const type::Type*& T) {
- if (ty->Is<Any>()) {
- T = ty;
- return true;
- }
- return false;
-}
-
-const type::Struct* build_modf_result(MatchState& state, const type::Type* el) {
- return type::CreateModfResult(state.builder.Types(), state.builder.Symbols(), el);
-}
-
-const type::Struct* build_modf_result_vec(MatchState& state, Number& n, const type::Type* el) {
- auto* vec = state.builder.create<type::Vector>(el, n.Value());
- return type::CreateModfResult(state.builder.Types(), state.builder.Symbols(), vec);
-}
-
-const type::Struct* build_frexp_result(MatchState& state, const type::Type* el) {
- return type::CreateFrexpResult(state.builder.Types(), state.builder.Symbols(), el);
-}
-
-const type::Struct* build_frexp_result_vec(MatchState& state, Number& n, const type::Type* el) {
- auto* vec = state.builder.create<type::Vector>(el, n.Value());
- return type::CreateFrexpResult(state.builder.Types(), state.builder.Symbols(), vec);
-}
-
-const type::Struct* build_atomic_compare_exchange_result(MatchState& state, const type::Type* ty) {
- return type::CreateAtomicCompareExchangeResult(state.builder.Types(), state.builder.Symbols(),
- ty);
-}
-
-/// ParameterInfo describes a parameter
-struct ParameterInfo {
- /// The parameter usage (parameter name in definition file)
- const ParameterUsage usage;
-
- /// Pointer to a list of indices that are used to match the parameter type.
- /// The matcher indices index on Matchers::type and / or Matchers::number.
- /// These indices are consumed by the matchers themselves.
- /// The first index is always a TypeMatcher.
- MatcherIndex const* const matcher_indices;
-};
-
-/// TemplateTypeInfo describes an template type
-struct TemplateTypeInfo {
- /// Name of the template type (e.g. 'T')
- const char* name;
- /// Optional type matcher constraint.
- /// Either an index in Matchers::type, or kNoMatcher
- const MatcherIndex matcher_index;
-};
-
-/// TemplateNumberInfo describes a template number
-struct TemplateNumberInfo {
- /// Name of the template number (e.g. 'N')
- const char* name;
- /// Optional number matcher constraint.
- /// Either an index in Matchers::number, or kNoMatcher
- const MatcherIndex matcher_index;
-};
-
-/// OverloadInfo describes a single function overload
-struct OverloadInfo {
- /// Total number of parameters for the overload
- const uint8_t num_parameters;
- /// Total number of template types for the overload
- const uint8_t num_template_types;
- /// Total number of template numbers for the overload
- const uint8_t num_template_numbers;
- /// Pointer to the first template type
- TemplateTypeInfo const* const template_types;
- /// Pointer to the first template number
- TemplateNumberInfo const* const template_numbers;
- /// Pointer to the first parameter
- ParameterInfo const* const parameters;
- /// Pointer to a list of matcher indices that index on Matchers::type and
- /// Matchers::number, used to build the return type. If the function has no
- /// return type then this is null
- MatcherIndex const* const return_matcher_indices;
- /// The flags for the overload
- OverloadFlags flags;
- /// The function used to evaluate the overload at shader-creation time.
- constant::Eval::Function const const_eval_fn;
-};
-
-/// IntrinsicInfo describes a builtin function or operator overload
-struct IntrinsicInfo {
- /// Number of overloads of the intrinsic
- const uint8_t num_overloads;
- /// Pointer to the start of the overloads for the function
- OverloadInfo const* const overloads;
-};
-
-#include "table.inl"
-
/// IntrinsicPrototype describes a fully matched intrinsic.
struct IntrinsicPrototype {
/// Parameter describes a single parameter
@@ -926,7 +108,7 @@
}
};
- const OverloadInfo* overload = nullptr;
+ const TableData::OverloadInfo* overload = nullptr;
type::Type const* return_type = nullptr;
Vector<Parameter, kNumFixedParams> parameters;
};
@@ -950,7 +132,7 @@
/// Impl is the private implementation of the Table interface.
class Impl : public Table {
public:
- explicit Impl(ProgramBuilder& builder);
+ Impl(ProgramBuilder& b, const TableData& d);
Builtin Lookup(core::Function builtin_type,
VectorRef<const type::Type*> args,
@@ -979,7 +161,7 @@
/// Candidate holds information about an overload evaluated for resolution.
struct Candidate {
/// The candidate overload
- const OverloadInfo* overload;
+ const TableData::OverloadInfo* overload;
/// The template types and numbers
TemplateState templates;
/// The parameter types for the candidate overload
@@ -1029,7 +211,7 @@
/// arguments. For example `vec3<f32>()` would have the first template-type
/// template as `f32`.
/// @returns the evaluated Candidate information.
- Candidate ScoreOverload(const OverloadInfo* overload,
+ Candidate ScoreOverload(const TableData::OverloadInfo* overload,
VectorRef<const type::Type*> args,
EvaluationStage earliest_eval_stage,
const TemplateState& templates) const;
@@ -1054,13 +236,13 @@
/// @param overload the overload being evaluated
/// @param matcher_indices pointer to a list of matcher indices
MatchState Match(TemplateState& templates,
- const OverloadInfo* overload,
+ const TableData::OverloadInfo* overload,
MatcherIndex const* matcher_indices,
EvaluationStage earliest_eval_stage) const;
// Prints the overload for emitting diagnostics
void PrintOverload(StringStream& ss,
- const OverloadInfo* overload,
+ const TableData::OverloadInfo* overload,
const char* intrinsic_name) const;
// Prints the list of candidates for emitting diagnostics
@@ -1075,7 +257,7 @@
VectorRef<Candidate> candidates) const;
ProgramBuilder& builder;
- Matchers matchers;
+ const TableData& data;
Hashmap<IntrinsicPrototype, sem::Builtin*, 64, IntrinsicPrototype::Hasher> builtins;
Hashmap<IntrinsicPrototype, sem::ValueConstructor*, 16, IntrinsicPrototype::Hasher>
constructors;
@@ -1108,15 +290,7 @@
return ss.str();
}
-std::string TemplateTypeMatcher::String(MatchState* state) const {
- return state->overload->template_types[index_].name;
-}
-
-std::string TemplateNumberMatcher::String(MatchState* state) const {
- return state->overload->template_numbers[index_].name;
-}
-
-Impl::Impl(ProgramBuilder& b) : builder(b) {}
+Impl::Impl(ProgramBuilder& b, const TableData& d) : builder(b), data(d) {}
Impl::Builtin Impl::Lookup(core::Function builtin_type,
VectorRef<const type::Type*> args,
@@ -1138,8 +312,8 @@
};
// Resolve the intrinsic overload
- auto match = MatchIntrinsic(kBuiltins[static_cast<size_t>(builtin_type)], intrinsic_name, args,
- earliest_eval_stage, TemplateState{}, on_no_match);
+ auto match = MatchIntrinsic(data.builtins[static_cast<size_t>(builtin_type)], intrinsic_name,
+ args, earliest_eval_stage, TemplateState{}, on_no_match);
if (!match.overload) {
return {};
}
@@ -1178,18 +352,23 @@
const type::Type* arg,
EvaluationStage earliest_eval_stage,
const Source& source) {
- auto [intrinsic_index, intrinsic_name] = [&]() -> std::pair<size_t, const char*> {
+ auto [intrinsic_info, intrinsic_name] = [&]() -> std::pair<const IntrinsicInfo*, const char*> {
switch (op) {
case core::UnaryOp::kComplement:
- return {kUnaryOperatorComplement, "operator ~ "};
+ return {&data.unary_complement, "operator ~ "};
case core::UnaryOp::kNegation:
- return {kUnaryOperatorMinus, "operator - "};
+ return {&data.unary_minus, "operator - "};
case core::UnaryOp::kNot:
- return {kUnaryOperatorNot, "operator ! "};
+ return {&data.unary_not, "operator ! "};
default:
- return {0, "<unknown>"};
+ break;
}
+ TINT_UNREACHABLE() << "invalid unary op: " << op;
+ return {};
}();
+ if (!intrinsic_info) {
+ return {};
+ }
Vector args{arg};
@@ -1207,8 +386,8 @@
};
// Resolve the intrinsic overload
- auto match = MatchIntrinsic(kUnaryOperators[intrinsic_index], intrinsic_name, args,
- earliest_eval_stage, TemplateState{}, on_no_match);
+ auto match = MatchIntrinsic(*intrinsic_info, intrinsic_name, args, earliest_eval_stage,
+ TemplateState{}, on_no_match);
if (!match.overload) {
return {};
}
@@ -1226,48 +405,51 @@
EvaluationStage earliest_eval_stage,
const Source& source,
bool is_compound) {
- auto [intrinsic_index, intrinsic_name] = [&]() -> std::pair<size_t, const char*> {
+ auto [intrinsic_info, intrinsic_name] = [&]() -> std::pair<const IntrinsicInfo*, const char*> {
switch (op) {
case core::BinaryOp::kAnd:
- return {kBinaryOperatorAnd, is_compound ? "operator &= " : "operator & "};
+ return {&data.binary_and, is_compound ? "operator &= " : "operator & "};
case core::BinaryOp::kOr:
- return {kBinaryOperatorOr, is_compound ? "operator |= " : "operator | "};
+ return {&data.binary_or, is_compound ? "operator |= " : "operator | "};
case core::BinaryOp::kXor:
- return {kBinaryOperatorXor, is_compound ? "operator ^= " : "operator ^ "};
+ return {&data.binary_xor, is_compound ? "operator ^= " : "operator ^ "};
case core::BinaryOp::kLogicalAnd:
- return {kBinaryOperatorLogicalAnd, "operator && "};
+ return {&data.binary_logical_and, "operator && "};
case core::BinaryOp::kLogicalOr:
- return {kBinaryOperatorLogicalOr, "operator || "};
+ return {&data.binary_logical_or, "operator || "};
case core::BinaryOp::kEqual:
- return {kBinaryOperatorEqual, "operator == "};
+ return {&data.binary_equal, "operator == "};
case core::BinaryOp::kNotEqual:
- return {kBinaryOperatorNotEqual, "operator != "};
+ return {&data.binary_not_equal, "operator != "};
case core::BinaryOp::kLessThan:
- return {kBinaryOperatorLessThan, "operator < "};
+ return {&data.binary_less_than, "operator < "};
case core::BinaryOp::kGreaterThan:
- return {kBinaryOperatorGreaterThan, "operator > "};
+ return {&data.binary_greater_than, "operator > "};
case core::BinaryOp::kLessThanEqual:
- return {kBinaryOperatorLessThanEqual, "operator <= "};
+ return {&data.binary_less_than_equal, "operator <= "};
case core::BinaryOp::kGreaterThanEqual:
- return {kBinaryOperatorGreaterThanEqual, "operator >= "};
+ return {&data.binary_greater_than_equal, "operator >= "};
case core::BinaryOp::kShiftLeft:
- return {kBinaryOperatorShiftLeft, is_compound ? "operator <<= " : "operator << "};
+ return {&data.binary_shift_left, is_compound ? "operator <<= " : "operator << "};
case core::BinaryOp::kShiftRight:
- return {kBinaryOperatorShiftRight, is_compound ? "operator >>= " : "operator >> "};
+ return {&data.binary_shift_right, is_compound ? "operator >>= " : "operator >> "};
case core::BinaryOp::kAdd:
- return {kBinaryOperatorPlus, is_compound ? "operator += " : "operator + "};
+ return {&data.binary_plus, is_compound ? "operator += " : "operator + "};
case core::BinaryOp::kSubtract:
- return {kBinaryOperatorMinus, is_compound ? "operator -= " : "operator - "};
+ return {&data.binary_minus, is_compound ? "operator -= " : "operator - "};
case core::BinaryOp::kMultiply:
- return {kBinaryOperatorStar, is_compound ? "operator *= " : "operator * "};
+ return {&data.binary_star, is_compound ? "operator *= " : "operator * "};
case core::BinaryOp::kDivide:
- return {kBinaryOperatorDivide, is_compound ? "operator /= " : "operator / "};
+ return {&data.binary_divide, is_compound ? "operator /= " : "operator / "};
case core::BinaryOp::kModulo:
- return {kBinaryOperatorModulo, is_compound ? "operator %= " : "operator % "};
+ return {&data.binary_modulo, is_compound ? "operator %= " : "operator % "};
}
TINT_UNREACHABLE() << "unhandled BinaryOp: " << op;
return {};
}();
+ if (!intrinsic_info) {
+ return {};
+ }
Vector args{lhs, rhs};
@@ -1285,8 +467,8 @@
};
// Resolve the intrinsic overload
- auto match = MatchIntrinsic(kBinaryOperators[intrinsic_index], intrinsic_name, args,
- earliest_eval_stage, TemplateState{}, on_no_match);
+ auto match = MatchIntrinsic(*intrinsic_info, intrinsic_name, args, earliest_eval_stage,
+ TemplateState{}, on_no_match);
if (!match.overload) {
return {};
}
@@ -1341,7 +523,7 @@
}
// Resolve the intrinsic overload
- auto match = MatchIntrinsic(kConstructorsAndConverters[static_cast<size_t>(type)], name, args,
+ auto match = MatchIntrinsic(data.ctor_conv[static_cast<size_t>(type)], name, args,
earliest_eval_stage, templates, on_no_match);
if (!match.overload) {
return {};
@@ -1435,7 +617,7 @@
return IntrinsicPrototype{match.overload, return_type, std::move(match.parameters)};
}
-Impl::Candidate Impl::ScoreOverload(const OverloadInfo* overload,
+Impl::Candidate Impl::ScoreOverload(const TableData::OverloadInfo* overload,
VectorRef<const type::Type*> args,
EvaluationStage earliest_eval_stage,
const TemplateState& in_templates) const {
@@ -1614,14 +796,15 @@
}
MatchState Impl::Match(TemplateState& templates,
- const OverloadInfo* overload,
+ const TableData::OverloadInfo* overload,
MatcherIndex const* matcher_indices,
EvaluationStage earliest_eval_stage) const {
- return MatchState(builder, templates, matchers, overload, matcher_indices, earliest_eval_stage);
+ return MatchState{builder.Types(), builder.Symbols(), templates, data,
+ overload, matcher_indices, earliest_eval_stage};
}
void Impl::PrintOverload(StringStream& ss,
- const OverloadInfo* overload,
+ const TableData::OverloadInfo* overload,
const char* intrinsic_name) const {
TemplateState templates;
@@ -1702,30 +885,6 @@
}
}
-const type::Type* MatchState::Type(const type::Type* ty) {
- MatcherIndex matcher_index = *matcher_indices_++;
- auto* matcher = matchers.type[matcher_index];
- return matcher->Match(*this, ty);
-}
-
-Number MatchState::Num(Number number) {
- MatcherIndex matcher_index = *matcher_indices_++;
- auto* matcher = matchers.number[matcher_index];
- return matcher->Match(*this, number);
-}
-
-std::string MatchState::TypeName() {
- MatcherIndex matcher_index = *matcher_indices_++;
- auto* matcher = matchers.type[matcher_index];
- return matcher->String(this);
-}
-
-std::string MatchState::NumName() {
- MatcherIndex matcher_index = *matcher_indices_++;
- auto* matcher = matchers.number[matcher_index];
- return matcher->String(this);
-}
-
void Impl::ErrAmbiguousOverload(const char* intrinsic_name,
VectorRef<const type::Type*> args,
TemplateState templates,
@@ -1765,7 +924,7 @@
} // namespace
std::unique_ptr<Table> Table::Create(ProgramBuilder& builder) {
- return std::make_unique<Impl>(builder);
+ return std::make_unique<Impl>(builder, CoreTableData());
}
Table::~Table() = default;
diff --git a/src/tint/lang/core/intrinsic/table_data.h b/src/tint/lang/core/intrinsic/table_data.h
new file mode 100644
index 0000000..6055d15
--- /dev/null
+++ b/src/tint/lang/core/intrinsic/table_data.h
@@ -0,0 +1,492 @@
+// Copyright 2023 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_LANG_CORE_INTRINSIC_TABLE_DATA_H_
+#define SRC_TINT_LANG_CORE_INTRINSIC_TABLE_DATA_H_
+
+#include <stdint.h>
+#include <limits>
+#include <string>
+
+#include "src/tint/lang/core/constant/eval.h"
+#include "src/tint/lang/core/evaluation_stage.h"
+#include "src/tint/lang/core/parameter_usage.h"
+#include "src/tint/utils/containers/enum_set.h"
+#include "src/tint/utils/containers/slice.h"
+
+namespace tint::type {
+class Manager;
+} // namespace tint::type
+
+namespace tint::core::intrinsic {
+
+/// TableData holds the immutable data that holds the intrinsic data for a language.
+struct TableData {
+ /// Index type used for matcher indices
+ using MatcherIndex = uint8_t;
+
+ /// Index value used for template types / numbers that do not have a constraint
+ static constexpr MatcherIndex kNoMatcher = std::numeric_limits<MatcherIndex>::max();
+
+ /// Unique flag bits for overloads
+ enum class OverloadFlag {
+ kIsBuiltin, // The overload is a builtin ('fn')
+ kIsOperator, // The overload is an operator ('op')
+ kIsConstructor, // The overload is a value constructor ('ctor')
+ kIsConverter, // The overload is a value converter ('conv')
+ kSupportsVertexPipeline, // The overload can be used in vertex shaders
+ kSupportsFragmentPipeline, // The overload can be used in fragment shaders
+ kSupportsComputePipeline, // The overload can be used in compute shaders
+ kMustUse, // The overload cannot be called as a statement
+ kIsDeprecated, // The overload is deprecated
+ };
+
+ /// An enum set of OverloadFlag, used by OperatorInfo
+ using OverloadFlags = tint::EnumSet<OverloadFlag>;
+
+ /// ParameterInfo describes a parameter
+ struct ParameterInfo {
+ /// The parameter usage (parameter name in definition file)
+ const ParameterUsage usage;
+
+ /// Pointer to a list of indices that are used to match the parameter type.
+ /// The matcher indices index on Matchers::type and / or Matchers::number.
+ /// These indices are consumed by the matchers themselves.
+ /// The first index is always a TypeMatcher.
+ MatcherIndex const* const matcher_indices;
+ };
+
+ /// TemplateTypeInfo describes an template type
+ struct TemplateTypeInfo {
+ /// Name of the template type (e.g. 'T')
+ const char* name;
+ /// Optional type matcher constraint.
+ /// Either an index in Matchers::type, or kNoMatcher
+ const MatcherIndex matcher_index;
+ };
+
+ /// TemplateNumberInfo describes a template number
+ struct TemplateNumberInfo {
+ /// Name of the template number (e.g. 'N')
+ const char* name;
+ /// Optional number matcher constraint.
+ /// Either an index in Matchers::number, or kNoMatcher
+ const MatcherIndex matcher_index;
+ };
+
+ /// OverloadInfo describes a single function overload
+ struct OverloadInfo {
+ /// Total number of parameters for the overload
+ const uint8_t num_parameters;
+ /// Total number of template types for the overload
+ const uint8_t num_template_types;
+ /// Total number of template numbers for the overload
+ const uint8_t num_template_numbers;
+ /// Pointer to the first template type
+ TemplateTypeInfo const* const template_types;
+ /// Pointer to the first template number
+ TemplateNumberInfo const* const template_numbers;
+ /// Pointer to the first parameter
+ ParameterInfo const* const parameters;
+ /// Pointer to a list of matcher indices that index on Matchers::type and
+ /// Matchers::number, used to build the return type. If the function has no
+ /// return type then this is null
+ MatcherIndex const* const return_matcher_indices;
+ /// The flags for the overload
+ OverloadFlags flags;
+ /// The function used to evaluate the overload at shader-creation time.
+ constant::Eval::Function const const_eval_fn;
+ };
+
+ /// IntrinsicInfo describes a builtin function or operator overload
+ struct IntrinsicInfo {
+ /// Number of overloads of the intrinsic
+ const uint8_t num_overloads;
+ /// Pointer to the start of the overloads for the function
+ OverloadInfo const* const overloads;
+ };
+
+ /// Number is an 32 bit unsigned integer, which can be in one of three states:
+ /// * Invalid - Number has not been assigned a value
+ /// * Valid - a fixed integer value
+ /// * Any - matches any other non-invalid number
+ class Number {
+ enum State {
+ kInvalid,
+ kValid,
+ kAny,
+ };
+
+ constexpr explicit Number(State state) : state_(state) {}
+
+ public:
+ /// A special number representing any number
+ static const Number any;
+ /// An invalid number
+ static const Number invalid;
+
+ /// Constructed as a valid number with the value v
+ /// @param v the value for the number
+ explicit constexpr Number(uint32_t v) : value_(v), state_(kValid) {}
+
+ /// @returns the value of the number
+ inline uint32_t Value() const { return value_; }
+
+ /// @returns the true if the number is valid
+ inline bool IsValid() const { return state_ == kValid; }
+
+ /// @returns the true if the number is any
+ inline bool IsAny() const { return state_ == kAny; }
+
+ /// Assignment operator.
+ /// The number becomes valid, with the value n
+ /// @param n the new value for the number
+ /// @returns this so calls can be chained
+ inline Number& operator=(uint32_t n) {
+ value_ = n;
+ state_ = kValid;
+ return *this;
+ }
+
+ private:
+ uint32_t value_ = 0;
+ State state_ = kInvalid;
+ };
+
+ /// A special type that matches all TypeMatchers
+ class Any final : public Castable<Any, type::Type> {
+ public:
+ Any();
+ ~Any() override;
+
+ /// @copydoc type::UniqueNode::Equals
+ bool Equals(const type::UniqueNode& other) const override;
+ /// @copydoc type::Type::FriendlyName
+ std::string FriendlyName() const override;
+ /// @copydoc type::Type::Clone
+ type::Type* Clone(type::CloneContext& ctx) const override;
+ };
+
+ /// TemplateState holds the state of the template numbers and types.
+ /// Used by the MatchState.
+ class TemplateState {
+ public:
+ /// If the template type with index @p idx is undefined, then it is defined with the @p ty
+ /// and Type() returns @p ty. If the template type is defined, and @p ty can be converted to
+ /// the template type then the template type is returned. If the template type is defined,
+ /// and the template type can be converted to @p ty, then the template type is replaced with
+ /// @p ty, and @p ty is returned. If none of the above applies, then @p ty is a type
+ /// mismatch for the template type, and nullptr is returned.
+ /// @param idx the index of the template type
+ /// @param ty the type
+ /// @returns true on match or newly defined
+ const type::Type* Type(size_t idx, const type::Type* ty) {
+ if (idx >= types_.Length()) {
+ types_.Resize(idx + 1);
+ }
+ auto& t = types_[idx];
+ if (t == nullptr) {
+ t = ty;
+ return ty;
+ }
+ ty = type::Type::Common(Vector{t, ty});
+ if (ty) {
+ t = ty;
+ }
+ return ty;
+ }
+
+ /// If the number with index @p idx is undefined, then it is defined with the number
+ /// `number` and Num() returns true. If the number is defined, then `Num()` returns true iff
+ /// it is equal to @p ty.
+ /// @param idx the index of the template number
+ /// @param number the number
+ /// @returns true on match or newly defined
+ bool Num(size_t idx, TableData::Number number) {
+ if (idx >= numbers_.Length()) {
+ numbers_.Resize(idx + 1, TableData::Number::invalid);
+ }
+ auto& n = numbers_[idx];
+ if (!n.IsValid()) {
+ n = number.Value();
+ return true;
+ }
+ return n.Value() == number.Value();
+ }
+
+ /// @param idx the index of the template type
+ /// @returns the template type with index @p idx, or nullptr if the type was not
+ /// defined.
+ const type::Type* Type(size_t idx) const {
+ if (idx >= types_.Length()) {
+ return nullptr;
+ }
+ return types_[idx];
+ }
+
+ /// SetType replaces the template type with index @p idx with type @p ty.
+ /// @param idx the index of the template type
+ /// @param ty the new type for the template
+ void SetType(size_t idx, const type::Type* ty) {
+ if (idx >= types_.Length()) {
+ types_.Resize(idx + 1);
+ }
+ types_[idx] = ty;
+ }
+
+ /// @returns the number type with index @p idx.
+ /// @param idx the index of the template number
+ TableData::Number Num(size_t idx) const {
+ if (idx >= numbers_.Length()) {
+ return TableData::Number::invalid;
+ }
+ return numbers_[idx];
+ }
+
+ /// @return the total number of type and number templates
+ size_t Count() const { return types_.Length() + numbers_.Length(); }
+
+ private:
+ Vector<const type::Type*, 4> types_;
+ Vector<TableData::Number, 2> numbers_;
+ };
+
+ /// The current overload match state
+ /// MatchState holds the state used to match an overload.
+ class MatchState {
+ public:
+ /// Constructor
+ /// @param ty_mgr the type manager
+ /// @param syms the symbol table
+ /// @param t the template state
+ /// @param d the table data
+ /// @param o the current overload
+ /// @param matcher_indices the remaining matcher indices
+ /// @param s the required evaluation stage of the overload
+ MatchState(type::Manager& ty_mgr,
+ SymbolTable& syms,
+ TemplateState& t,
+ const TableData& d,
+ const OverloadInfo* o,
+ MatcherIndex const* matcher_indices,
+ EvaluationStage s)
+ : types(ty_mgr),
+ symbols(syms),
+ templates(t),
+ data(d),
+ overload(o),
+ earliest_eval_stage(s),
+ matcher_indices_(matcher_indices) {}
+
+ /// The type manager
+ type::Manager& types;
+
+ /// The symbol manager
+ SymbolTable& symbols;
+
+ /// The template types and numbers
+ TemplateState& templates;
+
+ /// The table data
+ TableData const& data;
+
+ /// The current overload being evaluated
+ OverloadInfo const* const overload;
+
+ /// The earliest evaluation stage of the builtin call
+ EvaluationStage earliest_eval_stage;
+
+ /// Type uses the next TypeMatcher from the matcher indices to match the type @p ty.
+ /// @param ty the type to try matching
+ /// @returns the canonical expected type if the type matches, otherwise nullptr.
+ /// @note: The matcher indices are progressed on calling.
+ const type::Type* Type(const type::Type* ty) {
+ MatcherIndex matcher_index = *matcher_indices_++;
+ auto& matcher = data.type_matchers[matcher_index];
+ return matcher.match(*this, ty);
+ }
+
+ /// Num uses the next NumMatcher from the matcher indices to match @p number.
+ /// @param number the number to try matching
+ /// @returns the canonical expected number if the number matches, otherwise an invalid
+ /// number.
+ /// @note: The matcher indices are progressed on calling.
+ Number Num(Number number) {
+ MatcherIndex matcher_index = *matcher_indices_++;
+ auto& matcher = data.number_matchers[matcher_index];
+ return matcher.match(*this, number);
+ }
+
+ /// @returns a string representation of the next TypeMatcher from the matcher indices.
+ /// @note: The matcher indices are progressed on calling.
+ std::string TypeName() {
+ MatcherIndex matcher_index = *matcher_indices_++;
+ auto& matcher = data.type_matchers[matcher_index];
+ return matcher.string(this);
+ }
+
+ /// @returns a string representation of the next NumberMatcher from the matcher indices.
+ /// @note: The matcher indices are progressed on calling.
+ std::string NumName() {
+ MatcherIndex matcher_index = *matcher_indices_++;
+ auto& matcher = data.number_matchers[matcher_index];
+ return matcher.string(this);
+ }
+
+ private:
+ MatcherIndex const* matcher_indices_ = nullptr;
+ };
+
+ /// A TypeMatcher is the interface used to match an type used as part of an
+ /// overload's parameter or return type.
+ struct TypeMatcher {
+ /// Checks whether the given type matches the matcher rules, and returns the
+ /// expected, canonicalized type on success.
+ /// Match may define and refine the template types and numbers in state.
+ /// The parameter `type` is the type to match
+ /// Returns the canonicalized type on match, otherwise nullptr
+ using MatchFn = const type::Type*(MatchState& state, const type::Type* type);
+
+ /// @see #MatchFn
+ MatchFn* const match;
+
+ /// Returns a string representation of the matcher.
+ /// Used for printing error messages when no overload is found.
+ using StringFn = std::string(MatchState* state);
+
+ /// @see #StringFn
+ StringFn* const string;
+ };
+
+ /// A NumberMatcher is the interface used to match a number or enumerator used
+ /// as part of an overload's parameter or return type.
+ struct NumberMatcher {
+ /// Checks whether the given number matches the matcher rules.
+ /// Match may define template numbers in state.
+ /// The parameter `number` is the number to match
+ /// Returns true if the argument type is as expected.
+ using MatchFn = Number(MatchState& state, Number number);
+
+ /// @see #MatchFn
+ MatchFn* const match;
+
+ /// Returns a string representation of the matcher.
+ /// Used for printing error messages when no overload is found.
+ using StringFn = std::string(MatchState* state);
+
+ /// @see #StringFn
+ StringFn* const string;
+ };
+
+ /// TemplateTypeMatcher is a Matcher for a template type.
+ /// The TemplateTypeMatcher will initially match against any type, and then will only be further
+ /// constrained based on the conversion rules defined at
+ /// https://www.w3.org/TR/WGSL/#conversion-rank
+ template <size_t INDEX>
+ struct TemplateTypeMatcher {
+ /// The TypeMatcher for the template type with the index `INDEX`
+ static constexpr TypeMatcher matcher{
+ /* match */
+ [](MatchState& state, const type::Type* type) -> const type::Type* {
+ if (type->Is<Any>()) {
+ return state.templates.Type(INDEX);
+ }
+ if (auto* templates = state.templates.Type(INDEX, type)) {
+ return templates;
+ }
+ return nullptr;
+ },
+ /* string */
+ [](MatchState* state) -> std::string {
+ return state->overload->template_types[INDEX].name;
+ },
+ };
+ };
+
+ /// TemplateNumberMatcher is a Matcher for a template number.
+ /// The TemplateNumberMatcher will match against any number (so long as it is
+ /// consistent for all uses in the overload)
+ template <size_t INDEX>
+ struct TemplateNumberMatcher {
+ /// The NumberMatcher for the template number with the index `INDEX`
+ static constexpr NumberMatcher matcher{
+ /* match */
+ [](TableData::MatchState& state, TableData::Number number) -> TableData::Number {
+ if (number.IsAny()) {
+ return state.templates.Num(INDEX);
+ }
+ return state.templates.Num(INDEX, number) ? number : TableData::Number::invalid;
+ },
+ /* string */
+ [](TableData::MatchState* state) -> std::string {
+ return state->overload->template_numbers[INDEX].name;
+ },
+ };
+ };
+
+ /// The list of type matchers used by the intrinsic overloads
+ Slice<TypeMatcher const> const type_matchers;
+ /// The list of number matchers used by the intrinsic overloads
+ Slice<NumberMatcher const> const number_matchers;
+ /// The type constructor and convertor intrinsic overloads
+ Slice<IntrinsicInfo const> const ctor_conv;
+ /// The builtin function intrinsic overloads
+ Slice<IntrinsicInfo const> const builtins;
+ /// The IntrinsicInfo for the binary operator 'plus'
+ IntrinsicInfo const& binary_plus;
+ /// The IntrinsicInfo for the binary operator 'minus'
+ IntrinsicInfo const& binary_minus;
+ /// The IntrinsicInfo for the binary operator 'star'
+ IntrinsicInfo const& binary_star;
+ /// The IntrinsicInfo for the binary operator 'divide'
+ IntrinsicInfo const& binary_divide;
+ /// The IntrinsicInfo for the binary operator 'modulo'
+ IntrinsicInfo const& binary_modulo;
+ /// The IntrinsicInfo for the binary operator 'xor'
+ IntrinsicInfo const& binary_xor;
+ /// The IntrinsicInfo for the binary operator 'and'
+ IntrinsicInfo const& binary_and;
+ /// The IntrinsicInfo for the binary operator 'or'
+ IntrinsicInfo const& binary_or;
+ /// The IntrinsicInfo for the binary operator 'logical_and'
+ IntrinsicInfo const& binary_logical_and;
+ /// The IntrinsicInfo for the binary operator 'logical_or'
+ IntrinsicInfo const& binary_logical_or;
+ /// The IntrinsicInfo for the binary operator 'equal'
+ IntrinsicInfo const& binary_equal;
+ /// The IntrinsicInfo for the binary operator 'not_equal'
+ IntrinsicInfo const& binary_not_equal;
+ /// The IntrinsicInfo for the binary operator 'less_than'
+ IntrinsicInfo const& binary_less_than;
+ /// The IntrinsicInfo for the binary operator 'greater_than'
+ IntrinsicInfo const& binary_greater_than;
+ /// The IntrinsicInfo for the binary operator 'less_than_equal'
+ IntrinsicInfo const& binary_less_than_equal;
+ /// The IntrinsicInfo for the binary operator 'greater_than_equal'
+ IntrinsicInfo const& binary_greater_than_equal;
+ /// The IntrinsicInfo for the binary operator 'shift_left'
+ IntrinsicInfo const& binary_shift_left;
+ /// The IntrinsicInfo for the binary operator 'shift_right'
+ IntrinsicInfo const& binary_shift_right;
+ /// The IntrinsicInfo for the unary operator 'not'
+ IntrinsicInfo const& unary_not;
+ /// The IntrinsicInfo for the unary operator 'complement'
+ IntrinsicInfo const& unary_complement;
+ /// The IntrinsicInfo for the unary operator 'minus'
+ IntrinsicInfo const& unary_minus;
+};
+
+} // namespace tint::core::intrinsic
+
+#endif // SRC_TINT_LANG_CORE_INTRINSIC_TABLE_DATA_H_
diff --git a/src/tint/lang/core/type/manager.cc b/src/tint/lang/core/type/manager.cc
index 07bbf2a..a1178f2 100644
--- a/src/tint/lang/core/type/manager.cc
+++ b/src/tint/lang/core/type/manager.cc
@@ -100,6 +100,10 @@
return Get<type::Matrix>(vec(inner, rows), cols);
}
+const type::Matrix* Manager::mat(const type::Vector* column_type, uint32_t cols) {
+ return Get<type::Matrix>(column_type, cols);
+}
+
const type::Matrix* Manager::mat2x2(const type::Type* inner) {
return mat(inner, 2, 2);
}
diff --git a/src/tint/lang/core/type/manager.h b/src/tint/lang/core/type/manager.h
index 6189ccd..55def97 100644
--- a/src/tint/lang/core/type/manager.h
+++ b/src/tint/lang/core/type/manager.h
@@ -238,6 +238,11 @@
/// @returns the matrix type
const type::Matrix* mat(const type::Type* inner, uint32_t cols, uint32_t rows);
+ /// @param column_type the column vector type
+ /// @param cols the number of columns
+ /// @returns the matrix type
+ const type::Matrix* mat(const type::Vector* column_type, uint32_t cols);
+
/// @param inner the inner type
/// @returns a mat2x2 with the element @p inner
const type::Matrix* mat2x2(const type::Type* inner);
diff --git a/src/tint/lang/core/intrinsic/table.inl.tmpl b/src/tint/utils/templates/intrinsic_table_data.tmpl.inc
similarity index 63%
rename from src/tint/lang/core/intrinsic/table.inl.tmpl
rename to src/tint/utils/templates/intrinsic_table_data.tmpl.inc
index 0e9b104..467a871 100644
--- a/src/tint/lang/core/intrinsic/table.inl.tmpl
+++ b/src/tint/utils/templates/intrinsic_table_data.tmpl.inc
@@ -1,7 +1,7 @@
{{- /*
--------------------------------------------------------------------------------
-Template file for use with tools/src/cmd/gen to generate intrinsic_table.inl
-Used by BuiltinTable.cc for builtin overload resolution.
+Template file for use with tools/src/cmd/gen to generate the constant data that
+is held in a core::intrinsic::TableData.
To update the generated file, run:
./tools/run gen
@@ -12,7 +12,37 @@
--------------------------------------------------------------------------------
*/ -}}
-{{- $I := LoadIntrinsics "src/tint/lang/core/core.def" -}}
+
+{{- /* ------------------------------------------------------------------ */ -}}
+{{- define "Data" -}}
+{{- /* ------------------------------------------------------------------ */ -}}
+{{- $I := $.Intrinsics -}}
+
+namespace {{$.Namespace}} {
+namespace {
+
+using IntrinsicInfo = tint::core::intrinsic::TableData::IntrinsicInfo;
+using MatcherIndex = tint::core::intrinsic::TableData::MatcherIndex;
+using MatchState = tint::core::intrinsic::TableData::MatchState;
+using Number = tint::core::intrinsic::TableData::Number;
+using NumberMatcher = tint::core::intrinsic::TableData::NumberMatcher;
+using OverloadFlag = tint::core::intrinsic::TableData::OverloadFlag;
+using OverloadFlags = tint::core::intrinsic::TableData::OverloadFlags;
+using OverloadInfo = tint::core::intrinsic::TableData::OverloadInfo;
+using ParameterInfo = tint::core::intrinsic::TableData::ParameterInfo;
+using StringStream = tint::StringStream;
+using TemplateNumberInfo = tint::core::intrinsic::TableData::TemplateNumberInfo;
+using TemplateTypeInfo = tint::core::intrinsic::TableData::TemplateTypeInfo;
+using Type = tint::type::Type;
+using TypeMatcher = tint::core::intrinsic::TableData::TypeMatcher;
+
+template<size_t N>
+using TemplateNumberMatcher = tint::core::intrinsic::TableData::TemplateNumberMatcher<N>;
+
+template<size_t N>
+using TemplateTypeMatcher = tint::core::intrinsic::TableData::TemplateTypeMatcher<N>;
+
+static constexpr auto kNoMatcher = tint::core::intrinsic::TableData::kNoMatcher;
// clang-format off
@@ -178,153 +208,148 @@
};
// clang-format on
-{{ end -}}
+
+} // anonymous namespace
+
+const TableData& {{$.Name}}() {
+ static const TableData data{
+ /* type_matchers */ kTypeMatchers,
+ /* number_matchers */ kNumberMatchers,
+ /* ctor_conv */ kConstructorsAndConverters,
+ /* builtins */ kBuiltins,
+ /* binary_plus */ kBinaryOperators[kBinaryOperatorPlus],
+ /* binary_minus */ kBinaryOperators[kBinaryOperatorMinus],
+ /* binary_star */ kBinaryOperators[kBinaryOperatorStar],
+ /* binary_divide */ kBinaryOperators[kBinaryOperatorDivide],
+ /* binary_modulo */ kBinaryOperators[kBinaryOperatorModulo],
+ /* binary_xor */ kBinaryOperators[kBinaryOperatorXor],
+ /* binary_and */ kBinaryOperators[kBinaryOperatorAnd],
+ /* binary_or */ kBinaryOperators[kBinaryOperatorOr],
+ /* binary_logical_and */ kBinaryOperators[kBinaryOperatorLogicalAnd],
+ /* binary_logical_or */ kBinaryOperators[kBinaryOperatorLogicalOr],
+ /* binary_equal */ kBinaryOperators[kBinaryOperatorEqual],
+ /* binary_not_equal */ kBinaryOperators[kBinaryOperatorNotEqual],
+ /* binary_less_than */ kBinaryOperators[kBinaryOperatorLessThan],
+ /* binary_greater_than */ kBinaryOperators[kBinaryOperatorGreaterThan],
+ /* binary_less_than_equal */ kBinaryOperators[kBinaryOperatorLessThanEqual],
+ /* binary_greater_than_equal */ kBinaryOperators[kBinaryOperatorGreaterThanEqual],
+ /* binary_shift_left */ kBinaryOperators[kBinaryOperatorShiftLeft],
+ /* binary_shift_right */ kBinaryOperators[kBinaryOperatorShiftRight],
+ /* unary_not */ kUnaryOperators[kUnaryOperatorNot],
+ /* unary_complement */ kUnaryOperators[kUnaryOperatorComplement],
+ /* unary_minus */ kUnaryOperators[kUnaryOperatorMinus],
+ };
+ return data;
+}
+
+} // namespace {{$.Namespace}}
+
+{{ end -}}
+{{- end -}}
+
{{- /* ------------------------------------------------------------------ */ -}}
{{- define "Type" -}}
{{- /* ------------------------------------------------------------------ */ -}}
{{- $class := PascalCase .Name -}}
/// TypeMatcher for 'type {{.Name}}'
-{{- if .Decl.Source.S.Filepath }}
-{{- end }}
-class {{$class}} : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-const type::Type* {{$class}}::Match(MatchState& state, const type::Type* ty) const {
+constexpr TypeMatcher k{{$class}}Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
{{- range .TemplateParams }}
{{- template "DeclareLocalTemplateParam" . }}
{{- end }}
- if (!match_{{TrimLeft .Name "_"}}(state, ty{{range .TemplateParams}}, {{.GetName}}{{end}})) {
- return nullptr;
- }
+ if (!match_{{TrimLeft .Name "_"}}(state, ty{{range .TemplateParams}}, {{.GetName}}{{end}})) {
+ return nullptr;
+ }
{{- range .TemplateParams }}
- {{.Name}} = {{ template "MatchTemplateParam" .}}({{.Name}});
- if ({{ template "IsTemplateParamInvalid" .}}) {
- return nullptr;
- }
+ {{.Name}} = {{ template "MatchTemplateParam" .}}({{.Name}});
+ if ({{ template "IsTemplateParamInvalid" .}}) {
+ return nullptr;
+ }
{{- end }}
- return build_{{TrimLeft .Name "_"}}(state{{range .TemplateParams}}, {{.GetName}}{{end}});
-}
-
-std::string {{$class}}::String(MatchState*{{if .TemplateParams}} state{{end}}) const {
+ return build_{{TrimLeft .Name "_"}}(state{{range .TemplateParams}}, {{.GetName}}{{end}});
+ },
+/* string */ [](MatchState*{{if .TemplateParams}} state{{end}}) -> std::string {
{{- range .TemplateParams }}
{{- template "DeclareLocalTemplateParamName" . }}
{{- end }}
{{- if .DisplayName }}
- StringStream ss;
- ss{{range SplitDisplayName .DisplayName}} << {{.}}{{end}};
- return ss.str();
+ StringStream ss;
+ ss{{range SplitDisplayName .DisplayName}} << {{.}}{{end}};
+ return ss.str();
{{- else if .TemplateParams }}
- return "{{.Name}}<"{{template "AppendTemplateParamNames" .TemplateParams}} + ">";
+ return "{{.Name}}<"{{template "AppendTemplateParamNames" .TemplateParams}} + ">";
{{- else }}
- return "{{.Name}}";
+ return "{{.Name}}";
{{- end }}
-}
+ }
+};
+
{{ end -}}
+
{{- /* ------------------------------------------------------------------ */ -}}
{{- define "TypeMatcher" -}}
{{- /* ------------------------------------------------------------------ */ -}}
{{- $class := PascalCase .Name -}}
/// TypeMatcher for 'match {{.Name}}'
-{{- if .Decl.Source.S.Filepath }}
-{{- end }}
-class {{$class}} : public TypeMatcher {
- public:
- /// Checks whether the given type matches the matcher rules, and returns the
- /// expected, canonicalized type on success.
- /// Match may define and refine the template types and numbers in state.
- /// @param state the MatchState
- /// @param type the type to match
- /// @returns the canonicalized type on match, otherwise nullptr
- const type::Type* Match(MatchState& state,
- const type::Type* type) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
-const type::Type* {{$class}}::Match(MatchState& state, const type::Type* ty) const {
+constexpr TypeMatcher k{{$class}}Matcher {
+/* match */ [](MatchState& state, const Type* ty) -> const Type* {
{{- range .PrecedenceSortedTypes }}
- if (match_{{.Name}}(state, ty)) {
- return build_{{.Name}}(state);
- }
+ if (match_{{.Name}}(state, ty)) {
+ return build_{{.Name}}(state);
+ }
{{- end }}
- return nullptr;
-}
-
-std::string {{$class}}::String(MatchState*) const {
- StringStream ss;
- // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
- // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
- ss
+ return nullptr;
+ },
+/* string */ [](MatchState*) -> std::string {
+ StringStream ss;
+ // Note: We pass nullptr to the TypeMatcher::String() functions, as 'matcher's do not support
+ // template arguments, nor can they match sub-types. As such, they have no use for the MatchState.
+ ss
{{- range .Types -}}
-{{- if IsFirstIn . $.Types }} << {{PascalCase .Name}}().String(nullptr)
-{{- else if IsLastIn . $.Types }} << " or " << {{PascalCase .Name}}().String(nullptr)
-{{- else }} << ", " << {{PascalCase .Name}}().String(nullptr)
+{{- if IsFirstIn . $.Types }} << k{{PascalCase .Name}}Matcher.string(nullptr)
+{{- else if IsLastIn . $.Types }} << " or " << k{{PascalCase .Name}}Matcher.string(nullptr)
+{{- else }} << ", " << k{{PascalCase .Name}}Matcher.string(nullptr)
{{- end -}}
{{- end -}};
- return ss.str();
-}
+ return ss.str();
+ }
+};
{{ end -}}
+
{{- /* ------------------------------------------------------------------ */ -}}
{{- define "EnumMatcher" -}}
{{- /* ------------------------------------------------------------------ */ -}}
{{- $class := PascalCase .Name -}}
{{- $enum := PascalCase .Enum.Name -}}
/// EnumMatcher for 'match {{.Name}}'
-{{- if .Decl.Source.S.Filepath }}
-{{- end }}
-class {{$class}} : public NumberMatcher {
- public:
- /// Checks whether the given number matches the enum matcher rules.
- /// Match may define template numbers in state.
- /// @param state the MatchState
- /// @param number the enum value as a Number
- /// @return true if the enum value matches the set
- Number Match(MatchState& state, Number number) const override;
- /// @param state the MatchState
- /// @return a string representation of the matcher.
- std::string String(MatchState* state) const override;
-};
-
+constexpr NumberMatcher k{{$class}}Matcher {
{{ if eq 1 (len .Options) -}}
{{- $option := index .Options 0 }}
{{- $entry := printf "k%v" (PascalCase $option.Name) -}}
-Number {{$class}}::Match(MatchState&, Number number) const {
- if (number.IsAny() || number.Value() == static_cast<uint32_t>({{$enum}}::{{$entry}})) {
- return Number(static_cast<uint32_t>({{$enum}}::{{$entry}}));
- }
- return Number::invalid;
-}
+/* match */ [](MatchState&, Number number) -> Number {
+ if (number.IsAny() || number.Value() == static_cast<uint32_t>({{$enum}}::{{$entry}})) {
+ return Number(static_cast<uint32_t>({{$enum}}::{{$entry}}));
+ }
+ return Number::invalid;
+ },
{{- else -}}
-Number {{$class}}::Match(MatchState&, Number number) const {
- switch (static_cast<{{$enum}}>(number.Value())) {
+/* match */ [](MatchState&, Number number) -> Number {
+ switch (static_cast<{{$enum}}>(number.Value())) {
{{- range .Options }}
- case {{$enum}}::k{{PascalCase .Name}}:
+ case {{$enum}}::k{{PascalCase .Name}}:
{{- end }}
- return number;
- default:
- return Number::invalid;
- }
-}
+ return number;
+ default:
+ return Number::invalid;
+ }
+ },
{{- end }}
-
-std::string {{$class}}::String(MatchState*) const {
- return "
+/* string */ [](MatchState*) -> std::string {
+ return "
{{- range .Options -}}
{{- if IsFirstIn . $.Options }}{{.Name}}
{{- else if IsLastIn . $.Options }} or {{.Name}}
@@ -332,79 +357,65 @@
{{- end -}}
{{- end -}}
";
-}
+ }
+};
{{ end -}}
{{- /* ------------------------------------------------------------------ */ -}}
{{- define "Matchers" -}}
{{- /* ------------------------------------------------------------------ */ -}}
-/// Matchers holds type and number matchers
-class Matchers {
- private:
+/// Type and number matchers
{{- $t_names := Map -}}
{{- $n_names := Map -}}
{{- range Iterate $.Sem.MaxTemplateTypes -}}
-{{- $name := printf "template_type_%v" . -}}
+{{- $name := printf "TemplateTypeMatcher<%v>::matcher" . -}}
{{- $t_names.Put . $name }}
- TemplateTypeMatcher {{$name}}_{ {{- . -}} };
{{- end }}
{{- range Iterate $.Sem.MaxTemplateNumbers -}}
-{{- $name := printf "template_number_%v" . -}}
+{{- $name := printf "TemplateNumberMatcher<%v>::matcher" . -}}
{{- $n_names.Put . $name }}
- TemplateNumberMatcher {{$name}}_{ {{- . -}} };
{{- end }}
{{- range $.Sem.Types -}}
-{{- $name := PascalCase .Name -}}
+{{- $name := printf "k%vMatcher" (PascalCase .Name) -}}
{{- $t_names.Put . $name }}
- {{$name}} {{$name}}_;
{{- end }}
{{- range $.Sem.TypeMatchers -}}
-{{- $name := PascalCase .Name -}}
+{{- $name := printf "k%vMatcher" (PascalCase .Name) -}}
{{- $t_names.Put . $name }}
- {{$name}} {{$name}}_;
{{- end }}
{{- range $.Sem.EnumMatchers -}}
-{{- $name := PascalCase .Name -}}
+{{- $name := printf "k%vMatcher" (PascalCase .Name) -}}
{{- $n_names.Put . $name }}
- {{$name}} {{$name}}_;
{{- end }}
- public:
- /// Constructor
- Matchers();
- /// Destructor
- ~Matchers();
-
- /// The template types, types, and type matchers
- TypeMatcher const* const type[{{len $.Table.TMatchers}}] = {
+/// The template types, types, and type matchers
+constexpr TypeMatcher kTypeMatchers[] = {
{{- range $i, $m := $.Table.TMatchers }}
- /* [{{$i}}] */
-{{- if $m }} &{{$t_names.Get $m}}_,
-{{- else }} &{{$t_names.Get $i}}_,
+ /* [{{$i}}] */
+{{- if $m }} {{$t_names.Get $m}},
+{{- else }} {{$t_names.Get $i}},
{{- end }}
{{- end }}
- };
-
- /// The template numbers, and number matchers
- NumberMatcher const* const number[{{len $.Table.NMatchers}}] = {
-{{- range $i, $m := $.Table.NMatchers }}
- /* [{{$i}}] */
-{{- if $m }} &{{$n_names.Get $m}}_,
-{{- else }} &{{$n_names.Get $i}}_,
-{{- end }}
-{{- end }}
- };
};
-Matchers::Matchers() = default;
-Matchers::~Matchers() = default;
+/// The template numbers, and number matchers
+constexpr NumberMatcher kNumberMatchers[] = {
+{{- range $i, $m := $.Table.NMatchers }}
+ /* [{{$i}}] */
+{{- if $m }} {{$n_names.Get $m}},
+{{- else }} {{$n_names.Get $i}},
+{{- end }}
+{{- end }}
+};
+
{{- end -}}
+
{{- /* ------------------------------------------------------------------ */ -}}
{{- define "DeclareLocalTemplateParam" -}}
{{- /* ------------------------------------------------------------------ */ -}}
{{- if IsTemplateTypeParam . }}
- const type::Type* {{.Name}} = nullptr;
+ const Type* {{.Name}} = nullptr;
{{- else if IsTemplateNumberParam . }}
Number {{.Name}} = Number::invalid;
{{- else if IsTemplateEnumParam . }}
@@ -412,6 +423,7 @@
{{- end -}}
{{- end -}}
+
{{- /* ------------------------------------------------------------------ */ -}}
{{- define "DeclareLocalTemplateParamName" -}}
{{- /* ------------------------------------------------------------------ */ -}}
@@ -424,6 +436,7 @@
{{- end -}}
{{- end -}}
+
{{- /* ------------------------------------------------------------------ */ -}}
{{- define "MatchTemplateParam" -}}
{{- /* ------------------------------------------------------------------ */ -}}
@@ -436,6 +449,7 @@
{{- end -}}
{{- end -}}
+
{{- /* ------------------------------------------------------------------ */ -}}
{{- define "IsTemplateParamInvalid" -}}
{{- /* ------------------------------------------------------------------ */ -}}
@@ -448,6 +462,7 @@
{{- end -}}
{{- end -}}
+
{{- /* ------------------------------------------------------------------ */ -}}
{{- define "AppendTemplateParamNames" -}}
{{- /* ------------------------------------------------------------------ */ -}}
@@ -458,6 +473,7 @@
{{- end -}}
{{- end -}}
+
{{- /* ------------------------------------------------------------------ */ -}}
{{- define "ExpandName" -}}
{{- /* ------------------------------------------------------------------ */ -}}
@@ -494,4 +510,3 @@
{{- if eq .Kind "operator" -}}Op{{end -}}
{{template "ExpandName" .ConstEvalFunction}}
{{- end -}}
-
diff --git a/tools/src/cmd/git-stats/main.go b/tools/src/cmd/git-stats/main.go
index 1830e6f..38374de 100644
--- a/tools/src/cmd/git-stats/main.go
+++ b/tools/src/cmd/git-stats/main.go
@@ -62,6 +62,7 @@
"package-lock.json",
"src/tint/builtin_table.inl",
"src/tint/lang/core/intrinsic/table.inl",
+ "src/tint/lang/core/intrinsic/core_table_data.cc.tmpl",
"test/tint/",
"third_party/gn/webgpu-cts/test_list.txt",
"third_party/khronos/",