diff --git a/src/tint/ast/function.cc b/src/tint/ast/function.cc index 0f1d7e767e..5c0597a1a7 100644 --- a/src/tint/ast/function.cc +++ b/src/tint/ast/function.cc @@ -25,27 +25,30 @@ namespace tint::ast { Function::Function(ProgramID pid, NodeID nid, const Source& src, - Symbol sym, + const Identifier* n, utils::VectorRef parameters, const Type* return_ty, const BlockStatement* b, utils::VectorRef attrs, utils::VectorRef return_type_attrs) : Base(pid, nid, src), - symbol(sym), + name(n), params(std::move(parameters)), return_type(return_ty), body(b), attributes(std::move(attrs)), return_type_attributes(std::move(return_type_attrs)) { - TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, symbol, program_id); + TINT_ASSERT(AST, name); + if (name) { + TINT_ASSERT(AST, !name->Is()); + } + TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, name, program_id); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, return_ty, program_id); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, body, program_id); for (auto* param : params) { TINT_ASSERT(AST, tint::Is(param)); TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, param, program_id); } - TINT_ASSERT(AST, symbol.IsValid()); for (auto* attr : attributes) { TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, attr, program_id); } @@ -68,18 +71,18 @@ PipelineStage Function::PipelineStage() const { const Function* Function::Clone(CloneContext* ctx) const { // Clone arguments outside of create() call to have deterministic ordering auto src = ctx->Clone(source); - auto sym = ctx->Clone(symbol); + auto n = ctx->Clone(name); auto p = ctx->Clone(params); auto* ret = ctx->Clone(return_type); auto* b = ctx->Clone(body); auto attrs = ctx->Clone(attributes); auto ret_attrs = ctx->Clone(return_type_attributes); - return ctx->dst->create(src, sym, p, ret, b, attrs, ret_attrs); + return ctx->dst->create(src, n, p, ret, b, attrs, ret_attrs); } const Function* FunctionList::Find(Symbol sym) const { for (auto* func : *this) { - if (func->symbol == sym) { + if (func->name->symbol == sym) { return func; } } @@ -88,7 +91,7 @@ const Function* FunctionList::Find(Symbol sym) const { const Function* FunctionList::Find(Symbol sym, PipelineStage stage) const { for (auto* func : *this) { - if (func->symbol == sym && func->PipelineStage() == stage) { + if (func->name->symbol == sym && func->PipelineStage() == stage) { return func; } } diff --git a/src/tint/ast/function.h b/src/tint/ast/function.h index 61771bb4fb..fd39ba3974 100644 --- a/src/tint/ast/function.h +++ b/src/tint/ast/function.h @@ -29,6 +29,11 @@ #include "src/tint/ast/parameter.h" #include "src/tint/ast/pipeline_stage.h" +// Forward declarations +namespace tint::ast { +class Identifier; +} // namespace tint::ast + namespace tint::ast { /// A Function statement. @@ -38,7 +43,7 @@ class Function final : public Castable { /// @param pid the identifier of the program that owns this node /// @param nid the unique node identifier /// @param source the variable source - /// @param symbol the function symbol + /// @param name the function name /// @param params the function parameters /// @param return_type the return type /// @param body the function body @@ -47,7 +52,7 @@ class Function final : public Castable { Function(ProgramID pid, NodeID nid, const Source& source, - Symbol symbol, + const Identifier* name, utils::VectorRef params, const Type* return_type, const BlockStatement* body, @@ -70,8 +75,8 @@ class Function final : public Castable { /// @return the newly cloned node const Function* Clone(CloneContext* ctx) const override; - /// The function symbol - const Symbol symbol; + /// The function name + const Identifier* const name; /// The function params const utils::Vector params; diff --git a/src/tint/ast/function_test.cc b/src/tint/ast/function_test.cc index 1807bf3ef6..90afda1512 100644 --- a/src/tint/ast/function_test.cc +++ b/src/tint/ast/function_test.cc @@ -31,7 +31,7 @@ TEST_F(FunctionTest, Creation_i32ReturnType) { auto* var = params[0]; auto* f = Func("func", params, i32, utils::Empty); - EXPECT_EQ(f->symbol, Symbols().Get("func")); + EXPECT_EQ(f->name->symbol, Symbols().Get("func")); ASSERT_EQ(f->params.Length(), 1u); EXPECT_EQ(f->return_type, i32); EXPECT_EQ(f->params[0], var); @@ -42,7 +42,7 @@ TEST_F(FunctionTest, Creation_NoReturnType) { auto* var = params[0]; auto* f = Func("func", params, ty.void_(), utils::Empty); - EXPECT_EQ(f->symbol, Symbols().Get("func")); + EXPECT_EQ(f->name->symbol, Symbols().Get("func")); ASSERT_EQ(f->params.Length(), 1u); EXPECT_EQ(f->return_type, nullptr); EXPECT_EQ(f->params[0], var); @@ -53,7 +53,7 @@ TEST_F(FunctionTest, Creation_SingleParam) { auto* var = params[0]; auto* f = Func("func", params, ty.void_(), utils::Empty); - EXPECT_EQ(f->symbol, Symbols().Get("func")); + EXPECT_EQ(f->name->symbol, Symbols().Get("func")); ASSERT_EQ(f->params.Length(), 1u); EXPECT_EQ(f->return_type, nullptr); EXPECT_EQ(f->params[0], var); @@ -98,6 +98,24 @@ TEST_F(FunctionTest, Creation_WithSource) { EXPECT_EQ(src.range.begin.column, 2u); } +TEST_F(FunctionTest, Assert_NullName) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.Func(static_cast(nullptr), utils::Empty, b.ty.void_(), utils::Empty); + }, + "internal compiler error"); +} + +TEST_F(FunctionTest, Assert_TemplatedName) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.Func(b.Ident("a", "b"), utils::Empty, b.ty.void_(), utils::Empty); + }, + "internal compiler error"); +} + TEST_F(FunctionTest, Assert_InvalidName) { EXPECT_FATAL_FAILURE( { @@ -107,7 +125,7 @@ TEST_F(FunctionTest, Assert_InvalidName) { "internal compiler error"); } -TEST_F(FunctionTest, Assert_Null_Param) { +TEST_F(FunctionTest, Assert_NullParam) { using ParamList = utils::Vector; EXPECT_FATAL_FAILURE( { diff --git a/src/tint/ast/module_test.cc b/src/tint/ast/module_test.cc index b032561636..1a57fbb408 100644 --- a/src/tint/ast/module_test.cc +++ b/src/tint/ast/module_test.cc @@ -61,9 +61,9 @@ TEST_F(ModuleTest, Assert_DifferentProgramID_Function) { { ProgramBuilder b1; ProgramBuilder b2; - b1.AST().AddFunction(b2.create(b2.Symbols().Register("func"), - utils::Empty, b2.ty.f32(), b2.Block(), - utils::Empty, utils::Empty)); + b1.AST().AddFunction(b2.create(b2.Ident("func"), utils::Empty, + b2.ty.f32(), b2.Block(), utils::Empty, + utils::Empty)); }, "internal compiler error"); } diff --git a/src/tint/inspector/inspector.cc b/src/tint/inspector/inspector.cc index b07536d119..ca3f33a4bf 100644 --- a/src/tint/inspector/inspector.cc +++ b/src/tint/inspector/inspector.cc @@ -22,6 +22,7 @@ #include "src/tint/ast/extension.h" #include "src/tint/ast/float_literal_expression.h" #include "src/tint/ast/id_attribute.h" +#include "src/tint/ast/identifier.h" #include "src/tint/ast/int_literal_expression.h" #include "src/tint/ast/interpolate_attribute.h" #include "src/tint/ast/location_attribute.h" @@ -180,8 +181,8 @@ EntryPoint Inspector::GetEntryPoint(const tint::ast::Function* func) { auto* sem = program_->Sem().Get(func); - entry_point.name = program_->Symbols().NameFor(func->symbol); - entry_point.remapped_name = program_->Symbols().NameFor(func->symbol); + entry_point.name = program_->Symbols().NameFor(func->name->symbol); + entry_point.remapped_name = program_->Symbols().NameFor(func->name->symbol); switch (func->PipelineStage()) { case ast::PipelineStage::kCompute: { @@ -877,7 +878,7 @@ void Inspector::GenerateSamplerTargets() { for (auto* entry_point : entry_points) { const auto& ep_name = program_->Symbols().NameFor( - entry_point->Declaration()->symbol); + entry_point->Declaration()->name->symbol); (*sampler_targets_)[ep_name].Add( {sampler_binding_point, texture_binding_point}); } diff --git a/src/tint/ir/builder_impl.cc b/src/tint/ir/builder_impl.cc index cde71e2e0e..cbc71658e1 100644 --- a/src/tint/ir/builder_impl.cc +++ b/src/tint/ir/builder_impl.cc @@ -27,6 +27,7 @@ #include "src/tint/ast/for_loop_statement.h" #include "src/tint/ast/function.h" #include "src/tint/ast/id_attribute.h" +#include "src/tint/ast/identifier.h" #include "src/tint/ast/if_statement.h" #include "src/tint/ast/int_literal_expression.h" #include "src/tint/ast/literal_expression.h" @@ -178,7 +179,7 @@ bool BuilderImpl::EmitFunction(const ast::Function* ast_func) { TINT_ASSERT(IR, flow_stack.IsEmpty()); auto* ir_func = builder.CreateFunction(); - ir_func->name = CloneSymbol(ast_func->symbol); + ir_func->name = CloneSymbol(ast_func->name->symbol); current_function_ = ir_func; builder.ir.functions.Push(ir_func); diff --git a/src/tint/program_builder.h b/src/tint/program_builder.h index 5455609c5d..723a61869f 100644 --- a/src/tint/program_builder.h +++ b/src/tint/program_builder.h @@ -2510,7 +2510,7 @@ class ProgramBuilder { block = Block(std::forward(body)); } auto* func = - create(source, Sym(std::forward(name)), std::move(params), type, + create(source, Ident(std::forward(name)), std::move(params), type, block, std::move(attributes), std::move(return_type_attributes)); AST().AddFunction(func); return func; diff --git a/src/tint/program_builder_test.cc b/src/tint/program_builder_test.cc index 24e7344a98..02e3ba29b6 100644 --- a/src/tint/program_builder_test.cc +++ b/src/tint/program_builder_test.cc @@ -60,7 +60,7 @@ TEST_F(ProgramBuilderTest, WrapDoesntAffectInner) { ASSERT_EQ(inner.AST().Functions().Length(), 1u); ASSERT_EQ(outer.AST().Functions().Length(), 2u); EXPECT_EQ(inner.AST().Functions()[0], outer.AST().Functions()[0]); - EXPECT_EQ(outer.AST().Functions()[1]->symbol, outer.Symbols().Get("b")); + EXPECT_EQ(outer.AST().Functions()[1]->name->symbol, outer.Symbols().Get("b")); EXPECT_EQ(inner.Symbols().Get("a"), outer.Symbols().Get("a")); EXPECT_TRUE(inner.Symbols().Get("a").IsValid()); EXPECT_TRUE(outer.Symbols().Get("a").IsValid()); diff --git a/src/tint/reader/spirv/function.cc b/src/tint/reader/spirv/function.cc index 224888e678..1a61645a97 100644 --- a/src/tint/reader/spirv/function.cc +++ b/src/tint/reader/spirv/function.cc @@ -5787,7 +5787,7 @@ bool FunctionEmitter::EmitAtomicOp(const spvtools::opt::Instruction& inst) { }); // Emit call to stub, will be replaced with call to atomic builtin by transform::SpirvAtomic - auto* call = builder_.Call(Source{}, stub->symbol, std::move(exprs)); + auto* call = builder_.Call(Source{}, stub->name->symbol, std::move(exprs)); if (inst.type_id() != 0) { auto* result_type = parser_impl_.ConvertType(inst.type_id()); TypedExpression expr{result_type, call}; diff --git a/src/tint/reader/wgsl/parser_impl_function_decl_test.cc b/src/tint/reader/wgsl/parser_impl_function_decl_test.cc index 8fc0a3379c..9d249f588b 100644 --- a/src/tint/reader/wgsl/parser_impl_function_decl_test.cc +++ b/src/tint/reader/wgsl/parser_impl_function_decl_test.cc @@ -31,7 +31,7 @@ TEST_F(ParserImplTest, FunctionDecl) { EXPECT_TRUE(f.matched); ASSERT_NE(f.value, nullptr); - EXPECT_EQ(f->symbol, p->builder().Symbols().Get("main")); + EXPECT_EQ(f->name->symbol, p->builder().Symbols().Get("main")); EXPECT_EQ(f->return_type, nullptr); ASSERT_EQ(f->params.Length(), 2u); @@ -74,7 +74,7 @@ TEST_F(ParserImplTest, FunctionDecl_Unicode) { EXPECT_TRUE(f.matched); ASSERT_NE(f.value, nullptr); - EXPECT_EQ(f->symbol, p->builder().Symbols().Get(function_ident)); + EXPECT_EQ(f->name->symbol, p->builder().Symbols().Get(function_ident)); EXPECT_EQ(f->return_type, nullptr); ASSERT_EQ(f->params.Length(), 2u); @@ -100,7 +100,7 @@ TEST_F(ParserImplTest, FunctionDecl_AttributeList) { EXPECT_TRUE(f.matched); ASSERT_NE(f.value, nullptr); - EXPECT_EQ(f->symbol, p->builder().Symbols().Get("main")); + EXPECT_EQ(f->name->symbol, p->builder().Symbols().Get("main")); EXPECT_EQ(f->return_type, nullptr); ASSERT_EQ(f->params.Length(), 0u); @@ -144,7 +144,7 @@ fn main() { return; })"); EXPECT_TRUE(f.matched); ASSERT_NE(f.value, nullptr); - EXPECT_EQ(f->symbol, p->builder().Symbols().Get("main")); + EXPECT_EQ(f->name->symbol, p->builder().Symbols().Get("main")); EXPECT_EQ(f->return_type, nullptr); ASSERT_EQ(f->params.Length(), 0u); @@ -192,7 +192,7 @@ fn main() { return; })"); EXPECT_TRUE(f.matched); ASSERT_NE(f.value, nullptr); - EXPECT_EQ(f->symbol, p->builder().Symbols().Get("main")); + EXPECT_EQ(f->name->symbol, p->builder().Symbols().Get("main")); EXPECT_EQ(f->return_type, nullptr); ASSERT_EQ(f->params.Length(), 0u); @@ -237,7 +237,7 @@ TEST_F(ParserImplTest, FunctionDecl_ReturnTypeAttributeList) { EXPECT_TRUE(f.matched); ASSERT_NE(f.value, nullptr); - EXPECT_EQ(f->symbol, p->builder().Symbols().Get("main")); + EXPECT_EQ(f->name->symbol, p->builder().Symbols().Get("main")); ASSERT_NE(f->return_type, nullptr); EXPECT_TRUE(f->return_type->Is()); ASSERT_EQ(f->params.Length(), 0u); diff --git a/src/tint/reader/wgsl/parser_impl_global_decl_test.cc b/src/tint/reader/wgsl/parser_impl_global_decl_test.cc index 435c4ef974..c77ba014c3 100644 --- a/src/tint/reader/wgsl/parser_impl_global_decl_test.cc +++ b/src/tint/reader/wgsl/parser_impl_global_decl_test.cc @@ -192,7 +192,7 @@ TEST_F(ParserImplTest, GlobalDecl_Function) { auto program = p->program(); ASSERT_EQ(program.AST().Functions().Length(), 1u); - EXPECT_EQ(program.Symbols().NameFor(program.AST().Functions()[0]->symbol), "main"); + EXPECT_EQ(program.Symbols().NameFor(program.AST().Functions()[0]->name->symbol), "main"); } TEST_F(ParserImplTest, GlobalDecl_Function_WithAttribute) { @@ -202,7 +202,7 @@ TEST_F(ParserImplTest, GlobalDecl_Function_WithAttribute) { auto program = p->program(); ASSERT_EQ(program.AST().Functions().Length(), 1u); - EXPECT_EQ(program.Symbols().NameFor(program.AST().Functions()[0]->symbol), "main"); + EXPECT_EQ(program.Symbols().NameFor(program.AST().Functions()[0]->name->symbol), "main"); } TEST_F(ParserImplTest, GlobalDecl_Function_Invalid) { diff --git a/src/tint/resolver/dependency_graph.cc b/src/tint/resolver/dependency_graph.cc index 7326f818dc..c07eb0d6e4 100644 --- a/src/tint/resolver/dependency_graph.cc +++ b/src/tint/resolver/dependency_graph.cc @@ -195,7 +195,7 @@ class DependencyScanner { TraverseType(alias->type); }, [&](const ast::Function* func) { - Declare(func->symbol, func); + Declare(func->name->symbol, func); TraverseFunction(func); }, [&](const ast::Variable* var) { @@ -559,7 +559,7 @@ struct DependencyAnalysis { return Switch( node, // [&](const ast::TypeDecl* td) { return td->name; }, - [&](const ast::Function* func) { return func->symbol; }, + [&](const ast::Function* func) { return func->name->symbol; }, [&](const ast::Variable* var) { return var->symbol; }, [&](const ast::DiagnosticDirective*) { return Symbol(); }, [&](const ast::Enable*) { return Symbol(); }, diff --git a/src/tint/resolver/resolver.cc b/src/tint/resolver/resolver.cc index 947499bb46..e268107f71 100644 --- a/src/tint/resolver/resolver.cc +++ b/src/tint/resolver/resolver.cc @@ -350,7 +350,7 @@ type::Type* Resolver::Type(const ast::Type* ty) { return nullptr; }, [&](sem::Function* func) { - auto name = builder_->Symbols().NameFor(func->Declaration()->symbol); + auto name = builder_->Symbols().NameFor(func->Declaration()->name->symbol); AddError("cannot use function '" + name + "' as type", ty->source); AddNote("'" + name + "' declared here", func->Declaration()->source); return nullptr; @@ -993,6 +993,8 @@ sem::Statement* Resolver::ConstAssert(const ast::ConstAssert* assertion) { } sem::Function* Resolver::Function(const ast::Function* decl) { + Mark(decl->name); + uint32_t parameter_index = 0; utils::Hashmap parameter_names; utils::Vector parameters; @@ -1080,9 +1082,9 @@ sem::Function* Resolver::Function(const ast::Function* decl) { if (auto* str = return_type->As()) { if (!ApplyAddressSpaceUsageToType(type::AddressSpace::kNone, str, decl->source)) { - AddNote( - "while instantiating return type for " + builder_->Symbols().NameFor(decl->symbol), - decl->source); + AddNote("while instantiating return type for " + + builder_->Symbols().NameFor(decl->name->symbol), + decl->source); return nullptr; } @@ -1669,7 +1671,7 @@ bool Resolver::AliasAnalysis(const sem::Call* call) { break; case Alias::ModuleScope: { auto* func = var.expr->Stmt()->Function(); - auto func_name = builder_->Symbols().NameFor(func->Declaration()->symbol); + auto func_name = builder_->Symbols().NameFor(func->Declaration()->name->symbol); AddNote( "aliases with module-scope variable " + var.access + " in '" + func_name + "'", var.expr->Declaration()->source); diff --git a/src/tint/resolver/resolver_test.cc b/src/tint/resolver/resolver_test.cc index 21425da15e..1433a6eb85 100644 --- a/src/tint/resolver/resolver_test.cc +++ b/src/tint/resolver/resolver_test.cc @@ -2000,17 +2000,17 @@ TEST_F(ResolverTest, Function_EntryPoints_StageAttribute) { const auto& b_eps = func_b_sem->AncestorEntryPoints(); ASSERT_EQ(2u, b_eps.size()); - EXPECT_EQ(Symbols().Register("ep_1"), b_eps[0]->Declaration()->symbol); - EXPECT_EQ(Symbols().Register("ep_2"), b_eps[1]->Declaration()->symbol); + EXPECT_EQ(Symbols().Register("ep_1"), b_eps[0]->Declaration()->name->symbol); + EXPECT_EQ(Symbols().Register("ep_2"), b_eps[1]->Declaration()->name->symbol); const auto& a_eps = func_a_sem->AncestorEntryPoints(); ASSERT_EQ(1u, a_eps.size()); - EXPECT_EQ(Symbols().Register("ep_1"), a_eps[0]->Declaration()->symbol); + EXPECT_EQ(Symbols().Register("ep_1"), a_eps[0]->Declaration()->name->symbol); const auto& c_eps = func_c_sem->AncestorEntryPoints(); ASSERT_EQ(2u, c_eps.size()); - EXPECT_EQ(Symbols().Register("ep_1"), c_eps[0]->Declaration()->symbol); - EXPECT_EQ(Symbols().Register("ep_2"), c_eps[1]->Declaration()->symbol); + EXPECT_EQ(Symbols().Register("ep_1"), c_eps[0]->Declaration()->name->symbol); + EXPECT_EQ(Symbols().Register("ep_2"), c_eps[1]->Declaration()->name->symbol); EXPECT_TRUE(ep_1_sem->AncestorEntryPoints().empty()); EXPECT_TRUE(ep_2_sem->AncestorEntryPoints().empty()); diff --git a/src/tint/resolver/uniformity.cc b/src/tint/resolver/uniformity.cc index 8fa6d64182..bae85a4fff 100644 --- a/src/tint/resolver/uniformity.cc +++ b/src/tint/resolver/uniformity.cc @@ -171,7 +171,7 @@ struct FunctionInfo { /// @param func the AST function /// @param builder the program builder FunctionInfo(const ast::Function* func, const ProgramBuilder* builder) { - name = builder->Symbols().NameFor(func->symbol); + name = builder->Symbols().NameFor(func->name->symbol); callsite_tag = {CallSiteTag::CallSiteNoRestriction}; function_tag = NoRestriction; @@ -1769,7 +1769,7 @@ class UniformityGraph { if (auto* param = var->As()) { auto* func = param->Owner()->As(); ss << param_type(param) << "'" << NameFor(ident->identifier) << "' of '" - << NameFor(func->Declaration()) << "' may be non-uniform"; + << NameFor(func->Declaration()->name) << "' may be non-uniform"; } else { ss << "reading from " << var_type(var) << "'" << NameFor(ident->identifier) << "' may result in a non-uniform value"; diff --git a/src/tint/resolver/validator.cc b/src/tint/resolver/validator.cc index 02b8f39b1c..29218af7a1 100644 --- a/src/tint/resolver/validator.cc +++ b/src/tint/resolver/validator.cc @@ -1037,7 +1037,7 @@ bool Validator::Function(const sem::Function* func, ast::PipelineStage stage) co } else if (TINT_UNLIKELY(IsValidationEnabled( decl->attributes, ast::DisabledValidation::kFunctionHasNoBody))) { TINT_ICE(Resolver, diagnostics_) - << "Function " << symbols_.NameFor(decl->symbol) << " has no body"; + << "Function " << symbols_.NameFor(decl->name->symbol) << " has no body"; } for (auto* attr : decl->return_type_attributes) { @@ -1069,7 +1069,7 @@ bool Validator::Function(const sem::Function* func, ast::PipelineStage stage) co // a function behavior is always one of {}, or {Next}. if (TINT_UNLIKELY(func->Behaviors() != sem::Behaviors{} && func->Behaviors() != sem::Behavior::kNext)) { - auto name = symbols_.NameFor(decl->symbol); + auto name = symbols_.NameFor(decl->name->symbol); TINT_ICE(Resolver, diagnostics_) << "function '" << name << "' behaviors are: " << func->Behaviors(); } @@ -1236,30 +1236,30 @@ bool Validator::EntryPoint(const sem::Function* func, ast::PipelineStage stage) }; // Outer lambda for validating the entry point attributes for a type. - auto validate_entry_point_attributes = [&](utils::VectorRef attrs, - const type::Type* ty, Source source, - ParamOrRetType param_or_ret, - std::optional location) { - if (!validate_entry_point_attributes_inner(attrs, ty, source, param_or_ret, - /*is_struct_member*/ false, location)) { - return false; - } + auto validate_entry_point_attributes = + [&](utils::VectorRef attrs, const type::Type* ty, Source source, + ParamOrRetType param_or_ret, std::optional location) { + if (!validate_entry_point_attributes_inner(attrs, ty, source, param_or_ret, + /*is_struct_member*/ false, location)) { + return false; + } - if (auto* str = ty->As()) { - for (auto* member : str->Members()) { - if (!validate_entry_point_attributes_inner( - member->Declaration()->attributes, member->Type(), member->Source(), - param_or_ret, - /*is_struct_member*/ true, member->Location())) { - AddNote("while analyzing entry point '" + symbols_.NameFor(decl->symbol) + "'", - decl->source); - return false; + if (auto* str = ty->As()) { + for (auto* member : str->Members()) { + if (!validate_entry_point_attributes_inner( + member->Declaration()->attributes, member->Type(), member->Source(), + param_or_ret, + /*is_struct_member*/ true, member->Location())) { + AddNote("while analyzing entry point '" + + symbols_.NameFor(decl->name->symbol) + "'", + decl->source); + return false; + } } } - } - return true; - }; + return true; + }; for (auto* param : func->Parameters()) { auto* param_decl = param->Declaration(); @@ -1329,7 +1329,7 @@ bool Validator::EntryPoint(const sem::Function* func, ast::PipelineStage stage) // Bindings must not alias within a shader stage: two different variables in the // resource interface of a given shader must not have the same group and binding values, // when considered as a pair of values. - auto func_name = symbols_.NameFor(decl->symbol); + auto func_name = symbols_.NameFor(decl->name->symbol); AddError( "entry point '" + func_name + "' references multiple variables that use the same resource binding @group(" + @@ -1875,11 +1875,12 @@ bool Validator::PipelineStages(utils::VectorRef entry_points) co auto backtrace = [&](const sem::Function* func, const sem::Function* entry_point) { if (func != entry_point) { TraverseCallChain(diagnostics_, entry_point, func, [&](const sem::Function* f) { - AddNote("called by function '" + symbols_.NameFor(f->Declaration()->symbol) + "'", - f->Declaration()->source); + AddNote( + "called by function '" + symbols_.NameFor(f->Declaration()->name->symbol) + "'", + f->Declaration()->source); }); AddNote("called by entry point '" + - symbols_.NameFor(entry_point->Declaration()->symbol) + "'", + symbols_.NameFor(entry_point->Declaration()->name->symbol) + "'", entry_point->Declaration()->source); } }; @@ -1986,7 +1987,7 @@ bool Validator::PushConstants(utils::VectorRef entry_points) con continue; } - AddError("entry point '" + symbols_.NameFor(ep->Declaration()->symbol) + + AddError("entry point '" + symbols_.NameFor(ep->Declaration()->name->symbol) + "' uses two different 'push_constant' variables.", ep->Declaration()->source); AddNote("first 'push_constant' variable declaration is here", @@ -1994,11 +1995,11 @@ bool Validator::PushConstants(utils::VectorRef entry_points) con if (func != ep) { TraverseCallChain(diagnostics_, ep, func, [&](const sem::Function* f) { AddNote("called by function '" + - symbols_.NameFor(f->Declaration()->symbol) + "'", + symbols_.NameFor(f->Declaration()->name->symbol) + "'", f->Declaration()->source); }); AddNote("called by entry point '" + - symbols_.NameFor(ep->Declaration()->symbol) + "'", + symbols_.NameFor(ep->Declaration()->name->symbol) + "'", ep->Declaration()->source); } AddNote("second 'push_constant' variable declaration is here", @@ -2007,11 +2008,11 @@ bool Validator::PushConstants(utils::VectorRef entry_points) con TraverseCallChain( diagnostics_, ep, push_constant_func, [&](const sem::Function* f) { AddNote("called by function '" + - symbols_.NameFor(f->Declaration()->symbol) + "'", + symbols_.NameFor(f->Declaration()->name->symbol) + "'", f->Declaration()->source); }); AddNote("called by entry point '" + - symbols_.NameFor(ep->Declaration()->symbol) + "'", + symbols_.NameFor(ep->Declaration()->name->symbol) + "'", ep->Declaration()->source); } return false; diff --git a/src/tint/sem/function.cc b/src/tint/sem/function.cc index 3ce22a18d0..e7bf889ea2 100644 --- a/src/tint/sem/function.cc +++ b/src/tint/sem/function.cc @@ -15,6 +15,7 @@ #include "src/tint/sem/function.h" #include "src/tint/ast/function.h" +#include "src/tint/ast/identifier.h" #include "src/tint/sem/variable.h" #include "src/tint/type/depth_texture.h" #include "src/tint/type/external_texture.h" @@ -141,7 +142,7 @@ Function::VariableBindings Function::TransitivelyReferencedVariablesOfType( bool Function::HasAncestorEntryPoint(Symbol symbol) const { for (const auto* point : ancestor_entry_points_) { - if (point->Declaration()->symbol == symbol) { + if (point->Declaration()->name->symbol == symbol) { return true; } } diff --git a/src/tint/transform/calculate_array_length.cc b/src/tint/transform/calculate_array_length.cc index 7bdc9cdb63..de363159a7 100644 --- a/src/tint/transform/calculate_array_length.cc +++ b/src/tint/transform/calculate_array_length.cc @@ -107,7 +107,7 @@ Transform::ApplyResult CalculateArrayLength::Apply(const Program* src, auto* type = CreateASTTypeFor(ctx, buffer_type); auto* disable_validation = b.Disable(ast::DisabledValidation::kFunctionParameter); b.AST().AddFunction(b.create( - name, + b.Ident(name), utils::Vector{ b.Param("buffer", b.ty.pointer(type, buffer_type->AddressSpace(), buffer_type->Access()), diff --git a/src/tint/transform/canonicalize_entry_point_io.cc b/src/tint/transform/canonicalize_entry_point_io.cc index 4a223f63e2..9a9d91fc40 100644 --- a/src/tint/transform/canonicalize_entry_point_io.cc +++ b/src/tint/transform/canonicalize_entry_point_io.cc @@ -542,24 +542,25 @@ struct CanonicalizeEntryPointIO::State { if (cfg.shader_style == ShaderStyle::kGlsl) { // In GLSL, clone the original entry point name, as the wrapper will be // called "main". - inner_name = ctx.Clone(func_ast->symbol); + inner_name = ctx.Clone(func_ast->name->symbol); } else { // Add a suffix to the function name, as the wrapper function will take // the original entry point name. - auto ep_name = ctx.src->Symbols().NameFor(func_ast->symbol); + auto ep_name = ctx.src->Symbols().NameFor(func_ast->name->symbol); inner_name = ctx.dst->Symbols().New(ep_name + "_inner"); } // Clone everything, dropping the function and return type attributes. // The parameter attributes will have already been stripped during // processing. - auto* inner_function = ctx.dst->create( - inner_name, ctx.Clone(func_ast->params), ctx.Clone(func_ast->return_type), - ctx.Clone(func_ast->body), utils::Empty, utils::Empty); + auto* inner_function = + ctx.dst->create(ctx.dst->Ident(inner_name), ctx.Clone(func_ast->params), + ctx.Clone(func_ast->return_type), + ctx.Clone(func_ast->body), utils::Empty, utils::Empty); ctx.Replace(func_ast, inner_function); // Call the function. - return ctx.dst->Call(inner_function->symbol, inner_call_parameters); + return ctx.dst->Call(inner_function->name->symbol, inner_call_parameters); } /// Process the entry point function. @@ -656,12 +657,12 @@ struct CanonicalizeEntryPointIO::State { if (cfg.shader_style == ShaderStyle::kGlsl) { name = ctx.dst->Symbols().New("main"); } else { - name = ctx.Clone(func_ast->symbol); + name = ctx.Clone(func_ast->name->symbol); } auto* wrapper_func = ctx.dst->create( - name, wrapper_ep_parameters, wrapper_ret_type(), ctx.dst->Block(wrapper_body), - ctx.Clone(func_ast->attributes), utils::Empty); + ctx.dst->Ident(name), wrapper_ep_parameters, wrapper_ret_type(), + ctx.dst->Block(wrapper_body), ctx.Clone(func_ast->attributes), utils::Empty); ctx.InsertAfter(ctx.src->AST().GlobalDeclarations(), func_ast, wrapper_func); } diff --git a/src/tint/transform/combine_samplers.cc b/src/tint/transform/combine_samplers.cc index 7a39d6e35d..8703c90dce 100644 --- a/src/tint/transform/combine_samplers.cc +++ b/src/tint/transform/combine_samplers.cc @@ -214,12 +214,12 @@ struct CombineSamplers::State { } // Create a new function signature that differs only in the parameter // list. - auto symbol = ctx.Clone(ast_fn->symbol); + auto name = ctx.Clone(ast_fn->name); auto* return_type = ctx.Clone(ast_fn->return_type); auto* body = ctx.Clone(ast_fn->body); auto attributes = ctx.Clone(ast_fn->attributes); auto return_type_attributes = ctx.Clone(ast_fn->return_type_attributes); - return ctx.dst->create(symbol, params, return_type, body, + return ctx.dst->create(name, params, return_type, body, std::move(attributes), std::move(return_type_attributes)); } diff --git a/src/tint/transform/decompose_memory_access.cc b/src/tint/transform/decompose_memory_access.cc index ef0ce52ee2..fc2003c94c 100644 --- a/src/tint/transform/decompose_memory_access.cc +++ b/src/tint/transform/decompose_memory_access.cc @@ -483,7 +483,7 @@ struct DecomposeMemoryAccess::State { if (auto* intrinsic = IntrinsicLoadFor(ctx.dst, address_space, el_ty)) { auto* el_ast_ty = CreateASTTypeFor(ctx, el_ty); auto* func = b.create( - name, params, el_ast_ty, nullptr, + b.Ident(name), params, el_ast_ty, nullptr, utils::Vector{ intrinsic, b.Disable(ast::DisabledValidation::kFunctionHasNoBody), @@ -582,7 +582,7 @@ struct DecomposeMemoryAccess::State { if (auto* intrinsic = IntrinsicStoreFor(ctx.dst, address_space, el_ty)) { auto* func = b.create( - name, params, b.ty.void_(), nullptr, + b.Ident(name), params, b.ty.void_(), nullptr, utils::Vector{ intrinsic, b.Disable(ast::DisabledValidation::kFunctionHasNoBody), @@ -728,7 +728,8 @@ struct DecomposeMemoryAccess::State { } auto* func = b.create( - b.Symbols().New(std::string{"tint_"} + intrinsic->str()), params, ret_ty, nullptr, + b.Ident(b.Symbols().New(std::string{"tint_"} + intrinsic->str())), params, ret_ty, + nullptr, utils::Vector{ atomic, b.Disable(ast::DisabledValidation::kFunctionHasNoBody), @@ -736,7 +737,7 @@ struct DecomposeMemoryAccess::State { utils::Empty); b.AST().AddFunction(func); - return func->symbol; + return func->name->symbol; }); } }; diff --git a/src/tint/transform/direct_variable_access.cc b/src/tint/transform/direct_variable_access.cc index 84deea9901..3522086df6 100644 --- a/src/tint/transform/direct_variable_access.cc +++ b/src/tint/transform/direct_variable_access.cc @@ -600,7 +600,7 @@ struct DirectVariableAccess::State { // Function was not called. Create a single variant with an empty signature. FnVariant variant; - variant.name = ctx.Clone(fn->Declaration()->symbol); + variant.name = ctx.Clone(fn->Declaration()->name->symbol); variant.order = 0; // Unaltered comes first. fn_info->variants.Add(FnVariant::Signature{}, std::move(variant)); } @@ -679,7 +679,7 @@ struct DirectVariableAccess::State { if (target_signature.IsEmpty()) { // Call target does not require any argument changes. FnVariant variant; - variant.name = ctx.Clone(target->Declaration()->symbol); + variant.name = ctx.Clone(target->Declaration()->name->symbol); variant.order = 0; // Unaltered comes first. return variant; } @@ -688,7 +688,7 @@ struct DirectVariableAccess::State { // This is derived from the original function name and the pointer parameter // chains. std::stringstream ss; - ss << ctx.src->Symbols().NameFor(target->Declaration()->symbol); + ss << ctx.src->Symbols().NameFor(target->Declaration()->name->symbol); for (auto* param : target->Parameters()) { if (auto indices = target_signature.Find(param)) { ss << "_" << AccessShapeName(*indices); @@ -855,7 +855,7 @@ struct DirectVariableAccess::State { auto attrs = ctx.Clone(fn->Declaration()->attributes); auto ret_attrs = ctx.Clone(fn->Declaration()->return_type_attributes); pending_variant = - b.create(variant.name, std::move(params), ret_ty, body, + b.create(b.Ident(variant.name), std::move(params), ret_ty, body, std::move(attrs), std::move(ret_attrs)); } diff --git a/src/tint/transform/single_entry_point.cc b/src/tint/transform/single_entry_point.cc index 3fe3be2616..8a8daeba51 100644 --- a/src/tint/transform/single_entry_point.cc +++ b/src/tint/transform/single_entry_point.cc @@ -49,7 +49,7 @@ Transform::ApplyResult SingleEntryPoint::Apply(const Program* src, if (!f->IsEntryPoint()) { continue; } - if (src->Symbols().NameFor(f->symbol) == cfg->entry_point_name) { + if (src->Symbols().NameFor(f->name->symbol) == cfg->entry_point_name) { entry_point = f; break; } @@ -109,7 +109,7 @@ Transform::ApplyResult SingleEntryPoint::Apply(const Program* src, b.AST().AddGlobalVariable(ctx.Clone(c)); }, [&](const ast::Function* func) { - if (sem.Get(func)->HasAncestorEntryPoint(entry_point->symbol)) { + if (sem.Get(func)->HasAncestorEntryPoint(entry_point->name->symbol)) { b.AST().AddFunction(ctx.Clone(func)); } }, diff --git a/src/tint/transform/vertex_pulling.cc b/src/tint/transform/vertex_pulling.cc index c75b81cb6e..05668154ff 100644 --- a/src/tint/transform/vertex_pulling.cc +++ b/src/tint/transform/vertex_pulling.cc @@ -921,14 +921,14 @@ struct VertexPulling::State { } // Rewrite the function header with the new parameters. - auto func_sym = ctx.Clone(func->symbol); + auto func_sym = ctx.Clone(func->name->symbol); auto* ret_type = ctx.Clone(func->return_type); auto* body = ctx.Clone(func->body); auto attrs = ctx.Clone(func->attributes); auto ret_attrs = ctx.Clone(func->return_type_attributes); auto* new_func = - b.create(func->source, func_sym, new_function_parameters, ret_type, body, - std::move(attrs), std::move(ret_attrs)); + b.create(func->source, b.Ident(func_sym), new_function_parameters, + ret_type, body, std::move(attrs), std::move(ret_attrs)); ctx.Replace(func, new_func); } }; diff --git a/src/tint/writer/glsl/generator.cc b/src/tint/writer/glsl/generator.cc index 4b1e516655..bbe6380fd7 100644 --- a/src/tint/writer/glsl/generator.cc +++ b/src/tint/writer/glsl/generator.cc @@ -52,7 +52,7 @@ Result Generate(const Program* program, const Options& options, const std::strin // Collect the list of entry points in the sanitized program. for (auto* func : sanitized_result.program.AST().Functions()) { if (func->IsEntryPoint()) { - auto name = sanitized_result.program.Symbols().NameFor(func->symbol); + auto name = sanitized_result.program.Symbols().NameFor(func->name->symbol); result.entry_points.push_back({name, func->PipelineStage()}); } } diff --git a/src/tint/writer/glsl/generator_bench.cc b/src/tint/writer/glsl/generator_bench.cc index dddb303507..5a8e2779bb 100644 --- a/src/tint/writer/glsl/generator_bench.cc +++ b/src/tint/writer/glsl/generator_bench.cc @@ -14,6 +14,7 @@ #include +#include "src/tint/ast/identifier.h" #include "src/tint/ast/module.h" #include "src/tint/bench/benchmark.h" @@ -30,7 +31,7 @@ void GenerateGLSL(benchmark::State& state, std::string input_name) { std::vector entry_points; for (auto& fn : program.AST().Functions()) { if (fn->IsEntryPoint()) { - entry_points.emplace_back(program.Symbols().NameFor(fn->symbol)); + entry_points.emplace_back(program.Symbols().NameFor(fn->name->symbol)); } } diff --git a/src/tint/writer/glsl/generator_impl.cc b/src/tint/writer/glsl/generator_impl.cc index 381230cb83..597ac0270f 100644 --- a/src/tint/writer/glsl/generator_impl.cc +++ b/src/tint/writer/glsl/generator_impl.cc @@ -1882,7 +1882,7 @@ bool GeneratorImpl::EmitFunction(const ast::Function* func) { { auto out = line(); - auto name = builder_.Symbols().NameFor(func->symbol); + auto name = builder_.Symbols().NameFor(func->name->symbol); if (!EmitType(out, sem->ReturnType(), type::AddressSpace::kNone, type::Access::kReadWrite, "")) { return false; @@ -2261,7 +2261,8 @@ bool GeneratorImpl::EmitEntryPointFunction(const ast::Function* func) { { auto out = line(); if (!EmitTypeAndName(out, func_sem->ReturnType(), type::AddressSpace::kUndefined, - type::Access::kUndefined, builder_.Symbols().NameFor(func->symbol))) { + type::Access::kUndefined, + builder_.Symbols().NameFor(func->name->symbol))) { return false; } out << "("; diff --git a/src/tint/writer/hlsl/generator.cc b/src/tint/writer/hlsl/generator.cc index b514c2b641..788c5e84f8 100644 --- a/src/tint/writer/hlsl/generator.cc +++ b/src/tint/writer/hlsl/generator.cc @@ -51,7 +51,7 @@ Result Generate(const Program* program, const Options& options) { // Collect the list of entry points in the sanitized program. for (auto* func : sanitized_result.program.AST().Functions()) { if (func->IsEntryPoint()) { - auto name = sanitized_result.program.Symbols().NameFor(func->symbol); + auto name = sanitized_result.program.Symbols().NameFor(func->name->symbol); result.entry_points.push_back({name, func->PipelineStage()}); } } diff --git a/src/tint/writer/hlsl/generator_impl.cc b/src/tint/writer/hlsl/generator_impl.cc index 45fa593de6..21266c3ce3 100644 --- a/src/tint/writer/hlsl/generator_impl.cc +++ b/src/tint/writer/hlsl/generator_impl.cc @@ -923,7 +923,7 @@ bool GeneratorImpl::EmitFunctionCall(std::ostream& out, } } - out << builder_.Symbols().NameFor(func->Declaration()->symbol) << "("; + out << builder_.Symbols().NameFor(func->Declaration()->name->symbol) << "("; bool first = true; for (auto* arg : call->Arguments()) { @@ -1585,7 +1585,7 @@ bool GeneratorImpl::EmitStorageAtomicIntrinsic( const sem::Function* sem_func = builder_.Sem().Get(func); auto* result_ty = sem_func->ReturnType(); const auto& params = sem_func->Parameters(); - const auto name = builder_.Symbols().NameFor(func->symbol); + const auto name = builder_.Symbols().NameFor(func->name->symbol); auto& buf = *current_buffer_; auto rmw = [&](const char* hlsl) -> bool { @@ -2875,7 +2875,7 @@ bool GeneratorImpl::EmitFunction(const ast::Function* func) { { auto out = line(); - auto name = builder_.Symbols().NameFor(func->symbol); + auto name = builder_.Symbols().NameFor(func->name->symbol); // If the function returns an array, then we need to declare a typedef for // this. if (sem->ReturnType()->Is()) { @@ -3239,7 +3239,8 @@ bool GeneratorImpl::EmitEntryPointFunction(const ast::Function* func) { } if (!EmitTypeAndName(out, func_sem->ReturnType(), type::AddressSpace::kUndefined, - type::Access::kUndefined, builder_.Symbols().NameFor(func->symbol))) { + type::Access::kUndefined, + builder_.Symbols().NameFor(func->name->symbol))) { return false; } out << "("; diff --git a/src/tint/writer/msl/generator_impl.cc b/src/tint/writer/msl/generator_impl.cc index b1e98563f6..f41a4b32df 100644 --- a/src/tint/writer/msl/generator_impl.cc +++ b/src/tint/writer/msl/generator_impl.cc @@ -1873,7 +1873,7 @@ bool GeneratorImpl::EmitFunction(const ast::Function* func) { if (!EmitType(out, func_sem->ReturnType(), "")) { return false; } - out << " " << program_->Symbols().NameFor(func->symbol) << "("; + out << " " << program_->Symbols().NameFor(func->name->symbol) << "("; bool first = true; for (auto* v : func->params) { @@ -1975,7 +1975,7 @@ std::string GeneratorImpl::interpolation_to_attribute(ast::InterpolationType typ bool GeneratorImpl::EmitEntryPointFunction(const ast::Function* func) { auto* func_sem = builder_.Sem().Get(func); - auto func_name = program_->Symbols().NameFor(func->symbol); + auto func_name = program_->Symbols().NameFor(func->name->symbol); // Returns the binding index of a variable, requiring that the group // attribute have a value of zero. diff --git a/src/tint/writer/spirv/builder.cc b/src/tint/writer/spirv/builder.cc index c8f32bda34..805314716c 100644 --- a/src/tint/writer/spirv/builder.cc +++ b/src/tint/writer/spirv/builder.cc @@ -500,7 +500,7 @@ bool Builder::GenerateEntryPoint(const ast::Function* func, uint32_t id) { } OperandList operands = {Operand(stage), Operand(id), - Operand(builder_.Symbols().NameFor(func->symbol))}; + Operand(builder_.Symbols().NameFor(func->name->symbol))}; auto* func_sem = builder_.Sem().Get(func); for (const auto* var : func_sem->TransitivelyReferencedGlobals()) { @@ -602,7 +602,7 @@ bool Builder::GenerateFunction(const ast::Function* func_ast) { auto func_id = std::get(func_op); push_debug(spv::Op::OpName, - {Operand(func_id), Operand(builder_.Symbols().NameFor(func_ast->symbol))}); + {Operand(func_id), Operand(builder_.Symbols().NameFor(func_ast->name->symbol))}); auto ret_id = GenerateTypeIfNeeded(func->ReturnType()); if (ret_id == 0) { @@ -661,7 +661,7 @@ bool Builder::GenerateFunction(const ast::Function* func_ast) { } } - func_symbol_to_id_[func_ast->symbol] = func_id; + func_symbol_to_id_[func_ast->name->symbol] = func_id; return true; } diff --git a/src/tint/writer/wgsl/generator_impl.cc b/src/tint/writer/wgsl/generator_impl.cc index a4c1bb38ea..6a56a2166e 100644 --- a/src/tint/writer/wgsl/generator_impl.cc +++ b/src/tint/writer/wgsl/generator_impl.cc @@ -308,7 +308,7 @@ bool GeneratorImpl::EmitFunction(const ast::Function* func) { } { auto out = line(); - out << "fn " << program_->Symbols().NameFor(func->symbol) << "("; + out << "fn " << program_->Symbols().NameFor(func->name->symbol) << "("; bool first = true; for (auto* v : func->params) {