[Tint] Implement context dependent builtin values
Built-in value names were made context dependent in
https://github.com/gpuweb/gpuweb/pull/4559. The changes to the grammar
and AST resolution are now reflected in Tint, so the corresponding
previously failing CTS tests pass.
Bug: 42251275
Change-Id: I586ff25603fe4fc68d9d0ba22ab720c84d9309d8
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/197477
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Commit-Queue: Natalie Chouinard <chouinard@google.com>
diff --git a/src/tint/lang/msl/writer/ast_raise/subgroup_ballot.cc b/src/tint/lang/msl/writer/ast_raise/subgroup_ballot.cc
index 781e245..77f401c 100644
--- a/src/tint/lang/msl/writer/ast_raise/subgroup_ballot.cc
+++ b/src/tint/lang/msl/writer/ast_raise/subgroup_ballot.cc
@@ -157,10 +157,7 @@
Symbol subgroup_size;
for (auto* param : ep->params) {
auto* builtin = ast::GetAttribute<ast::BuiltinAttribute>(param->attributes);
- if (builtin &&
- src.Sem()
- .Get<sem::BuiltinEnumExpression<core::BuiltinValue>>(builtin->builtin)
- ->Value() == core::BuiltinValue::kSubgroupSize) {
+ if (builtin && src.Sem().Get(builtin)->Value() == core::BuiltinValue::kSubgroupSize) {
subgroup_size = ctx.Clone(param->name->symbol);
}
}
diff --git a/src/tint/lang/spirv/writer/ast_printer/builder.cc b/src/tint/lang/spirv/writer/ast_printer/builder.cc
index 9a42478..1d925a2 100644
--- a/src/tint/lang/spirv/writer/ast_printer/builder.cc
+++ b/src/tint/lang/spirv/writer/ast_printer/builder.cc
@@ -50,6 +50,7 @@
#include "src/tint/lang/wgsl/ast/traverse_expressions.h"
#include "src/tint/lang/wgsl/helpers/append_vector.h"
#include "src/tint/lang/wgsl/helpers/check_supported_extensions.h"
+#include "src/tint/lang/wgsl/sem/builtin_enum_expression.h"
#include "src/tint/lang/wgsl/sem/builtin_fn.h"
#include "src/tint/lang/wgsl/sem/call.h"
#include "src/tint/lang/wgsl/sem/function.h"
diff --git a/src/tint/lang/wgsl/ast/BUILD.bazel b/src/tint/lang/wgsl/ast/BUILD.bazel
index e038bf6..9baea14 100644
--- a/src/tint/lang/wgsl/ast/BUILD.bazel
+++ b/src/tint/lang/wgsl/ast/BUILD.bazel
@@ -52,6 +52,7 @@
"break_statement.cc",
"builder.cc",
"builtin_attribute.cc",
+ "builtin_value_name.cc",
"call_expression.cc",
"call_statement.cc",
"case_selector.cc",
@@ -133,6 +134,7 @@
"break_statement.h",
"builder.h",
"builtin_attribute.h",
+ "builtin_value_name.h",
"call_expression.h",
"call_statement.h",
"case_selector.h",
@@ -241,6 +243,7 @@
"builtin_attribute_test.cc",
"builtin_texture_helper_test.cc",
"builtin_texture_helper_test.h",
+ "builtin_value_name_test.cc",
"call_expression_test.cc",
"call_statement_test.cc",
"case_selector_test.cc",
diff --git a/src/tint/lang/wgsl/ast/BUILD.cmake b/src/tint/lang/wgsl/ast/BUILD.cmake
index 6afc090..de65c9c 100644
--- a/src/tint/lang/wgsl/ast/BUILD.cmake
+++ b/src/tint/lang/wgsl/ast/BUILD.cmake
@@ -67,6 +67,8 @@
lang/wgsl/ast/builder.h
lang/wgsl/ast/builtin_attribute.cc
lang/wgsl/ast/builtin_attribute.h
+ lang/wgsl/ast/builtin_value_name.cc
+ lang/wgsl/ast/builtin_value_name.h
lang/wgsl/ast/call_expression.cc
lang/wgsl/ast/call_expression.h
lang/wgsl/ast/call_statement.cc
@@ -241,6 +243,7 @@
lang/wgsl/ast/builtin_attribute_test.cc
lang/wgsl/ast/builtin_texture_helper_test.cc
lang/wgsl/ast/builtin_texture_helper_test.h
+ lang/wgsl/ast/builtin_value_name_test.cc
lang/wgsl/ast/call_expression_test.cc
lang/wgsl/ast/call_statement_test.cc
lang/wgsl/ast/case_selector_test.cc
diff --git a/src/tint/lang/wgsl/ast/BUILD.gn b/src/tint/lang/wgsl/ast/BUILD.gn
index a1b43d7..05c02bb 100644
--- a/src/tint/lang/wgsl/ast/BUILD.gn
+++ b/src/tint/lang/wgsl/ast/BUILD.gn
@@ -70,6 +70,8 @@
"builder.h",
"builtin_attribute.cc",
"builtin_attribute.h",
+ "builtin_value_name.cc",
+ "builtin_value_name.h",
"call_expression.cc",
"call_expression.h",
"call_statement.cc",
@@ -241,6 +243,7 @@
"builtin_attribute_test.cc",
"builtin_texture_helper_test.cc",
"builtin_texture_helper_test.h",
+ "builtin_value_name_test.cc",
"call_expression_test.cc",
"call_statement_test.cc",
"case_selector_test.cc",
diff --git a/src/tint/lang/wgsl/ast/builder.h b/src/tint/lang/wgsl/ast/builder.h
index 33fbe7a..9fd60a8 100644
--- a/src/tint/lang/wgsl/ast/builder.h
+++ b/src/tint/lang/wgsl/ast/builder.h
@@ -47,6 +47,7 @@
#include "src/tint/lang/wgsl/ast/bool_literal_expression.h"
#include "src/tint/lang/wgsl/ast/break_if_statement.h"
#include "src/tint/lang/wgsl/ast/break_statement.h"
+#include "src/tint/lang/wgsl/ast/builtin_value_name.h"
#include "src/tint/lang/wgsl/ast/call_expression.h"
#include "src/tint/lang/wgsl/ast/call_statement.h"
#include "src/tint/lang/wgsl/ast/case_statement.h"
@@ -3054,13 +3055,44 @@
/// @returns the selector pointer
const ast::CaseSelector* DefaultCaseSelector() { return create<ast::CaseSelector>(nullptr); }
+ /// Passthrough overload
+ /// @param name the builtin value name
+ /// @returns @p name
+ const ast::BuiltinValueName* BuiltinValueName(const ast::BuiltinValueName* name) {
+ return name;
+ }
+
+ /// Creates an ast::BuiltinValueName
+ /// @param name the builtin value name
+ /// @returns the builtin value name
+ template <typename NAME>
+ const ast::BuiltinValueName* BuiltinValueName(NAME&& name) {
+ static_assert(!traits::IsType<traits::PtrElTy<NAME>, ast::TemplatedIdentifier>,
+ "it is invalid for a builtin value name to be templated");
+ auto* name_ident = Ident(std::forward<NAME>(name));
+ return create<ast::BuiltinValueName>(name_ident ? name_ident->source : source_, name_ident);
+ }
+
+ /// Creates an ast::BuiltinValueName
+ /// @param source the source information
+ /// @param name the builtin value name
+ /// @returns the builtin value name
+ template <typename NAME>
+ const ast::BuiltinValueName* BuiltinValueName(const Source& source, NAME&& name) {
+ static_assert(!traits::IsType<traits::PtrElTy<NAME>, ast::TemplatedIdentifier>,
+ "it is invalid for a builtin value name to be templated");
+ auto* name_ident = Ident(std::forward<NAME>(name));
+ return create<ast::BuiltinValueName>(source, name_ident);
+ }
+
/// Creates an ast::BuiltinAttribute
/// @param source the source information
/// @param builtin the builtin value
/// @returns the builtin attribute pointer
template <typename BUILTIN>
const ast::BuiltinAttribute* Builtin(const Source& source, BUILTIN&& builtin) {
- return create<ast::BuiltinAttribute>(source, Expr(std::forward<BUILTIN>(builtin)));
+ return create<ast::BuiltinAttribute>(source,
+ BuiltinValueName(std::forward<BUILTIN>(builtin)));
}
/// Creates an ast::BuiltinAttribute
@@ -3068,7 +3100,8 @@
/// @returns the builtin attribute pointer
template <typename BUILTIN>
const ast::BuiltinAttribute* Builtin(BUILTIN&& builtin) {
- return create<ast::BuiltinAttribute>(source_, Expr(std::forward<BUILTIN>(builtin)));
+ return create<ast::BuiltinAttribute>(source_,
+ BuiltinValueName(std::forward<BUILTIN>(builtin)));
}
/// Creates an ast::InterpolateAttribute
diff --git a/src/tint/lang/wgsl/ast/builtin_attribute.cc b/src/tint/lang/wgsl/ast/builtin_attribute.cc
index 7f5c0ca..b39ecd2 100644
--- a/src/tint/lang/wgsl/ast/builtin_attribute.cc
+++ b/src/tint/lang/wgsl/ast/builtin_attribute.cc
@@ -30,6 +30,7 @@
#include <string>
#include "src/tint/lang/wgsl/ast/builder.h"
+#include "src/tint/lang/wgsl/ast/builtin_value_name.h"
#include "src/tint/lang/wgsl/ast/clone_context.h"
TINT_INSTANTIATE_TYPEINFO(tint::ast::BuiltinAttribute);
@@ -39,7 +40,7 @@
BuiltinAttribute::BuiltinAttribute(GenerationID pid,
NodeID nid,
const Source& src,
- const Expression* b)
+ const BuiltinValueName* b)
: Base(pid, nid, src), builtin(b) {
TINT_ASSERT_GENERATION_IDS_EQUAL(b, generation_id);
}
diff --git a/src/tint/lang/wgsl/ast/builtin_attribute.h b/src/tint/lang/wgsl/ast/builtin_attribute.h
index 08815d7..8f80137 100644
--- a/src/tint/lang/wgsl/ast/builtin_attribute.h
+++ b/src/tint/lang/wgsl/ast/builtin_attribute.h
@@ -34,7 +34,7 @@
// Forward declarations
namespace tint::ast {
-class Expression;
+class BuiltinValueName;
}
namespace tint::ast {
@@ -47,7 +47,10 @@
/// @param nid the unique node identifier
/// @param src the source of this node
/// @param builtin the builtin value
- BuiltinAttribute(GenerationID pid, NodeID nid, const Source& src, const Expression* builtin);
+ BuiltinAttribute(GenerationID pid,
+ NodeID nid,
+ const Source& src,
+ const BuiltinValueName* builtin);
~BuiltinAttribute() override;
/// @returns the WGSL name for the attribute
@@ -60,7 +63,7 @@
const BuiltinAttribute* Clone(CloneContext& ctx) const override;
/// The builtin value
- const Expression* const builtin;
+ const BuiltinValueName* const builtin;
};
} // namespace tint::ast
diff --git a/src/tint/lang/wgsl/ast/builtin_attribute_test.cc b/src/tint/lang/wgsl/ast/builtin_attribute_test.cc
index 42aefe7..5561224 100644
--- a/src/tint/lang/wgsl/ast/builtin_attribute_test.cc
+++ b/src/tint/lang/wgsl/ast/builtin_attribute_test.cc
@@ -26,6 +26,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "src/tint/lang/core/builtin_value.h"
+#include "src/tint/lang/wgsl/ast/builtin_value_name.h"
#include "src/tint/lang/wgsl/ast/helper_test.h"
namespace tint::ast {
@@ -36,7 +37,7 @@
TEST_F(BuiltinAttributeTest, Creation) {
auto* d = Builtin(core::BuiltinValue::kFragDepth);
- CheckIdentifier(d->builtin, "frag_depth");
+ CheckIdentifier(d->builtin->name, "frag_depth");
}
TEST_F(BuiltinAttributeDeathTest, Assert_Null_Builtin) {
@@ -53,7 +54,7 @@
{
ProgramBuilder b1;
ProgramBuilder b2;
- b1.Builtin(b2.Expr("bang"));
+ b1.Builtin(b2.BuiltinValueName("bang"));
},
"internal compiler error");
}
diff --git a/src/tint/lang/wgsl/ast/builtin_value_name.cc b/src/tint/lang/wgsl/ast/builtin_value_name.cc
new file mode 100644
index 0000000..28a94a1
--- /dev/null
+++ b/src/tint/lang/wgsl/ast/builtin_value_name.cc
@@ -0,0 +1,58 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/wgsl/ast/builtin_value_name.h"
+
+#include <string>
+
+#include "src/tint/lang/wgsl/ast/builder.h"
+#include "src/tint/lang/wgsl/ast/clone_context.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::ast::BuiltinValueName);
+
+namespace tint::ast {
+
+BuiltinValueName::BuiltinValueName(GenerationID pid,
+ NodeID nid,
+ const Source& src,
+ const Identifier* n)
+ : Base(pid, nid, src), name(n) {
+ TINT_ASSERT(name != nullptr);
+ TINT_ASSERT_GENERATION_IDS_EQUAL_IF_VALID(name, generation_id);
+}
+
+const BuiltinValueName* BuiltinValueName::Clone(CloneContext& ctx) const {
+ auto src = ctx.Clone(source);
+ auto n = ctx.Clone(name);
+ return ctx.dst->create<BuiltinValueName>(src, n);
+}
+
+std::string BuiltinValueName::String() const {
+ return name->symbol.Name();
+}
+
+} // namespace tint::ast
diff --git a/src/tint/lang/wgsl/ast/builtin_value_name.h b/src/tint/lang/wgsl/ast/builtin_value_name.h
new file mode 100644
index 0000000..5655967
--- /dev/null
+++ b/src/tint/lang/wgsl/ast/builtin_value_name.h
@@ -0,0 +1,66 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_TINT_LANG_WGSL_AST_BUILTIN_VALUE_NAME_H_
+#define SRC_TINT_LANG_WGSL_AST_BUILTIN_VALUE_NAME_H_
+
+#include <string>
+
+#include "src/tint/lang/wgsl/ast/node.h"
+
+// Forward declarations
+namespace tint::ast {
+class Identifier;
+} // namespace tint::ast
+
+namespace tint::ast {
+
+/// A builtin value name used for builtin value attributes.
+class BuiltinValueName final : public Castable<BuiltinValueName, Node> {
+ public:
+ /// Constructor
+ /// @param pid the identifier of the program that owns this node
+ /// @param nid the unique node identifier
+ /// @param src the source of this node
+ /// @param name the rule name
+ BuiltinValueName(GenerationID pid, NodeID nid, const Source& src, const Identifier* name);
+
+ /// Clones this node and all transitive child nodes using the `CloneContext` `ctx`.
+ /// @param ctx the clone context
+ /// @return the newly cloned node
+ const BuiltinValueName* Clone(CloneContext& ctx) const override;
+
+ /// @return the full name of this builtin value.
+ std::string String() const;
+
+ /// The builtin value name.
+ Identifier const* const name;
+};
+
+} // namespace tint::ast
+
+#endif // SRC_TINT_LANG_WGSL_AST_BUILTIN_VALUE_NAME_H_
diff --git a/src/tint/lang/wgsl/ast/builtin_value_name_test.cc b/src/tint/lang/wgsl/ast/builtin_value_name_test.cc
new file mode 100644
index 0000000..22d859b
--- /dev/null
+++ b/src/tint/lang/wgsl/ast/builtin_value_name_test.cc
@@ -0,0 +1,63 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/wgsl/ast/builtin_value_name.h"
+#include "src/tint/lang/core/builtin_value.h"
+#include "src/tint/lang/wgsl/ast/helper_test.h"
+
+namespace tint::ast {
+namespace {
+
+using BuiltinValueNameTest = TestHelper;
+using BuiltinValueNameDeathTest = BuiltinValueNameTest;
+
+TEST_F(BuiltinValueNameTest, Creation) {
+ auto* builtin = BuiltinValueName(core::BuiltinValue::kNumWorkgroups);
+ CheckIdentifier(builtin->name, "num_workgroups");
+}
+
+TEST_F(BuiltinValueNameDeathTest, Assert_Null) {
+ EXPECT_DEATH_IF_SUPPORTED(
+ {
+ ProgramBuilder b;
+ b.BuiltinValueName(nullptr);
+ },
+ "internal compiler error");
+}
+
+TEST_F(BuiltinValueNameDeathTest, Assert_DifferentGenerationID) {
+ EXPECT_DEATH_IF_SUPPORTED(
+ {
+ ProgramBuilder b1;
+ ProgramBuilder b2;
+ b1.BuiltinValueName(b2.Ident("bang"));
+ },
+ "internal compiler error");
+}
+
+} // namespace
+} // namespace tint::ast
diff --git a/src/tint/lang/wgsl/ast/transform/renamer.cc b/src/tint/lang/wgsl/ast/transform/renamer.cc
index 25485b2..296f66c 100644
--- a/src/tint/lang/wgsl/ast/transform/renamer.cc
+++ b/src/tint/lang/wgsl/ast/transform/renamer.cc
@@ -1340,6 +1340,9 @@
[&](const sem::ValueConstructor*) {
preserve_if_builtin_type(call->target->identifier);
});
+ },
+ [&](const BuiltinAttribute* builtin) {
+ preserved_identifiers.Add(builtin->builtin->name);
});
}
diff --git a/src/tint/lang/wgsl/ls/sem_tokens.cc b/src/tint/lang/wgsl/ls/sem_tokens.cc
index c389b8c..7340c1f 100644
--- a/src/tint/lang/wgsl/ls/sem_tokens.cc
+++ b/src/tint/lang/wgsl/ls/sem_tokens.cc
@@ -39,6 +39,7 @@
#include "src/tint/lang/wgsl/ls/sem_token.h"
#include "src/tint/lang/wgsl/ls/server.h"
#include "src/tint/lang/wgsl/ls/utils.h"
+#include "src/tint/lang/wgsl/sem/builtin_enum_expression.h"
#include "src/tint/lang/wgsl/sem/function_expression.h"
#include "src/tint/lang/wgsl/sem/type_expression.h"
#include "src/tint/lang/wgsl/sem/variable.h"
diff --git a/src/tint/lang/wgsl/reader/parser/param_list_test.cc b/src/tint/lang/wgsl/reader/parser/param_list_test.cc
index 65550c7..512bd4a 100644
--- a/src/tint/lang/wgsl/reader/parser/param_list_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/param_list_test.cc
@@ -25,6 +25,7 @@
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#include "src/tint/lang/wgsl/ast/builtin_value_name.h"
#include "src/tint/lang/wgsl/ast/helper_test.h"
#include "src/tint/lang/wgsl/reader/parser/helper_test.h"
@@ -115,7 +116,7 @@
auto attrs_0 = e.value[0]->attributes;
ASSERT_EQ(attrs_0.Length(), 1u);
EXPECT_TRUE(attrs_0[0]->Is<ast::BuiltinAttribute>());
- ast::CheckIdentifier(attrs_0[0]->As<ast::BuiltinAttribute>()->builtin, "position");
+ ast::CheckIdentifier(attrs_0[0]->As<ast::BuiltinAttribute>()->builtin->name, "position");
ASSERT_EQ(e.value[0]->source.range.begin.line, 1u);
ASSERT_EQ(e.value[0]->source.range.begin.column, 20u);
diff --git a/src/tint/lang/wgsl/reader/parser/parser.cc b/src/tint/lang/wgsl/reader/parser/parser.cc
index b85555e..a79d213 100644
--- a/src/tint/lang/wgsl/reader/parser/parser.cc
+++ b/src/tint/lang/wgsl/reader/parser/parser.cc
@@ -3038,6 +3038,19 @@
break;
}
+ if (attr.value == core::Attribute::kBuiltin) {
+ return expect_paren_block(
+ "builtin attribute", [&]() -> Expect<const ast::BuiltinAttribute*> {
+ auto name = expect_builtin_value_name();
+ if (name.errored) {
+ return Failure::kErrored;
+ }
+ match(Token::Type::kComma);
+
+ return create<ast::BuiltinAttribute>(t.source(), std::move(name.value));
+ });
+ }
+
Vector<const ast::Expression*, 2> args;
// Handle no parameter items which should have no parens
@@ -3089,8 +3102,6 @@
return create<ast::BindingAttribute>(t.source(), args[0]);
case core::Attribute::kBlendSrc:
return create<ast::BlendSrcAttribute>(t.source(), args[0]);
- case core::Attribute::kBuiltin:
- return create<ast::BuiltinAttribute>(t.source(), args[0]);
case core::Attribute::kColor:
return create<ast::ColorAttribute>(t.source(), args[0]);
case core::Attribute::kCompute:
@@ -3189,6 +3200,17 @@
wgsl::kDiagnosticSeverityStrings);
}
+// builtin_value_name :
+// | ident_pattern_token
+Expect<const ast::BuiltinValueName*> Parser::expect_builtin_value_name() {
+ auto name = expect_ident("", "builtin value name");
+ if (name.errored) {
+ return Failure::kErrored;
+ }
+
+ return builder_.BuiltinValueName(name.value);
+}
+
// diagnostic_control
// : PAREN_LEFT severity_control_name COMMA diagnostic_rule_name COMMA ? PAREN_RIGHT
Expect<ast::DiagnosticControl> Parser::expect_diagnostic_control() {
diff --git a/src/tint/lang/wgsl/reader/parser/parser.h b/src/tint/lang/wgsl/reader/parser/parser.h
index 993c544..205c6dd 100644
--- a/src/tint/lang/wgsl/reader/parser/parser.h
+++ b/src/tint/lang/wgsl/reader/parser/parser.h
@@ -683,6 +683,9 @@
/// Parses a diagnostic_rule_name grammar element.
/// @return the parsed diagnostic rule name.
Expect<const ast::DiagnosticRuleName*> expect_diagnostic_rule_name();
+ /// Parses a builtin_value_name grammar element.
+ /// @return the parsed builtin value name.
+ Expect<const ast::BuiltinValueName*> expect_builtin_value_name();
/// Splits a peekable token into to parts filling in the peekable fields.
/// @param lhs the token to set in the current position
diff --git a/src/tint/lang/wgsl/reader/parser/variable_attribute_list_test.cc b/src/tint/lang/wgsl/reader/parser/variable_attribute_list_test.cc
index c1361b7..c72fa38 100644
--- a/src/tint/lang/wgsl/reader/parser/variable_attribute_list_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/variable_attribute_list_test.cc
@@ -52,7 +52,7 @@
EXPECT_EQ(exp->value, 4u);
ASSERT_TRUE(attr_1->Is<ast::BuiltinAttribute>());
- ast::CheckIdentifier(attr_1->As<ast::BuiltinAttribute>()->builtin, "position");
+ ast::CheckIdentifier(attr_1->As<ast::BuiltinAttribute>()->builtin->name, "position");
}
TEST_F(WGSLParserTest, VariableAttributeList_Invalid) {
diff --git a/src/tint/lang/wgsl/reader/parser/variable_attribute_test.cc b/src/tint/lang/wgsl/reader/parser/variable_attribute_test.cc
index c61f47d..bc930e7 100644
--- a/src/tint/lang/wgsl/reader/parser/variable_attribute_test.cc
+++ b/src/tint/lang/wgsl/reader/parser/variable_attribute_test.cc
@@ -246,7 +246,7 @@
ASSERT_TRUE(var_attr->Is<ast::BuiltinAttribute>());
auto* builtin = var_attr->As<ast::BuiltinAttribute>();
- ast::CheckIdentifier(builtin->builtin, str);
+ ast::CheckIdentifier(builtin->builtin->name, str);
}
TEST_P(BuiltinTest, Attribute_Builtin_TrailingComma) {
auto str = tint::ToString(GetParam());
@@ -262,7 +262,7 @@
ASSERT_TRUE(var_attr->Is<ast::BuiltinAttribute>());
auto* builtin = var_attr->As<ast::BuiltinAttribute>();
- ast::CheckIdentifier(builtin->builtin, str);
+ ast::CheckIdentifier(builtin->builtin->name, str);
}
INSTANTIATE_TEST_SUITE_P(WGSLParserTest,
BuiltinTest,
@@ -306,7 +306,7 @@
EXPECT_TRUE(attr.errored);
EXPECT_EQ(attr.value, nullptr);
EXPECT_TRUE(p->has_error());
- EXPECT_EQ(p->error(), "1:1: builtin expects 1 argument");
+ EXPECT_EQ(p->error(), "1:9: expected builtin value name");
}
TEST_F(WGSLParserTest, Attribute_Interpolate_Flat) {
diff --git a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
index 49570b4..7b6e2c8 100644
--- a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
+++ b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
@@ -87,6 +87,7 @@
#include "src/tint/lang/wgsl/ast/while_statement.h"
#include "src/tint/lang/wgsl/ir/builtin_call.h"
#include "src/tint/lang/wgsl/program/program.h"
+#include "src/tint/lang/wgsl/sem/builtin_enum_expression.h"
#include "src/tint/lang/wgsl/sem/builtin_fn.h"
#include "src/tint/lang/wgsl/sem/call.h"
#include "src/tint/lang/wgsl/sem/function.h"
@@ -316,10 +317,7 @@
},
[&](const ast::InvariantAttribute*) { ir_func->SetReturnInvariant(true); },
[&](const ast::BuiltinAttribute* b) {
- if (auto* ident_sem =
- program_.Sem()
- .Get(b)
- ->As<sem::BuiltinEnumExpression<core::BuiltinValue>>()) {
+ if (auto* ident_sem = program_.Sem().Get(b)->As<sem::BuiltinAttribute>()) {
ir_func->SetReturnBuiltin(ident_sem->Value());
} else {
TINT_ICE() << "Builtin attribute sem invalid";
@@ -346,10 +344,7 @@
},
[&](const ast::InvariantAttribute*) { param->SetInvariant(true); },
[&](const ast::BuiltinAttribute* b) {
- if (auto* ident_sem =
- program_.Sem()
- .Get(b)
- ->As<sem::BuiltinEnumExpression<core::BuiltinValue>>()) {
+ if (auto* ident_sem = program_.Sem().Get(b)->As<sem::BuiltinAttribute>()) {
param->SetBuiltin(ident_sem->Value());
} else {
TINT_ICE() << "Builtin attribute sem invalid";
diff --git a/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc b/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc
index 16793d3..28f52e9 100644
--- a/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc
+++ b/src/tint/lang/wgsl/resolver/compatibility_mode_test.cc
@@ -103,7 +103,8 @@
Func("main",
Vector{Param("mask", ty.i32(),
Vector{
- create<ast::BuiltinAttribute>({}, Expr(Source{{12, 34}}, "sample_mask")),
+ create<ast::BuiltinAttribute>(
+ {}, BuiltinValueName(Source{{12, 34}}, "sample_mask")),
})},
ty.void_(), Empty,
Vector{
@@ -133,7 +134,7 @@
Stage(ast::PipelineStage::kFragment),
},
Vector{
- create<ast::BuiltinAttribute>({}, Expr(Source{{12, 34}}, "sample_mask")),
+ create<ast::BuiltinAttribute>({}, BuiltinValueName(Source{{12, 34}}, "sample_mask")),
});
EXPECT_FALSE(r()->Resolve());
@@ -147,14 +148,13 @@
// @builtin(sample_mask) mask : u32,
// }
- Structure(
- "S",
- Vector{
- Member("mask", ty.u32(),
- Vector{
- create<ast::BuiltinAttribute>({}, Expr(Source{{12, 34}}, "sample_mask")),
- }),
- });
+ Structure("S", Vector{
+ Member("mask", ty.u32(),
+ Vector{
+ create<ast::BuiltinAttribute>(
+ {}, BuiltinValueName(Source{{12, 34}}, "sample_mask")),
+ }),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
@@ -170,7 +170,8 @@
Func("main",
Vector{Param("mask", ty.i32(),
Vector{
- create<ast::BuiltinAttribute>({}, Expr(Source{{12, 34}}, "sample_index")),
+ create<ast::BuiltinAttribute>(
+ {}, BuiltinValueName(Source{{12, 34}}, "sample_index")),
})},
ty.void_(), Empty,
Vector{
@@ -200,7 +201,7 @@
Stage(ast::PipelineStage::kFragment),
},
Vector{
- create<ast::BuiltinAttribute>({}, Expr(Source{{12, 34}}, "sample_index")),
+ create<ast::BuiltinAttribute>({}, BuiltinValueName(Source{{12, 34}}, "sample_index")),
});
EXPECT_FALSE(r()->Resolve());
@@ -214,14 +215,13 @@
// @builtin(sample_index) mask : u32,
// }
- Structure(
- "S",
- Vector{
- Member("mask", ty.u32(),
- Vector{
- create<ast::BuiltinAttribute>({}, Expr(Source{{12, 34}}, "sample_index")),
- }),
- });
+ Structure("S", Vector{
+ Member("mask", ty.u32(),
+ Vector{
+ create<ast::BuiltinAttribute>(
+ {}, BuiltinValueName(Source{{12, 34}}, "sample_index")),
+ }),
+ });
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(
diff --git a/src/tint/lang/wgsl/resolver/dependency_graph.cc b/src/tint/lang/wgsl/resolver/dependency_graph.cc
index bffa92e..730845c 100644
--- a/src/tint/lang/wgsl/resolver/dependency_graph.cc
+++ b/src/tint/lang/wgsl/resolver/dependency_graph.cc
@@ -376,7 +376,6 @@
Switch(
attr, //
[&](const ast::BindingAttribute* binding) { TraverseExpression(binding->expr); },
- [&](const ast::BuiltinAttribute* builtin) { TraverseExpression(builtin->builtin); },
[&](const ast::ColorAttribute* color) { TraverseExpression(color->expr); },
[&](const ast::GroupAttribute* group) { TraverseExpression(group->expr); },
[&](const ast::IdAttribute* id) { TraverseExpression(id->expr); },
@@ -417,8 +416,6 @@
kFunction,
/// Builtin
kBuiltin,
- /// Builtin value
- kBuiltinValue,
/// Address space
kAddressSpace,
/// Texel format
@@ -443,7 +440,6 @@
std::variant<std::monostate,
wgsl::BuiltinFn,
core::BuiltinType,
- core::BuiltinValue,
core::AddressSpace,
core::TexelFormat,
core::Access,
@@ -465,10 +461,6 @@
builtin_ty != core::BuiltinType::kUndefined) {
return BuiltinInfo{BuiltinType::kBuiltin, builtin_ty};
}
- if (auto builtin_val = core::ParseBuiltinValue(symbol.NameView());
- builtin_val != core::BuiltinValue::kUndefined) {
- return BuiltinInfo{BuiltinType::kBuiltinValue, builtin_val};
- }
if (auto addr = core::ParseAddressSpace(symbol.NameView());
addr != core::AddressSpace::kUndefined) {
return BuiltinInfo{BuiltinType::kAddressSpace, addr};
@@ -511,10 +503,6 @@
graph_.resolved_identifiers.Add(
from, ResolvedIdentifier(builtin_info.Value<core::BuiltinType>()));
break;
- case BuiltinType::kBuiltinValue:
- graph_.resolved_identifiers.Add(
- from, ResolvedIdentifier(builtin_info.Value<core::BuiltinValue>()));
- break;
case BuiltinType::kAddressSpace:
graph_.resolved_identifiers.Add(
from, ResolvedIdentifier(builtin_info.Value<core::AddressSpace>()));
@@ -885,9 +873,6 @@
if (auto builtin_ty = BuiltinType(); builtin_ty != core::BuiltinType::kUndefined) {
return "builtin type '" + tint::ToString(builtin_ty) + "'";
}
- if (auto builtin_val = BuiltinValue(); builtin_val != core::BuiltinValue::kUndefined) {
- return "builtin value '" + tint::ToString(builtin_val) + "'";
- }
if (auto access = Access(); access != core::Access::kUndefined) {
return "access '" + tint::ToString(access) + "'";
}
diff --git a/src/tint/lang/wgsl/resolver/dependency_graph.h b/src/tint/lang/wgsl/resolver/dependency_graph.h
index 1e103d4..80f99cf 100644
--- a/src/tint/lang/wgsl/resolver/dependency_graph.h
+++ b/src/tint/lang/wgsl/resolver/dependency_graph.h
@@ -54,7 +54,6 @@
/// - core::Access
/// - core::AddressSpace
/// - core::BuiltinType
-/// - core::BuiltinValue
/// - core::InterpolationSampling
/// - core::InterpolationType
/// - core::TexelFormat
@@ -123,15 +122,6 @@
return core::BuiltinType::kUndefined;
}
- /// @return the builtin value if the ResolvedIdentifier holds core::BuiltinValue, otherwise
- /// core::BuiltinValue::kUndefined
- core::BuiltinValue BuiltinValue() const {
- if (auto n = std::get_if<core::BuiltinValue>(&value_)) {
- return *n;
- }
- return core::BuiltinValue::kUndefined;
- }
-
/// @return the texel format if the ResolvedIdentifier holds type::InterpolationSampling,
/// otherwise type::InterpolationSampling::kUndefined
core::InterpolationSampling InterpolationSampling() const {
@@ -186,7 +176,6 @@
core::Access,
core::AddressSpace,
core::BuiltinType,
- core::BuiltinValue,
core::InterpolationSampling,
core::InterpolationType,
core::TexelFormat>
diff --git a/src/tint/lang/wgsl/resolver/dependency_graph_test.cc b/src/tint/lang/wgsl/resolver/dependency_graph_test.cc
index f64306a..a145a93 100644
--- a/src/tint/lang/wgsl/resolver/dependency_graph_test.cc
+++ b/src/tint/lang/wgsl/resolver/dependency_graph_test.cc
@@ -1349,46 +1349,6 @@
} // namespace resolve_to_address_space
////////////////////////////////////////////////////////////////////////////////
-// Resolve to core::BuiltinValue tests
-////////////////////////////////////////////////////////////////////////////////
-namespace resolve_to_builtin_value {
-
-using ResolverDependencyGraphResolveToBuiltinValue =
- ResolverDependencyGraphTestWithParam<std::tuple<SymbolUseKind, std::string_view>>;
-
-TEST_P(ResolverDependencyGraphResolveToBuiltinValue, Resolve) {
- const auto use = std::get<0>(GetParam());
- const auto name = std::get<1>(GetParam());
- const auto symbol = Symbols().New(name);
-
- SymbolTestHelper helper(this);
- auto* ident = helper.Add(use, symbol);
- helper.Build();
-
- auto graph = Build();
- auto resolved = graph.resolved_identifiers.Get(ident);
- ASSERT_TRUE(resolved);
- EXPECT_EQ(resolved->BuiltinValue(), core::ParseBuiltinValue(name)) << resolved->String();
-}
-
-INSTANTIATE_TEST_SUITE_P(Types,
- ResolverDependencyGraphResolveToBuiltinValue,
- testing::Combine(testing::ValuesIn(kTypeUseKinds),
- testing::ValuesIn(core::kBuiltinValueStrings)));
-
-INSTANTIATE_TEST_SUITE_P(Values,
- ResolverDependencyGraphResolveToBuiltinValue,
- testing::Combine(testing::ValuesIn(kValueUseKinds),
- testing::ValuesIn(core::kBuiltinValueStrings)));
-
-INSTANTIATE_TEST_SUITE_P(Functions,
- ResolverDependencyGraphResolveToBuiltinValue,
- testing::Combine(testing::ValuesIn(kFuncUseKinds),
- testing::ValuesIn(core::kBuiltinValueStrings)));
-
-} // namespace resolve_to_builtin_value
-
-////////////////////////////////////////////////////////////////////////////////
// Resolve to core::InterpolationSampling tests
////////////////////////////////////////////////////////////////////////////////
namespace resolve_to_interpolation_sampling {
@@ -1704,7 +1664,6 @@
Vector{
Location(V), // Parameter attributes
Color(V),
- Builtin(V),
Interpolate(V),
Interpolate(V, V),
}),
diff --git a/src/tint/lang/wgsl/resolver/expression_kind_test.cc b/src/tint/lang/wgsl/resolver/expression_kind_test.cc
index 1334b8b..5a60449 100644
--- a/src/tint/lang/wgsl/resolver/expression_kind_test.cc
+++ b/src/tint/lang/wgsl/resolver/expression_kind_test.cc
@@ -42,7 +42,6 @@
kAddressSpace,
kBuiltinFunction,
kBuiltinType,
- kBuiltinValue,
kFunction,
kInterpolationSampling,
kInterpolationType,
@@ -63,8 +62,6 @@
return out << "Def::kBuiltinFunction";
case Def::kBuiltinType:
return out << "Def::kBuiltinType";
- case Def::kBuiltinValue:
- return out << "Def::kBuiltinValue";
case Def::kFunction:
return out << "Def::kFunction";
case Def::kInterpolationSampling:
@@ -89,7 +86,6 @@
kAccess,
kAddressSpace,
kBinaryOp,
- kBuiltinValue,
kCallExpr,
kCallStmt,
kFunctionReturnType,
@@ -110,8 +106,6 @@
return out << "Use::kAddressSpace";
case Use::kBinaryOp:
return out << "Use::kBinaryOp";
- case Use::kBuiltinValue:
- return out << "Use::kBuiltinValue";
case Use::kCallExpr:
return out << "Use::kCallExpr";
case Use::kCallStmt:
@@ -202,16 +196,6 @@
};
break;
}
- case Def::kBuiltinValue: {
- sym = Sym("position");
- check_expr = [](const sem::Expression* expr) {
- ASSERT_NE(expr, nullptr);
- auto* enum_expr = expr->As<sem::BuiltinEnumExpression<core::BuiltinValue>>();
- ASSERT_NE(enum_expr, nullptr);
- EXPECT_EQ(enum_expr->Value(), core::BuiltinValue::kPosition);
- };
- break;
- }
case Def::kFunction: {
sym = Sym("FUNCTION");
auto* fn = Func(kDefSource, sym, tint::Empty, ty.i32(), Return(1_i));
@@ -303,7 +287,8 @@
}
}
- auto* expr = Expr(Ident(kUseSource, sym));
+ auto* ident = Ident(kUseSource, sym);
+ auto* expr = Expr(ident);
switch (GetParam().use) {
case Use::kAccess:
GlobalVar("v", ty("texture_storage_2d", "rgba8unorm", expr), Group(0_u), Binding(0_u));
@@ -321,10 +306,6 @@
case Use::kBinaryOp:
fn_stmts.Push(Decl(Var("v", Mul(1_a, expr))));
break;
- case Use::kBuiltinValue:
- Func(Symbols().New(), Vector{Param("p", ty.vec4<f32>(), Vector{Builtin(expr)})},
- ty.void_(), tint::Empty, Vector{Stage(ast::PipelineStage::kFragment)});
- break;
case Use::kFunctionReturnType:
Func(Symbols().New(), tint::Empty, ty(expr), Return(Call(sym)));
break;
@@ -387,8 +368,6 @@
{Def::kAccess, Use::kAddressSpace,
R"(5:6 error: cannot use access 'write' as address space)"},
{Def::kAccess, Use::kBinaryOp, R"(5:6 error: cannot use access 'write' as value)"},
- {Def::kAccess, Use::kBuiltinValue,
- R"(5:6 error: cannot use access 'write' as builtin value)"},
{Def::kAccess, Use::kCallExpr, R"(5:6 error: cannot use access 'write' as call target)"},
{Def::kAccess, Use::kCallStmt, R"(5:6 error: cannot use access 'write' as call target)"},
{Def::kAccess, Use::kFunctionReturnType, R"(5:6 error: cannot use access 'write' as type)"},
@@ -408,8 +387,6 @@
{Def::kAddressSpace, Use::kAddressSpace, kPass},
{Def::kAddressSpace, Use::kBinaryOp,
R"(5:6 error: cannot use address space 'workgroup' as value)"},
- {Def::kAddressSpace, Use::kBuiltinValue,
- R"(5:6 error: cannot use address space 'workgroup' as builtin value)"},
{Def::kAddressSpace, Use::kCallExpr,
R"(5:6 error: cannot use address space 'workgroup' as call target)"},
{Def::kAddressSpace, Use::kCallStmt,
@@ -438,8 +415,6 @@
{Def::kBuiltinFunction, Use::kBinaryOp,
R"(5:6 error: cannot use builtin function 'workgroupBarrier' as value
7:8 note: are you missing '()'?)"},
- {Def::kBuiltinFunction, Use::kBuiltinValue,
- R"(5:6 error: cannot use builtin function 'workgroupBarrier' as builtin value)"},
{Def::kBuiltinFunction, Use::kCallStmt, kPass},
{Def::kBuiltinFunction, Use::kFunctionReturnType,
R"(5:6 error: cannot use builtin function 'workgroupBarrier' as type)"},
@@ -466,8 +441,6 @@
{Def::kBuiltinType, Use::kBinaryOp,
R"(5:6 error: cannot use type 'vec4<f32>' as value
7:8 note: are you missing '()'?)"},
- {Def::kBuiltinType, Use::kBuiltinValue,
- R"(5:6 error: cannot use type 'vec4<f32>' as builtin value)"},
{Def::kBuiltinType, Use::kCallExpr, kPass},
{Def::kBuiltinType, Use::kFunctionReturnType, kPass},
{Def::kBuiltinType, Use::kInterpolationSampling,
@@ -485,34 +458,6 @@
R"(5:6 error: cannot use type 'vec4<f32>' as value
7:8 note: are you missing '()'?)"},
- {Def::kBuiltinValue, Use::kAccess,
- R"(5:6 error: cannot use builtin value 'position' as access)"},
- {Def::kBuiltinValue, Use::kAddressSpace,
- R"(5:6 error: cannot use builtin value 'position' as address space)"},
- {Def::kBuiltinValue, Use::kBinaryOp,
- R"(5:6 error: cannot use builtin value 'position' as value)"},
- {Def::kBuiltinValue, Use::kBuiltinValue, kPass},
- {Def::kBuiltinValue, Use::kCallStmt,
- R"(5:6 error: cannot use builtin value 'position' as call target)"},
- {Def::kBuiltinValue, Use::kCallExpr,
- R"(5:6 error: cannot use builtin value 'position' as call target)"},
- {Def::kBuiltinValue, Use::kFunctionReturnType,
- R"(5:6 error: cannot use builtin value 'position' as type)"},
- {Def::kBuiltinValue, Use::kInterpolationSampling,
- R"(5:6 error: cannot use builtin value 'position' as interpolation sampling)"},
- {Def::kBuiltinValue, Use::kInterpolationType,
- R"(5:6 error: cannot use builtin value 'position' as interpolation type)"},
- {Def::kBuiltinValue, Use::kMemberType,
- R"(5:6 error: cannot use builtin value 'position' as type)"},
- {Def::kBuiltinValue, Use::kTexelFormat,
- R"(5:6 error: cannot use builtin value 'position' as texel format)"},
- {Def::kBuiltinValue, Use::kValueExpression,
- R"(5:6 error: cannot use builtin value 'position' as value)"},
- {Def::kBuiltinValue, Use::kVariableType,
- R"(5:6 error: cannot use builtin value 'position' as type)"},
- {Def::kBuiltinValue, Use::kUnaryOp,
- R"(5:6 error: cannot use builtin value 'position' as value)"},
-
{Def::kFunction, Use::kAccess, R"(5:6 error: cannot use function 'FUNCTION' as access
1:2 note: function 'FUNCTION' declared here)"},
{Def::kFunction, Use::kAddressSpace,
@@ -521,9 +466,6 @@
{Def::kFunction, Use::kBinaryOp, R"(5:6 error: cannot use function 'FUNCTION' as value
1:2 note: function 'FUNCTION' declared here
7:8 note: are you missing '()'?)"},
- {Def::kFunction, Use::kBuiltinValue,
- R"(5:6 error: cannot use function 'FUNCTION' as builtin value
-1:2 note: function 'FUNCTION' declared here)"},
{Def::kFunction, Use::kCallExpr, kPass},
{Def::kFunction, Use::kCallStmt, kPass},
{Def::kFunction, Use::kFunctionReturnType,
@@ -558,8 +500,6 @@
R"(5:6 error: cannot use interpolation sampling 'center' as address space)"},
{Def::kInterpolationSampling, Use::kBinaryOp,
R"(5:6 error: cannot use interpolation sampling 'center' as value)"},
- {Def::kInterpolationSampling, Use::kBuiltinValue,
- R"(5:6 error: cannot use interpolation sampling 'center' as builtin value)"},
{Def::kInterpolationSampling, Use::kCallStmt,
R"(5:6 error: cannot use interpolation sampling 'center' as call target)"},
{Def::kInterpolationSampling, Use::kCallExpr,
@@ -586,8 +526,6 @@
R"(5:6 error: cannot use interpolation type 'linear' as address space)"},
{Def::kInterpolationType, Use::kBinaryOp,
R"(5:6 error: cannot use interpolation type 'linear' as value)"},
- {Def::kInterpolationType, Use::kBuiltinValue,
- R"(5:6 error: cannot use interpolation type 'linear' as builtin value)"},
{Def::kInterpolationType, Use::kCallStmt,
R"(5:6 error: cannot use interpolation type 'linear' as call target)"},
{Def::kInterpolationType, Use::kCallExpr,
@@ -629,9 +567,6 @@
{Def::kStruct, Use::kBinaryOp, R"(5:6 error: cannot use type 'STRUCT' as value
1:2 note: 'struct STRUCT' declared here
7:8 note: are you missing '()'?)"},
- {Def::kStruct, Use::kBuiltinValue,
- R"(5:6 error: cannot use type 'STRUCT' as builtin value
-1:2 note: 'struct STRUCT' declared here)"},
{Def::kStruct, Use::kFunctionReturnType, kPass},
{Def::kStruct, Use::kInterpolationSampling,
R"(5:6 error: cannot use type 'STRUCT' as interpolation sampling
@@ -658,8 +593,6 @@
R"(5:6 error: cannot use texel format 'rgba8unorm' as address space)"},
{Def::kTexelFormat, Use::kBinaryOp,
R"(5:6 error: cannot use texel format 'rgba8unorm' as value)"},
- {Def::kTexelFormat, Use::kBuiltinValue,
- R"(5:6 error: cannot use texel format 'rgba8unorm' as builtin value)"},
{Def::kTexelFormat, Use::kCallExpr,
R"(5:6 error: cannot use texel format 'rgba8unorm' as call target)"},
{Def::kTexelFormat, Use::kCallStmt,
@@ -686,8 +619,6 @@
{Def::kTypeAlias, Use::kBinaryOp,
R"(5:6 error: cannot use type 'i32' as value
7:8 note: are you missing '()'?)"},
- {Def::kTypeAlias, Use::kBuiltinValue,
- R"(5:6 error: cannot use type 'i32' as builtin value)"},
{Def::kTypeAlias, Use::kCallExpr, kPass},
{Def::kTypeAlias, Use::kFunctionReturnType, kPass},
{Def::kTypeAlias, Use::kInterpolationSampling,
@@ -710,9 +641,6 @@
R"(5:6 error: cannot use 'const VARIABLE' as address space
1:2 note: 'const VARIABLE' declared here)"},
{Def::kVariable, Use::kBinaryOp, kPass},
- {Def::kVariable, Use::kBuiltinValue,
- R"(5:6 error: cannot use 'const VARIABLE' as builtin value
-1:2 note: 'const VARIABLE' declared here)"},
{Def::kVariable, Use::kCallStmt,
R"(5:6 error: cannot use 'const VARIABLE' as call target
1:2 note: 'const VARIABLE' declared here)"},
diff --git a/src/tint/lang/wgsl/resolver/ptr_ref_validation_test.cc b/src/tint/lang/wgsl/resolver/ptr_ref_validation_test.cc
index e7b05da..a25b36b 100644
--- a/src/tint/lang/wgsl/resolver/ptr_ref_validation_test.cc
+++ b/src/tint/lang/wgsl/resolver/ptr_ref_validation_test.cc
@@ -182,13 +182,13 @@
EXPECT_EQ(r()->error(), R"(12:34 error: cannot use address space 'uniform' as value)");
}
-TEST_F(ResolverPtrRefValidationTest, AddressOfBuiltinValue) {
+TEST_F(ResolverPtrRefValidationTest, AddressOfUnresolvedValue) {
// &position
auto* expr = AddressOf(Expr(Source{{12, 34}}, "position"));
WrapInFunction(expr);
EXPECT_FALSE(r()->Resolve());
- EXPECT_EQ(r()->error(), R"(12:34 error: cannot use builtin value 'position' as value)");
+ EXPECT_EQ(r()->error(), R"(12:34 error: unresolved value 'position')");
}
TEST_F(ResolverPtrRefValidationTest, AddressOfInterpolationSampling) {
diff --git a/src/tint/lang/wgsl/resolver/resolver.cc b/src/tint/lang/wgsl/resolver/resolver.cc
index 2362908..0250d5f 100644
--- a/src/tint/lang/wgsl/resolver/resolver.cc
+++ b/src/tint/lang/wgsl/resolver/resolver.cc
@@ -58,6 +58,7 @@
#include "src/tint/lang/wgsl/ast/assignment_statement.h"
#include "src/tint/lang/wgsl/ast/attribute.h"
#include "src/tint/lang/wgsl/ast/break_statement.h"
+#include "src/tint/lang/wgsl/ast/builtin_value_name.h"
#include "src/tint/lang/wgsl/ast/call_statement.h"
#include "src/tint/lang/wgsl/ast/continue_statement.h"
#include "src/tint/lang/wgsl/ast/disable_validation_attribute.h"
@@ -83,6 +84,7 @@
#include "src/tint/lang/wgsl/resolver/unresolved_identifier.h"
#include "src/tint/lang/wgsl/sem/array.h"
#include "src/tint/lang/wgsl/sem/break_if_statement.h"
+#include "src/tint/lang/wgsl/sem/builtin_attribute.h"
#include "src/tint/lang/wgsl/sem/builtin_enum_expression.h"
#include "src/tint/lang/wgsl/sem/call.h"
#include "src/tint/lang/wgsl/sem/for_loop_statement.h"
@@ -1672,11 +1674,6 @@
return address_space_expr;
}
-sem::BuiltinEnumExpression<core::BuiltinValue>* Resolver::BuiltinValueExpression(
- const ast::Expression* expr) {
- return sem_.AsBuiltinValue(Expression(expr));
-}
-
sem::BuiltinEnumExpression<core::TexelFormat>* Resolver::TexelFormatExpression(
const ast::Expression* expr) {
return sem_.AsTexelFormat(Expression(expr));
@@ -3405,13 +3402,6 @@
: nullptr;
}
- if (auto builtin = resolved->BuiltinValue(); builtin != core::BuiltinValue::kUndefined) {
- return CheckNotTemplated("builtin value", ident)
- ? b.create<sem::BuiltinEnumExpression<core::BuiltinValue>>(
- expr, current_statement_, builtin)
- : nullptr;
- }
-
if (auto i_smpl = resolved->InterpolationSampling();
i_smpl != core::InterpolationSampling::kUndefined) {
return CheckNotTemplated("interpolation sampling", ident)
@@ -4015,14 +4005,25 @@
tint::Result<tint::core::BuiltinValue> Resolver::BuiltinAttribute(
const ast::BuiltinAttribute* attr) {
- auto* builtin_expr = BuiltinValueExpression(attr->builtin);
- if (!builtin_expr) {
+ const ast::BuiltinValueName* builtin_val = attr->builtin;
+ Mark(builtin_val);
+
+ const ast::Identifier* ident = builtin_val->name;
+ if (!TINT_LIKELY(CheckNotTemplated("builtin value", ident))) {
return Failure{};
}
- // Apply the resolved tint::sem::BuiltinEnumExpression<tint::core::BuiltinValue> to the
- // attribute.
- b.Sem().Add(attr, builtin_expr);
- return builtin_expr->Value();
+ Mark(ident);
+
+ core::BuiltinValue builtin = core::ParseBuiltinValue(ident->symbol.NameView());
+ if (builtin == core::BuiltinValue::kUndefined) {
+ sem_.ErrorUnexpectedIdent(ident, "builtin value", core::kBuiltinValueStrings);
+ return Failure{};
+ }
+
+ auto* sem = b.create<sem::BuiltinAttribute>(attr, builtin);
+ // Apply the resolved tint::sem::BuiltinAttribute to the attribute.
+ b.Sem().Add(attr, sem);
+ return builtin;
}
bool Resolver::DiagnosticAttribute(const ast::DiagnosticAttribute* attr) {
diff --git a/src/tint/lang/wgsl/resolver/resolver.h b/src/tint/lang/wgsl/resolver/resolver.h
index e57b6ad..bd09492 100644
--- a/src/tint/lang/wgsl/resolver/resolver.h
+++ b/src/tint/lang/wgsl/resolver/resolver.h
@@ -254,13 +254,6 @@
const ast::Expression* expr);
/// @returns the call of Expression() cast to a
- /// sem::BuiltinEnumExpression<core::BuiltinValue>. If the sem::Expression is not a
- /// sem::BuiltinEnumExpression<core::BuiltinValue>, then an error diagnostic is raised and
- /// nullptr is returned.
- sem::BuiltinEnumExpression<core::BuiltinValue>* BuiltinValueExpression(
- const ast::Expression* expr);
-
- /// @returns the call of Expression() cast to a
/// sem::BuiltinEnumExpression<core::type::TexelFormat>. If the sem::Expression is not a
/// sem::BuiltinEnumExpression<core::type::TexelFormat>, then an error diagnostic is raised and
/// nullptr is returned.
diff --git a/src/tint/lang/wgsl/resolver/sem_helper.cc b/src/tint/lang/wgsl/resolver/sem_helper.cc
index 1fe3934..19f8657 100644
--- a/src/tint/lang/wgsl/resolver/sem_helper.cc
+++ b/src/tint/lang/wgsl/resolver/sem_helper.cc
@@ -117,9 +117,6 @@
[&](const sem::BuiltinEnumExpression<core::AddressSpace>* addr) {
text << "address space " << style::Enum(addr->Value());
},
- [&](const sem::BuiltinEnumExpression<core::BuiltinValue>* builtin) {
- text << "builtin value " << style::Enum(builtin->Value());
- },
[&](const sem::BuiltinEnumExpression<core::InterpolationSampling>* fmt) {
text << "interpolation sampling " << style::Enum(fmt->Value());
},
@@ -138,28 +135,33 @@
return text;
}
+void SemHelper::ErrorUnexpectedIdent(
+ const ast::Identifier* ident,
+ std::string_view wanted,
+ tint::Slice<const std::string_view> suggestions /* = Empty */) const {
+ auto name = ident->symbol.NameView();
+ AddError(ident->source) << "unresolved " << wanted << " " << style::Code(name);
+ if (!suggestions.IsEmpty()) {
+ // Filter out suggestions that have a leading underscore.
+ Vector<std::string_view, 8> filtered;
+ for (auto str : suggestions) {
+ if (str[0] != '_') {
+ filtered.Push(str);
+ }
+ }
+ auto& note = AddNote(ident->source);
+ SuggestAlternativeOptions opts;
+ opts.alternatives_style = style::Enum;
+ SuggestAlternatives(name, filtered.Slice(), note.message, opts);
+ }
+}
+
void SemHelper::ErrorUnexpectedExprKind(
const sem::Expression* expr,
std::string_view wanted,
tint::Slice<const std::string_view> suggestions /* = Empty */) const {
if (auto* ui = expr->As<UnresolvedIdentifier>()) {
- auto* ident = ui->Identifier();
- auto name = ident->identifier->symbol.NameView();
- AddError(ident->source) << "unresolved " << wanted << " " << style::Code(name);
- if (!suggestions.IsEmpty()) {
- // Filter out suggestions that have a leading underscore.
- Vector<std::string_view, 8> filtered;
- for (auto str : suggestions) {
- if (str[0] != '_') {
- filtered.Push(str);
- }
- }
- auto& note = AddNote(ident->source);
- SuggestAlternativeOptions opts;
- opts.alternatives_style = style::Enum;
- SuggestAlternatives(name, filtered.Slice(), note.message, opts);
- }
- return;
+ return ErrorUnexpectedIdent(ui->Identifier()->identifier, wanted, suggestions);
}
AddError(expr->Declaration()->source) << "cannot use " << Describe(expr) << " as " << wanted;
diff --git a/src/tint/lang/wgsl/resolver/sem_helper.h b/src/tint/lang/wgsl/resolver/sem_helper.h
index fd7b700..f8e123c 100644
--- a/src/tint/lang/wgsl/resolver/sem_helper.h
+++ b/src/tint/lang/wgsl/resolver/sem_helper.h
@@ -154,21 +154,6 @@
/// @param expr the semantic node
/// @returns nullptr if @p expr is nullptr, or @p expr cast to
- /// sem::BuiltinEnumExpression<core::BuiltinValue> if the cast is successful, otherwise an
- /// error diagnostic is raised.
- sem::BuiltinEnumExpression<core::BuiltinValue>* AsBuiltinValue(sem::Expression* expr) const {
- if (TINT_LIKELY(expr)) {
- auto* enum_expr = expr->As<sem::BuiltinEnumExpression<core::BuiltinValue>>();
- if (TINT_LIKELY(enum_expr)) {
- return enum_expr;
- }
- ErrorUnexpectedExprKind(expr, "builtin value", core::kBuiltinValueStrings);
- }
- return nullptr;
- }
-
- /// @param expr the semantic node
- /// @returns nullptr if @p expr is nullptr, or @p expr cast to
/// sem::BuiltinEnumExpression<core::type::TexelFormat> if the cast is successful, otherwise an
/// error diagnostic is raised.
sem::BuiltinEnumExpression<core::TexelFormat>* AsTexelFormat(sem::Expression* expr) const {
@@ -273,6 +258,14 @@
/// @param expr the expression
void ErrorExpectedValueExpr(const sem::Expression* expr) const;
+ /// Raises an error diagnostic that the identifier @p got was not of the kind @p wanted.
+ /// @param ident the identifier
+ /// @param wanted the expected identifier kind
+ /// @param suggestions suggested valid identifiers
+ void ErrorUnexpectedIdent(const ast::Identifier* ident,
+ std::string_view wanted,
+ tint::Slice<const std::string_view> suggestions = Empty) const;
+
/// Raises an error diagnostic that the expression @p got was not of the kind @p wanted.
/// @param expr the expression
/// @param wanted the expected expression kind
diff --git a/src/tint/lang/wgsl/resolver/unresolved_identifier_test.cc b/src/tint/lang/wgsl/resolver/unresolved_identifier_test.cc
index 98aa12d..c87cd04 100644
--- a/src/tint/lang/wgsl/resolver/unresolved_identifier_test.cc
+++ b/src/tint/lang/wgsl/resolver/unresolved_identifier_test.cc
@@ -55,7 +55,7 @@
}
TEST_F(ResolverUnresolvedIdentifierSuggestions, BuiltinValue) {
- Func("f", Vector{Param("p", ty.i32(), Vector{Builtin(Expr(Source{{12, 34}}, "positon"))})},
+ Func("f", Vector{Param("p", ty.i32(), Vector{Builtin(Ident(Source{{12, 34}}, "positon"))})},
ty.void_(), tint::Empty, Vector{Stage(ast::PipelineStage::kVertex)});
EXPECT_FALSE(r()->Resolve());
diff --git a/src/tint/lang/wgsl/sem/BUILD.bazel b/src/tint/lang/wgsl/sem/BUILD.bazel
index 37b8323..2407e96 100644
--- a/src/tint/lang/wgsl/sem/BUILD.bazel
+++ b/src/tint/lang/wgsl/sem/BUILD.bazel
@@ -45,6 +45,7 @@
"behavior.cc",
"block_statement.cc",
"break_if_statement.cc",
+ "builtin_attribute.cc",
"builtin_enum_expression.cc",
"builtin_fn.cc",
"call.cc",
@@ -79,6 +80,7 @@
"behavior.h",
"block_statement.h",
"break_if_statement.h",
+ "builtin_attribute.h",
"builtin_enum_expression.h",
"builtin_fn.h",
"call.h",
diff --git a/src/tint/lang/wgsl/sem/BUILD.cmake b/src/tint/lang/wgsl/sem/BUILD.cmake
index 6120b90..c83602b 100644
--- a/src/tint/lang/wgsl/sem/BUILD.cmake
+++ b/src/tint/lang/wgsl/sem/BUILD.cmake
@@ -51,6 +51,8 @@
lang/wgsl/sem/block_statement.h
lang/wgsl/sem/break_if_statement.cc
lang/wgsl/sem/break_if_statement.h
+ lang/wgsl/sem/builtin_attribute.cc
+ lang/wgsl/sem/builtin_attribute.h
lang/wgsl/sem/builtin_enum_expression.cc
lang/wgsl/sem/builtin_enum_expression.h
lang/wgsl/sem/builtin_fn.cc
diff --git a/src/tint/lang/wgsl/sem/BUILD.gn b/src/tint/lang/wgsl/sem/BUILD.gn
index e6b2b06..4131c9a 100644
--- a/src/tint/lang/wgsl/sem/BUILD.gn
+++ b/src/tint/lang/wgsl/sem/BUILD.gn
@@ -56,6 +56,8 @@
"block_statement.h",
"break_if_statement.cc",
"break_if_statement.h",
+ "builtin_attribute.cc",
+ "builtin_attribute.h",
"builtin_enum_expression.cc",
"builtin_enum_expression.h",
"builtin_fn.cc",
diff --git a/src/tint/lang/wgsl/sem/builtin_attribute.cc b/src/tint/lang/wgsl/sem/builtin_attribute.cc
new file mode 100644
index 0000000..d6e3784
--- /dev/null
+++ b/src/tint/lang/wgsl/sem/builtin_attribute.cc
@@ -0,0 +1,48 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/wgsl/sem/builtin_attribute.h"
+
+TINT_INSTANTIATE_TYPEINFO(tint::sem::BuiltinAttribute);
+
+namespace tint::sem {
+
+BuiltinAttribute::BuiltinAttribute(const ast::BuiltinAttribute* declaration,
+ const core::BuiltinValue value)
+ : Base(), declaration_(declaration), value_(value) {}
+
+BuiltinAttribute::~BuiltinAttribute() = default;
+
+const ast::BuiltinAttribute* BuiltinAttribute::Declaration() const {
+ return declaration_;
+}
+
+core::BuiltinValue BuiltinAttribute::Value() const {
+ return value_;
+}
+
+} // namespace tint::sem
diff --git a/src/tint/lang/wgsl/sem/builtin_attribute.h b/src/tint/lang/wgsl/sem/builtin_attribute.h
new file mode 100644
index 0000000..4906cf8
--- /dev/null
+++ b/src/tint/lang/wgsl/sem/builtin_attribute.h
@@ -0,0 +1,62 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_TINT_LANG_WGSL_SEM_BUILTIN_ATTRIBUTE_H_
+#define SRC_TINT_LANG_WGSL_SEM_BUILTIN_ATTRIBUTE_H_
+
+#include "src/tint/lang/core/builtin_value.h"
+#include "src/tint/lang/wgsl/ast/builtin_attribute.h"
+#include "src/tint/lang/wgsl/sem/expression.h"
+
+namespace tint::sem {
+
+/// BuiltinAttribute holds the semantic information for ast nodes that resolve to a
+/// builtin value.
+class BuiltinAttribute : public Castable<BuiltinAttribute, Node> {
+ public:
+ /// Constructor
+ /// @param declaration the AST node
+ /// @param value the builtin value
+ BuiltinAttribute(const ast::BuiltinAttribute* declaration, core::BuiltinValue value);
+
+ /// Destructor
+ ~BuiltinAttribute() override;
+
+ /// @returns the case selector declaration
+ const ast::BuiltinAttribute* Declaration() const;
+
+ /// @return the enumerator value
+ core::BuiltinValue Value() const;
+
+ private:
+ const ast::BuiltinAttribute* declaration_;
+ const core::BuiltinValue value_;
+};
+
+} // namespace tint::sem
+
+#endif // SRC_TINT_LANG_WGSL_SEM_BUILTIN_ATTRIBUTE_H_
diff --git a/src/tint/lang/wgsl/sem/type_mappings.h b/src/tint/lang/wgsl/sem/type_mappings.h
index ec3f852..9bb8f59 100644
--- a/src/tint/lang/wgsl/sem/type_mappings.h
+++ b/src/tint/lang/wgsl/sem/type_mappings.h
@@ -30,7 +30,7 @@
#include <type_traits>
-#include "src/tint/lang/wgsl/sem/builtin_enum_expression.h"
+#include "src/tint/lang/wgsl/sem/builtin_attribute.h"
// Forward declarations
namespace tint {
@@ -95,7 +95,7 @@
struct TypeMappings {
//! @cond Doxygen_Suppress
BlockStatement* operator()(ast::BlockStatement*);
- BuiltinEnumExpression<core::BuiltinValue>* operator()(ast::BuiltinAttribute*);
+ BuiltinAttribute* operator()(ast::BuiltinAttribute*);
CastableBase* operator()(ast::Node*);
Expression* operator()(ast::Expression*);
ForLoopStatement* operator()(ast::ForLoopStatement*);
diff --git a/src/tint/lang/wgsl/writer/ast_printer/ast_printer.cc b/src/tint/lang/wgsl/writer/ast_printer/ast_printer.cc
index 62f9e82..0f3f77e 100644
--- a/src/tint/lang/wgsl/writer/ast_printer/ast_printer.cc
+++ b/src/tint/lang/wgsl/writer/ast_printer/ast_printer.cc
@@ -38,6 +38,7 @@
#include "src/tint/lang/wgsl/ast/bool_literal_expression.h"
#include "src/tint/lang/wgsl/ast/break_if_statement.h"
#include "src/tint/lang/wgsl/ast/break_statement.h"
+#include "src/tint/lang/wgsl/ast/builtin_value_name.h"
#include "src/tint/lang/wgsl/ast/call_expression.h"
#include "src/tint/lang/wgsl/ast/call_statement.h"
#include "src/tint/lang/wgsl/ast/color_attribute.h"
@@ -508,7 +509,7 @@
},
[&](const ast::BuiltinAttribute* builtin) {
out << "builtin(";
- EmitExpression(out, builtin->builtin);
+ out << builtin->builtin->String();
out << ")";
},
[&](const ast::DiagnosticAttribute* diagnostic) {
diff --git a/src/tint/lang/wgsl/writer/syntax_tree_printer/syntax_tree_printer.cc b/src/tint/lang/wgsl/writer/syntax_tree_printer/syntax_tree_printer.cc
index 299dd88..f62759b 100644
--- a/src/tint/lang/wgsl/writer/syntax_tree_printer/syntax_tree_printer.cc
+++ b/src/tint/lang/wgsl/writer/syntax_tree_printer/syntax_tree_printer.cc
@@ -35,6 +35,7 @@
#include "src/tint/lang/wgsl/ast/bool_literal_expression.h"
#include "src/tint/lang/wgsl/ast/break_if_statement.h"
#include "src/tint/lang/wgsl/ast/break_statement.h"
+#include "src/tint/lang/wgsl/ast/builtin_value_name.h"
#include "src/tint/lang/wgsl/ast/call_expression.h"
#include "src/tint/lang/wgsl/ast/call_statement.h"
#include "src/tint/lang/wgsl/ast/compound_assignment_statement.h"
@@ -552,12 +553,7 @@
Line() << "]";
},
[&](const ast::BuiltinAttribute* builtin) {
- Line() << "BuiltinAttribute [";
- {
- ScopedIndent ba(this);
- EmitExpression(builtin->builtin);
- }
- Line() << "]";
+ Line() << "BuiltinAttribute [" << builtin->builtin->String() << "]";
},
[&](const ast::DiagnosticAttribute* diagnostic) {
EmitDiagnosticControl(diagnostic->control);
diff --git a/webgpu-cts/expectations.txt b/webgpu-cts/expectations.txt
index ebf3079..bf79c2c 100644
--- a/webgpu-cts/expectations.txt
+++ b/webgpu-cts/expectations.txt
@@ -1602,7 +1602,6 @@
crbug.com/42251274 [ nvidia-0x2184 ubuntu ] webgpu:shader,validation,expression,binary,div_rem:scalar_vector_out_of_range:* [ Failure ]
crbug.com/42251274 [ nvidia-0x2184 webgpu-dxc-disabled win10 ] webgpu:shader,validation,expression,binary,div_rem:scalar_vector_out_of_range:* [ Failure ]
crbug.com/42251274 [ nvidia-0x2184 webgpu-dxc-enabled win10 ] webgpu:shader,validation,expression,binary,div_rem:scalar_vector_out_of_range:* [ Failure ]
-crbug.com/tint/2219 webgpu:shader,validation,decl,context_dependent_resolution:builtin_value_names:* [ Failure ]
crbug.com/tint/2219 webgpu:shader,validation,decl,context_dependent_resolution:interpolation_sampling_names:* [ Failure ]
crbug.com/tint/2219 webgpu:shader,validation,decl,context_dependent_resolution:interpolation_type_names:* [ Failure ]
crbug.com/tint/2225 webgpu:shader,execution,expression,unary,i32_conversion:abstract_float:* [ Failure ]