diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-08-11 14:44:18 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-11 14:44:18 +0000 |
commit | a0ba86c3bef853ff8a0c282c10c3e0cb1811a507 (patch) | |
tree | 1503b24e108ce680a9f959917c2ac8edc02e9746 /gcc | |
parent | ed64f39213d764206997ee88c2ef89c601763eca (diff) | |
parent | 06ce0a66557f7989a945733e9e51250a7d05f266 (diff) | |
download | gcc-a0ba86c3bef853ff8a0c282c10c3e0cb1811a507.zip gcc-a0ba86c3bef853ff8a0c282c10c3e0cb1811a507.tar.gz gcc-a0ba86c3bef853ff8a0c282c10c3e0cb1811a507.tar.bz2 |
Merge #623
623: Add mappings for canonical paths r=philberty a=philberty
We need to be able to lookup canonical paths in order
to do proper name mangling as well as give more meaning
full names to the GENERIC IR. This is important since
the gcc IR is flat and makes it hard to distinguish which function
is which, especially when modules support will be added.
Co-authored-by: Philip Herron <philip.herron@embecosm.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/backend/rust-compile-implitem.h | 18 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-item.h | 26 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-name-resolver.h | 110 | ||||
-rw-r--r-- | gcc/rust/util/rust-canonical-path.h | 141 | ||||
-rw-r--r-- | gcc/rust/util/rust-hir-map.h | 62 | ||||
-rw-r--r-- | gcc/rust/util/rust-mapping-common.h | 48 |
6 files changed, 270 insertions, 135 deletions
diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h index 83af5de..7608599 100644 --- a/gcc/rust/backend/rust-compile-implitem.h +++ b/gcc/rust/backend/rust-compile-implitem.h @@ -52,7 +52,12 @@ public: ::Btype *type = TyTyResolveCompile::compile (ctx, resolved_type); Bexpression *value = CompileExpr::Compile (constant.get_expr (), ctx); - std::string ident = self->get_name () + "_" + constant.get_identifier (); + const Resolver::CanonicalPath *canonical_path = nullptr; + rust_assert (ctx->get_mappings ()->lookup_canonical_path ( + constant.get_mappings ().get_crate_num (), + constant.get_mappings ().get_nodeid (), &canonical_path)); + + std::string ident = canonical_path->get (); Bexpression *const_expr = ctx->get_backend ()->named_constant_expression ( type, constant.get_identifier (), value, constant.get_locus ()); @@ -121,13 +126,18 @@ public: if (function.has_visibility ()) flags |= Backend::function_is_visible; - std::string fn_identifier - = self->get_name () + "_" + function.get_function_name (); + const Resolver::CanonicalPath *canonical_path = nullptr; + rust_assert (ctx->get_mappings ()->lookup_canonical_path ( + function.get_mappings ().get_crate_num (), + function.get_mappings ().get_nodeid (), &canonical_path)); + + std::string ir_symbol_name + = canonical_path->get () + fntype->subst_as_string (); std::string asm_name = ctx->mangle_impl_item (self, fntype, function.get_function_name ()); Bfunction *fndecl - = ctx->get_backend ()->function (compiled_fn_type, fn_identifier, + = ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name, asm_name, flags, function.get_locus ()); ctx->insert_function_decl (fntype->get_ty_ref (), fndecl, fntype); diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h index a6bc7f3..719d51c 100644 --- a/gcc/rust/backend/rust-compile-item.h +++ b/gcc/rust/backend/rust-compile-item.h @@ -53,7 +53,12 @@ public: Btype *type = TyTyResolveCompile::compile (ctx, resolved_type); Bexpression *value = CompileExpr::Compile (var.get_expr (), ctx); - std::string name = var.get_identifier (); + const Resolver::CanonicalPath *canonical_path = nullptr; + rust_assert (ctx->get_mappings ()->lookup_canonical_path ( + var.get_mappings ().get_crate_num (), var.get_mappings ().get_nodeid (), + &canonical_path)); + + std::string name = canonical_path->get (); std::string asm_name = ctx->mangle_item (resolved_type, name); bool is_external = false; @@ -81,8 +86,15 @@ public: ::Btype *type = TyTyResolveCompile::compile (ctx, resolved_type); Bexpression *value = CompileExpr::Compile (constant.get_expr (), ctx); - Bexpression *const_expr = ctx->get_backend ()->named_constant_expression ( - type, constant.get_identifier (), value, constant.get_locus ()); + const Resolver::CanonicalPath *canonical_path = nullptr; + rust_assert (ctx->get_mappings ()->lookup_canonical_path ( + constant.get_mappings ().get_crate_num (), + constant.get_mappings ().get_nodeid (), &canonical_path)); + + std::string ident = canonical_path->get (); + Bexpression *const_expr + = ctx->get_backend ()->named_constant_expression (type, ident, value, + constant.get_locus ()); ctx->push_const (const_expr); ctx->insert_const_decl (constant.get_mappings ().get_hirid (), const_expr); @@ -149,7 +161,13 @@ public: if (is_main_fn || function.has_visibility ()) flags |= Backend::function_is_visible; - std::string ir_symbol_name = function.get_function_name (); + const Resolver::CanonicalPath *canonical_path = nullptr; + rust_assert (ctx->get_mappings ()->lookup_canonical_path ( + function.get_mappings ().get_crate_num (), + function.get_mappings ().get_nodeid (), &canonical_path)); + + std::string ir_symbol_name + = canonical_path->get () + fntype->subst_as_string (); std::string asm_name = function.get_function_name (); // we don't mangle the main fn since we haven't implemented the main shim diff --git a/gcc/rust/resolve/rust-name-resolver.h b/gcc/rust/resolve/rust-name-resolver.h index 5f01b94..1b26a46 100644 --- a/gcc/rust/resolve/rust-name-resolver.h +++ b/gcc/rust/resolve/rust-name-resolver.h @@ -20,118 +20,13 @@ #define RUST_NAME_RESOLVER_H #include "rust-system.h" +#include "rust-canonical-path.h" #include "rust-hir-map.h" #include "rust-hir-type-check.h" namespace Rust { namespace Resolver { -// https://doc.rust-lang.org/reference/paths.html#canonical-paths -// -// struct X - path X -// impl X { fn test - path X::test } -// -// struct X<T> - path X -// -// impl X<T> { fn test - path X::test} -// impl X<i32> { fn test - path X<i32>::test } -// impl X<f32> { fn test - path X<f32>::test } -// -// pub trait Trait { // ::a::Trait -// fn f(&self); // ::a::Trait::f -// } -// -// impl Trait for Struct { -// fn f(&self) {} // <::a::Struct as ::a::Trait>::f -// } -class CanonicalPath -{ -public: - CanonicalPath (const CanonicalPath &other) : segs (other.segs) {} - - CanonicalPath &operator= (const CanonicalPath &other) - { - segs = other.segs; - return *this; - } - - static CanonicalPath new_seg (NodeId id, const std::string &path) - { - rust_assert (!path.empty ()); - return CanonicalPath ({std::pair<NodeId, std::string> (id, path)}); - } - - std::string get () const - { - std::string buf; - for (size_t i = 0; i < segs.size (); i++) - { - bool have_more = (i + 1) < segs.size (); - const std::string &seg = segs.at (i).second; - buf += seg + (have_more ? "::" : ""); - } - return buf; - } - - static CanonicalPath get_big_self (NodeId id) - { - return CanonicalPath::new_seg (id, "Self"); - } - - static CanonicalPath create_empty () { return CanonicalPath ({}); } - - bool is_empty () const { return segs.size () == 0; } - - CanonicalPath append (const CanonicalPath &other) const - { - rust_assert (!other.is_empty ()); - if (is_empty ()) - return CanonicalPath (other.segs); - - std::vector<std::pair<NodeId, std::string>> copy (segs); - for (auto &s : other.segs) - copy.push_back (s); - - return CanonicalPath (copy); - } - - // if we have the path A::B::C this will give a callback for each segment - // example: - // A - // A::B - // A::B::C - void iterate (std::function<bool (const CanonicalPath &)> cb) const - { - std::vector<std::pair<NodeId, std::string>> buf; - for (auto &seg : segs) - { - buf.push_back (seg); - if (!cb (CanonicalPath (buf))) - return; - } - } - - NodeId get_id () const - { - rust_assert (!segs.empty ()); - return segs.back ().first; - } - - bool operator== (const CanonicalPath &b) const - { - return get ().compare (b.get ()) == 0; - } - - bool operator< (const CanonicalPath &b) const { return get () < b.get (); } - -private: - explicit CanonicalPath (std::vector<std::pair<NodeId, std::string>> path) - : segs (path) - {} - - std::vector<std::pair<NodeId, std::string>> segs; -}; - class Rib { public: @@ -167,6 +62,9 @@ public: reverse_mappings.insert (std::pair<NodeId, CanonicalPath> (id, path)); decls_within_rib.insert (std::pair<NodeId, Location> (id, locus)); references[id] = {}; + + auto mappings = Analysis::Mappings::get (); + mappings->insert_canonical_path (mappings->get_current_crate (), id, path); } bool lookup_name (const CanonicalPath &ident, NodeId *id) diff --git a/gcc/rust/util/rust-canonical-path.h b/gcc/rust/util/rust-canonical-path.h new file mode 100644 index 0000000..d6ba90d --- /dev/null +++ b/gcc/rust/util/rust-canonical-path.h @@ -0,0 +1,141 @@ +// Copyright (C) 2020 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_CANONICAL_PATH +#define RUST_CANONICAL_PATH + +#include "rust-system.h" +#include "rust-mapping-common.h" + +namespace Rust { +namespace Resolver { + +// https://doc.rust-lang.org/reference/paths.html#canonical-paths +// +// struct X - path X +// impl X { fn test - path X::test } +// +// struct X<T> - path X +// +// impl X<T> { fn test - path X::test} +// impl X<i32> { fn test - path X<i32>::test } +// impl X<f32> { fn test - path X<f32>::test } +// +// pub trait Trait { // ::a::Trait +// fn f(&self); // ::a::Trait::f +// } +// +// impl Trait for Struct { +// fn f(&self) {} // <::a::Struct as ::a::Trait>::f +// } +class CanonicalPath +{ +public: + CanonicalPath (const CanonicalPath &other) : segs (other.segs) {} + + CanonicalPath &operator= (const CanonicalPath &other) + { + segs = other.segs; + return *this; + } + + static CanonicalPath new_seg (NodeId id, const std::string &path) + { + rust_assert (!path.empty ()); + return CanonicalPath ({std::pair<NodeId, std::string> (id, path)}); + } + + std::string get () const + { + std::string buf; + for (size_t i = 0; i < segs.size (); i++) + { + bool have_more = (i + 1) < segs.size (); + const std::string &seg = segs.at (i).second; + buf += seg + (have_more ? "::" : ""); + } + return buf; + } + + static CanonicalPath get_big_self (NodeId id) + { + return CanonicalPath::new_seg (id, "Self"); + } + + static CanonicalPath create_empty () { return CanonicalPath ({}); } + + bool is_empty () const { return segs.size () == 0; } + + CanonicalPath append (const CanonicalPath &other) const + { + rust_assert (!other.is_empty ()); + if (is_empty ()) + return CanonicalPath (other.segs); + + std::vector<std::pair<NodeId, std::string>> copy (segs); + for (auto &s : other.segs) + copy.push_back (s); + + return CanonicalPath (copy); + } + + // if we have the path A::B::C this will give a callback for each segment + // example: + // A + // A::B + // A::B::C + void iterate (std::function<bool (const CanonicalPath &)> cb) const + { + std::vector<std::pair<NodeId, std::string>> buf; + for (auto &seg : segs) + { + buf.push_back (seg); + if (!cb (CanonicalPath (buf))) + return; + } + } + + size_t size () const { return segs.size (); } + + NodeId get_id () const + { + rust_assert (!segs.empty ()); + return segs.back ().first; + } + + bool is_equal (const CanonicalPath &b) const + { + return get ().compare (b.get ()) == 0; + } + + bool operator== (const CanonicalPath &b) const { return is_equal (b); } + + bool operator< (const CanonicalPath &b) const { return get () < b.get (); } + +private: + explicit CanonicalPath (std::vector<std::pair<NodeId, std::string>> path) + : segs (path) + {} + + std::vector<std::pair<NodeId, std::string>> segs; +}; + +} // namespace Resolver +} // namespace Rust + +#endif // RUST_CANONICAL_PATH diff --git a/gcc/rust/util/rust-hir-map.h b/gcc/rust/util/rust-hir-map.h index f689abf..5c839b0 100644 --- a/gcc/rust/util/rust-hir-map.h +++ b/gcc/rust/util/rust-hir-map.h @@ -21,32 +21,13 @@ #include "rust-system.h" #include "rust-location.h" +#include "rust-mapping-common.h" +#include "rust-canonical-path.h" #include "rust-ast-full-decls.h" #include "rust-hir-full-decls.h" namespace Rust { - -// refers to a Crate -typedef uint32_t CrateNum; -// refers to any node in the AST in current Crate -typedef uint32_t NodeId; -// refers to any node in the HIR for the current crate -typedef uint32_t HirId; -// refers to any top-level decl in HIR -typedef uint32_t LocalDefId; -// refers to <Crate><DefId> -typedef uint64_t DefId; - -#define DEF_ID_CRATE_MASK 0xFFFFFFFF00000000 -#define DEF_ID_LOCAL_DEF_MASK 0x00000000FFFFFFFF - -#define UNKNOWN_CREATENUM ((uint32_t) (0)) -#define UNKNOWN_NODEID ((uint32_t) (0)) -#define UNKNOWN_HIRID ((uint32_t) (0)) -#define UNKNOWN_LOCAL_DEFID ((uint32_t) (0)) -#define UNKNOWN_DEFID ((uint64_t) (0)) - namespace Analysis { class NodeMapping @@ -247,6 +228,42 @@ public: return lookup->second; } + void insert_canonical_path (CrateNum crate, NodeId id, + const Resolver::CanonicalPath path) + { + const Resolver::CanonicalPath *p = nullptr; + if (lookup_canonical_path (crate, id, &p)) + { + // if we have already stored a canonical path this is ok so long as this + // new path is equal or is smaller that the existing one but in that + // case we ignore it. + if (p->is_equal (path)) + return; + else + { + rust_assert (p->size () >= path.size ()); + return; + } + } + + paths[crate].emplace (id, std::move (path)); + } + + bool lookup_canonical_path (CrateNum crate, NodeId id, + const Resolver::CanonicalPath **path) + { + auto it = paths.find (crate); + if (it == paths.end ()) + return false; + + auto iy = it->second.find (id); + if (iy == it->second.end ()) + return false; + + *path = &iy->second; + return true; + } + private: Mappings (); @@ -283,6 +300,9 @@ private: hirGenericParamMappings; std::map<HirId, HIR::Trait *> hirTraitItemsToTraitMappings; + // canonical paths + std::map<CrateNum, std::map<NodeId, const Resolver::CanonicalPath> > paths; + // location info std::map<CrateNum, std::map<NodeId, Location> > locations; diff --git a/gcc/rust/util/rust-mapping-common.h b/gcc/rust/util/rust-mapping-common.h new file mode 100644 index 0000000..45af11b --- /dev/null +++ b/gcc/rust/util/rust-mapping-common.h @@ -0,0 +1,48 @@ +// Copyright (C) 2020 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_MAPPING_COMMON +#define RUST_MAPPING_COMMON + +#include "rust-system.h" + +namespace Rust { + +// refers to a Crate +typedef uint32_t CrateNum; +// refers to any node in the AST in current Crate +typedef uint32_t NodeId; +// refers to any node in the HIR for the current crate +typedef uint32_t HirId; +// refers to any top-level decl in HIR +typedef uint32_t LocalDefId; +// refers to <Crate><DefId> +typedef uint64_t DefId; + +#define DEF_ID_CRATE_MASK 0xFFFFFFFF00000000 +#define DEF_ID_LOCAL_DEF_MASK 0x00000000FFFFFFFF + +#define UNKNOWN_CREATENUM ((uint32_t) (0)) +#define UNKNOWN_NODEID ((uint32_t) (0)) +#define UNKNOWN_HIRID ((uint32_t) (0)) +#define UNKNOWN_LOCAL_DEFID ((uint32_t) (0)) +#define UNKNOWN_DEFID ((uint64_t) (0)) + +} // namespace Rust + +#endif // RUST_MAPPING_COMMON |