Import Tint changes from Dawn
Changes:
- bfced8b81864de13fff25d48a50d09a5d87d99be [tint][wgsl] Hide 'chromium' extensions in diagnostics by Ben Clayton <bclayton@google.com>
- 0b255d2da6884122ffced19bddffcb87510c1a3b [tint] Use std::string_view for generated enum strings by Ben Clayton <bclayton@google.com>
- 1d6f3543b9e5a5dcce74a7b94db867649d82253e [tint][wgsl] Generate kAllExtensions, kAllLanguageFeatures by Ben Clayton <bclayton@google.com>
GitOrigin-RevId: bfced8b81864de13fff25d48a50d09a5d87d99be
Change-Id: Ifce700708546f2ca59aa9471cac7827d9a0d60a6
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/159700
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/lang/core/access.h b/src/tint/lang/core/access.h
index 2dfea06..9ace935 100644
--- a/src/tint/lang/core/access.h
+++ b/src/tint/lang/core/access.h
@@ -68,7 +68,7 @@
/// @returns the parsed enum, or Access::kUndefined if the string could not be parsed.
Access ParseAccess(std::string_view str);
-constexpr const char* kAccessStrings[] = {
+constexpr std::string_view kAccessStrings[] = {
"read",
"read_write",
"write",
diff --git a/src/tint/lang/core/address_space.h b/src/tint/lang/core/address_space.h
index bb2ac7a..8418574 100644
--- a/src/tint/lang/core/address_space.h
+++ b/src/tint/lang/core/address_space.h
@@ -75,7 +75,7 @@
/// @returns the parsed enum, or AddressSpace::kUndefined if the string could not be parsed.
AddressSpace ParseAddressSpace(std::string_view str);
-constexpr const char* kAddressSpaceStrings[] = {
+constexpr std::string_view kAddressSpaceStrings[] = {
"__in", "__out", "function", "pixel_local", "private",
"push_constant", "storage", "uniform", "workgroup",
};
diff --git a/src/tint/lang/core/attribute.h b/src/tint/lang/core/attribute.h
index 606f4b6..3e7b087 100644
--- a/src/tint/lang/core/attribute.h
+++ b/src/tint/lang/core/attribute.h
@@ -84,7 +84,7 @@
/// @returns the parsed enum, or Attribute::kUndefined if the string could not be parsed.
Attribute ParseAttribute(std::string_view str);
-constexpr const char* kAttributeStrings[] = {
+constexpr std::string_view kAttributeStrings[] = {
"align", "binding", "builtin", "compute", "diagnostic", "fragment",
"group", "id", "index", "interpolate", "invariant", "location",
"must_use", "size", "vertex", "workgroup_size",
diff --git a/src/tint/lang/core/builtin_type.h b/src/tint/lang/core/builtin_type.h
index 6817791..ac0a22e 100644
--- a/src/tint/lang/core/builtin_type.h
+++ b/src/tint/lang/core/builtin_type.h
@@ -161,7 +161,7 @@
/// @returns the parsed enum, or BuiltinType::kUndefined if the string could not be parsed.
BuiltinType ParseBuiltinType(std::string_view str);
-constexpr const char* kBuiltinTypeStrings[] = {
+constexpr std::string_view kBuiltinTypeStrings[] = {
"__atomic_compare_exchange_result_i32",
"__atomic_compare_exchange_result_u32",
"__frexp_result_abstract",
diff --git a/src/tint/lang/core/builtin_value.h b/src/tint/lang/core/builtin_value.h
index 917ba14..1af2585 100644
--- a/src/tint/lang/core/builtin_value.h
+++ b/src/tint/lang/core/builtin_value.h
@@ -80,7 +80,7 @@
/// @returns the parsed enum, or BuiltinValue::kUndefined if the string could not be parsed.
BuiltinValue ParseBuiltinValue(std::string_view str);
-constexpr const char* kBuiltinValueStrings[] = {
+constexpr std::string_view kBuiltinValueStrings[] = {
"__point_size", "frag_depth", "front_facing",
"global_invocation_id", "instance_index", "local_invocation_id",
"local_invocation_index", "num_workgroups", "position",
diff --git a/src/tint/lang/core/interpolation_sampling.h b/src/tint/lang/core/interpolation_sampling.h
index ebec530..ca7e075 100644
--- a/src/tint/lang/core/interpolation_sampling.h
+++ b/src/tint/lang/core/interpolation_sampling.h
@@ -70,7 +70,7 @@
/// parsed.
InterpolationSampling ParseInterpolationSampling(std::string_view str);
-constexpr const char* kInterpolationSamplingStrings[] = {
+constexpr std::string_view kInterpolationSamplingStrings[] = {
"center",
"centroid",
"sample",
diff --git a/src/tint/lang/core/interpolation_type.h b/src/tint/lang/core/interpolation_type.h
index e1eeb15..a71af66 100644
--- a/src/tint/lang/core/interpolation_type.h
+++ b/src/tint/lang/core/interpolation_type.h
@@ -69,7 +69,7 @@
/// @returns the parsed enum, or InterpolationType::kUndefined if the string could not be parsed.
InterpolationType ParseInterpolationType(std::string_view str);
-constexpr const char* kInterpolationTypeStrings[] = {
+constexpr std::string_view kInterpolationTypeStrings[] = {
"flat",
"linear",
"perspective",
diff --git a/src/tint/lang/core/texel_format.h b/src/tint/lang/core/texel_format.h
index f99504b..da6791d 100644
--- a/src/tint/lang/core/texel_format.h
+++ b/src/tint/lang/core/texel_format.h
@@ -82,7 +82,7 @@
/// @returns the parsed enum, or TexelFormat::kUndefined if the string could not be parsed.
TexelFormat ParseTexelFormat(std::string_view str);
-constexpr const char* kTexelFormatStrings[] = {
+constexpr std::string_view kTexelFormatStrings[] = {
"bgra8unorm", "r32float", "r32sint", "r32uint", "rg32float", "rg32sint",
"rg32uint", "rgba16float", "rgba16sint", "rgba16uint", "rgba32float", "rgba32sint",
"rgba32uint", "rgba8sint", "rgba8snorm", "rgba8uint", "rgba8unorm",
diff --git a/src/tint/lang/wgsl/ast/transform/renamer_test.cc b/src/tint/lang/wgsl/ast/transform/renamer_test.cc
index d31f0a6..fca0b22 100644
--- a/src/tint/lang/wgsl/ast/transform/renamer_test.cc
+++ b/src/tint/lang/wgsl/ast/transform/renamer_test.cc
@@ -1791,22 +1791,21 @@
return std::string(name);
}
-std::vector<const char*> ConstructableTypes() {
- std::vector<const char*> out;
- for (auto* ty : core::kBuiltinTypeStrings) {
- std::string_view type(ty);
+std::vector<std::string_view> ConstructableTypes() {
+ std::vector<std::string_view> out;
+ for (auto type : core::kBuiltinTypeStrings) {
if (type != "ptr" && type != "atomic" && !tint::HasPrefix(type, "sampler") &&
!tint::HasPrefix(type, "texture") && !tint::HasPrefix(type, "__")) {
- out.push_back(ty);
+ out.push_back(type);
}
}
return out;
}
-using RenamerBuiltinTypeTest = TransformTestWithParam<const char*>;
+using RenamerBuiltinTypeTest = TransformTestWithParam<std::string_view>;
TEST_P(RenamerBuiltinTypeTest, PreserveTypeUsage) {
- auto expand = [&](const char* source) {
+ auto expand = [&](std::string_view source) {
return tint::ReplaceAll(source, "$type", ExpandBuiltinType(GetParam()));
};
@@ -1845,7 +1844,7 @@
EXPECT_EQ(expect, str(got));
}
TEST_P(RenamerBuiltinTypeTest, PreserveTypeInitializer) {
- auto expand = [&](const char* source) {
+ auto expand = [&](std::string_view source) {
return tint::ReplaceAll(source, "$type", ExpandBuiltinType(GetParam()));
};
@@ -1877,7 +1876,7 @@
return; // Cannot value convert arrays.
}
- auto expand = [&](const char* source) {
+ auto expand = [&](std::string_view source) {
return tint::ReplaceAll(source, "$type", ExpandBuiltinType(GetParam()));
};
@@ -1929,7 +1928,7 @@
}
TEST_P(RenamerBuiltinTypeTest, RenameShadowedByAlias) {
- auto expand = [&](const char* source) {
+ auto expand = [&](std::string_view source) {
std::string_view ty = GetParam();
auto out = tint::ReplaceAll(source, "$name", ty);
out = tint::ReplaceAll(out, "$type", ExpandBuiltinType(ty));
@@ -1961,7 +1960,7 @@
}
TEST_P(RenamerBuiltinTypeTest, RenameShadowedByStruct) {
- auto expand = [&](const char* source) {
+ auto expand = [&](std::string_view source) {
std::string_view ty = GetParam();
auto out = tint::ReplaceAll(source, "$name", ty);
out = tint::ReplaceAll(out, "$type", ExpandBuiltinType(ty));
@@ -2003,31 +2002,33 @@
testing::ValuesIn(ConstructableTypes()));
/// @return WGSL builtin identifier keywords
-std::vector<const char*> Identifiers() {
- std::vector<const char*> out;
- for (auto* ident : core::kBuiltinTypeStrings) {
+std::vector<std::string_view> Identifiers() {
+ std::vector<std::string_view> out;
+ for (auto ident : core::kBuiltinTypeStrings) {
if (!tint::HasPrefix(ident, "__")) {
out.push_back(ident);
}
}
- for (auto* ident : core::kAddressSpaceStrings) {
+ for (auto ident : core::kAddressSpaceStrings) {
if (!tint::HasPrefix(ident, "_")) {
out.push_back(ident);
}
}
- for (auto* ident : core::kTexelFormatStrings) {
+ for (auto ident : core::kTexelFormatStrings) {
out.push_back(ident);
}
- for (auto* ident : core::kAccessStrings) {
+ for (auto ident : core::kAccessStrings) {
out.push_back(ident);
}
return out;
}
-using RenamerBuiltinIdentifierTest = TransformTestWithParam<const char*>;
+using RenamerBuiltinIdentifierTest = TransformTestWithParam<std::string_view>;
TEST_P(RenamerBuiltinIdentifierTest, GlobalConstName) {
- auto expand = [&](const char* source) { return tint::ReplaceAll(source, "$name", GetParam()); };
+ auto expand = [&](std::string_view source) {
+ return tint::ReplaceAll(source, "$name", GetParam());
+ };
auto src = expand(R"(
const $name = 42;
@@ -2051,7 +2052,9 @@
}
TEST_P(RenamerBuiltinIdentifierTest, LocalVarName) {
- auto expand = [&](const char* source) { return tint::ReplaceAll(source, "$name", GetParam()); };
+ auto expand = [&](std::string_view source) {
+ return tint::ReplaceAll(source, "$name", GetParam());
+ };
auto src = expand(R"(
fn f() {
@@ -2071,7 +2074,9 @@
}
TEST_P(RenamerBuiltinIdentifierTest, FunctionName) {
- auto expand = [&](const char* source) { return tint::ReplaceAll(source, "$name", GetParam()); };
+ auto expand = [&](std::string_view source) {
+ return tint::ReplaceAll(source, "$name", GetParam());
+ };
auto src = expand(R"(
fn $name() {
@@ -2097,7 +2102,7 @@
}
TEST_P(RenamerBuiltinIdentifierTest, StructName) {
- auto expand = [&](const char* source) {
+ auto expand = [&](std::string_view source) {
std::string_view name = GetParam();
auto out = tint::ReplaceAll(source, "$name", name);
return tint::ReplaceAll(out, "$other_type", name == "i32" ? "u32" : "i32");
diff --git a/src/tint/lang/wgsl/common/allowed_features.h b/src/tint/lang/wgsl/common/allowed_features.h
index 080e3c8..d494352 100644
--- a/src/tint/lang/wgsl/common/allowed_features.h
+++ b/src/tint/lang/wgsl/common/allowed_features.h
@@ -50,21 +50,14 @@
AllowedFeatures allowed_features;
// Allow all extensions.
- allowed_features.extensions.insert(wgsl::Extension::kChromiumDisableUniformityAnalysis);
- allowed_features.extensions.insert(wgsl::Extension::kChromiumExperimentalDp4A);
- allowed_features.extensions.insert(wgsl::Extension::kChromiumExperimentalFullPtrParameters);
- allowed_features.extensions.insert(wgsl::Extension::kChromiumExperimentalPixelLocal);
- allowed_features.extensions.insert(wgsl::Extension::kChromiumExperimentalPushConstant);
- allowed_features.extensions.insert(
- wgsl::Extension::kChromiumExperimentalReadWriteStorageTexture);
- allowed_features.extensions.insert(wgsl::Extension::kChromiumExperimentalSubgroups);
- allowed_features.extensions.insert(wgsl::Extension::kChromiumInternalDualSourceBlending);
- allowed_features.extensions.insert(wgsl::Extension::kChromiumInternalRelaxedUniformLayout);
- allowed_features.extensions.insert(wgsl::Extension::kF16);
+ for (auto extension : wgsl::kAllExtensions) {
+ allowed_features.extensions.insert(extension);
+ }
// Allow all language features.
- allowed_features.features.insert(
- wgsl::LanguageFeature::kReadonlyAndReadwriteStorageTextures);
+ for (auto feature : wgsl::kAllLanguageFeatures) {
+ allowed_features.features.insert(feature);
+ }
return allowed_features;
}
diff --git a/src/tint/lang/wgsl/diagnostic_rule.h b/src/tint/lang/wgsl/diagnostic_rule.h
index db19783..cf2d8f0 100644
--- a/src/tint/lang/wgsl/diagnostic_rule.h
+++ b/src/tint/lang/wgsl/diagnostic_rule.h
@@ -68,7 +68,7 @@
/// @returns the parsed enum, or CoreDiagnosticRule::kUndefined if the string could not be parsed.
CoreDiagnosticRule ParseCoreDiagnosticRule(std::string_view str);
-constexpr const char* kCoreDiagnosticRuleStrings[] = {
+constexpr std::string_view kCoreDiagnosticRuleStrings[] = {
"derivative_uniformity",
};
@@ -96,7 +96,7 @@
/// parsed.
ChromiumDiagnosticRule ParseChromiumDiagnosticRule(std::string_view str);
-constexpr const char* kChromiumDiagnosticRuleStrings[] = {
+constexpr std::string_view kChromiumDiagnosticRuleStrings[] = {
"unreachable_code",
};
diff --git a/src/tint/lang/wgsl/diagnostic_severity.h b/src/tint/lang/wgsl/diagnostic_severity.h
index 026b421..dfccb5d 100644
--- a/src/tint/lang/wgsl/diagnostic_severity.h
+++ b/src/tint/lang/wgsl/diagnostic_severity.h
@@ -72,7 +72,7 @@
/// @returns the parsed enum, or DiagnosticSeverity::kUndefined if the string could not be parsed.
DiagnosticSeverity ParseDiagnosticSeverity(std::string_view str);
-constexpr const char* kDiagnosticSeverityStrings[] = {
+constexpr std::string_view kDiagnosticSeverityStrings[] = {
"error",
"info",
"off",
diff --git a/src/tint/lang/wgsl/extension.h b/src/tint/lang/wgsl/extension.h
index dfcb7e1..931c1ad 100644
--- a/src/tint/lang/wgsl/extension.h
+++ b/src/tint/lang/wgsl/extension.h
@@ -75,7 +75,7 @@
/// @returns the parsed enum, or Extension::kUndefined if the string could not be parsed.
Extension ParseExtension(std::string_view str);
-constexpr const char* kExtensionStrings[] = {
+constexpr std::string_view kExtensionStrings[] = {
"chromium_disable_uniformity_analysis", "chromium_experimental_dp4a",
"chromium_experimental_full_ptr_parameters", "chromium_experimental_pixel_local",
"chromium_experimental_push_constant", "chromium_experimental_read_write_storage_texture",
@@ -83,7 +83,21 @@
"chromium_internal_relaxed_uniform_layout", "f16",
};
-// A unique vector of extensions
+/// All extensions
+static constexpr Extension kAllExtensions[] = {
+ Extension::kChromiumDisableUniformityAnalysis,
+ Extension::kChromiumExperimentalDp4A,
+ Extension::kChromiumExperimentalFullPtrParameters,
+ Extension::kChromiumExperimentalPixelLocal,
+ Extension::kChromiumExperimentalPushConstant,
+ Extension::kChromiumExperimentalReadWriteStorageTexture,
+ Extension::kChromiumExperimentalSubgroups,
+ Extension::kChromiumInternalDualSourceBlending,
+ Extension::kChromiumInternalRelaxedUniformLayout,
+ Extension::kF16,
+};
+
+/// A unique vector of extensions
using Extensions = UniqueVector<Extension, 4>;
} // namespace tint::wgsl
diff --git a/src/tint/lang/wgsl/extension.h.tmpl b/src/tint/lang/wgsl/extension.h.tmpl
index 1c69ee1..3ea8b69 100644
--- a/src/tint/lang/wgsl/extension.h.tmpl
+++ b/src/tint/lang/wgsl/extension.h.tmpl
@@ -24,7 +24,14 @@
/// @see src/tint/lang/wgsl/intrinsics.def for extension descriptions
{{ Eval "DeclareEnum" $enum}}
-// A unique vector of extensions
+/// All extensions
+static constexpr Extension kAllExtensions[] = {
+{{- range $entry := $enum.Entries }}
+ Extension::k{{PascalCase $entry.Name}},
+{{- end }}
+};
+
+/// A unique vector of extensions
using Extensions = UniqueVector<Extension, 4>;
} // namespace tint::wgsl
diff --git a/src/tint/lang/wgsl/language_feature.h b/src/tint/lang/wgsl/language_feature.h
index 0a5573a..afdbdba 100644
--- a/src/tint/lang/wgsl/language_feature.h
+++ b/src/tint/lang/wgsl/language_feature.h
@@ -66,11 +66,16 @@
/// @returns the parsed enum, or LanguageFeature::kUndefined if the string could not be parsed.
LanguageFeature ParseLanguageFeature(std::string_view str);
-constexpr const char* kLanguageFeatureStrings[] = {
+constexpr std::string_view kLanguageFeatureStrings[] = {
"readonly_and_readwrite_storage_textures",
};
-// A unique vector of language features
+/// All features
+static constexpr LanguageFeature kAllLanguageFeatures[] = {
+ LanguageFeature::kReadonlyAndReadwriteStorageTextures,
+};
+
+/// A unique vector of language features
using LanguageFeatures = UniqueVector<LanguageFeature, 4>;
} // namespace tint::wgsl
diff --git a/src/tint/lang/wgsl/language_feature.h.tmpl b/src/tint/lang/wgsl/language_feature.h.tmpl
index cbe9f78..7c88975 100644
--- a/src/tint/lang/wgsl/language_feature.h.tmpl
+++ b/src/tint/lang/wgsl/language_feature.h.tmpl
@@ -24,7 +24,14 @@
/// @see src/tint/lang/wgsl/intrinsics.def for language feature descriptions
{{ Eval "DeclareEnum" $enum}}
-// A unique vector of language features
+/// All features
+static constexpr LanguageFeature kAllLanguageFeatures[] = {
+{{- range $entry := $enum.Entries }}
+ LanguageFeature::k{{PascalCase $entry.Name}},
+{{- end }}
+};
+
+/// A unique vector of language features
using LanguageFeatures = UniqueVector<LanguageFeature, 4>;
} // namespace tint::wgsl
diff --git a/src/tint/lang/wgsl/reader/parser/enable_directive_test.cc b/src/tint/lang/wgsl/reader/parser/enable_directive_test.cc
index e43af72..26bd8dc 100644
--- a/src/tint/lang/wgsl/reader/parser/enable_directive_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/enable_directive_test.cc
@@ -171,26 +171,40 @@
}
// Test an unknown extension identifier.
-TEST_F(EnableDirectiveTest, InvalidIdentifier) {
+TEST_F(EnableDirectiveTest, InvalidExtension) {
auto p = parser("enable NotAValidExtensionName;");
p->enable_directive();
// Error when unknown extension found
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
-Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_pixel_local', 'chromium_experimental_push_constant', 'chromium_experimental_read_write_storage_texture', 'chromium_experimental_subgroups', 'chromium_internal_dual_source_blending', 'chromium_internal_relaxed_uniform_layout', 'f16')");
+Possible values: 'f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
EXPECT_EQ(ast.GlobalDeclarations().Length(), 0u);
}
-TEST_F(EnableDirectiveTest, InvalidIdentifierSuggest) {
+TEST_F(EnableDirectiveTest, InvalidExtensionSuggest) {
auto p = parser("enable f15;");
p->enable_directive();
// Error when unknown extension found
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
Did you mean 'f16'?
+Possible values: 'f16')");
+ auto program = p->program();
+ auto& ast = program.AST();
+ EXPECT_EQ(ast.Enables().Length(), 0u);
+ EXPECT_EQ(ast.GlobalDeclarations().Length(), 0u);
+}
+
+// Test an unknown extension identifier, starting with 'chromium'
+TEST_F(EnableDirectiveTest, InvalidChromiumExtension) {
+ auto p = parser("enable chromium_blah;");
+ p->enable_directive();
+ // Error when unknown extension found
+ EXPECT_TRUE(p->has_error());
+ EXPECT_EQ(p->error(), R"(1:8: expected extension
Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_pixel_local', 'chromium_experimental_push_constant', 'chromium_experimental_read_write_storage_texture', 'chromium_experimental_subgroups', 'chromium_internal_dual_source_blending', 'chromium_internal_relaxed_uniform_layout', 'f16')");
auto program = p->program();
auto& ast = program.AST();
@@ -239,7 +253,7 @@
p->translation_unit();
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
-Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_pixel_local', 'chromium_experimental_push_constant', 'chromium_experimental_read_write_storage_texture', 'chromium_experimental_subgroups', 'chromium_internal_dual_source_blending', 'chromium_internal_relaxed_uniform_layout', 'f16')");
+Possible values: 'f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
@@ -250,7 +264,7 @@
p->translation_unit();
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
-Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_pixel_local', 'chromium_experimental_push_constant', 'chromium_experimental_read_write_storage_texture', 'chromium_experimental_subgroups', 'chromium_internal_dual_source_blending', 'chromium_internal_relaxed_uniform_layout', 'f16')");
+Possible values: 'f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
@@ -262,7 +276,7 @@
EXPECT_TRUE(p->has_error());
EXPECT_EQ(p->error(), R"(1:8: expected extension
Did you mean 'f16'?
-Possible values: 'chromium_disable_uniformity_analysis', 'chromium_experimental_dp4a', 'chromium_experimental_full_ptr_parameters', 'chromium_experimental_pixel_local', 'chromium_experimental_push_constant', 'chromium_experimental_read_write_storage_texture', 'chromium_experimental_subgroups', 'chromium_internal_dual_source_blending', 'chromium_internal_relaxed_uniform_layout', 'f16')");
+Possible values: 'f16')");
auto program = p->program();
auto& ast = program.AST();
EXPECT_EQ(ast.Enables().Length(), 0u);
diff --git a/src/tint/lang/wgsl/reader/parser/lexer.cc b/src/tint/lang/wgsl/reader/parser/lexer.cc
index ebc5522..7b19d4c 100644
--- a/src/tint/lang/wgsl/reader/parser/lexer.cc
+++ b/src/tint/lang/wgsl/reader/parser/lexer.cc
@@ -132,7 +132,7 @@
return tokens;
}
-const std::string_view Lexer::line() const {
+std::string_view Lexer::line() const {
if (file_->content.lines.size() == 0) {
static const char* empty_string = "";
return empty_string;
diff --git a/src/tint/lang/wgsl/reader/parser/lexer.h b/src/tint/lang/wgsl/reader/parser/lexer.h
index 23676c2..7d10dd9 100644
--- a/src/tint/lang/wgsl/reader/parser/lexer.h
+++ b/src/tint/lang/wgsl/reader/parser/lexer.h
@@ -87,7 +87,7 @@
void end_source(Source&) const;
/// @returns view of current line
- const std::string_view line() const;
+ std::string_view line() const;
/// @returns position in current line
size_t pos() const;
/// @returns length of current line
diff --git a/src/tint/lang/wgsl/reader/parser/parser.cc b/src/tint/lang/wgsl/reader/parser/parser.cc
index 54aeb27..6a10c72 100644
--- a/src/tint/lang/wgsl/reader/parser/parser.cc
+++ b/src/tint/lang/wgsl/reader/parser/parser.cc
@@ -907,14 +907,15 @@
return builder_.ty(builder_.Ident(source.Source(), ident.to_str(), std::move(args.value)));
}
-template <typename ENUM, size_t N>
+template <typename ENUM>
Expect<ENUM> Parser::expect_enum(std::string_view name,
ENUM (*parse)(std::string_view str),
- const char* const (&strings)[N],
+ Slice<const std::string_view> strings,
std::string_view use) {
auto& t = peek();
+ auto ident = t.to_str();
if (t.IsIdentifier()) {
- auto val = parse(t.to_str());
+ auto val = parse(ident);
if (val != ENUM::kUndefined) {
synchronized_ = true;
next();
@@ -936,7 +937,20 @@
}
err << "\n";
- tint::SuggestAlternatives(t.to_str(), strings, err);
+ if (strings == wgsl::kExtensionStrings && !HasPrefix(ident, "chromium")) {
+ // Filter out 'chromium' prefixed extensions. We don't want to advertise experimental
+ // extensions to end users (unless it looks like they've actually mis-typed a chromium
+ // extension name)
+ Vector<std::string_view, 8> filtered;
+ for (auto str : strings) {
+ if (!HasPrefix(str, "chromium")) {
+ filtered.Push(str);
+ }
+ }
+ tint::SuggestAlternatives(ident, filtered.Slice(), err);
+ } else {
+ tint::SuggestAlternatives(ident, strings, err);
+ }
synchronized_ = false;
return add_error(t.source(), err.str());
diff --git a/src/tint/lang/wgsl/reader/parser/parser.h b/src/tint/lang/wgsl/reader/parser/parser.h
index c489700..0e6c152 100644
--- a/src/tint/lang/wgsl/reader/parser/parser.h
+++ b/src/tint/lang/wgsl/reader/parser/parser.h
@@ -868,10 +868,10 @@
/// @param parse the optimized function used to parse the enum
/// @param strings the list of possible strings in the enum
/// @param use an optional description of what was being parsed if an error was raised.
- template <typename ENUM, size_t N>
+ template <typename ENUM>
Expect<ENUM> expect_enum(std::string_view name,
ENUM (*parse)(std::string_view str),
- const char* const (&strings)[N],
+ Slice<const std::string_view> strings,
std::string_view use = "");
Expect<ast::Type> expect_type(std::string_view use);
diff --git a/src/tint/lang/wgsl/reader/parser/token.cc b/src/tint/lang/wgsl/reader/parser/token.cc
index 89d58e8..9ed9460 100644
--- a/src/tint/lang/wgsl/reader/parser/token.cc
+++ b/src/tint/lang/wgsl/reader/parser/token.cc
@@ -213,7 +213,7 @@
Token::Token() : type_(Type::kUninitialized) {}
-Token::Token(Type type, const Source& source, const std::string_view& view)
+Token::Token(Type type, const Source& source, std::string_view view)
: type_(type), source_(source), value_(view) {}
Token::Token(Type type, const Source& source, const std::string& str)
diff --git a/src/tint/lang/wgsl/reader/parser/token.h b/src/tint/lang/wgsl/reader/parser/token.h
index 8ea96f9..b3cdebe 100644
--- a/src/tint/lang/wgsl/reader/parser/token.h
+++ b/src/tint/lang/wgsl/reader/parser/token.h
@@ -238,7 +238,7 @@
/// @param type the Token::Type of the token
/// @param source the source of the token
/// @param view the source string view for the token
- Token(Type type, const Source& source, const std::string_view& view);
+ Token(Type type, const Source& source, std::string_view view);
/// Create a string Token
/// @param type the Token::Type of the token
/// @param source the source of the token
diff --git a/src/tint/lang/wgsl/resolver/builtin_enum_test.cc b/src/tint/lang/wgsl/resolver/builtin_enum_test.cc
index 265cab8..cc7bbeb 100644
--- a/src/tint/lang/wgsl/resolver/builtin_enum_test.cc
+++ b/src/tint/lang/wgsl/resolver/builtin_enum_test.cc
@@ -46,7 +46,7 @@
////////////////////////////////////////////////////////////////////////////////
// access
////////////////////////////////////////////////////////////////////////////////
-using ResolverAccessUsedWithTemplateArgs = ResolverTestWithParam<const char*>;
+using ResolverAccessUsedWithTemplateArgs = ResolverTestWithParam<std::string_view>;
TEST_P(ResolverAccessUsedWithTemplateArgs, Test) {
// @group(0) @binding(0) var t : texture_storage_2d<rgba8unorm, ACCESS<i32>>;
@@ -65,7 +65,7 @@
////////////////////////////////////////////////////////////////////////////////
// address space
////////////////////////////////////////////////////////////////////////////////
-using ResolverAddressSpaceUsedWithTemplateArgs = ResolverTestWithParam<const char*>;
+using ResolverAddressSpaceUsedWithTemplateArgs = ResolverTestWithParam<std::string_view>;
TEST_P(ResolverAddressSpaceUsedWithTemplateArgs, Test) {
// fn f(p : ptr<ADDRESS_SPACE<T>, f32) {}
@@ -85,7 +85,7 @@
////////////////////////////////////////////////////////////////////////////////
// builtin value
////////////////////////////////////////////////////////////////////////////////
-using ResolverBuiltinValueUsedWithTemplateArgs = ResolverTestWithParam<const char*>;
+using ResolverBuiltinValueUsedWithTemplateArgs = ResolverTestWithParam<std::string_view>;
TEST_P(ResolverBuiltinValueUsedWithTemplateArgs, Test) {
// fn f(@builtin(BUILTIN<T>) p : vec4<f32>) {}
@@ -104,7 +104,7 @@
////////////////////////////////////////////////////////////////////////////////
// interpolation sampling
////////////////////////////////////////////////////////////////////////////////
-using ResolverInterpolationSamplingUsedWithTemplateArgs = ResolverTestWithParam<const char*>;
+using ResolverInterpolationSamplingUsedWithTemplateArgs = ResolverTestWithParam<std::string_view>;
TEST_P(ResolverInterpolationSamplingUsedWithTemplateArgs, Test) {
// @fragment
@@ -132,7 +132,7 @@
////////////////////////////////////////////////////////////////////////////////
// interpolation type
////////////////////////////////////////////////////////////////////////////////
-using ResolverInterpolationTypeUsedWithTemplateArgs = ResolverTestWithParam<const char*>;
+using ResolverInterpolationTypeUsedWithTemplateArgs = ResolverTestWithParam<std::string_view>;
TEST_P(ResolverInterpolationTypeUsedWithTemplateArgs, Test) {
// @fragment
@@ -160,7 +160,7 @@
////////////////////////////////////////////////////////////////////////////////
// texel format
////////////////////////////////////////////////////////////////////////////////
-using ResolverTexelFormatUsedWithTemplateArgs = ResolverTestWithParam<const char*>;
+using ResolverTexelFormatUsedWithTemplateArgs = ResolverTestWithParam<std::string_view>;
TEST_P(ResolverTexelFormatUsedWithTemplateArgs, Test) {
// @group(0) @binding(0) var t : texture_storage_2d<TEXEL_FORMAT<T>, write>
diff --git a/src/tint/lang/wgsl/resolver/dependency_graph_test.cc b/src/tint/lang/wgsl/resolver/dependency_graph_test.cc
index 8a1f136..05a83d4 100644
--- a/src/tint/lang/wgsl/resolver/dependency_graph_test.cc
+++ b/src/tint/lang/wgsl/resolver/dependency_graph_test.cc
@@ -1233,7 +1233,7 @@
namespace resolve_to_builtin_type {
using ResolverDependencyGraphResolveToBuiltinType =
- ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, const char*>>;
+ ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, std::string_view>>;
TEST_P(ResolverDependencyGraphResolveToBuiltinType, Resolve) {
const auto use = std::get<0>(GetParam());
@@ -1272,7 +1272,7 @@
namespace resolve_to_access {
using ResolverDependencyGraphResolveToAccess =
- ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, const char*>>;
+ ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, std::string_view>>;
TEST_P(ResolverDependencyGraphResolveToAccess, Resolve) {
const auto use = std::get<0>(GetParam());
@@ -1311,7 +1311,7 @@
namespace resolve_to_address_space {
using ResolverDependencyGraphResolveToAddressSpace =
- ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, const char*>>;
+ ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, std::string_view>>;
TEST_P(ResolverDependencyGraphResolveToAddressSpace, Resolve) {
const auto use = std::get<0>(GetParam());
@@ -1350,7 +1350,7 @@
namespace resolve_to_builtin_value {
using ResolverDependencyGraphResolveToBuiltinValue =
- ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, const char*>>;
+ ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, std::string_view>>;
TEST_P(ResolverDependencyGraphResolveToBuiltinValue, Resolve) {
const auto use = std::get<0>(GetParam());
@@ -1389,7 +1389,7 @@
namespace resolve_to_interpolation_sampling {
using ResolverDependencyGraphResolveToInterpolationSampling =
- ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, const char*>>;
+ ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, std::string_view>>;
TEST_P(ResolverDependencyGraphResolveToInterpolationSampling, Resolve) {
const auto use = std::get<0>(GetParam());
@@ -1429,7 +1429,7 @@
namespace resolve_to_interpolation_sampling {
using ResolverDependencyGraphResolveToInterpolationType =
- ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, const char*>>;
+ ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, std::string_view>>;
TEST_P(ResolverDependencyGraphResolveToInterpolationType, Resolve) {
const auto use = std::get<0>(GetParam());
@@ -1469,7 +1469,7 @@
namespace resolve_to_texel_format {
using ResolverDependencyGraphResolveToTexelFormat =
- ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, const char*>>;
+ ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, std::string_view>>;
TEST_P(ResolverDependencyGraphResolveToTexelFormat, Resolve) {
const auto use = std::get<0>(GetParam());
@@ -1546,7 +1546,7 @@
SymbolDeclKind::NestedLocalLet)));
using ResolverDependencyGraphShadowKindTest =
- ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, const char*>>;
+ ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, std::string_view>>;
TEST_P(ResolverDependencyGraphShadowKindTest, ShadowedByGlobalVar) {
const auto use = std::get<0>(GetParam());
@@ -1667,10 +1667,10 @@
Vector<SymbolUse, 64> symbol_uses;
- auto add_use = [&](const ast::Node* decl, auto use, int line, const char* kind) {
- symbol_uses.Push(
- SymbolUse{decl, IdentifierOf(use),
- std::string(__FILE__) + ":" + std::to_string(line) + ": " + kind});
+ auto add_use = [&](const ast::Node* decl, auto use, int line, std::string_view kind) {
+ symbol_uses.Push(SymbolUse{
+ decl, IdentifierOf(use),
+ std::string(__FILE__) + ":" + std::to_string(line) + ": " + std::string(kind)});
return use;
};
diff --git a/src/tint/lang/wgsl/resolver/sem_helper.cc b/src/tint/lang/wgsl/resolver/sem_helper.cc
index adb384e..a68734a 100644
--- a/src/tint/lang/wgsl/resolver/sem_helper.cc
+++ b/src/tint/lang/wgsl/resolver/sem_helper.cc
@@ -136,21 +136,21 @@
void SemHelper::ErrorUnexpectedExprKind(
const sem::Expression* expr,
std::string_view wanted,
- tint::Slice<char const* const> suggestions /* = Empty */) const {
+ tint::Slice<const std::string_view> suggestions /* = Empty */) const {
if (auto* ui = expr->As<UnresolvedIdentifier>()) {
auto* ident = ui->Identifier();
auto name = ident->identifier->symbol.Name();
AddError("unresolved " + std::string(wanted) + " '" + name + "'", ident->source);
if (!suggestions.IsEmpty()) {
// Filter out suggestions that have a leading underscore.
- Vector<const char*, 8> filtered;
- for (auto* str : suggestions) {
+ Vector<std::string_view, 8> filtered;
+ for (auto str : suggestions) {
if (str[0] != '_') {
filtered.Push(str);
}
}
StringStream msg;
- tint::SuggestAlternatives(name, filtered.Slice().Reinterpret<char const* const>(), msg);
+ tint::SuggestAlternatives(name, filtered.Slice(), msg);
AddNote(msg.str(), ident->source);
}
return;
diff --git a/src/tint/lang/wgsl/resolver/sem_helper.h b/src/tint/lang/wgsl/resolver/sem_helper.h
index bda2b0d..ad63ac2 100644
--- a/src/tint/lang/wgsl/resolver/sem_helper.h
+++ b/src/tint/lang/wgsl/resolver/sem_helper.h
@@ -278,7 +278,7 @@
/// @param suggestions suggested valid identifiers
void ErrorUnexpectedExprKind(const sem::Expression* expr,
std::string_view wanted,
- tint::Slice<char const* const> suggestions = Empty) const;
+ tint::Slice<const std::string_view> suggestions = Empty) const;
/// If @p node is a module-scope type, variable or function declaration, then appends a note
/// diagnostic where this declaration was declared, otherwise the function does nothing.
diff --git a/src/tint/utils/containers/slice.h b/src/tint/utils/containers/slice.h
index b88863a..f2cf7c3 100644
--- a/src/tint/utils/containers/slice.h
+++ b/src/tint/utils/containers/slice.h
@@ -265,6 +265,18 @@
/// @returns the end for a reverse iterator
auto rend() const { return std::reverse_iterator<const T*>(begin()); }
+
+ /// Equality operator.
+ /// @param other the other slice to compare against
+ /// @returns true if all fields of this slice are equal to the fields of @p other
+ bool operator==(const Slice& other) {
+ return data == other.data && len == other.len && cap == other.cap;
+ }
+
+ /// Inequality operator.
+ /// @param other the other slice to compare against
+ /// @returns false if any fields of this slice are not equal to the fields of @p other
+ bool operator!=(const Slice& other) { return !(*this == other); }
};
/// Deduction guide for Slice from c-array
diff --git a/src/tint/utils/containers/slice_test.cc b/src/tint/utils/containers/slice_test.cc
index 99f2f99..2432aeb 100644
--- a/src/tint/utils/containers/slice_test.cc
+++ b/src/tint/utils/containers/slice_test.cc
@@ -194,5 +194,33 @@
EXPECT_EQ(truncated[2], 3);
}
+TEST(TintSliceTest, Equality) {
+ int elements[] = {1, 2, 3};
+ auto a = Slice{elements};
+ {
+ auto b = a;
+ EXPECT_TRUE(a == b);
+ EXPECT_FALSE(a != b);
+ }
+ {
+ auto b = a;
+ b.data++;
+ EXPECT_FALSE(a == b);
+ EXPECT_TRUE(a != b);
+ }
+ {
+ auto b = a;
+ b.len++;
+ EXPECT_FALSE(a == b);
+ EXPECT_TRUE(a != b);
+ }
+ {
+ auto b = a;
+ b.cap++;
+ EXPECT_FALSE(a == b);
+ EXPECT_TRUE(a != b);
+ }
+}
+
} // namespace
} // namespace tint
diff --git a/src/tint/utils/templates/enums.tmpl.inc b/src/tint/utils/templates/enums.tmpl.inc
index 5bd899e..dd848a3 100644
--- a/src/tint/utils/templates/enums.tmpl.inc
+++ b/src/tint/utils/templates/enums.tmpl.inc
@@ -64,7 +64,7 @@
/// @returns the parsed enum, or {{$enum}}::kUndefined if the string could not be parsed.
{{$enum}} Parse{{$enum}}(std::string_view str);
-constexpr const char* k{{$enum}}Strings[] = {
+constexpr std::string_view k{{$enum}}Strings[] = {
{{- range $entry := $.Entries }}
{{- if not $entry.IsInternal}}
"{{$entry.Name}}",
diff --git a/src/tint/utils/text/string.cc b/src/tint/utils/text/string.cc
index a84a5b1..0812dad 100644
--- a/src/tint/utils/text/string.cc
+++ b/src/tint/utils/text/string.cc
@@ -63,15 +63,7 @@
}
void SuggestAlternatives(std::string_view got,
- Slice<char const* const> strings,
- StringStream& ss,
- const SuggestAlternativeOptions& options /* = {} */) {
- auto views = Transform<8>(strings, [](char const* const str) { return std::string_view(str); });
- SuggestAlternatives(got, views.Slice(), ss, options);
-}
-
-void SuggestAlternatives(std::string_view got,
- Slice<std::string_view> strings,
+ Slice<const std::string_view> strings,
StringStream& ss,
const SuggestAlternativeOptions& options /* = {} */) {
// If the string typed was within kSuggestionDistance of one of the possible enum values,
diff --git a/src/tint/utils/text/string.h b/src/tint/utils/text/string.h
index f98f4b6..6ae2894 100644
--- a/src/tint/utils/text/string.h
+++ b/src/tint/utils/text/string.h
@@ -52,6 +52,20 @@
return str;
}
+/// @copydoc ReplaceAll(std::string, std::string_view, std::string_view)
+[[nodiscard]] inline std::string ReplaceAll(std::string_view str,
+ std::string_view substr,
+ std::string_view replacement) {
+ return ReplaceAll(std::string(str), substr, replacement);
+}
+
+/// @copydoc ReplaceAll(std::string, std::string_view, std::string_view)
+[[nodiscard]] inline std::string ReplaceAll(const char* str,
+ std::string_view substr,
+ std::string_view replacement) {
+ return ReplaceAll(std::string(str), substr, replacement);
+}
+
/// @param value the boolean value to be printed as a string
/// @returns value printed as a string via the stream `<<` operator
inline std::string ToString(bool value) {
@@ -109,17 +123,7 @@
/// @param ss the stream to write the suggest and list of possible values to
/// @param options options for the suggestion
void SuggestAlternatives(std::string_view got,
- Slice<char const* const> strings,
- StringStream& ss,
- const SuggestAlternativeOptions& options = {});
-
-/// Suggest alternatives for an unrecognized string from a list of possible values.
-/// @param got the unrecognized string
-/// @param strings the list of possible values
-/// @param ss the stream to write the suggest and list of possible values to
-/// @param options options for the suggestion
-void SuggestAlternatives(std::string_view got,
- Slice<std::string_view> strings,
+ Slice<const std::string_view> strings,
StringStream& ss,
const SuggestAlternativeOptions& options = {});
diff --git a/src/tint/utils/text/string_test.cc b/src/tint/utils/text/string_test.cc
index fccf0fa..b14aaac 100644
--- a/src/tint/utils/text/string_test.cc
+++ b/src/tint/utils/text/string_test.cc
@@ -94,20 +94,20 @@
TEST(StringTest, SuggestAlternatives) {
{
- const char* alternatives[] = {"hello world", "Hello World"};
+ std::string_view alternatives[] = {"hello world", "Hello World"};
StringStream ss;
SuggestAlternatives("hello wordl", alternatives, ss);
EXPECT_EQ(ss.str(), R"(Did you mean 'hello world'?
Possible values: 'hello world', 'Hello World')");
}
{
- const char* alternatives[] = {"foobar", "something else"};
+ std::string_view alternatives[] = {"foobar", "something else"};
StringStream ss;
SuggestAlternatives("hello world", alternatives, ss);
EXPECT_EQ(ss.str(), R"(Possible values: 'foobar', 'something else')");
}
{
- const char* alternatives[] = {"hello world", "Hello World"};
+ std::string_view alternatives[] = {"hello world", "Hello World"};
StringStream ss;
SuggestAlternativeOptions opts;
opts.prefix = "$";
@@ -116,7 +116,7 @@
Possible values: '$hello world', '$Hello World')");
}
{
- const char* alternatives[] = {"hello world", "Hello World"};
+ std::string_view alternatives[] = {"hello world", "Hello World"};
StringStream ss;
SuggestAlternativeOptions opts;
opts.list_possible_values = false;