From c87b1fe8c96efd1661551d0e4e87c1ddf5fa0ec3 Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Thu, 2 Feb 2023 15:04:31 +0000 Subject: [PATCH] tint: Add ast::Identifier An identifier node that is not an expression. Will be used by: * CallExpression * DiagnosticControl * IdentifierExpression * MemberAccessorExpression * TypeName Bug: tint:1257 Bug: tint:1810 Change-Id: I1de719d8c570992fed08789c35ca6c4409789520 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/118340 Kokoro: Kokoro Commit-Queue: Ben Clayton Reviewed-by: Dan Sinclair Reviewed-by: James Price --- src/tint/BUILD.gn | 4 +++ src/tint/CMakeLists.txt | 3 ++ src/tint/ast/identifier.cc | 40 +++++++++++++++++++++ src/tint/ast/identifier.h | 47 +++++++++++++++++++++++++ src/tint/ast/identifier_test.cc | 62 +++++++++++++++++++++++++++++++++ src/tint/program_builder.h | 16 +++++++++ 6 files changed, 172 insertions(+) create mode 100644 src/tint/ast/identifier.cc create mode 100644 src/tint/ast/identifier.h create mode 100644 src/tint/ast/identifier_test.cc diff --git a/src/tint/BUILD.gn b/src/tint/BUILD.gn index 62da3d15a4..7f5e77e4b2 100644 --- a/src/tint/BUILD.gn +++ b/src/tint/BUILD.gn @@ -278,6 +278,7 @@ libtint_source_set("libtint_syntax_tree_src") { "ast/group_attribute.h", "ast/i32.h", "ast/id_attribute.h", + "ast/identifier.h", "ast/identifier_expression.h", "ast/if_statement.h", "ast/increment_decrement_statement.h", @@ -623,6 +624,8 @@ libtint_source_set("libtint_ast_src") { "ast/i32.h", "ast/id_attribute.cc", "ast/id_attribute.h", + "ast/identifier.cc", + "ast/identifier.h", "ast/identifier_expression.cc", "ast/identifier_expression.h", "ast/if_statement.cc", @@ -1328,6 +1331,7 @@ if (tint_build_unittests) { "ast/i32_test.cc", "ast/id_attribute_test.cc", "ast/identifier_expression_test.cc", + "ast/identifier_test.cc", "ast/if_statement_test.cc", "ast/increment_decrement_statement_test.cc", "ast/index_accessor_expression_test.cc", diff --git a/src/tint/CMakeLists.txt b/src/tint/CMakeLists.txt index 16bda12a4e..f537720134 100644 --- a/src/tint/CMakeLists.txt +++ b/src/tint/CMakeLists.txt @@ -156,6 +156,8 @@ list(APPEND TINT_LIB_SRCS ast/i32.h ast/id_attribute.cc ast/id_attribute.h + ast/identifier.cc + ast/identifier.h ast/identifier_expression.cc ast/identifier_expression.h ast/if_statement.cc @@ -850,6 +852,7 @@ if(TINT_BUILD_TESTS) ast/group_attribute_test.cc ast/i32_test.cc ast/id_attribute_test.cc + ast/identifier_test.cc ast/identifier_expression_test.cc ast/if_statement_test.cc ast/increment_decrement_statement_test.cc diff --git a/src/tint/ast/identifier.cc b/src/tint/ast/identifier.cc new file mode 100644 index 0000000000..8b8c3f51ca --- /dev/null +++ b/src/tint/ast/identifier.cc @@ -0,0 +1,40 @@ +// Copyright 2023 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "src/tint/ast/identifier.h" + +#include "src/tint/program_builder.h" + +TINT_INSTANTIATE_TYPEINFO(tint::ast::Identifier); + +namespace tint::ast { + +Identifier::Identifier(ProgramID pid, NodeID nid, const Source& src, Symbol sym) + : Base(pid, nid, src), symbol(sym) { + TINT_ASSERT_PROGRAM_IDS_EQUAL_IF_VALID(AST, symbol, program_id); + TINT_ASSERT(AST, symbol.IsValid()); +} + +Identifier::Identifier(Identifier&&) = default; + +Identifier::~Identifier() = default; + +const Identifier* Identifier::Clone(CloneContext* ctx) const { + // Clone arguments outside of create() call to have deterministic ordering + auto src = ctx->Clone(source); + auto sym = ctx->Clone(symbol); + return ctx->dst->create(src, sym); +} + +} // namespace tint::ast diff --git a/src/tint/ast/identifier.h b/src/tint/ast/identifier.h new file mode 100644 index 0000000000..9176403c9a --- /dev/null +++ b/src/tint/ast/identifier.h @@ -0,0 +1,47 @@ +// Copyright 2023 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef SRC_TINT_AST_IDENTIFIER_H_ +#define SRC_TINT_AST_IDENTIFIER_H_ + +#include "src/tint/ast/node.h" + +namespace tint::ast { + +/// An identifier +class Identifier final : public Castable { + 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 sym the symbol for the identifier + Identifier(ProgramID pid, NodeID nid, const Source& src, Symbol sym); + /// Move constructor + Identifier(Identifier&&); + ~Identifier() override; + + /// Clones this node and all transitive child nodes using the `CloneContext` + /// `ctx`. + /// @param ctx the clone context + /// @return the newly cloned node + const Identifier* Clone(CloneContext* ctx) const override; + + /// The symbol for the identifier + const Symbol symbol; +}; + +} // namespace tint::ast + +#endif // SRC_TINT_AST_IDENTIFIER_H_ diff --git a/src/tint/ast/identifier_test.cc b/src/tint/ast/identifier_test.cc new file mode 100644 index 0000000000..2d9d48fe99 --- /dev/null +++ b/src/tint/ast/identifier_test.cc @@ -0,0 +1,62 @@ +// Copyright 2023 The Tint Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "gtest/gtest-spi.h" +#include "src/tint/ast/test_helper.h" + +namespace tint::ast { +namespace { + +using IdentifierTest = TestHelper; + +TEST_F(IdentifierTest, Creation) { + auto* i = Ident("ident"); + EXPECT_EQ(i->symbol, Symbol(1, ID())); +} + +TEST_F(IdentifierTest, Creation_WithSource) { + auto* i = Ident(Source{{20, 2}}, "ident"); + EXPECT_EQ(i->symbol, Symbol(1, ID())); + + auto src = i->source; + EXPECT_EQ(src.range.begin.line, 20u); + EXPECT_EQ(src.range.begin.column, 2u); +} + +TEST_F(IdentifierTest, IsIdentifier) { + auto* i = Ident("ident"); + EXPECT_TRUE(i->Is()); +} + +TEST_F(IdentifierTest, Assert_InvalidSymbol) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b; + b.Ident(""); + }, + "internal compiler error"); +} + +TEST_F(IdentifierTest, Assert_DifferentProgramID_Symbol) { + EXPECT_FATAL_FAILURE( + { + ProgramBuilder b1; + ProgramBuilder b2; + b1.Ident(b2.Sym("b2")); + }, + "internal compiler error"); +} + +} // namespace +} // namespace tint::ast diff --git a/src/tint/program_builder.h b/src/tint/program_builder.h index 1c60784588..aaee0af549 100644 --- a/src/tint/program_builder.h +++ b/src/tint/program_builder.h @@ -54,6 +54,7 @@ #include "src/tint/ast/for_loop_statement.h" #include "src/tint/ast/i32.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/increment_decrement_statement.h" #include "src/tint/ast/index_accessor_expression.h" @@ -1147,6 +1148,21 @@ class ProgramBuilder { /// @return `sym` Symbol Sym(Symbol sym) { return sym; } + /// @param source the source information + /// @param identifier the identifier symbol + /// @return an ast::Identifier with the given symbol + template + const ast::Identifier* Ident(const Source& source, IDENTIFIER&& identifier) { + return create(source, Sym(std::forward(identifier))); + } + + /// @param identifier the identifier symbol + /// @return an ast::Identifier with the given symbol + template + const ast::Identifier* Ident(IDENTIFIER&& identifier) { + return create(Sym(std::forward(identifier))); + } + /// @param expr the expression /// @return expr template