diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn index 3290694f62..c426520c33 100644 --- a/src/tint/BUILD.gn +++ b/src/tint/BUILD.gn @@ -1043,6 +1043,7 @@ if (tint_build_unittests) { "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 8f8f19c343..3a804048f0 100644 --- a/src/tint/CMakeLists.txt +++ b/src/tint/CMakeLists.txt @@ -739,6 +739,7 @@ if(TINT_BUILD_TESTS) 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 @@ if(TINT_BUILD_BENCHMARKS) 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 903d27a71f..303c04e8f7 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 0000000000..e2903b7ea2 --- /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 74515876d0..cb21115182 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 @@ namespace tint::ast { /// 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 0000000000..d885c72ef7 --- /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 + +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 0000000000..d1232dfeb0 --- /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 + +#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 0000000000..d9ea8cb0b2 --- /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 + +#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 0000000000..20851682cb --- /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 + +#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; + +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; + +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 0000000000..3696aab3cb --- /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 + +#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 7c7e0ef34b..c9d0c43771 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 + +#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 11fb871101..30bf8a87a4 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 d83bbf4040..c40752ae38 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 @@ inline std::ostream& operator<<(std::ostream& out, StorageClassData data) { return out; } -class StorageClassTest : public ParserImplTestWithParam {}; +class ParserStorageClassTest : public ParserImplTestWithParam {}; -TEST_P(StorageClassTest, Parses) { +TEST_P(ParserStorageClassTest, Parses) { auto params = GetParam(); auto p = parser(params.input); @@ -42,7 +42,7 @@ TEST_P(StorageClassTest, Parses) { } 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 1f3d7cda88..00ac21beee 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 a28eba4d97..349f93907e 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 9e6749ce2e..91e03c37e6 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 @@ std::string Bool::String(MatchState*) const { } /// 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 @@ std::string Fa::String(MatchState*) const { } /// 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 @@ std::string Ia::String(MatchState*) const { } /// 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 @@ std::string I32::String(MatchState*) const { } /// 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 @@ std::string U32::String(MatchState*) const { } /// 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 @@ std::string F32::String(MatchState*) const { } /// 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 @@ std::string F16::String(MatchState*) const { } /// 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 @@ std::string Vec2::String(MatchState* state) const { } /// 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 @@ std::string Vec3::String(MatchState* state) const { } /// 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 @@ std::string Vec4::String(MatchState* state) const { } /// 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 @@ std::string Mat2X2::String(MatchState* state) const { } /// 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 @@ std::string Mat2X3::String(MatchState* state) const { } /// 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 @@ std::string Mat2X4::String(MatchState* state) const { } /// 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 @@ std::string Mat3X2::String(MatchState* state) const { } /// 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 @@ std::string Mat3X3::String(MatchState* state) const { } /// 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 @@ std::string Mat3X4::String(MatchState* state) const { } /// 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 @@ std::string Mat4X2::String(MatchState* state) const { } /// 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 @@ std::string Mat4X3::String(MatchState* state) const { } /// 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 @@ std::string Mat4X4::String(MatchState* state) const { } /// 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 @@ std::string Vec::String(MatchState* state) const { } /// 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 @@ std::string Mat::String(MatchState* state) const { } /// 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 @@ std::string Ptr::String(MatchState* state) const { } /// 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 @@ std::string Atomic::String(MatchState* state) const { } /// 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 @@ std::string Array::String(MatchState* state) const { } /// 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 @@ std::string Sampler::String(MatchState*) const { } /// 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 @@ std::string SamplerComparison::String(MatchState*) const { } /// 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 @@ std::string Texture1D::String(MatchState* state) const { } /// 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 @@ std::string Texture2D::String(MatchState* state) const { } /// 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 @@ std::string Texture2DArray::String(MatchState* state) const { } /// 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 @@ std::string Texture3D::String(MatchState* state) const { } /// 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 @@ std::string TextureCube::String(MatchState* state) const { } /// 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 @@ std::string TextureCubeArray::String(MatchState* state) const { } /// 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 @@ std::string TextureMultisampled2D::String(MatchState* state) const { } /// 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 @@ std::string TextureDepth2D::String(MatchState*) const { } /// 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 @@ std::string TextureDepth2DArray::String(MatchState*) const { } /// 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 @@ std::string TextureDepthCube::String(MatchState*) const { } /// 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 @@ std::string TextureDepthCubeArray::String(MatchState*) const { } /// 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 @@ std::string TextureDepthMultisampled2D::String(MatchState*) const { } /// 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 @@ std::string TextureStorage1D::String(MatchState* state) const { } /// 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 @@ std::string TextureStorage2D::String(MatchState* state) const { } /// 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 @@ std::string TextureStorage2DArray::String(MatchState* state) const { } /// 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 @@ std::string TextureStorage3D::String(MatchState* state) const { } /// 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 @@ std::string TextureExternal::String(MatchState*) const { } /// 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 @@ std::string ModfResult::String(MatchState*) const { } /// 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 @@ std::string ModfResultVec::String(MatchState* state) const { } /// 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 @@ std::string FrexpResult::String(MatchState*) const { } /// 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 @@ std::string FrexpResultVec::String(MatchState* state) const { } /// 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 @@ std::string AtomicCompareExchangeResult::String(MatchState* state) const { } /// 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 @@ std::string AbstractOrScalar::String(MatchState*) const { } /// 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 @@ std::string Scalar::String(MatchState*) const { } /// 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 @@ std::string ScalarNoF32::String(MatchState*) const { } /// 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 @@ std::string ScalarNoF16::String(MatchState*) const { } /// 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 @@ std::string ScalarNoI32::String(MatchState*) const { } /// 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 @@ std::string ScalarNoU32::String(MatchState*) const { } /// 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 @@ std::string ScalarNoBool::String(MatchState*) const { } /// 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 @@ std::string FiaFi32F16::String(MatchState*) const { } /// 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 @@ std::string FiaFiu32::String(MatchState*) const { } /// 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 @@ std::string FaF32::String(MatchState*) const { } /// 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 @@ std::string FaF32F16::String(MatchState*) const { } /// 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 @@ std::string IaIu32::String(MatchState*) const { } /// 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 @@ std::string Fiu32F16::String(MatchState*) const { } /// 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 @@ std::string Fiu32::String(MatchState*) const { } /// 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 @@ std::string Fi32F16::String(MatchState*) const { } /// 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 @@ std::string Fi32::String(MatchState*) const { } /// 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 @@ std::string F32F16::String(MatchState*) const { } /// 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 @@ std::string Iu32::String(MatchState*) const { } /// 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 @@ std::string F32TexelFormat::String(MatchState*) const { } /// 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 @@ std::string I32TexelFormat::String(MatchState*) const { } /// 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 @@ std::string U32TexelFormat::String(MatchState*) const { } /// 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 @@ std::string Write::String(MatchState*) const { } /// 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 @@ std::string ReadWrite::String(MatchState*) const { } /// 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 @@ std::string FunctionPrivateWorkgroup::String(MatchState*) const { } /// 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 @@ std::string WorkgroupOrStorage::String(MatchState*) const { } /// 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 e78e5cbe40..340ae45a67 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 cc1e68279b..5737d8d05a 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 9202a3d87d..84ceffcff7 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 7bb8b2e6e5..62cb42e6f2 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 5aaa8b4537..7c09805572 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 0000000000..d05d76331d --- /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 << ""; +} +{{- 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; + +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; + +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 -}}