tint/ast: Generate ast::StorageClass from intrinsics.def
Emit unit tests for parsing and printing.
Emit benchmarks for parsing.
Uses intrinsics.def as a single-source-of-truth.
The generators provide a way to optimize the enum parsers.
Change-Id: I1669c123d375f24aca45f3ea4abf04d7892673c7
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/97150
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
Commit-Queue: Ben Clayton <bclayton@chromium.org>
diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn
index 3290694..c426520 100644
--- a/src/tint/BUILD.gn
+++ b/src/tint/BUILD.gn
@@ -1043,6 +1043,7 @@
"ast/sampled_texture_test.cc",
"ast/sampler_test.cc",
"ast/stage_attribute_test.cc",
+ "ast/storage_class_test.cc",
"ast/storage_texture_test.cc",
"ast/stride_attribute_test.cc",
"ast/struct_member_align_attribute_test.cc",
diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt
index 8f8f19c..3a80404 100644
--- a/src/tint/CMakeLists.txt
+++ b/src/tint/CMakeLists.txt
@@ -739,6 +739,7 @@
ast/sampled_texture_test.cc
ast/sampler_test.cc
ast/stage_attribute_test.cc
+ ast/storage_class_test.cc
ast/storage_texture_test.cc
ast/stride_attribute_test.cc
ast/struct_member_align_attribute_test.cc
@@ -1277,6 +1278,7 @@
set(TINT_BENCHMARK_SRC
"castable_bench.cc"
+ "ast/storage_class_bench.cc"
"bench/benchmark.cc"
"reader/wgsl/parser_bench.cc"
)
diff --git a/src/tint/ast/storage_class.cc b/src/tint/ast/storage_class.cc
index 903d27a..303c04e 100644
--- a/src/tint/ast/storage_class.cc
+++ b/src/tint/ast/storage_class.cc
@@ -12,6 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+// src/tint/ast/storage_class.cc.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
#include "src/tint/ast/storage_class.h"
namespace tint::ast {
diff --git a/src/tint/ast/storage_class.cc.tmpl b/src/tint/ast/storage_class.cc.tmpl
new file mode 100644
index 0000000..e2903b7
--- /dev/null
+++ b/src/tint/ast/storage_class.cc.tmpl
@@ -0,0 +1,25 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/src/cmd/gen to generate storage_class.cc
+
+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/templates/enums.tmpl.inc" -}}
+{{- $enum := (Sem.Enum "storage_class") -}}
+
+#include "src/tint/ast/storage_class.h"
+
+namespace tint::ast {
+
+{{ Eval "ParseEnum" $enum}}
+
+{{ Eval "EnumOStream" $enum}}
+
+} // namespace tint::ast
diff --git a/src/tint/ast/storage_class.h b/src/tint/ast/storage_class.h
index 7451587..cb21115 100644
--- a/src/tint/ast/storage_class.h
+++ b/src/tint/ast/storage_class.h
@@ -12,6 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+// src/tint/ast/storage_class.h.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
#ifndef SRC_TINT_AST_STORAGE_CLASS_H_
#define SRC_TINT_AST_STORAGE_CLASS_H_
@@ -22,21 +30,21 @@
/// Storage class of a given pointer.
enum class StorageClass {
kInvalid,
- kNone,
+ kNone, // Tint-internal enum entry - not parsed
kFunction,
kPrivate,
kWorkgroup,
kUniform,
kStorage,
- kHandle,
- kIn,
- kOut,
+ kHandle, // Tint-internal enum entry - not parsed
+ kIn, // Tint-internal enum entry - not parsed
+ kOut, // Tint-internal enum entry - not parsed
};
/// @param out the std::ostream to write to
-/// @param sc the StorageClass
-/// @return the std::ostream so calls can be chained
-std::ostream& operator<<(std::ostream& out, StorageClass sc);
+/// @param value the StorageClass
+/// @returns `out` so calls can be chained
+std::ostream& operator<<(std::ostream& out, StorageClass value);
/// ParseStorageClass parses a StorageClass from a string.
/// @param str the string to parse
diff --git a/src/tint/ast/storage_class.h.tmpl b/src/tint/ast/storage_class.h.tmpl
new file mode 100644
index 0000000..d885c72
--- /dev/null
+++ b/src/tint/ast/storage_class.h.tmpl
@@ -0,0 +1,36 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/src/cmd/gen to generate storage_class.h
+
+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/templates/enums.tmpl.inc" -}}
+{{- $enum := (Sem.Enum "storage_class") -}}
+
+#ifndef SRC_TINT_AST_STORAGE_CLASS_H_
+#define SRC_TINT_AST_STORAGE_CLASS_H_
+
+#include <ostream>
+
+namespace tint::ast {
+
+/// Storage class of a given pointer.
+{{ Eval "DeclareEnum" $enum}}
+
+/// @returns true if the StorageClass is host-shareable
+/// @param sc the StorageClass
+/// @see https://gpuweb.github.io/gpuweb/wgsl.html#host-shareable
+inline bool IsHostShareable(StorageClass sc) {
+ return sc == ast::StorageClass::kUniform || sc == ast::StorageClass::kStorage;
+}
+
+} // namespace tint::ast
+
+#endif // SRC_TINT_AST_STORAGE_CLASS_H_
diff --git a/src/tint/ast/storage_class_bench.cc b/src/tint/ast/storage_class_bench.cc
new file mode 100644
index 0000000..d1232df
--- /dev/null
+++ b/src/tint/ast/storage_class_bench.cc
@@ -0,0 +1,81 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+// src/tint/ast/storage_class_bench.cc.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+#include "src/tint/ast/storage_class.h"
+
+#include <array>
+
+#include "benchmark/benchmark.h"
+
+namespace tint::ast {
+namespace {
+
+void StorageClassParser(::benchmark::State& state) {
+ std::array kStrings{
+ "fccnctin",
+ "ucti3",
+ "functVon",
+ "function",
+ "1unction",
+ "unJtqqon",
+ "llun77tion",
+ "ppqqivtHH",
+ "prcv",
+ "bivaGe",
+ "private",
+ "priviive",
+ "8WWivate",
+ "pxxvate",
+ "wXkgrggup",
+ "worXVup",
+ "3orkgroup",
+ "workgroup",
+ "workgroEp",
+ "woTTPkroup",
+ "ddorkroxxp",
+ "u44iform",
+ "unSSfoVVm",
+ "RniR22m",
+ "uniform",
+ "uFfo9m",
+ "uniorm",
+ "VOORRHrm",
+ "straye",
+ "llntrrr77ge",
+ "stor4g00",
+ "storage",
+ "trooe",
+ "zzrage",
+ "siioppa1",
+ };
+ for (auto _ : state) {
+ for (auto& str : kStrings) {
+ auto result = ParseStorageClass(str);
+ benchmark::DoNotOptimize(result);
+ }
+ }
+}
+
+BENCHMARK(StorageClassParser);
+
+} // namespace
+} // namespace tint::ast
diff --git a/src/tint/ast/storage_class_bench.cc.tmpl b/src/tint/ast/storage_class_bench.cc.tmpl
new file mode 100644
index 0000000..d9ea8cb
--- /dev/null
+++ b/src/tint/ast/storage_class_bench.cc.tmpl
@@ -0,0 +1,29 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/src/cmd/gen to generate storage_class_bench.cc
+
+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/templates/enums.tmpl.inc" -}}
+{{- $enum := (Sem.Enum "storage_class") -}}
+
+#include "src/tint/ast/storage_class.h"
+
+#include <array>
+
+#include "benchmark/benchmark.h"
+
+namespace tint::ast {
+namespace {
+
+{{ Eval "BenchmarkParseEnum" $enum }}
+
+} // namespace
+} // namespace tint::ast
diff --git a/src/tint/ast/storage_class_test.cc b/src/tint/ast/storage_class_test.cc
new file mode 100644
index 0000000..2085168
--- /dev/null
+++ b/src/tint/ast/storage_class_test.cc
@@ -0,0 +1,94 @@
+// Copyright 2022 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+////////////////////////////////////////////////////////////////////////////////
+// File generated by tools/src/cmd/gen
+// using the template:
+// src/tint/ast/storage_class_test.cc.tmpl
+//
+// Do not modify this file directly
+////////////////////////////////////////////////////////////////////////////////
+
+#include "src/tint/ast/storage_class.h"
+
+#include <string>
+
+#include "src/tint/ast/test_helper.h"
+#include "src/tint/utils/string.h"
+
+namespace tint::ast {
+namespace {
+
+namespace parse_print_tests {
+
+struct Case {
+ const char* string;
+ StorageClass value;
+};
+
+inline std::ostream& operator<<(std::ostream& out, Case c) {
+ return out << "'" << std::string(c.string) << "'";
+}
+
+static constexpr Case kValidCases[] = {
+ {"function", StorageClass::kFunction},
+ {"private", StorageClass::kPrivate},
+ {"workgroup", StorageClass::kWorkgroup},
+ {"uniform", StorageClass::kUniform},
+ {"storage", StorageClass::kStorage},
+};
+
+static constexpr Case kInvalidCases[] = {
+ {"fccnctin", StorageClass::kInvalid},
+ {"ucti3", StorageClass::kInvalid},
+ {"functVon", StorageClass::kInvalid},
+ {"priv1te", StorageClass::kInvalid},
+ {"pqiJate", StorageClass::kInvalid},
+ {"privat7ll", StorageClass::kInvalid},
+ {"workroppqHH", StorageClass::kInvalid},
+ {"workru", StorageClass::kInvalid},
+ {"wbkgGoup", StorageClass::kInvalid},
+ {"unifiivm", StorageClass::kInvalid},
+ {"8WWiform", StorageClass::kInvalid},
+ {"uxxform", StorageClass::kInvalid},
+ {"sXraggg", StorageClass::kInvalid},
+ {"traXe", StorageClass::kInvalid},
+ {"stor3ge", StorageClass::kInvalid},
+};
+
+using StorageClassParseTest = testing::TestWithParam<Case>;
+
+TEST_P(StorageClassParseTest, Parse) {
+ const char* string = GetParam().string;
+ StorageClass expect = GetParam().value;
+ EXPECT_EQ(expect, ParseStorageClass(string));
+}
+
+INSTANTIATE_TEST_SUITE_P(ValidCases, StorageClassParseTest, testing::ValuesIn(kValidCases));
+INSTANTIATE_TEST_SUITE_P(InvalidCases, StorageClassParseTest, testing::ValuesIn(kInvalidCases));
+
+using StorageClassPrintTest = testing::TestWithParam<Case>;
+
+TEST_P(StorageClassPrintTest, Print) {
+ StorageClass value = GetParam().value;
+ const char* expect = GetParam().string;
+ EXPECT_EQ(expect, utils::ToString(value));
+}
+
+INSTANTIATE_TEST_SUITE_P(ValidCases, StorageClassPrintTest, testing::ValuesIn(kValidCases));
+
+} // namespace parse_print_tests
+
+} // namespace
+} // namespace tint::ast
diff --git a/src/tint/ast/storage_class_test.cc.tmpl b/src/tint/ast/storage_class_test.cc.tmpl
new file mode 100644
index 0000000..3696aab
--- /dev/null
+++ b/src/tint/ast/storage_class_test.cc.tmpl
@@ -0,0 +1,30 @@
+{{- /*
+--------------------------------------------------------------------------------
+Template file for use with tools/src/cmd/gen to generate storage_class_test.cc
+
+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/templates/enums.tmpl.inc" -}}
+{{- $enum := (Sem.Enum "storage_class") -}}
+
+#include "src/tint/ast/storage_class.h"
+
+#include <string>
+
+#include "src/tint/ast/test_helper.h"
+#include "src/tint/utils/string.h"
+
+namespace tint::ast {
+namespace {
+
+{{ Eval "TestParsePrintEnum" $enum}}
+
+} // namespace
+} // namespace tint::ast
diff --git a/src/tint/castable_bench.cc b/src/tint/castable_bench.cc
index 7c7e0ef..c9d0c43 100644
--- a/src/tint/castable_bench.cc
+++ b/src/tint/castable_bench.cc
@@ -12,7 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "bench/benchmark.h"
+#include <memory>
+
+#include "benchmark/benchmark.h"
+
+#include "src/tint/castable.h"
namespace tint {
namespace {
diff --git a/src/tint/intrinsics.def b/src/tint/intrinsics.def
index 11fb871..30bf8a8 100644
--- a/src/tint/intrinsics.def
+++ b/src/tint/intrinsics.def
@@ -25,12 +25,15 @@
// https://gpuweb.github.io/gpuweb/wgsl/#storage-class
enum storage_class {
+ @internal none
function
private
workgroup
uniform
storage
@internal handle
+ @internal in
+ @internal out
}
// https://gpuweb.github.io/gpuweb/wgsl/#memory-access-mode
diff --git a/src/tint/reader/wgsl/parser_impl_storage_class_test.cc b/src/tint/reader/wgsl/parser_impl_storage_class_test.cc
index d83bbf4..c40752a 100644
--- a/src/tint/reader/wgsl/parser_impl_storage_class_test.cc
+++ b/src/tint/reader/wgsl/parser_impl_storage_class_test.cc
@@ -26,9 +26,9 @@
return out;
}
-class StorageClassTest : public ParserImplTestWithParam<StorageClassData> {};
+class ParserStorageClassTest : public ParserImplTestWithParam<StorageClassData> {};
-TEST_P(StorageClassTest, Parses) {
+TEST_P(ParserStorageClassTest, Parses) {
auto params = GetParam();
auto p = parser(params.input);
@@ -42,7 +42,7 @@
}
INSTANTIATE_TEST_SUITE_P(
ParserImplTest,
- StorageClassTest,
+ ParserStorageClassTest,
testing::Values(StorageClassData{"uniform", ast::StorageClass::kUniform},
StorageClassData{"workgroup", ast::StorageClass::kWorkgroup},
StorageClassData{"storage", ast::StorageClass::kStorage},
diff --git a/src/tint/resolver/ctor_conv_intrinsic.cc.tmpl b/src/tint/resolver/ctor_conv_intrinsic.cc.tmpl
index 1f3d7cd..00ac21b 100644
--- a/src/tint/resolver/ctor_conv_intrinsic.cc.tmpl
+++ b/src/tint/resolver/ctor_conv_intrinsic.cc.tmpl
@@ -2,6 +2,9 @@
--------------------------------------------------------------------------------
Template file for use with tools/src/cmd/gen to generate ctor_conv_intrinsic.cc
+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
diff --git a/src/tint/resolver/ctor_conv_intrinsic.h.tmpl b/src/tint/resolver/ctor_conv_intrinsic.h.tmpl
index a28eba4..349f939 100644
--- a/src/tint/resolver/ctor_conv_intrinsic.h.tmpl
+++ b/src/tint/resolver/ctor_conv_intrinsic.h.tmpl
@@ -2,6 +2,9 @@
--------------------------------------------------------------------------------
Template file for use with tools/src/cmd/gen to generate ctor_conv_intrinsic.h
+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
diff --git a/src/tint/resolver/intrinsic_table.inl b/src/tint/resolver/intrinsic_table.inl
index 9e6749c..91e03c3 100644
--- a/src/tint/resolver/intrinsic_table.inl
+++ b/src/tint/resolver/intrinsic_table.inl
@@ -23,7 +23,7 @@
// clang-format off
/// TypeMatcher for 'type bool'
-/// @see src/tint/intrinsics.def:73:6
+/// @see src/tint/intrinsics.def:76:6
class Bool : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -50,7 +50,7 @@
}
/// TypeMatcher for 'type fa'
-/// @see src/tint/intrinsics.def:74:48
+/// @see src/tint/intrinsics.def:77:48
class Fa : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -79,7 +79,7 @@
}
/// TypeMatcher for 'type ia'
-/// @see src/tint/intrinsics.def:75:48
+/// @see src/tint/intrinsics.def:78:48
class Ia : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -108,7 +108,7 @@
}
/// TypeMatcher for 'type i32'
-/// @see src/tint/intrinsics.def:76:21
+/// @see src/tint/intrinsics.def:79:21
class I32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -135,7 +135,7 @@
}
/// TypeMatcher for 'type u32'
-/// @see src/tint/intrinsics.def:77:21
+/// @see src/tint/intrinsics.def:80:21
class U32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -162,7 +162,7 @@
}
/// TypeMatcher for 'type f32'
-/// @see src/tint/intrinsics.def:78:21
+/// @see src/tint/intrinsics.def:81:21
class F32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -189,7 +189,7 @@
}
/// TypeMatcher for 'type f16'
-/// @see src/tint/intrinsics.def:79:21
+/// @see src/tint/intrinsics.def:82:21
class F16 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -216,7 +216,7 @@
}
/// TypeMatcher for 'type vec2'
-/// @see src/tint/intrinsics.def:80:6
+/// @see src/tint/intrinsics.def:83:6
class Vec2 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -249,7 +249,7 @@
}
/// TypeMatcher for 'type vec3'
-/// @see src/tint/intrinsics.def:81:6
+/// @see src/tint/intrinsics.def:84:6
class Vec3 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -282,7 +282,7 @@
}
/// TypeMatcher for 'type vec4'
-/// @see src/tint/intrinsics.def:82:6
+/// @see src/tint/intrinsics.def:85:6
class Vec4 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -315,7 +315,7 @@
}
/// TypeMatcher for 'type mat2x2'
-/// @see src/tint/intrinsics.def:83:6
+/// @see src/tint/intrinsics.def:86:6
class Mat2X2 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -348,7 +348,7 @@
}
/// TypeMatcher for 'type mat2x3'
-/// @see src/tint/intrinsics.def:84:6
+/// @see src/tint/intrinsics.def:87:6
class Mat2X3 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -381,7 +381,7 @@
}
/// TypeMatcher for 'type mat2x4'
-/// @see src/tint/intrinsics.def:85:6
+/// @see src/tint/intrinsics.def:88:6
class Mat2X4 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -414,7 +414,7 @@
}
/// TypeMatcher for 'type mat3x2'
-/// @see src/tint/intrinsics.def:86:6
+/// @see src/tint/intrinsics.def:89:6
class Mat3X2 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -447,7 +447,7 @@
}
/// TypeMatcher for 'type mat3x3'
-/// @see src/tint/intrinsics.def:87:6
+/// @see src/tint/intrinsics.def:90:6
class Mat3X3 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -480,7 +480,7 @@
}
/// TypeMatcher for 'type mat3x4'
-/// @see src/tint/intrinsics.def:88:6
+/// @see src/tint/intrinsics.def:91:6
class Mat3X4 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -513,7 +513,7 @@
}
/// TypeMatcher for 'type mat4x2'
-/// @see src/tint/intrinsics.def:89:6
+/// @see src/tint/intrinsics.def:92:6
class Mat4X2 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -546,7 +546,7 @@
}
/// TypeMatcher for 'type mat4x3'
-/// @see src/tint/intrinsics.def:90:6
+/// @see src/tint/intrinsics.def:93:6
class Mat4X3 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -579,7 +579,7 @@
}
/// TypeMatcher for 'type mat4x4'
-/// @see src/tint/intrinsics.def:91:6
+/// @see src/tint/intrinsics.def:94:6
class Mat4X4 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -612,7 +612,7 @@
}
/// TypeMatcher for 'type vec'
-/// @see src/tint/intrinsics.def:92:34
+/// @see src/tint/intrinsics.def:95:34
class Vec : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -653,7 +653,7 @@
}
/// TypeMatcher for 'type mat'
-/// @see src/tint/intrinsics.def:93:34
+/// @see src/tint/intrinsics.def:96:34
class Mat : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -700,7 +700,7 @@
}
/// TypeMatcher for 'type ptr'
-/// @see src/tint/intrinsics.def:94:6
+/// @see src/tint/intrinsics.def:97:6
class Ptr : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -745,7 +745,7 @@
}
/// TypeMatcher for 'type atomic'
-/// @see src/tint/intrinsics.def:95:6
+/// @see src/tint/intrinsics.def:98:6
class Atomic : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -778,7 +778,7 @@
}
/// TypeMatcher for 'type array'
-/// @see src/tint/intrinsics.def:96:6
+/// @see src/tint/intrinsics.def:99:6
class Array : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -811,7 +811,7 @@
}
/// TypeMatcher for 'type sampler'
-/// @see src/tint/intrinsics.def:97:6
+/// @see src/tint/intrinsics.def:100:6
class Sampler : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -838,7 +838,7 @@
}
/// TypeMatcher for 'type sampler_comparison'
-/// @see src/tint/intrinsics.def:98:6
+/// @see src/tint/intrinsics.def:101:6
class SamplerComparison : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -865,7 +865,7 @@
}
/// TypeMatcher for 'type texture_1d'
-/// @see src/tint/intrinsics.def:99:6
+/// @see src/tint/intrinsics.def:102:6
class Texture1D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -898,7 +898,7 @@
}
/// TypeMatcher for 'type texture_2d'
-/// @see src/tint/intrinsics.def:100:6
+/// @see src/tint/intrinsics.def:103:6
class Texture2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -931,7 +931,7 @@
}
/// TypeMatcher for 'type texture_2d_array'
-/// @see src/tint/intrinsics.def:101:6
+/// @see src/tint/intrinsics.def:104:6
class Texture2DArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -964,7 +964,7 @@
}
/// TypeMatcher for 'type texture_3d'
-/// @see src/tint/intrinsics.def:102:6
+/// @see src/tint/intrinsics.def:105:6
class Texture3D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -997,7 +997,7 @@
}
/// TypeMatcher for 'type texture_cube'
-/// @see src/tint/intrinsics.def:103:6
+/// @see src/tint/intrinsics.def:106:6
class TextureCube : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1030,7 +1030,7 @@
}
/// TypeMatcher for 'type texture_cube_array'
-/// @see src/tint/intrinsics.def:104:6
+/// @see src/tint/intrinsics.def:107:6
class TextureCubeArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1063,7 +1063,7 @@
}
/// TypeMatcher for 'type texture_multisampled_2d'
-/// @see src/tint/intrinsics.def:105:6
+/// @see src/tint/intrinsics.def:108:6
class TextureMultisampled2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1096,7 +1096,7 @@
}
/// TypeMatcher for 'type texture_depth_2d'
-/// @see src/tint/intrinsics.def:106:6
+/// @see src/tint/intrinsics.def:109:6
class TextureDepth2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1123,7 +1123,7 @@
}
/// TypeMatcher for 'type texture_depth_2d_array'
-/// @see src/tint/intrinsics.def:107:6
+/// @see src/tint/intrinsics.def:110:6
class TextureDepth2DArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1150,7 +1150,7 @@
}
/// TypeMatcher for 'type texture_depth_cube'
-/// @see src/tint/intrinsics.def:108:6
+/// @see src/tint/intrinsics.def:111:6
class TextureDepthCube : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1177,7 +1177,7 @@
}
/// TypeMatcher for 'type texture_depth_cube_array'
-/// @see src/tint/intrinsics.def:109:6
+/// @see src/tint/intrinsics.def:112:6
class TextureDepthCubeArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1204,7 +1204,7 @@
}
/// TypeMatcher for 'type texture_depth_multisampled_2d'
-/// @see src/tint/intrinsics.def:110:6
+/// @see src/tint/intrinsics.def:113:6
class TextureDepthMultisampled2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1231,7 +1231,7 @@
}
/// TypeMatcher for 'type texture_storage_1d'
-/// @see src/tint/intrinsics.def:111:6
+/// @see src/tint/intrinsics.def:114:6
class TextureStorage1D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1270,7 +1270,7 @@
}
/// TypeMatcher for 'type texture_storage_2d'
-/// @see src/tint/intrinsics.def:112:6
+/// @see src/tint/intrinsics.def:115:6
class TextureStorage2D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1309,7 +1309,7 @@
}
/// TypeMatcher for 'type texture_storage_2d_array'
-/// @see src/tint/intrinsics.def:113:6
+/// @see src/tint/intrinsics.def:116:6
class TextureStorage2DArray : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1348,7 +1348,7 @@
}
/// TypeMatcher for 'type texture_storage_3d'
-/// @see src/tint/intrinsics.def:114:6
+/// @see src/tint/intrinsics.def:117:6
class TextureStorage3D : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1387,7 +1387,7 @@
}
/// TypeMatcher for 'type texture_external'
-/// @see src/tint/intrinsics.def:115:6
+/// @see src/tint/intrinsics.def:118:6
class TextureExternal : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1414,7 +1414,7 @@
}
/// TypeMatcher for 'type __modf_result'
-/// @see src/tint/intrinsics.def:117:6
+/// @see src/tint/intrinsics.def:120:6
class ModfResult : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1441,7 +1441,7 @@
}
/// TypeMatcher for 'type __modf_result_vec'
-/// @see src/tint/intrinsics.def:118:39
+/// @see src/tint/intrinsics.def:121:39
class ModfResultVec : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1476,7 +1476,7 @@
}
/// TypeMatcher for 'type __frexp_result'
-/// @see src/tint/intrinsics.def:119:6
+/// @see src/tint/intrinsics.def:122:6
class FrexpResult : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1503,7 +1503,7 @@
}
/// TypeMatcher for 'type __frexp_result_vec'
-/// @see src/tint/intrinsics.def:120:40
+/// @see src/tint/intrinsics.def:123:40
class FrexpResultVec : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1538,7 +1538,7 @@
}
/// TypeMatcher for 'type __atomic_compare_exchange_result'
-/// @see src/tint/intrinsics.def:122:6
+/// @see src/tint/intrinsics.def:125:6
class AtomicCompareExchangeResult : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules.
@@ -1571,7 +1571,7 @@
}
/// TypeMatcher for 'match abstract_or_scalar'
-/// @see src/tint/intrinsics.def:130:7
+/// @see src/tint/intrinsics.def:133:7
class AbstractOrScalar : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1621,7 +1621,7 @@
}
/// TypeMatcher for 'match scalar'
-/// @see src/tint/intrinsics.def:131:7
+/// @see src/tint/intrinsics.def:134:7
class Scalar : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1665,7 +1665,7 @@
}
/// TypeMatcher for 'match scalar_no_f32'
-/// @see src/tint/intrinsics.def:132:7
+/// @see src/tint/intrinsics.def:135:7
class ScalarNoF32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1706,7 +1706,7 @@
}
/// TypeMatcher for 'match scalar_no_f16'
-/// @see src/tint/intrinsics.def:133:7
+/// @see src/tint/intrinsics.def:136:7
class ScalarNoF16 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1747,7 +1747,7 @@
}
/// TypeMatcher for 'match scalar_no_i32'
-/// @see src/tint/intrinsics.def:134:7
+/// @see src/tint/intrinsics.def:137:7
class ScalarNoI32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1788,7 +1788,7 @@
}
/// TypeMatcher for 'match scalar_no_u32'
-/// @see src/tint/intrinsics.def:135:7
+/// @see src/tint/intrinsics.def:138:7
class ScalarNoU32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1829,7 +1829,7 @@
}
/// TypeMatcher for 'match scalar_no_bool'
-/// @see src/tint/intrinsics.def:136:7
+/// @see src/tint/intrinsics.def:139:7
class ScalarNoBool : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1870,7 +1870,7 @@
}
/// TypeMatcher for 'match fia_fi32_f16'
-/// @see src/tint/intrinsics.def:137:7
+/// @see src/tint/intrinsics.def:140:7
class FiaFi32F16 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1914,7 +1914,7 @@
}
/// TypeMatcher for 'match fia_fiu32'
-/// @see src/tint/intrinsics.def:138:7
+/// @see src/tint/intrinsics.def:141:7
class FiaFiu32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1958,7 +1958,7 @@
}
/// TypeMatcher for 'match fa_f32'
-/// @see src/tint/intrinsics.def:139:7
+/// @see src/tint/intrinsics.def:142:7
class FaF32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -1993,7 +1993,7 @@
}
/// TypeMatcher for 'match fa_f32_f16'
-/// @see src/tint/intrinsics.def:140:7
+/// @see src/tint/intrinsics.def:143:7
class FaF32F16 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -2031,7 +2031,7 @@
}
/// TypeMatcher for 'match ia_iu32'
-/// @see src/tint/intrinsics.def:141:7
+/// @see src/tint/intrinsics.def:144:7
class IaIu32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -2069,7 +2069,7 @@
}
/// TypeMatcher for 'match fiu32_f16'
-/// @see src/tint/intrinsics.def:142:7
+/// @see src/tint/intrinsics.def:145:7
class Fiu32F16 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -2110,7 +2110,7 @@
}
/// TypeMatcher for 'match fiu32'
-/// @see src/tint/intrinsics.def:143:7
+/// @see src/tint/intrinsics.def:146:7
class Fiu32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -2148,7 +2148,7 @@
}
/// TypeMatcher for 'match fi32_f16'
-/// @see src/tint/intrinsics.def:144:7
+/// @see src/tint/intrinsics.def:147:7
class Fi32F16 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -2186,7 +2186,7 @@
}
/// TypeMatcher for 'match fi32'
-/// @see src/tint/intrinsics.def:145:7
+/// @see src/tint/intrinsics.def:148:7
class Fi32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -2221,7 +2221,7 @@
}
/// TypeMatcher for 'match f32_f16'
-/// @see src/tint/intrinsics.def:146:7
+/// @see src/tint/intrinsics.def:149:7
class F32F16 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -2256,7 +2256,7 @@
}
/// TypeMatcher for 'match iu32'
-/// @see src/tint/intrinsics.def:147:7
+/// @see src/tint/intrinsics.def:150:7
class Iu32 : public TypeMatcher {
public:
/// Checks whether the given type matches the matcher rules, and returns the
@@ -2291,7 +2291,7 @@
}
/// EnumMatcher for 'match f32_texel_format'
-/// @see src/tint/intrinsics.def:158:7
+/// @see src/tint/intrinsics.def:161:7
class F32TexelFormat : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@@ -2324,7 +2324,7 @@
}
/// EnumMatcher for 'match i32_texel_format'
-/// @see src/tint/intrinsics.def:165:7
+/// @see src/tint/intrinsics.def:168:7
class I32TexelFormat : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@@ -2356,7 +2356,7 @@
}
/// EnumMatcher for 'match u32_texel_format'
-/// @see src/tint/intrinsics.def:171:7
+/// @see src/tint/intrinsics.def:174:7
class U32TexelFormat : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@@ -2388,7 +2388,7 @@
}
/// EnumMatcher for 'match write'
-/// @see src/tint/intrinsics.def:178:7
+/// @see src/tint/intrinsics.def:181:7
class Write : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@@ -2414,7 +2414,7 @@
}
/// EnumMatcher for 'match read_write'
-/// @see src/tint/intrinsics.def:179:7
+/// @see src/tint/intrinsics.def:182:7
class ReadWrite : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@@ -2440,7 +2440,7 @@
}
/// EnumMatcher for 'match function_private_workgroup'
-/// @see src/tint/intrinsics.def:181:7
+/// @see src/tint/intrinsics.def:184:7
class FunctionPrivateWorkgroup : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@@ -2470,7 +2470,7 @@
}
/// EnumMatcher for 'match workgroup_or_storage'
-/// @see src/tint/intrinsics.def:185:7
+/// @see src/tint/intrinsics.def:188:7
class WorkgroupOrStorage : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
@@ -2499,7 +2499,7 @@
}
/// EnumMatcher for 'match storage'
-/// @see src/tint/intrinsics.def:188:7
+/// @see src/tint/intrinsics.def:191:7
class Storage : public NumberMatcher {
public:
/// Checks whether the given number matches the enum matcher rules.
diff --git a/src/tint/resolver/intrinsic_table.inl.tmpl b/src/tint/resolver/intrinsic_table.inl.tmpl
index e78e5cb..340ae45 100644
--- a/src/tint/resolver/intrinsic_table.inl.tmpl
+++ b/src/tint/resolver/intrinsic_table.inl.tmpl
@@ -3,6 +3,9 @@
Template file for use with tools/src/cmd/gen to generate builtin_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
diff --git a/src/tint/sem/builtin_type.cc.tmpl b/src/tint/sem/builtin_type.cc.tmpl
index cc1e682..5737d8d 100644
--- a/src/tint/sem/builtin_type.cc.tmpl
+++ b/src/tint/sem/builtin_type.cc.tmpl
@@ -2,6 +2,9 @@
--------------------------------------------------------------------------------
Template file for use with tools/src/cmd/gen to generate builtin_type.cc
+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
diff --git a/src/tint/sem/builtin_type.h.tmpl b/src/tint/sem/builtin_type.h.tmpl
index 9202a3d..84ceffc 100644
--- a/src/tint/sem/builtin_type.h.tmpl
+++ b/src/tint/sem/builtin_type.h.tmpl
@@ -2,6 +2,9 @@
--------------------------------------------------------------------------------
Template file for use with tools/src/cmd/gen to generate builtin_type.h
+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
diff --git a/src/tint/sem/parameter_usage.cc.tmpl b/src/tint/sem/parameter_usage.cc.tmpl
index 7bb8b2e..62cb42e 100644
--- a/src/tint/sem/parameter_usage.cc.tmpl
+++ b/src/tint/sem/parameter_usage.cc.tmpl
@@ -2,6 +2,9 @@
--------------------------------------------------------------------------------
Template file for use with tools/src/cmd/gen to generate parameter_usage.cc
+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
diff --git a/src/tint/sem/parameter_usage.h.tmpl b/src/tint/sem/parameter_usage.h.tmpl
index 5aaa8b4..7c09805 100644
--- a/src/tint/sem/parameter_usage.h.tmpl
+++ b/src/tint/sem/parameter_usage.h.tmpl
@@ -2,6 +2,9 @@
--------------------------------------------------------------------------------
Template file for use with tools/src/cmd/gen to generate parameter_usage.h
+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
diff --git a/src/tint/templates/enums.tmpl.inc b/src/tint/templates/enums.tmpl.inc
new file mode 100644
index 0000000..d05d763
--- /dev/null
+++ b/src/tint/templates/enums.tmpl.inc
@@ -0,0 +1,160 @@
+{{- /* ------------------------------------------------------------------ */ -}}
+{{- define "EnumCase" -}}
+{{- /* Prints the 'Enum::kEntry' name for the provided sem.EnumEntry */ -}}
+{{- /* argument. */ -}}
+{{- /* ------------------------------------------------------------------ */ -}}
+{{PascalCase $.Enum.Name}}::k{{PascalCase $.Name}}
+{{- end -}}
+
+{{- /* ------------------------------------------------------------------ */ -}}
+{{- define "DeclareEnum" -}}
+{{- /* Declares the 'enum class' for the provided sem.Enum argument. */ -}}
+{{- /* ------------------------------------------------------------------ */ -}}
+{{- $enum := PascalCase $.Name -}}
+enum class {{$enum}} {
+ kInvalid,
+{{- range $entry := $.Entries }}
+ k{{PascalCase $entry.Name}},{{if $entry.IsInternal}} // Tint-internal enum entry - not parsed{{end}}
+{{- end }}
+};
+
+/// @param out the std::ostream to write to
+/// @param value the {{$enum}}
+/// @returns `out` so calls can be chained
+std::ostream& operator<<(std::ostream& out, {{$enum}} value);
+
+/// Parse{{$enum}} parses a {{$enum}} from a string.
+/// @param str the string to parse
+/// @returns the parsed enum, or {{$enum}}::kInvalid if the string could not be parsed.
+{{$enum}} Parse{{$enum}}(std::string_view str);
+
+{{- end -}}
+
+
+{{- /* ------------------------------------------------------------------ */ -}}
+{{- define "ParseEnum" -}}
+{{- /* Implements the 'ParseEnum' function for the provided sem.Enum */ -}}
+{{- /* argument. */ -}}
+{{- /* ------------------------------------------------------------------ */ -}}
+{{- $enum := PascalCase $.Name -}}
+/// Parse{{$enum}} parses a {{$enum}} from a string.
+/// @param str the string to parse
+/// @returns the parsed enum, or {{$enum}}::kInvalid if the string could not be parsed.
+{{$enum}} Parse{{$enum}}(std::string_view str) {
+{{- range $entry := $.PublicEntries }}
+ if (str == "{{$entry.Name}}") {
+ return {{template "EnumCase" $entry}};
+ }
+{{- end }}
+ return {{$enum}}::kInvalid;
+}
+{{- end -}}
+
+
+{{- /* ------------------------------------------------------------------ */ -}}
+{{- define "EnumOStream" -}}
+{{- /* Implements the std::ostream 'operator<<()' function to print the */ -}}
+{{- /* provided sem.Enum. */ -}}
+{{- /* ------------------------------------------------------------------ */ -}}
+{{- $enum := PascalCase $.Name -}}
+std::ostream& operator<<(std::ostream& out, {{$enum}} value) {
+ switch (value) {
+ case {{$enum}}::kInvalid:
+ return out << "invalid";
+{{- range $entry := $.Entries }}
+ case {{template "EnumCase" $entry}}:
+ return out << "{{$entry.Name}}";
+{{- end }}
+ }
+ return out << "<unknown>";
+}
+{{- end -}}
+
+
+{{- /* ------------------------------------------------------------------ */ -}}
+{{- define "TestParsePrintEnum" -}}
+{{- /* Implements unit tests for parsing and printing the provided */ -}}
+{{- /* sem.Enum argument. */ -}}
+{{- /* ------------------------------------------------------------------ */ -}}
+{{- $enum := PascalCase $.Name -}}
+namespace parse_print_tests {
+
+struct Case {
+ const char* string;
+ {{$enum}} value;
+};
+
+inline std::ostream& operator<<(std::ostream& out, Case c) {
+ return out << "'" << std::string(c.string) << "'";
+}
+
+static constexpr Case kValidCases[] = {
+{{- range $entry := $.PublicEntries }}
+ {"{{$entry.Name}}", {{template "EnumCase" $entry}}},
+{{- end }}
+};
+
+static constexpr Case kInvalidCases[] = {
+{{- $exclude := $.NameSet -}}
+{{- range $entry := $.PublicEntries }}
+ {"{{Scramble $entry.Name $exclude}}", {{$enum}}::kInvalid},
+ {"{{Scramble $entry.Name $exclude}}", {{$enum}}::kInvalid},
+ {"{{Scramble $entry.Name $exclude}}", {{$enum}}::kInvalid},
+{{- end }}
+};
+
+using {{$enum}}ParseTest = testing::TestWithParam<Case>;
+
+TEST_P({{$enum}}ParseTest, Parse) {
+ const char* string = GetParam().string;
+ {{$enum}} expect = GetParam().value;
+ EXPECT_EQ(expect, Parse{{$enum}}(string));
+}
+
+INSTANTIATE_TEST_SUITE_P(ValidCases, {{$enum}}ParseTest, testing::ValuesIn(kValidCases));
+INSTANTIATE_TEST_SUITE_P(InvalidCases, {{$enum}}ParseTest, testing::ValuesIn(kInvalidCases));
+
+using {{$enum}}PrintTest = testing::TestWithParam<Case>;
+
+TEST_P({{$enum}}PrintTest, Print) {
+ {{$enum}} value = GetParam().value;
+ const char* expect = GetParam().string;
+ EXPECT_EQ(expect, utils::ToString(value));
+}
+
+INSTANTIATE_TEST_SUITE_P(ValidCases, {{$enum}}PrintTest, testing::ValuesIn(kValidCases));
+
+} // namespace parse_print_tests
+
+{{- end -}}
+
+
+{{- /* ------------------------------------------------------------------ */ -}}
+{{- define "BenchmarkParseEnum" -}}
+{{- /* Implements a micro-benchmark for parsing the provided sem.Enum */ -}}
+{{- /* argument. */ -}}
+{{- /* ------------------------------------------------------------------ */ -}}
+{{- $enum := PascalCase $.Name -}}
+void {{$enum}}Parser(::benchmark::State& state) {
+ std::array kStrings{
+{{- $exclude := $.NameSet -}}
+{{- range $entry := $.PublicEntries }}
+ "{{Scramble $entry.Name $exclude}}",
+ "{{Scramble $entry.Name $exclude}}",
+ "{{Scramble $entry.Name $exclude}}",
+ "{{$entry.Name}}",
+ "{{Scramble $entry.Name $exclude}}",
+ "{{Scramble $entry.Name $exclude}}",
+ "{{Scramble $entry.Name $exclude}}",
+{{- end }}
+ };
+ for (auto _ : state) {
+ for (auto& str : kStrings) {
+ auto result = Parse{{$enum}}(str);
+ benchmark::DoNotOptimize(result);
+ }
+ }
+}
+
+BENCHMARK({{$enum}}Parser);
+{{- end -}}