aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/rust/Make-lang.in1
-rw-r--r--gcc/rust/backend/rust-compile-base.cc100
-rw-r--r--gcc/rust/backend/rust-compile-base.h10
-rw-r--r--gcc/rust/resolve/rust-ast-resolve.cc294
-rw-r--r--gcc/rust/resolve/rust-name-resolver.cc513
-rw-r--r--gcc/rust/resolve/rust-name-resolver.h244
-rw-r--r--gcc/rust/util/rust-attributes.cc1
-rw-r--r--gcc/testsuite/rust/compile/attr_cold.rs4
-rw-r--r--gcc/testsuite/rust/debug/no_mangle.rs17
9 files changed, 630 insertions, 554 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index d25f403..436d9c3 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -85,6 +85,7 @@ GRS_OBJS = \
rust/rust-ast-lower.o \
rust/rust-ast-lower-base.o \
rust/rust-ast-lower-pattern.o \
+ rust/rust-name-resolver.o \
rust/rust-ast-resolve.o \
rust/rust-ast-resolve-pattern.o \
rust/rust-ast-resolve-expr.o \
diff --git a/gcc/rust/backend/rust-compile-base.cc b/gcc/rust/backend/rust-compile-base.cc
index 84afa1e..b969b7a 100644
--- a/gcc/rust/backend/rust-compile-base.cc
+++ b/gcc/rust/backend/rust-compile-base.cc
@@ -26,14 +26,21 @@
#include "fold-const.h"
#include "stringpool.h"
+#include "attribs.h"
namespace Rust {
namespace Compile {
+bool inline should_mangle_item (const tree fndecl)
+{
+ return lookup_attribute ("no_mangle", DECL_ATTRIBUTES (fndecl)) == NULL_TREE;
+}
+
void
-HIRCompileBase::setup_attributes_on_fndecl (
- tree fndecl, bool is_main_entry_point, HIR::Visibility &visibility,
- const HIR::FunctionQualifiers &qualifiers, const AST::AttrVec &attrs)
+HIRCompileBase::setup_fndecl (tree fndecl, bool is_main_entry_point,
+ HIR::Visibility &visibility,
+ const HIR::FunctionQualifiers &qualifiers,
+ const AST::AttrVec &attrs)
{
// if its the main fn or pub visibility mark its as DECL_PUBLIC
// please see https://github.com/Rust-GCC/gccrs/pull/137
@@ -58,6 +65,7 @@ HIRCompileBase::setup_attributes_on_fndecl (
bool is_cold = attr.get_path ().as_string ().compare ("cold") == 0;
bool is_link_section
= attr.get_path ().as_string ().compare ("link_section") == 0;
+ bool no_mangle = attr.get_path ().as_string ().compare ("no_mangle") == 0;
if (is_inline)
{
handle_inline_attribute_on_fndecl (fndecl, attr);
@@ -74,6 +82,10 @@ HIRCompileBase::setup_attributes_on_fndecl (
{
handle_link_section_attribute_on_fndecl (fndecl, attr);
}
+ else if (no_mangle)
+ {
+ handle_no_mangle_attribute_on_fndecl (fndecl, attr);
+ }
}
}
@@ -121,6 +133,21 @@ HIRCompileBase::handle_link_section_attribute_on_fndecl (
}
void
+HIRCompileBase::handle_no_mangle_attribute_on_fndecl (
+ tree fndecl, const AST::Attribute &attr)
+{
+ if (attr.has_attr_input ())
+ {
+ rust_error_at (attr.get_locus (),
+ "attribute %<no_mangle%> does not accept any arguments");
+ return;
+ }
+
+ DECL_ATTRIBUTES (fndecl) = tree_cons (get_identifier ("no_mangle"), NULL_TREE,
+ DECL_ATTRIBUTES (fndecl));
+}
+
+void
HIRCompileBase::handle_inline_attribute_on_fndecl (tree fndecl,
const AST::Attribute &attr)
{
@@ -306,33 +333,33 @@ HIRCompileBase::compile_locals_for_block (Context *ctx, Resolver::Rib &rib,
tree fndecl)
{
std::vector<Bvariable *> locals;
- rib.iterate_decls ([&] (NodeId n, Location) mutable -> bool {
- Resolver::Definition d;
- bool ok = ctx->get_resolver ()->lookup_definition (n, &d);
- rust_assert (ok);
-
- HIR::Stmt *decl = nullptr;
- ok = ctx->get_mappings ()->resolve_nodeid_to_stmt (d.parent, &decl);
- rust_assert (ok);
-
- // if its a function we extract this out side of this fn context
- // and it is not a local to this function
- bool is_item = ctx->get_mappings ()->lookup_hir_item (
- decl->get_mappings ().get_crate_num (),
- decl->get_mappings ().get_hirid ())
- != nullptr;
- if (is_item)
- {
- HIR::Item *item = static_cast<HIR::Item *> (decl);
- CompileItem::compile (item, ctx);
- return true;
- }
-
- Bvariable *compiled = CompileVarDecl::compile (fndecl, decl, ctx);
- locals.push_back (compiled);
+ for (auto it : rib.get_declarations ())
+ {
+ auto node_id = it.first;
+
+ Resolver::Definition d;
+ bool ok = ctx->get_resolver ()->lookup_definition (node_id, &d);
+ rust_assert (ok);
+
+ HIR::Stmt *decl = nullptr;
+ ok = ctx->get_mappings ()->resolve_nodeid_to_stmt (d.parent, &decl);
+ rust_assert (ok);
+
+ // if its a function we extract this out side of this fn context
+ // and it is not a local to this function
+ bool is_item = ctx->get_mappings ()->lookup_hir_item (
+ decl->get_mappings ().get_crate_num (),
+ decl->get_mappings ().get_hirid ())
+ != nullptr;
+ if (is_item)
+ {
+ HIR::Item *item = static_cast<HIR::Item *> (decl);
+ CompileItem::compile (item, ctx);
+ }
- return true;
- });
+ Bvariable *compiled = CompileVarDecl::compile (fndecl, decl, ctx);
+ locals.push_back (compiled);
+ };
return locals;
}
@@ -396,16 +423,21 @@ HIRCompileBase::compile_function (
// we don't mangle the main fn since we haven't implemented the main shim
bool is_main_fn = fn_name.compare ("main") == 0;
std::string asm_name = fn_name;
- if (!is_main_fn)
- asm_name = ctx->mangle_item (fntype, *canonical_path);
unsigned int flags = 0;
tree fndecl = ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
- asm_name, flags, locus);
- setup_attributes_on_fndecl (fndecl, is_main_fn, visibility, qualifiers,
- outer_attrs);
+ "" /* asm_name */, flags, locus);
+ setup_fndecl (fndecl, is_main_fn, visibility, qualifiers, outer_attrs);
setup_abi_options (fndecl, fntype->get_abi ());
+ // conditionally mangle the function name
+ bool should_mangle = should_mangle_item (fndecl);
+ if (!is_main_fn && should_mangle)
+ asm_name = ctx->mangle_item (fntype, *canonical_path);
+ SET_DECL_ASSEMBLER_NAME (fndecl,
+ get_identifier_with_length (asm_name.data (),
+ asm_name.length ()));
+
// insert into the context
ctx->insert_function_decl (fntype, fndecl);
diff --git a/gcc/rust/backend/rust-compile-base.h b/gcc/rust/backend/rust-compile-base.h
index 70506c2..c09c562 100644
--- a/gcc/rust/backend/rust-compile-base.h
+++ b/gcc/rust/backend/rust-compile-base.h
@@ -75,9 +75,10 @@ protected:
tree resolve_unsized_adjustment (Resolver::Adjustment &adjustment,
tree expression, Location locus);
- static void setup_attributes_on_fndecl (
- tree fndecl, bool is_main_entry_point, HIR::Visibility &visibility,
- const HIR::FunctionQualifiers &qualifiers, const AST::AttrVec &attrs);
+ static void setup_fndecl (tree fndecl, bool is_main_entry_point,
+ HIR::Visibility &visibility,
+ const HIR::FunctionQualifiers &qualifiers,
+ const AST::AttrVec &attrs);
static void handle_inline_attribute_on_fndecl (tree fndecl,
const AST::Attribute &attr);
@@ -92,6 +93,9 @@ protected:
handle_link_section_attribute_on_fndecl (tree fndecl,
const AST::Attribute &attr);
+ static void handle_no_mangle_attribute_on_fndecl (tree fndecl,
+ const AST::Attribute &attr);
+
static void setup_abi_options (tree fndecl, ABI abi);
static tree address_expression (tree, Location);
diff --git a/gcc/rust/resolve/rust-ast-resolve.cc b/gcc/rust/resolve/rust-ast-resolve.cc
index 86c159d..723c460 100644
--- a/gcc/rust/resolve/rust-ast-resolve.cc
+++ b/gcc/rust/resolve/rust-ast-resolve.cc
@@ -24,306 +24,12 @@
#include "rust-ast-resolve-expr.h"
#include "rust-ast-resolve-struct-expr-field.h"
-#define MKBUILTIN_TYPE(_X, _R, _TY) \
- do \
- { \
- AST::PathIdentSegment seg (_X, Linemap::predeclared_location ()); \
- auto typePath = ::std::unique_ptr<AST::TypePathSegment> ( \
- new AST::TypePathSegment (::std::move (seg), false, \
- Linemap::predeclared_location ())); \
- ::std::vector< ::std::unique_ptr<AST::TypePathSegment> > segs; \
- segs.push_back (::std::move (typePath)); \
- auto builtin_type \
- = new AST::TypePath (::std::move (segs), \
- Linemap::predeclared_location (), false); \
- _R.push_back (builtin_type); \
- tyctx->insert_builtin (_TY->get_ref (), builtin_type->get_node_id (), \
- _TY); \
- } \
- while (0)
-
extern bool
saw_errors (void);
namespace Rust {
namespace Resolver {
-// Resolver
-
-Resolver::Resolver ()
- : mappings (Analysis::Mappings::get ()), tyctx (TypeCheckContext::get ()),
- name_scope (Scope (mappings->get_current_crate ())),
- type_scope (Scope (mappings->get_current_crate ())),
- label_scope (Scope (mappings->get_current_crate ())),
- macro_scope (Scope (mappings->get_current_crate ())),
- global_type_node_id (UNKNOWN_NODEID), unit_ty_node_id (UNKNOWN_NODEID)
-{
- generate_builtins ();
-}
-
-Resolver *
-Resolver::get ()
-{
- static Resolver *instance;
- if (instance == nullptr)
- instance = new Resolver ();
-
- return instance;
-}
-
-void
-Resolver::push_new_name_rib (Rib *r)
-{
- rust_assert (name_ribs.find (r->get_node_id ()) == name_ribs.end ());
- name_ribs[r->get_node_id ()] = r;
-}
-
-void
-Resolver::push_new_type_rib (Rib *r)
-{
- if (type_ribs.size () == 0)
- global_type_node_id = r->get_node_id ();
-
- rust_assert (type_ribs.find (r->get_node_id ()) == type_ribs.end ());
- type_ribs[r->get_node_id ()] = r;
-}
-
-void
-Resolver::push_new_label_rib (Rib *r)
-{
- rust_assert (label_ribs.find (r->get_node_id ()) == label_ribs.end ());
- label_ribs[r->get_node_id ()] = r;
-}
-
-void
-Resolver::push_new_macro_rib (Rib *r)
-{
- rust_assert (label_ribs.find (r->get_node_id ()) == label_ribs.end ());
- macro_ribs[r->get_node_id ()] = r;
-}
-
-bool
-Resolver::find_name_rib (NodeId id, Rib **rib)
-{
- auto it = name_ribs.find (id);
- if (it == name_ribs.end ())
- return false;
-
- *rib = it->second;
- return true;
-}
-
-bool
-Resolver::find_type_rib (NodeId id, Rib **rib)
-{
- auto it = type_ribs.find (id);
- if (it == type_ribs.end ())
- return false;
-
- *rib = it->second;
- return true;
-}
-
-bool
-Resolver::find_macro_rib (NodeId id, Rib **rib)
-{
- auto it = macro_ribs.find (id);
- if (it == macro_ribs.end ())
- return false;
-
- *rib = it->second;
- return true;
-}
-
-void
-Resolver::insert_builtin_types (Rib *r)
-{
- auto builtins = get_builtin_types ();
- for (auto &builtin : builtins)
- {
- CanonicalPath builtin_path
- = CanonicalPath::new_seg (builtin->get_node_id (),
- builtin->as_string ());
- r->insert_name (builtin_path, builtin->get_node_id (),
- Linemap::predeclared_location (), false,
- [] (const CanonicalPath &, NodeId, Location) -> void {});
- }
-}
-
-std::vector<AST::Type *> &
-Resolver::get_builtin_types ()
-{
- return builtins;
-}
-
-void
-Resolver::generate_builtins ()
-{
- auto u8
- = new TyTy::UintType (mappings->get_next_hir_id (), TyTy::UintType::U8);
- auto u16
- = new TyTy::UintType (mappings->get_next_hir_id (), TyTy::UintType::U16);
- auto u32
- = new TyTy::UintType (mappings->get_next_hir_id (), TyTy::UintType::U32);
- auto u64
- = new TyTy::UintType (mappings->get_next_hir_id (), TyTy::UintType::U64);
- auto u128
- = new TyTy::UintType (mappings->get_next_hir_id (), TyTy::UintType::U128);
- auto i8 = new TyTy::IntType (mappings->get_next_hir_id (), TyTy::IntType::I8);
- auto i16
- = new TyTy::IntType (mappings->get_next_hir_id (), TyTy::IntType::I16);
- auto i32
- = new TyTy::IntType (mappings->get_next_hir_id (), TyTy::IntType::I32);
- auto i64
- = new TyTy::IntType (mappings->get_next_hir_id (), TyTy::IntType::I64);
- auto i128
- = new TyTy::IntType (mappings->get_next_hir_id (), TyTy::IntType::I128);
- auto rbool = new TyTy::BoolType (mappings->get_next_hir_id ());
- auto f32
- = new TyTy::FloatType (mappings->get_next_hir_id (), TyTy::FloatType::F32);
- auto f64
- = new TyTy::FloatType (mappings->get_next_hir_id (), TyTy::FloatType::F64);
- auto usize = new TyTy::USizeType (mappings->get_next_hir_id ());
- auto isize = new TyTy::ISizeType (mappings->get_next_hir_id ());
- auto char_tyty = new TyTy::CharType (mappings->get_next_hir_id ());
- auto str = new TyTy::StrType (mappings->get_next_hir_id ());
- auto never = new TyTy::NeverType (mappings->get_next_hir_id ());
-
- MKBUILTIN_TYPE ("u8", builtins, u8);
- MKBUILTIN_TYPE ("u16", builtins, u16);
- MKBUILTIN_TYPE ("u32", builtins, u32);
- MKBUILTIN_TYPE ("u64", builtins, u64);
- MKBUILTIN_TYPE ("u128", builtins, u128);
- MKBUILTIN_TYPE ("i8", builtins, i8);
- MKBUILTIN_TYPE ("i16", builtins, i16);
- MKBUILTIN_TYPE ("i32", builtins, i32);
- MKBUILTIN_TYPE ("i64", builtins, i64);
- MKBUILTIN_TYPE ("i128", builtins, i128);
- MKBUILTIN_TYPE ("bool", builtins, rbool);
- MKBUILTIN_TYPE ("f32", builtins, f32);
- MKBUILTIN_TYPE ("f64", builtins, f64);
- MKBUILTIN_TYPE ("usize", builtins, usize);
- MKBUILTIN_TYPE ("isize", builtins, isize);
- MKBUILTIN_TYPE ("char", builtins, char_tyty);
- MKBUILTIN_TYPE ("str", builtins, str);
- MKBUILTIN_TYPE ("!", builtins, never);
-
- // unit type ()
- TyTy::TupleType *unit_tyty
- = TyTy::TupleType::get_unit_type (mappings->get_next_hir_id ());
- std::vector<std::unique_ptr<AST::Type> > elems;
- AST::TupleType *unit_type
- = new AST::TupleType (std::move (elems), Linemap::predeclared_location ());
- builtins.push_back (unit_type);
- tyctx->insert_builtin (unit_tyty->get_ref (), unit_type->get_node_id (),
- unit_tyty);
- set_unit_type_node_id (unit_type->get_node_id ());
-}
-
-void
-Resolver::insert_new_definition (NodeId id, Definition def)
-{
- auto it = name_definitions.find (id);
- if (it != name_definitions.end ())
- {
- rust_assert (it->second.is_equal (def));
- return;
- }
- name_definitions[id] = def;
-}
-
-bool
-Resolver::lookup_definition (NodeId id, Definition *def)
-{
- auto it = name_definitions.find (id);
- if (it == name_definitions.end ())
- return false;
-
- *def = it->second;
- return true;
-}
-
-void
-Resolver::insert_resolved_name (NodeId refId, NodeId defId)
-{
- resolved_names[refId] = defId;
- get_name_scope ().append_reference_for_def (refId, defId);
-}
-
-bool
-Resolver::lookup_resolved_name (NodeId refId, NodeId *defId)
-{
- auto it = resolved_names.find (refId);
- if (it == resolved_names.end ())
- return false;
-
- *defId = it->second;
- return true;
-}
-
-void
-Resolver::insert_resolved_type (NodeId refId, NodeId defId)
-{
- // auto it = resolved_types.find (refId);
- // rust_assert (it == resolved_types.end ());
-
- resolved_types[refId] = defId;
- get_type_scope ().append_reference_for_def (refId, defId);
-}
-
-bool
-Resolver::lookup_resolved_type (NodeId refId, NodeId *defId)
-{
- auto it = resolved_types.find (refId);
- if (it == resolved_types.end ())
- return false;
-
- *defId = it->second;
- return true;
-}
-
-void
-Resolver::insert_resolved_label (NodeId refId, NodeId defId)
-{
- auto it = resolved_labels.find (refId);
- rust_assert (it == resolved_labels.end ());
-
- resolved_labels[refId] = defId;
- get_label_scope ().append_reference_for_def (refId, defId);
-}
-
-bool
-Resolver::lookup_resolved_label (NodeId refId, NodeId *defId)
-{
- auto it = resolved_labels.find (refId);
- if (it == resolved_labels.end ())
- return false;
-
- *defId = it->second;
- return true;
-}
-
-void
-Resolver::insert_resolved_macro (NodeId refId, NodeId defId)
-{
- auto it = resolved_macros.find (refId);
- rust_assert (it == resolved_macros.end ());
-
- resolved_labels[refId] = defId;
- get_label_scope ().append_reference_for_def (refId, defId);
-}
-
-bool
-Resolver::lookup_resolved_macro (NodeId refId, NodeId *defId)
-{
- auto it = resolved_macros.find (refId);
- if (it == resolved_macros.end ())
- return false;
-
- *defId = it->second;
- return true;
-}
-
// NameResolution
NameResolution *
diff --git a/gcc/rust/resolve/rust-name-resolver.cc b/gcc/rust/resolve/rust-name-resolver.cc
new file mode 100644
index 0000000..fc1f361
--- /dev/null
+++ b/gcc/rust/resolve/rust-name-resolver.cc
@@ -0,0 +1,513 @@
+// Copyright (C) 2020-2022 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-name-resolver.h"
+#include "rust-ast-full.h"
+
+#define MKBUILTIN_TYPE(_X, _R, _TY) \
+ do \
+ { \
+ AST::PathIdentSegment seg (_X, Linemap::predeclared_location ()); \
+ auto typePath = ::std::unique_ptr<AST::TypePathSegment> ( \
+ new AST::TypePathSegment (::std::move (seg), false, \
+ Linemap::predeclared_location ())); \
+ ::std::vector< ::std::unique_ptr<AST::TypePathSegment> > segs; \
+ segs.push_back (::std::move (typePath)); \
+ auto builtin_type \
+ = new AST::TypePath (::std::move (segs), \
+ Linemap::predeclared_location (), false); \
+ _R.push_back (builtin_type); \
+ tyctx->insert_builtin (_TY->get_ref (), builtin_type->get_node_id (), \
+ _TY); \
+ } \
+ while (0)
+
+namespace Rust {
+namespace Resolver {
+
+Rib::Rib (CrateNum crateNum, NodeId node_id)
+ : crate_num (crateNum), node_id (node_id),
+ mappings (Analysis::Mappings::get ())
+{}
+
+void
+Rib::insert_name (
+ const CanonicalPath &path, NodeId id, Location locus, bool shadow,
+ std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb)
+{
+ auto it = path_mappings.find (path);
+ bool path_already_exists = it != path_mappings.end ();
+ if (path_already_exists && !shadow)
+ {
+ const auto &decl = decls_within_rib.find (it->second);
+ if (decl != decls_within_rib.end ())
+ dup_cb (path, it->second, decl->second);
+ else
+ dup_cb (path, it->second, locus);
+
+ return;
+ }
+
+ path_mappings[path] = id;
+ reverse_path_mappings.insert (std::pair<NodeId, CanonicalPath> (id, path));
+ decls_within_rib.insert (std::pair<NodeId, Location> (id, locus));
+ references[id] = {};
+}
+
+bool
+Rib::lookup_name (const CanonicalPath &ident, NodeId *id)
+{
+ auto it = path_mappings.find (ident);
+ if (it == path_mappings.end ())
+ return false;
+
+ *id = it->second;
+ return true;
+}
+
+void
+Rib::clear_name (const CanonicalPath &ident, NodeId id)
+{
+ auto ii = path_mappings.find (ident);
+ if (ii != path_mappings.end ())
+ path_mappings.erase (ii);
+
+ auto ij = reverse_path_mappings.find (id);
+ if (ij != reverse_path_mappings.end ())
+ reverse_path_mappings.erase (ij);
+
+ auto ik = decls_within_rib.find (id);
+ if (ik != decls_within_rib.end ())
+ decls_within_rib.erase (ik);
+}
+
+void
+Rib::append_reference_for_def (NodeId def, NodeId ref)
+{
+ references[def].insert (ref);
+}
+
+bool
+Rib::have_references_for_node (NodeId def) const
+{
+ auto it = references.find (def);
+ if (it == references.end ())
+ return false;
+
+ return !it->second.empty ();
+}
+
+bool
+Rib::decl_was_declared_here (NodeId def) const
+{
+ for (auto &it : decls_within_rib)
+ {
+ if (it.first == def)
+ return true;
+ }
+ return false;
+}
+
+Scope::Scope (CrateNum crate_num) : crate_num (crate_num) {}
+
+void
+Scope::insert (
+ const CanonicalPath &ident, NodeId id, Location locus, bool shadow,
+ std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb)
+{
+ peek ()->insert_name (ident, id, locus, shadow, dup_cb);
+}
+
+void
+Scope::insert (const CanonicalPath &ident, NodeId id, Location locus)
+{
+ peek ()->insert_name (ident, id, locus, true,
+ [] (const CanonicalPath &, NodeId, Location) -> void {
+ });
+}
+
+bool
+Scope::lookup (const CanonicalPath &ident, NodeId *id)
+{
+ NodeId lookup = UNKNOWN_NODEID;
+ iterate ([&] (Rib *r) mutable -> bool {
+ if (r->lookup_name (ident, &lookup))
+ return false;
+ return true;
+ });
+
+ *id = lookup;
+ return lookup != UNKNOWN_NODEID;
+}
+
+void
+Scope::iterate (std::function<bool (Rib *)> cb)
+{
+ for (auto it = stack.rbegin (); it != stack.rend (); ++it)
+ {
+ if (!cb (*it))
+ return;
+ }
+}
+
+Rib *
+Scope::peek ()
+{
+ return stack.back ();
+}
+
+void
+Scope::push (NodeId id)
+{
+ stack.push_back (new Rib (get_crate_num (), id));
+}
+
+Rib *
+Scope::pop ()
+{
+ Rib *r = peek ();
+ stack.pop_back ();
+ return r;
+}
+
+void
+Scope::append_reference_for_def (NodeId refId, NodeId defId)
+{
+ bool ok = false;
+ iterate ([&] (Rib *r) mutable -> bool {
+ if (r->decl_was_declared_here (defId))
+ {
+ ok = true;
+ r->append_reference_for_def (defId, refId);
+ }
+ return true;
+ });
+ rust_assert (ok);
+}
+
+Resolver::Resolver ()
+ : mappings (Analysis::Mappings::get ()), tyctx (TypeCheckContext::get ()),
+ name_scope (Scope (mappings->get_current_crate ())),
+ type_scope (Scope (mappings->get_current_crate ())),
+ label_scope (Scope (mappings->get_current_crate ())),
+ macro_scope (Scope (mappings->get_current_crate ())),
+ global_type_node_id (UNKNOWN_NODEID), unit_ty_node_id (UNKNOWN_NODEID)
+{
+ generate_builtins ();
+}
+
+Resolver *
+Resolver::get ()
+{
+ static Resolver *instance;
+ if (instance == nullptr)
+ instance = new Resolver ();
+
+ return instance;
+}
+
+void
+Resolver::push_new_name_rib (Rib *r)
+{
+ rust_assert (name_ribs.find (r->get_node_id ()) == name_ribs.end ());
+ name_ribs[r->get_node_id ()] = r;
+}
+
+void
+Resolver::push_new_type_rib (Rib *r)
+{
+ if (type_ribs.size () == 0)
+ global_type_node_id = r->get_node_id ();
+
+ rust_assert (type_ribs.find (r->get_node_id ()) == type_ribs.end ());
+ type_ribs[r->get_node_id ()] = r;
+}
+
+void
+Resolver::push_new_label_rib (Rib *r)
+{
+ rust_assert (label_ribs.find (r->get_node_id ()) == label_ribs.end ());
+ label_ribs[r->get_node_id ()] = r;
+}
+
+void
+Resolver::push_new_macro_rib (Rib *r)
+{
+ rust_assert (label_ribs.find (r->get_node_id ()) == label_ribs.end ());
+ macro_ribs[r->get_node_id ()] = r;
+}
+
+bool
+Resolver::find_name_rib (NodeId id, Rib **rib)
+{
+ auto it = name_ribs.find (id);
+ if (it == name_ribs.end ())
+ return false;
+
+ *rib = it->second;
+ return true;
+}
+
+bool
+Resolver::find_type_rib (NodeId id, Rib **rib)
+{
+ auto it = type_ribs.find (id);
+ if (it == type_ribs.end ())
+ return false;
+
+ *rib = it->second;
+ return true;
+}
+
+bool
+Resolver::find_macro_rib (NodeId id, Rib **rib)
+{
+ auto it = macro_ribs.find (id);
+ if (it == macro_ribs.end ())
+ return false;
+
+ *rib = it->second;
+ return true;
+}
+
+void
+Resolver::insert_builtin_types (Rib *r)
+{
+ auto builtins = get_builtin_types ();
+ for (auto &builtin : builtins)
+ {
+ CanonicalPath builtin_path
+ = CanonicalPath::new_seg (builtin->get_node_id (),
+ builtin->as_string ());
+ r->insert_name (builtin_path, builtin->get_node_id (),
+ Linemap::predeclared_location (), false,
+ [] (const CanonicalPath &, NodeId, Location) -> void {});
+ }
+}
+
+std::vector<AST::Type *> &
+Resolver::get_builtin_types ()
+{
+ return builtins;
+}
+
+void
+Resolver::generate_builtins ()
+{
+ auto u8
+ = new TyTy::UintType (mappings->get_next_hir_id (), TyTy::UintType::U8);
+ auto u16
+ = new TyTy::UintType (mappings->get_next_hir_id (), TyTy::UintType::U16);
+ auto u32
+ = new TyTy::UintType (mappings->get_next_hir_id (), TyTy::UintType::U32);
+ auto u64
+ = new TyTy::UintType (mappings->get_next_hir_id (), TyTy::UintType::U64);
+ auto u128
+ = new TyTy::UintType (mappings->get_next_hir_id (), TyTy::UintType::U128);
+ auto i8 = new TyTy::IntType (mappings->get_next_hir_id (), TyTy::IntType::I8);
+ auto i16
+ = new TyTy::IntType (mappings->get_next_hir_id (), TyTy::IntType::I16);
+ auto i32
+ = new TyTy::IntType (mappings->get_next_hir_id (), TyTy::IntType::I32);
+ auto i64
+ = new TyTy::IntType (mappings->get_next_hir_id (), TyTy::IntType::I64);
+ auto i128
+ = new TyTy::IntType (mappings->get_next_hir_id (), TyTy::IntType::I128);
+ auto rbool = new TyTy::BoolType (mappings->get_next_hir_id ());
+ auto f32
+ = new TyTy::FloatType (mappings->get_next_hir_id (), TyTy::FloatType::F32);
+ auto f64
+ = new TyTy::FloatType (mappings->get_next_hir_id (), TyTy::FloatType::F64);
+ auto usize = new TyTy::USizeType (mappings->get_next_hir_id ());
+ auto isize = new TyTy::ISizeType (mappings->get_next_hir_id ());
+ auto char_tyty = new TyTy::CharType (mappings->get_next_hir_id ());
+ auto str = new TyTy::StrType (mappings->get_next_hir_id ());
+ auto never = new TyTy::NeverType (mappings->get_next_hir_id ());
+
+ MKBUILTIN_TYPE ("u8", builtins, u8);
+ MKBUILTIN_TYPE ("u16", builtins, u16);
+ MKBUILTIN_TYPE ("u32", builtins, u32);
+ MKBUILTIN_TYPE ("u64", builtins, u64);
+ MKBUILTIN_TYPE ("u128", builtins, u128);
+ MKBUILTIN_TYPE ("i8", builtins, i8);
+ MKBUILTIN_TYPE ("i16", builtins, i16);
+ MKBUILTIN_TYPE ("i32", builtins, i32);
+ MKBUILTIN_TYPE ("i64", builtins, i64);
+ MKBUILTIN_TYPE ("i128", builtins, i128);
+ MKBUILTIN_TYPE ("bool", builtins, rbool);
+ MKBUILTIN_TYPE ("f32", builtins, f32);
+ MKBUILTIN_TYPE ("f64", builtins, f64);
+ MKBUILTIN_TYPE ("usize", builtins, usize);
+ MKBUILTIN_TYPE ("isize", builtins, isize);
+ MKBUILTIN_TYPE ("char", builtins, char_tyty);
+ MKBUILTIN_TYPE ("str", builtins, str);
+ MKBUILTIN_TYPE ("!", builtins, never);
+
+ // unit type ()
+ TyTy::TupleType *unit_tyty
+ = TyTy::TupleType::get_unit_type (mappings->get_next_hir_id ());
+ std::vector<std::unique_ptr<AST::Type> > elems;
+ AST::TupleType *unit_type
+ = new AST::TupleType (std::move (elems), Linemap::predeclared_location ());
+ builtins.push_back (unit_type);
+ tyctx->insert_builtin (unit_tyty->get_ref (), unit_type->get_node_id (),
+ unit_tyty);
+ set_unit_type_node_id (unit_type->get_node_id ());
+}
+
+void
+Resolver::insert_new_definition (NodeId id, Definition def)
+{
+ auto it = name_definitions.find (id);
+ if (it != name_definitions.end ())
+ {
+ rust_assert (it->second.is_equal (def));
+ return;
+ }
+ name_definitions[id] = def;
+}
+
+bool
+Resolver::lookup_definition (NodeId id, Definition *def)
+{
+ auto it = name_definitions.find (id);
+ if (it == name_definitions.end ())
+ return false;
+
+ *def = it->second;
+ return true;
+}
+
+void
+Resolver::insert_resolved_name (NodeId refId, NodeId defId)
+{
+ resolved_names[refId] = defId;
+ get_name_scope ().append_reference_for_def (refId, defId);
+}
+
+bool
+Resolver::lookup_resolved_name (NodeId refId, NodeId *defId)
+{
+ auto it = resolved_names.find (refId);
+ if (it == resolved_names.end ())
+ return false;
+
+ *defId = it->second;
+ return true;
+}
+
+void
+Resolver::insert_resolved_type (NodeId refId, NodeId defId)
+{
+ // auto it = resolved_types.find (refId);
+ // rust_assert (it == resolved_types.end ());
+
+ resolved_types[refId] = defId;
+ get_type_scope ().append_reference_for_def (refId, defId);
+}
+
+bool
+Resolver::lookup_resolved_type (NodeId refId, NodeId *defId)
+{
+ auto it = resolved_types.find (refId);
+ if (it == resolved_types.end ())
+ return false;
+
+ *defId = it->second;
+ return true;
+}
+
+void
+Resolver::insert_resolved_label (NodeId refId, NodeId defId)
+{
+ auto it = resolved_labels.find (refId);
+ rust_assert (it == resolved_labels.end ());
+
+ resolved_labels[refId] = defId;
+ get_label_scope ().append_reference_for_def (refId, defId);
+}
+
+bool
+Resolver::lookup_resolved_label (NodeId refId, NodeId *defId)
+{
+ auto it = resolved_labels.find (refId);
+ if (it == resolved_labels.end ())
+ return false;
+
+ *defId = it->second;
+ return true;
+}
+
+void
+Resolver::insert_resolved_macro (NodeId refId, NodeId defId)
+{
+ auto it = resolved_macros.find (refId);
+ rust_assert (it == resolved_macros.end ());
+
+ resolved_labels[refId] = defId;
+ get_label_scope ().append_reference_for_def (refId, defId);
+}
+
+bool
+Resolver::lookup_resolved_macro (NodeId refId, NodeId *defId)
+{
+ auto it = resolved_macros.find (refId);
+ if (it == resolved_macros.end ())
+ return false;
+
+ *defId = it->second;
+ return true;
+}
+
+void
+Resolver::mark_decl_mutability (NodeId id, bool mut)
+{
+ rust_assert (decl_mutability.find (id) == decl_mutability.end ());
+ decl_mutability[id] = mut;
+}
+
+bool
+Resolver::decl_is_mutable (NodeId id) const
+{
+ auto it = decl_mutability.find (id);
+ rust_assert (it != decl_mutability.end ());
+ return it->second;
+}
+
+void
+Resolver::mark_assignment_to_decl (NodeId id, NodeId assignment)
+{
+ auto it = assignment_to_decl.find (id);
+ if (it == assignment_to_decl.end ())
+ assignment_to_decl[id] = {};
+
+ assignment_to_decl[id].insert (assignment);
+}
+
+size_t
+Resolver::get_num_assignments_to_decl (NodeId id) const
+{
+ auto it = assignment_to_decl.find (id);
+ if (it == assignment_to_decl.end ())
+ return 0;
+
+ return it->second.size ();
+}
+
+} // namespace Resolver
+} // namespace Rust
diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h
index 2084480..ab7cb55 100644
--- a/gcc/rust/resolve/rust-name-resolver.h
+++ b/gcc/rust/resolve/rust-name-resolver.h
@@ -32,120 +32,23 @@ class Rib
public:
// Rust uses local_def_ids assigned by def_collector on the AST
// lets use NodeId instead
- Rib (CrateNum crateNum, NodeId node_id)
- : crate_num (crateNum), node_id (node_id),
- mappings (Analysis::Mappings::get ())
- {}
-
- ~Rib () {}
+ Rib (CrateNum crateNum, NodeId node_id);
// this takes the relative paths of items within a compilation unit for lookup
void insert_name (
const CanonicalPath &path, NodeId id, Location locus, bool shadow,
- std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb)
- {
- auto it = path_mappings.find (path);
- bool path_already_exists = it != path_mappings.end ();
- if (path_already_exists && !shadow)
- {
- const auto &decl = decls_within_rib.find (it->second);
- if (decl != decls_within_rib.end ())
- dup_cb (path, it->second, decl->second);
- else
- dup_cb (path, it->second, locus);
-
- return;
- }
-
- path_mappings[path] = id;
- reverse_path_mappings.insert (std::pair<NodeId, CanonicalPath> (id, path));
- decls_within_rib.insert (std::pair<NodeId, Location> (id, locus));
- references[id] = {};
- }
-
- bool lookup_name (const CanonicalPath &ident, NodeId *id)
- {
- auto it = path_mappings.find (ident);
- if (it == path_mappings.end ())
- return false;
-
- *id = it->second;
- return true;
- }
-
- bool lookup_canonical_path (const NodeId &id, CanonicalPath *ident)
- {
- auto it = reverse_path_mappings.find (id);
- if (it == reverse_path_mappings.end ())
- return false;
+ std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb);
- *ident = it->second;
- return true;
- }
-
- void clear_name (const CanonicalPath &ident, NodeId id)
- {
- auto ii = path_mappings.find (ident);
- if (ii != path_mappings.end ())
- path_mappings.erase (ii);
-
- auto ij = reverse_path_mappings.find (id);
- if (ij != reverse_path_mappings.end ())
- reverse_path_mappings.erase (ij);
-
- auto ik = decls_within_rib.find (id);
- if (ik != decls_within_rib.end ())
- decls_within_rib.erase (ik);
- }
+ bool lookup_canonical_path (const NodeId &id, CanonicalPath *ident);
+ bool lookup_name (const CanonicalPath &ident, NodeId *id);
+ void clear_name (const CanonicalPath &ident, NodeId id);
+ void append_reference_for_def (NodeId def, NodeId ref);
+ bool have_references_for_node (NodeId def) const;
+ bool decl_was_declared_here (NodeId def) const;
CrateNum get_crate_num () const { return crate_num; }
NodeId get_node_id () const { return node_id; }
-
- void iterate_decls (std::function<bool (NodeId, Location)> cb)
- {
- for (auto it : decls_within_rib)
- {
- if (!cb (it.first, it.second))
- return;
- }
- }
-
- void iterate_references_for_def (NodeId def, std::function<bool (NodeId)> cb)
- {
- auto it = references.find (def);
- if (it == references.end ())
- return;
-
- for (auto ref : it->second)
- {
- if (!cb (ref))
- return;
- }
- }
-
- void append_reference_for_def (NodeId def, NodeId ref)
- {
- references[def].insert (ref);
- }
-
- bool have_references_for_node (NodeId def) const
- {
- auto it = references.find (def);
- if (it == references.end ())
- return false;
-
- return !it->second.empty ();
- }
-
- bool decl_was_declared_here (NodeId def) const
- {
- for (auto &it : decls_within_rib)
- {
- if (it.first == def)
- return true;
- }
- return false;
- }
+ std::map<NodeId, Location> &get_declarations () { return decls_within_rib; }
private:
CrateNum crate_num;
@@ -160,73 +63,25 @@ private:
class Scope
{
public:
- Scope (CrateNum crate_num) : crate_num (crate_num) {}
-
- ~Scope () {}
+ Scope (CrateNum crate_num);
void
insert (const CanonicalPath &ident, NodeId id, Location locus, bool shadow,
- std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb)
- {
- peek ()->insert_name (ident, id, locus, shadow, dup_cb);
- }
-
- void insert (const CanonicalPath &ident, NodeId id, Location locus)
- {
- peek ()->insert_name (ident, id, locus, true,
- [] (const CanonicalPath &, NodeId, Location) -> void {
- });
- }
+ std::function<void (const CanonicalPath &, NodeId, Location)> dup_cb);
- bool lookup (const CanonicalPath &ident, NodeId *id)
- {
- NodeId lookup = UNKNOWN_NODEID;
- iterate ([&] (Rib *r) mutable -> bool {
- if (r->lookup_name (ident, &lookup))
- return false;
- return true;
- });
-
- *id = lookup;
- return lookup != UNKNOWN_NODEID;
- }
+ void insert (const CanonicalPath &ident, NodeId id, Location locus);
+ bool lookup (const CanonicalPath &ident, NodeId *id);
- void iterate (std::function<bool (Rib *)> cb)
- {
- for (auto it = stack.rbegin (); it != stack.rend (); ++it)
- {
- if (!cb (*it))
- return;
- }
- }
+ void iterate (std::function<bool (Rib *)> cb);
- Rib *peek () { return stack.back (); }
+ Rib *peek ();
+ void push (NodeId id);
+ Rib *pop ();
- void push (NodeId id) { stack.push_back (new Rib (get_crate_num (), id)); }
-
- Rib *pop ()
- {
- Rib *r = peek ();
- stack.pop_back ();
- return r;
- }
+ void append_reference_for_def (NodeId refId, NodeId defId);
CrateNum get_crate_num () const { return crate_num; }
- void append_reference_for_def (NodeId refId, NodeId defId)
- {
- bool ok = false;
- iterate ([&] (Rib *r) mutable -> bool {
- if (r->decl_was_declared_here (defId))
- {
- ok = true;
- r->append_reference_for_def (defId, refId);
- }
- return true;
- });
- rust_assert (ok);
- }
-
private:
CrateNum crate_num;
std::vector<Rib *> stack;
@@ -296,6 +151,11 @@ public:
void insert_resolved_macro (NodeId refId, NodeId defId);
bool lookup_resolved_macro (NodeId refId, NodeId *defId);
+ void mark_decl_mutability (NodeId id, bool mut);
+ bool decl_is_mutable (NodeId id) const;
+ void mark_assignment_to_decl (NodeId id, NodeId assignment);
+ size_t get_num_assignments_to_decl (NodeId id) const;
+
// proxy for scoping
Scope &get_name_scope () { return name_scope; }
Scope &get_type_scope () { return type_scope; }
@@ -303,67 +163,9 @@ public:
Scope &get_macro_scope () { return macro_scope; }
NodeId get_global_type_node_id () { return global_type_node_id; }
-
void set_unit_type_node_id (NodeId id) { unit_ty_node_id = id; }
NodeId get_unit_type_node_id () { return unit_ty_node_id; }
- void mark_decl_mutability (NodeId id, bool mut)
- {
- rust_assert (decl_mutability.find (id) == decl_mutability.end ());
- decl_mutability[id] = mut;
- }
-
- bool decl_is_mutable (NodeId id) const
- {
- auto it = decl_mutability.find (id);
- rust_assert (it != decl_mutability.end ());
- return it->second;
- }
-
- void mark_assignment_to_decl (NodeId id, NodeId assignment)
- {
- auto it = assignment_to_decl.find (id);
- if (it == assignment_to_decl.end ())
- assignment_to_decl[id] = {};
-
- assignment_to_decl[id].insert (assignment);
- }
-
- size_t get_num_assignments_to_decl (NodeId id) const
- {
- auto it = assignment_to_decl.find (id);
- if (it == assignment_to_decl.end ())
- return 0;
-
- return it->second.size ();
- }
-
- void iterate_name_ribs (std::function<bool (Rib *)> cb)
- {
- for (auto it = name_ribs.begin (); it != name_ribs.end (); it++)
- if (!cb (it->second))
- break;
- }
-
- void iterate_type_ribs (std::function<bool (Rib *)> cb)
- {
- for (auto it = type_ribs.begin (); it != type_ribs.end (); it++)
- {
- if (it->first == global_type_node_id)
- continue;
-
- if (!cb (it->second))
- break;
- }
- }
-
- void iterate_label_ribs (std::function<bool (Rib *)> cb)
- {
- for (auto it = label_ribs.begin (); it != label_ribs.end (); it++)
- if (!cb (it->second))
- break;
- }
-
private:
Resolver ();
diff --git a/gcc/rust/util/rust-attributes.cc b/gcc/rust/util/rust-attributes.cc
index c9112eb..77f884e 100644
--- a/gcc/rust/util/rust-attributes.cc
+++ b/gcc/rust/util/rust-attributes.cc
@@ -32,6 +32,7 @@ static const BuiltinAttrDefinition __definitions[] = {
{"must_use", STATIC_ANALYSIS},
{"lang", HIR_LOWERING},
{"link_section", CODE_GENERATION},
+ {"no_mangle", CODE_GENERATION},
};
BuiltinAttributeMappings *
diff --git a/gcc/testsuite/rust/compile/attr_cold.rs b/gcc/testsuite/rust/compile/attr_cold.rs
index 883d2f8..f705ea9 100644
--- a/gcc/testsuite/rust/compile/attr_cold.rs
+++ b/gcc/testsuite/rust/compile/attr_cold.rs
@@ -1,11 +1,11 @@
-// { dg-additional-options "-fdump-tree-gimple }
+// { dg-additional-options "-fdump-tree-gimple" }
#[cold]
fn cold_function() -> i32 {
42
}
fn main() -> i32 {
- // { dg-final { scan-tree-dump-times {__attribute__((cdecl, cold))} 1 gimple } }
+ // { dg-final { scan-tree-dump-times {__attribute__\(\(cdecl, cold\)\)} 1 gimple } }
cold_function();
0
diff --git a/gcc/testsuite/rust/debug/no_mangle.rs b/gcc/testsuite/rust/debug/no_mangle.rs
new file mode 100644
index 0000000..0cef404
--- /dev/null
+++ b/gcc/testsuite/rust/debug/no_mangle.rs
@@ -0,0 +1,17 @@
+#[no_mangle]
+fn do_not_mangle() -> i32 {
+ 0
+}
+
+fn please_mangle() {}
+
+fn main() {
+// { dg-do compile }
+// { dg-options "-gdwarf-5 -dA" }
+ let _ = do_not_mangle();
+ please_mangle();
+// look for unmangled function name:
+// { dg-final { scan-assembler "do_not_mangle:" } } */
+// look for legacy mangled function name:
+// { dg-final { scan-assembler "13please_mangle" } } */
+}