diff options
-rw-r--r-- | gcc/rust/Make-lang.in | 1 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-base.cc | 100 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-base.h | 10 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve.cc | 294 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-name-resolver.cc | 513 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-name-resolver.h | 244 | ||||
-rw-r--r-- | gcc/rust/util/rust-attributes.cc | 1 | ||||
-rw-r--r-- | gcc/testsuite/rust/compile/attr_cold.rs | 4 | ||||
-rw-r--r-- | gcc/testsuite/rust/debug/no_mangle.rs | 17 |
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" } } */ +} |