aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorThomas Schwinge <thomas@codesourcery.com>2021-09-09 14:17:41 +0200
committerThomas Schwinge <thomas@codesourcery.com>2021-09-09 14:17:41 +0200
commite17824d3c307376ac79041836dc3eea6ffcb6046 (patch)
treeeb8033b46d5d9fe7fcae7542913b100552c0af75 /gcc
parenta8fb0fd650712b91c7c18a493b56e10faa5a1fd0 (diff)
parentbca1debe33bf477df850db5979e4206627b3790b (diff)
downloadgcc-e17824d3c307376ac79041836dc3eea6ffcb6046.zip
gcc-e17824d3c307376ac79041836dc3eea6ffcb6046.tar.gz
gcc-e17824d3c307376ac79041836dc3eea6ffcb6046.tar.bz2
Merge commit 'bca1debe33bf477df850db5979e4206627b3790b' into HEAD
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/Make-lang.in1
-rw-r--r--gcc/rust/backend/rust-compile-context.h16
-rw-r--r--gcc/rust/backend/rust-compile.cc103
-rw-r--r--gcc/rust/backend/rust-mangle.cc152
-rw-r--r--gcc/rust/backend/rust-mangle.h54
-rw-r--r--gcc/rust/lang.opt13
-rw-r--r--gcc/rust/rust-gcc.cc1
-rw-r--r--gcc/rust/rust-session-manager.cc2
8 files changed, 235 insertions, 107 deletions
diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index d2d74e3..0e181a6 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -70,6 +70,7 @@ GRS_OBJS = \
rust/rust-ast-full-test.o \
rust/rust-session-manager.o \
rust/rust-compile.o \
+ rust/rust-mangle.o \
rust/rust-compile-resolve-path.o \
rust/rust-macro-expand.o \
rust/rust-hir-full-test.o \
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index bffe97c..05c15e3 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -28,6 +28,7 @@
#include "rust-ast-full.h"
#include "rust-hir-full.h"
#include "rust-hir-const-fold-ctx.h"
+#include "rust-mangle.h"
namespace Rust {
namespace Compile {
@@ -45,7 +46,7 @@ public:
: backend (backend), resolver (Resolver::Resolver::get ()),
tyctx (Resolver::TypeCheckContext::get ()),
mappings (Analysis::Mappings::get ()),
- const_ctx (ConstFold::Context::get ())
+ const_ctx (ConstFold::Context::get ()), mangler (Mangler ())
{
// insert the builtins
auto builtins = resolver->get_builtin_types ();
@@ -285,13 +286,19 @@ public:
return pop;
}
- // this needs to support Legacy and V0 see github #429 or #305
std::string mangle_item (const TyTy::BaseType *ty,
- const Resolver::CanonicalPath &path) const;
+ const Resolver::CanonicalPath &path) const
+ {
+ return mangler.mangle_item (ty, path, mappings->get_current_crate_name ());
+ }
std::string mangle_impl_item (const TyTy::BaseType *self,
const TyTy::BaseType *ty,
- const std::string &name) const;
+ const std::string &name) const
+ {
+ return mangler.mangle_impl_item (self, ty, name,
+ mappings->get_current_crate_name ());
+ }
private:
::Backend *backend;
@@ -300,6 +307,7 @@ private:
Analysis::Mappings *mappings;
ConstFold::Context *const_ctx;
std::set<HirId> builtin_range;
+ Mangler mangler;
// state
std::vector<fncontext> fn_stack;
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 0a65b15..ef2c16a 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -22,7 +22,6 @@
#include "rust-compile-struct-field-expr.h"
#include "rust-hir-trait-resolve.h"
#include "rust-hir-path-probe.h"
-#include "fnv-hash.h"
namespace Rust {
namespace Compile {
@@ -538,107 +537,5 @@ HIRCompileBase::compile_locals_for_block (Resolver::Rib &rib, Bfunction *fndecl,
return true;
}
-
-// Mr Mangle time
-
-static const std::string kMangledSymbolPrefix = "_ZN";
-static const std::string kMangledSymbolDelim = "E";
-static const std::string kMangledGenericDelim = "$C$";
-static const std::string kMangledSubstBegin = "$LT$";
-static const std::string kMangledSubstEnd = "$GT$";
-
-static std::string
-mangle_name (const std::string &name)
-{
- return std::to_string (name.size ()) + name;
-}
-
-static std::string
-mangle_canonical_path (const Resolver::CanonicalPath &path)
-{
- std::string buffer;
- path.iterate_segs ([&] (const Resolver::CanonicalPath &p) -> bool {
- buffer += mangle_name (p.get ());
- return true;
- });
- return buffer;
-}
-
-// rustc uses a sip128 hash for legacy mangling, but an fnv 128 was quicker to
-// implement for now
-static std::string
-legacy_hash (const std::string &fingerprint)
-{
- Hash::FNV128 hasher;
- hasher.write ((const unsigned char *) fingerprint.c_str (),
- fingerprint.size ());
-
- uint64_t hi, lo;
- hasher.sum (&hi, &lo);
-
- char hex[16 + 1];
- memset (hex, 0, sizeof hex);
- snprintf (hex, sizeof hex, "%08" PRIx64 "%08" PRIx64, lo, hi);
-
- return "h" + std::string (hex, sizeof (hex) - 1);
-}
-
-static std::string
-mangle_self (const TyTy::BaseType *self)
-{
- if (self->get_kind () != TyTy::TypeKind::ADT)
- return mangle_name (self->get_name ());
-
- const TyTy::ADTType *s = static_cast<const TyTy::ADTType *> (self);
- std::string buf = s->get_identifier ();
-
- if (s->has_subsititions_defined ())
- {
- buf += kMangledSubstBegin;
-
- const std::vector<TyTy::SubstitutionParamMapping> &params
- = s->get_substs ();
- for (size_t i = 0; i < params.size (); i++)
- {
- const TyTy::SubstitutionParamMapping &sub = params.at (i);
- buf += sub.as_string ();
-
- if ((i + 1) < params.size ())
- buf += kMangledGenericDelim;
- }
-
- buf += kMangledSubstEnd;
- }
-
- return mangle_name (buf);
-}
-
-std::string
-Context::mangle_item (const TyTy::BaseType *ty,
- const Resolver::CanonicalPath &path) const
-{
- const std::string &crate_name = mappings->get_current_crate_name ();
-
- const std::string hash = legacy_hash (ty->as_string ());
- const std::string hash_sig = mangle_name (hash);
-
- return kMangledSymbolPrefix + mangle_name (crate_name)
- + mangle_canonical_path (path) + hash_sig + kMangledSymbolDelim;
-}
-
-// FIXME this is a wee bit broken
-std::string
-Context::mangle_impl_item (const TyTy::BaseType *self, const TyTy::BaseType *ty,
- const std::string &name) const
-{
- const std::string &crate_name = mappings->get_current_crate_name ();
-
- const std::string hash = legacy_hash (ty->as_string ());
- const std::string hash_sig = mangle_name (hash);
-
- return kMangledSymbolPrefix + mangle_name (crate_name) + mangle_self (self)
- + mangle_name (name) + hash_sig + kMangledSymbolDelim;
-}
-
} // namespace Compile
} // namespace Rust
diff --git a/gcc/rust/backend/rust-mangle.cc b/gcc/rust/backend/rust-mangle.cc
new file mode 100644
index 0000000..40822b4
--- /dev/null
+++ b/gcc/rust/backend/rust-mangle.cc
@@ -0,0 +1,152 @@
+#include "rust-mangle.h"
+#include "fnv-hash.h"
+
+// FIXME: Rename those to legacy_*
+static const std::string kMangledSymbolPrefix = "_ZN";
+static const std::string kMangledSymbolDelim = "E";
+static const std::string kMangledGenericDelim = "$C$";
+static const std::string kMangledSubstBegin = "$LT$";
+static const std::string kMangledSubstEnd = "$GT$";
+
+namespace Rust {
+namespace Compile {
+
+Mangler::MangleVersion Mangler::version = MangleVersion::LEGACY;
+
+static std::string
+legacy_mangle_name (const std::string &name)
+{
+ return std::to_string (name.size ()) + name;
+}
+
+static std::string
+legacy_mangle_canonical_path (const Resolver::CanonicalPath &path)
+{
+ std::string buffer;
+ path.iterate_segs ([&] (const Resolver::CanonicalPath &p) -> bool {
+ buffer += legacy_mangle_name (p.get ());
+ return true;
+ });
+ return buffer;
+}
+
+// rustc uses a sip128 hash for legacy mangling, but an fnv 128 was quicker to
+// implement for now
+static std::string
+legacy_hash (const std::string &fingerprint)
+{
+ Hash::FNV128 hasher;
+ hasher.write ((const unsigned char *) fingerprint.c_str (),
+ fingerprint.size ());
+
+ uint64_t hi, lo;
+ hasher.sum (&hi, &lo);
+
+ char hex[16 + 1];
+ memset (hex, 0, sizeof hex);
+ snprintf (hex, sizeof hex, "%08" PRIx64 "%08" PRIx64, lo, hi);
+
+ return "h" + std::string (hex, sizeof (hex) - 1);
+}
+
+static std::string
+legacy_mangle_self (const TyTy::BaseType *self)
+{
+ if (self->get_kind () != TyTy::TypeKind::ADT)
+ return legacy_mangle_name (self->get_name ());
+
+ const TyTy::ADTType *s = static_cast<const TyTy::ADTType *> (self);
+ std::string buf = s->get_identifier ();
+
+ if (s->has_subsititions_defined ())
+ {
+ buf += kMangledSubstBegin;
+
+ const std::vector<TyTy::SubstitutionParamMapping> &params
+ = s->get_substs ();
+ for (size_t i = 0; i < params.size (); i++)
+ {
+ const TyTy::SubstitutionParamMapping &sub = params.at (i);
+ buf += sub.as_string ();
+
+ if ((i + 1) < params.size ())
+ buf += kMangledGenericDelim;
+ }
+
+ buf += kMangledSubstEnd;
+ }
+
+ return legacy_mangle_name (buf);
+}
+
+static std::string
+legacy_mangle_item (const TyTy::BaseType *ty,
+ const Resolver::CanonicalPath &path,
+ const std::string &crate_name)
+{
+ const std::string hash = legacy_hash (ty->as_string ());
+ const std::string hash_sig = legacy_mangle_name (hash);
+
+ return kMangledSymbolPrefix + legacy_mangle_name (crate_name)
+ + legacy_mangle_canonical_path (path) + hash_sig + kMangledSymbolDelim;
+}
+
+// FIXME this is a wee bit broken
+static std::string
+legacy_mangle_impl_item (const TyTy::BaseType *self, const TyTy::BaseType *ty,
+ const std::string &name, const std::string &crate_name)
+{
+ const std::string hash = legacy_hash (ty->as_string ());
+ const std::string hash_sig = legacy_mangle_name (hash);
+
+ return kMangledSymbolPrefix + legacy_mangle_name (crate_name)
+ + legacy_mangle_self (self) + legacy_mangle_name (name) + hash_sig
+ + kMangledSymbolDelim;
+}
+
+// FIXME: Uncomment once v0 mangling is implemented
+// static std::string
+// Mangler::v0_mangle_item (const TyTy::BaseType *ty,
+// const std::string &name)
+// {}
+//
+// static std::string
+// Mangler::v0_mangle_impl_item (const TyTy::BaseType *self,
+// const TyTy::BaseType *ty,
+// const std::string &name)
+// {}
+
+std::string
+Mangler::mangle_item (const TyTy::BaseType *ty,
+ const Resolver::CanonicalPath &path,
+ const std::string &crate_name) const
+{
+ switch (version)
+ {
+ case Mangler::MangleVersion::LEGACY:
+ return legacy_mangle_item (ty, path, crate_name);
+ case Mangler::MangleVersion::V0:
+ gcc_unreachable ();
+ default:
+ gcc_unreachable ();
+ }
+}
+
+std::string
+Mangler::mangle_impl_item (const TyTy::BaseType *self, const TyTy::BaseType *ty,
+ const std::string &name,
+ const std::string &crate_name) const
+{
+ switch (version)
+ {
+ case Mangler::MangleVersion::LEGACY:
+ return legacy_mangle_impl_item (self, ty, name, crate_name);
+ case Mangler::MangleVersion::V0:
+ gcc_unreachable ();
+ default:
+ gcc_unreachable ();
+ }
+}
+
+} // namespace Compile
+} // namespace Rust
diff --git a/gcc/rust/backend/rust-mangle.h b/gcc/rust/backend/rust-mangle.h
new file mode 100644
index 0000000..9e77c54
--- /dev/null
+++ b/gcc/rust/backend/rust-mangle.h
@@ -0,0 +1,54 @@
+// 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_MANGLE_H
+#define RUST_MANGLE_H
+
+#include "rust-compile-tyty.h"
+
+namespace Rust {
+namespace Compile {
+class Mangler
+{
+public:
+ enum MangleVersion
+ {
+ // Values defined in rust/lang.opt
+ LEGACY = 0,
+ V0 = 1,
+ };
+
+ // this needs to support Legacy and V0 see github #429 or #305
+ std::string mangle_item (const TyTy::BaseType *ty,
+ const Resolver::CanonicalPath &path,
+ const std::string &crate_name) const;
+
+ std::string mangle_impl_item (const TyTy::BaseType *self,
+ const TyTy::BaseType *ty,
+ const std::string &name,
+ const std::string &crate_name) const;
+
+ static void set_mangling (int frust_mangling_value)
+ {
+ version = static_cast<MangleVersion> (frust_mangling_value);
+ }
+
+private:
+ static enum MangleVersion version;
+};
+} // namespace Compile
+} // namespace Rust
+#endif // RUST_MANGLE_H
diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt
index 707feeb..27e3c44 100644
--- a/gcc/rust/lang.opt
+++ b/gcc/rust/lang.opt
@@ -43,6 +43,19 @@ frust-dump-
Rust Joined RejectNegative
-frust-dump-<type> Dump Rust frontend internal information.
+frust-mangling=
+Rust Joined RejectNegative Enum(frust_mangling) Var(flag_rust_mangling)
+-frust-mangling=[legacy|v0] Choose which version to use for name mangling
+
+Enum
+Name(frust_mangling) Type(int) UnknownError(unknown rust mangling option %qs)
+
+EnumValue
+Enum(frust_mangling) String(legacy) Value(0)
+
+EnumValue
+Enum(frust_mangling) String(v0) Value(1)
+
o
Rust Joined Separate
; Documented in common.opt
diff --git a/gcc/rust/rust-gcc.cc b/gcc/rust/rust-gcc.cc
index 453481e..4c1dda8 100644
--- a/gcc/rust/rust-gcc.cc
+++ b/gcc/rust/rust-gcc.cc
@@ -3499,6 +3499,7 @@ Gcc_backend::write_global_definitions (
rust_preserve_from_gc (decl);
if (DECL_STRUCT_FUNCTION (decl) == NULL)
allocate_struct_function (decl, false);
+ dump_function (TDI_original, decl);
cgraph_node::finalize_function (decl, true);
defs[i] = decl;
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 504f308..a924c4b 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -370,6 +370,8 @@ Session::handle_option (
ret = false;
}
break;
+ case OPT_frust_mangling_:
+ Compile::Mangler::set_mangling (flag_rust_mangling);
// no option handling for -o
default:
// return 1 to indicate option is valid