public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-7874] gccrs: top-level: Add base `TopLevel` visitor
@ 2024-01-16 18:03 Arthur Cohen
0 siblings, 0 replies; only message in thread
From: Arthur Cohen @ 2024-01-16 18:03 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:daae0c5dffa45f5300b9af372e13a6ae3ef56366
commit r14-7874-gdaae0c5dffa45f5300b9af372e13a6ae3ef56366
Author: Arthur Cohen <arthur.cohen@embecosm.com>
Date: Thu Jul 20 14:15:14 2023 +0200
gccrs: top-level: Add base `TopLevel` visitor
The `TopLevel` pass takes care of collecting definitions, placing them
in the proper namespaces, and making them accessible for later resolution
passes like `Early` and `Late`. It is meant to be run in a fixed point
fashion, as import resolution, macro resolution and macro expansion
may generate multiple new definitions.
gcc/rust/ChangeLog:
* Make-lang.in: Add new object file.
* resolve/rust-toplevel-name-resolver-2.0.cc: New file.
* resolve/rust-toplevel-name-resolver-2.0.h: New file.
Diff:
---
gcc/rust/Make-lang.in | 1 +
.../resolve/rust-toplevel-name-resolver-2.0.cc | 212 +++++++++++++++++++++
gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h | 76 ++++++++
3 files changed, 289 insertions(+)
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 2ebe3b2e218..dc56eeafedd 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -111,6 +111,7 @@ GRS_OBJS = \
rust/rust-ast-lower-stmt.o \
rust/rust-rib.o \
rust/rust-name-resolution-context.o \
+ rust/rust-toplevel-name-resolver-2.0.o \
rust/rust-early-name-resolver.o \
rust/rust-name-resolver.o \
rust/rust-ast-resolve.o \
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
new file mode 100644
index 00000000000..73c857e3ba7
--- /dev/null
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.cc
@@ -0,0 +1,212 @@
+// Copyright (C) 2020-2023 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-toplevel-name-resolver-2.0.h"
+#include "rust-ast-full.h"
+#include "rust-hir-map.h"
+
+namespace Rust {
+namespace Resolver2_0 {
+
+TopLevel::TopLevel (NameResolutionContext &resolver) : ctx (resolver) {}
+
+template <typename T>
+void
+TopLevel::insert_or_error_out (const Identifier &identifier, const T &node,
+ Namespace ns)
+{
+ auto loc = node.get_locus ();
+ auto node_id = node.get_node_id ();
+
+ // keep track of each node's location to provide useful errors
+ node_locations.emplace (node_id, loc);
+
+ auto result = ctx.insert (identifier, node_id, ns);
+
+ if (!result)
+ {
+ rich_location rich_loc (line_table, loc);
+ rich_loc.add_range (node_locations[result.error ().existing]);
+
+ rust_error_at (rich_loc, "already defined");
+ }
+}
+
+void
+TopLevel::go (AST::Crate &crate)
+{
+ for (auto &item : crate.items)
+ item->accept_vis (*this);
+}
+
+void
+TopLevel::visit (AST::Module &module)
+{
+ // FIXME: Do we need to insert the module in the type namespace?
+
+ auto sub_visitor = [this, &module] () {
+ for (auto &item : module.get_items ())
+ item->accept_vis (*this);
+ };
+
+ ctx.scoped (Rib::Kind::Module, module.get_node_id (), sub_visitor,
+ module.get_name ());
+}
+
+void
+TopLevel::visit (AST::MacroRulesDefinition ¯o)
+{
+ // FIXME: Do we want to insert macro rules here already? Probably, right?
+ // So that we can easily resolve in `Early`?
+ insert_or_error_out (macro.get_rule_name (), macro, Namespace::Macros);
+}
+
+void
+TopLevel::visit (AST::Function &function)
+{
+ insert_or_error_out (function.get_function_name (), function,
+ Namespace::Values);
+
+ auto def_fn
+ = [this, &function] () { function.get_definition ()->accept_vis (*this); };
+
+ ctx.scoped (Rib::Kind::Function, function.get_node_id (), def_fn);
+}
+
+void
+TopLevel::visit (AST::Method &method)
+{
+ insert_or_error_out (method.get_method_name (), method, Namespace::Values);
+
+ method.get_definition ()->accept_vis (*this);
+}
+
+void
+TopLevel::visit (AST::BlockExpr &expr)
+{
+ // extracting the lambda from the `scoped` call otherwise the code looks like
+ // a hot turd thanks to our .clang-format
+
+ auto sub_vis = [this, &expr] () {
+ for (auto &stmt : expr.get_statements ())
+ stmt->accept_vis (*this);
+
+ if (expr.has_tail_expr ())
+ expr.get_tail_expr ()->accept_vis (*this);
+ };
+
+ ctx.scoped (Rib::Kind::Normal, expr.get_node_id (), sub_vis);
+}
+
+void
+TopLevel::visit (AST::StaticItem &static_item)
+{
+ auto sub_vis
+ = [this, &static_item] () { static_item.get_expr ()->accept_vis (*this); };
+
+ ctx.scoped (Rib::Kind::Item, static_item.get_node_id (), sub_vis);
+}
+
+void
+TopLevel::visit (AST::TraitItemFunc &item)
+{
+ auto def_vis
+ = [this, &item] () { item.get_definition ()->accept_vis (*this); };
+
+ if (item.has_definition ())
+ ctx.scoped (Rib::Kind::Function, item.get_node_id (), def_vis);
+}
+
+void
+TopLevel::visit (AST::StructStruct &struct_item)
+{
+ insert_or_error_out (struct_item.get_struct_name (), struct_item,
+ Namespace::Types);
+
+ // Do we need to insert the constructor in the value namespace as well?
+
+ // Do we need to do anything if the struct is a unit struct?
+ if (struct_item.is_unit_struct ())
+ insert_or_error_out (struct_item.get_struct_name (), struct_item,
+ Namespace::Values);
+}
+
+void
+TopLevel::visit (AST::TupleStruct &tuple_struct)
+{
+ insert_or_error_out (tuple_struct.get_struct_name (), tuple_struct,
+ Namespace::Types);
+}
+
+void
+TopLevel::visit (AST::EnumItem &variant)
+{
+ insert_or_error_out (variant.get_identifier (), variant, Namespace::Types);
+}
+
+void
+TopLevel::visit (AST::EnumItemTuple &variant)
+{
+ insert_or_error_out (variant.get_identifier (), variant, Namespace::Types);
+}
+
+void
+TopLevel::visit (AST::EnumItemStruct &variant)
+{
+ insert_or_error_out (variant.get_identifier (), variant, Namespace::Types);
+}
+
+void
+TopLevel::visit (AST::EnumItemDiscriminant &variant)
+{
+ insert_or_error_out (variant.get_identifier (), variant, Namespace::Types);
+}
+
+void
+TopLevel::visit (AST::Enum &enum_item)
+{
+ insert_or_error_out (enum_item.get_identifier (), enum_item,
+ Namespace::Types);
+
+ auto field_vis = [this, &enum_item] () {
+ for (auto &variant : enum_item.get_variants ())
+ variant->accept_vis (*this);
+ };
+
+ ctx.scoped (Rib::Kind::Item /* FIXME: Is that correct? */,
+ enum_item.get_node_id (), field_vis, enum_item.get_identifier ());
+}
+
+void
+TopLevel::visit (AST::Union &union_item)
+{
+ insert_or_error_out (union_item.get_identifier (), union_item,
+ Namespace::Types);
+}
+
+void
+TopLevel::visit (AST::ConstantItem &const_item)
+{
+ auto expr_vis
+ = [this, &const_item] () { const_item.get_expr ()->accept_vis (*this); };
+
+ ctx.scoped (Rib::Kind::ConstantItem, const_item.get_node_id (), expr_vis);
+}
+
+} // namespace Resolver2_0
+} // namespace Rust
diff --git a/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
new file mode 100644
index 00000000000..db2033fc91c
--- /dev/null
+++ b/gcc/rust/resolve/rust-toplevel-name-resolver-2.0.h
@@ -0,0 +1,76 @@
+// Copyright (C) 2020-2023 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_TOPLEVEL_NAME_RESOLVER_2_0_H
+#define RUST_TOPLEVEL_NAME_RESOLVER_2_0_H
+
+#include "rust-ast-visitor.h"
+#include "rust-name-resolution-context.h"
+#include "rust-ast-resolve-base.h"
+
+namespace Rust {
+namespace Resolver2_0 {
+
+/**
+ * The `TopLevel` visitor takes care of collecting all the definitions in a
+ * crate, and inserting them into the proper namespaces. These definitions can
+ * then be accessed by subsequent resolvers, such as `Early` or `Late`.
+ */
+// TODO: Merge Resolver namespaces and use `public ResolverBase`
+class TopLevel : public ::Rust::Resolver::ResolverBase
+{
+ using ::Rust::Resolver::ResolverBase::visit;
+
+public:
+ TopLevel (NameResolutionContext &resolver);
+
+ void go (AST::Crate &crate);
+
+private:
+ NameResolutionContext &ctx;
+
+ // FIXME: Documentation
+ template <typename T>
+ void insert_or_error_out (const Identifier &identifier, const T &node,
+ Namespace ns);
+
+ // FIXME: Do we move these to our mappings?
+ std::unordered_map<NodeId, location_t> node_locations;
+
+ void visit (AST::Module &module) override;
+ void visit (AST::MacroRulesDefinition ¯o) override;
+ void visit (AST::Function &function) override;
+ void visit (AST::Method &method) override;
+ void visit (AST::BlockExpr &expr) override;
+ void visit (AST::StaticItem &static_item) override;
+ void visit (AST::TraitItemFunc &item) override;
+ void visit (AST::StructStruct &struct_item) override;
+ void visit (AST::TupleStruct &tuple_struct) override;
+ void visit (AST::EnumItem &variant) override;
+ void visit (AST::EnumItemTuple &variant) override;
+ void visit (AST::EnumItemStruct &variant) override;
+ void visit (AST::EnumItemDiscriminant &variant) override;
+ void visit (AST::Enum &enum_item) override;
+ void visit (AST::Union &union_item) override;
+ void visit (AST::ConstantItem &const_item) override;
+};
+
+} // namespace Resolver2_0
+} // namespace Rust
+
+#endif // !RUST_TOPLEVEL_NAME_RESOLVER_2_0_H
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2024-01-16 18:03 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-16 18:03 [gcc r14-7874] gccrs: top-level: Add base `TopLevel` visitor Arthur Cohen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).