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