From: Arthur Cohen <arthur.co...@embecosm.com>

gcc/rust/ChangeLog:

        * Make-lang.in: Add new object file.
        * rust-session-manager.cc (Session::compile_crate): Call 
CollectLangItems.
        * ast/rust-collect-lang-items.cc: New file.
        * ast/rust-collect-lang-items.h: New file.
---
 gcc/rust/Make-lang.in                   |  3 +-
 gcc/rust/ast/rust-collect-lang-items.cc | 97 +++++++++++++++++++++++++
 gcc/rust/ast/rust-collect-lang-items.h  | 58 +++++++++++++++
 gcc/rust/rust-session-manager.cc        |  3 +
 4 files changed, 160 insertions(+), 1 deletion(-)
 create mode 100644 gcc/rust/ast/rust-collect-lang-items.cc
 create mode 100644 gcc/rust/ast/rust-collect-lang-items.h

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index 9c5ec49ec4e..8771cdf91e1 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -227,8 +227,9 @@ GRS_OBJS = \
     rust/rust-dir-owner.o \
     rust/rust-unicode.o \
     rust/rust-punycode.o \
-       rust/rust-lang-item.o \
        rust/rust-expand-format-args.o \
+       rust/rust-lang-item.o \
+       rust/rust-collect-lang-items.o \
     $(END)
 # removed object files from here
 
diff --git a/gcc/rust/ast/rust-collect-lang-items.cc 
b/gcc/rust/ast/rust-collect-lang-items.cc
new file mode 100644
index 00000000000..11a30aa37a7
--- /dev/null
+++ b/gcc/rust/ast/rust-collect-lang-items.cc
@@ -0,0 +1,97 @@
+// Copyright (C) 2024 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-collect-lang-items.h"
+#include "optional.h"
+#include "rust-ast-collector.h"
+#include "rust-ast.h"
+#include "rust-attribute-values.h"
+#include "rust-attributes.h"
+#include "rust-hir-map.h"
+
+namespace Rust {
+namespace AST {
+
+// FIXME: Before merging: De-duplicate with function in rust-ast-lower-base.cc
+bool
+is_known_attribute (const std::string &attribute_path)
+{
+  const auto &lookup
+    = Analysis::BuiltinAttributeMappings::get ()->lookup_builtin (
+      attribute_path);
+
+  return !lookup.is_error ();
+}
+
+template <typename T>
+tl::optional<LangItem::Kind>
+get_lang_item_attr (const T &maybe_lang_item)
+{
+  for (const auto &attr : maybe_lang_item.get_outer_attrs ())
+    {
+      const auto &str_path = attr.get_path ().as_string ();
+      if (!is_known_attribute (str_path))
+       {
+         rust_error_at (attr.get_locus (), "unknown attribute");
+         continue;
+       }
+
+      bool is_lang_item = str_path == Values::Attributes::LANG
+                         && attr.has_attr_input ()
+                         && attr.get_attr_input ().get_attr_input_type ()
+                              == AST::AttrInput::AttrInputType::LITERAL;
+
+      if (is_lang_item)
+       {
+         auto &literal
+           = static_cast<AST::AttrInputLiteral &> (attr.get_attr_input ());
+         const auto &lang_item_type_str = literal.get_literal ().as_string ();
+
+         return LangItem::Parse (lang_item_type_str);
+       }
+    }
+
+  return tl::nullopt;
+}
+
+template <typename T>
+void
+CollectLangItems::maybe_add_lang_item (const T &item)
+{
+  if (auto lang_item = get_lang_item_attr (item))
+    mappings.insert_lang_item_node (lang_item.value (), item.get_node_id ());
+}
+
+void
+CollectLangItems::visit (AST::Trait &item)
+{
+  maybe_add_lang_item (item);
+
+  DefaultASTVisitor::visit (item);
+}
+
+void
+CollectLangItems::visit (AST::TraitItemType &item)
+{
+  maybe_add_lang_item (item);
+
+  DefaultASTVisitor::visit (item);
+}
+
+} // namespace AST
+} // namespace Rust
diff --git a/gcc/rust/ast/rust-collect-lang-items.h 
b/gcc/rust/ast/rust-collect-lang-items.h
new file mode 100644
index 00000000000..552648f04ed
--- /dev/null
+++ b/gcc/rust/ast/rust-collect-lang-items.h
@@ -0,0 +1,58 @@
+// Copyright (C) 2024 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_COLLECT_LANG_ITEMS_H
+#define RUST_COLLECT_LANG_ITEMS_H
+
+#include "rust-ast-visitor.h"
+#include "rust-ast.h"
+#include "rust-hir-map.h"
+#include "rust-item.h"
+
+namespace Rust {
+namespace AST {
+
+// This class collects lang items ahead of lowering, as they are now needed for
+// some parts of name resolution
+class CollectLangItems : public DefaultASTVisitor
+{
+public:
+  CollectLangItems () : mappings (Analysis::Mappings::get ()){};
+
+  void go (AST::Crate &crate) { DefaultASTVisitor::visit (crate); }
+
+  Analysis::Mappings &mappings;
+
+  // We must implement visitors for all constructs that could be lang items.
+  // Lang items can be traits, but also enums, and even enum variants.
+  //
+  // 
https://github.com/rust-lang/rust/blob/master/compiler/rustc_hir/src/lang_items.rs
+
+  using DefaultASTVisitor::visit;
+
+  void visit (AST::Trait &item) override;
+  void visit (AST::TraitItemType &item) override;
+
+private:
+  template <typename T> void maybe_add_lang_item (const T &item);
+};
+
+} // namespace AST
+} // namespace Rust
+
+#endif // ! RUST_COLLECT_LANG_ITEMS_H
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 11ff25062d0..c0b4796c4e9 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -17,6 +17,7 @@
 // <http://www.gnu.org/licenses/>.
 
 #include "rust-session-manager.h"
+#include "rust-collect-lang-items.h"
 #include "rust-diagnostics.h"
 #include "rust-hir-pattern-analysis.h"
 #include "rust-immutable-name-resolution-context.h"
@@ -600,6 +601,8 @@ Session::compile_crate (const char *filename)
   if (last_step == CompileOptions::CompileStep::Expansion)
     return;
 
+  AST::CollectLangItems ().go (parsed_crate);
+
   auto name_resolution_ctx = Resolver2_0::NameResolutionContext ();
   // expansion pipeline stage
 
-- 
2.45.2

Reply via email to