From: Pierre-Emmanuel Patry <[email protected]>

The core library is made accessible through the `core` identifier in
every crate unless the crate opt out with the `#![no_core]` attribute.
This commit implicitely inject this extern crate when required.

gcc/rust/ChangeLog:

        * ast/rust-ast.cc (Crate::inject_extern_crate): Add a function to
        inject an extern crate item to a crate.
        * ast/rust-ast.h: Add function prototype for inject_extern_crate.
        * rust-session-manager.cc (has_attribute): Add helper to determine if
        a crate has a given inner attribute.
        (Session::compile_crate): Add a step to inject the core extern crate
        when the no_core attribute is missing.
        * util/rust-attribute-values.h: Add the no_core attribute value.

Signed-off-by: Pierre-Emmanuel Patry <[email protected]>
---
 gcc/rust/ast/rust-ast.cc              |  8 ++++++++
 gcc/rust/ast/rust-ast.h               |  2 ++
 gcc/rust/rust-session-manager.cc      | 15 +++++++++++++++
 gcc/rust/util/rust-attribute-values.h |  1 +
 4 files changed, 26 insertions(+)

diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index f550edb088d..37c38494968 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -235,6 +235,14 @@ Crate::as_string () const
   return str + "\n";
 }
 
+void
+Crate::inject_extern_crate (std::string name)
+{
+  items.push_back (std::make_unique<AST::ExternCrate> (
+    AST::ExternCrate (name, AST::Visibility::create_public (UNKNOWN_LOCATION),
+                     {}, UNKNOWN_LOCATION)));
+}
+
 std::string
 Attribute::as_string () const
 {
diff --git a/gcc/rust/ast/rust-ast.h b/gcc/rust/ast/rust-ast.h
index 65d1c3f0a2a..02fbb52a217 100644
--- a/gcc/rust/ast/rust-ast.h
+++ b/gcc/rust/ast/rust-ast.h
@@ -2116,6 +2116,8 @@ public:
     // TODO: is this the best way to do this?
   }
 
+  void inject_extern_crate (std::string name);
+
   NodeId get_node_id () const { return node_id; }
   const std::vector<Attribute> &get_inner_attrs () const { return inner_attrs; 
}
   std::vector<Attribute> &get_inner_attrs () { return inner_attrs; }
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 2235876c59d..4a2f5a5ad70 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -162,6 +162,16 @@ validate_crate_name (const std::string &crate_name, Error 
&error)
   return true;
 }
 
+static bool
+has_attribute (AST::Crate crate, std::string attribute)
+{
+  auto &crate_attrs = crate.get_inner_attrs ();
+  auto has_attr = [&attribute] (AST::Attribute &attr) {
+    return attr.as_string () == attribute;
+  };
+  return std::any_of (crate_attrs.begin (), crate_attrs.end (), has_attr);
+}
+
 void
 Session::init ()
 {
@@ -658,6 +668,11 @@ Session::compile_crate (const char *filename)
 
   Analysis::AttributeChecker ().go (parsed_crate);
 
+  if (!has_attribute (parsed_crate, std::string (Values::Attributes::NO_CORE)))
+    {
+      parsed_crate.inject_extern_crate ("core");
+    }
+
   if (last_step == CompileOptions::CompileStep::Expansion)
     return;
 
diff --git a/gcc/rust/util/rust-attribute-values.h 
b/gcc/rust/util/rust-attribute-values.h
index 45a81e4418a..85d3bac9242 100644
--- a/gcc/rust/util/rust-attribute-values.h
+++ b/gcc/rust/util/rust-attribute-values.h
@@ -37,6 +37,7 @@ public:
   static constexpr auto &MUST_USE = "must_use";
   static constexpr auto &LANG = "lang";
   static constexpr auto &LINK_NAME = "link_name";
+  static constexpr auto &NO_CORE = "no_core";
   static constexpr auto &LINK_SECTION = "link_section";
   static constexpr auto &NO_MANGLE = "no_mangle";
   static constexpr auto &EXPORT_NAME = "export_name";
-- 
2.50.1

Reply via email to