aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend/rust-mangle.cc
diff options
context:
space:
mode:
authorCohenArthur <arthur.cohen@epita.fr>2021-08-11 23:30:11 +0200
committerCohenArthur <arthur.cohen@epita.fr>2021-09-05 17:21:40 +0200
commit91507076503d57982218c726a712c48adc7a4e1d (patch)
tree2a84bd1e2ea1df140aa3ac31b1c3fd5dbf0cea33 /gcc/rust/backend/rust-mangle.cc
parent50623899998de5a8ffe47227a351c2b3dd29aa0a (diff)
downloadgcc-91507076503d57982218c726a712c48adc7a4e1d.zip
gcc-91507076503d57982218c726a712c48adc7a4e1d.tar.gz
gcc-91507076503d57982218c726a712c48adc7a4e1d.tar.bz2
name_mangling: Add Mangler class with multiple versions
Diffstat (limited to 'gcc/rust/backend/rust-mangle.cc')
-rw-r--r--gcc/rust/backend/rust-mangle.cc149
1 files changed, 149 insertions, 0 deletions
diff --git a/gcc/rust/backend/rust-mangle.cc b/gcc/rust/backend/rust-mangle.cc
new file mode 100644
index 0000000..f2e6e15
--- /dev/null
+++ b/gcc/rust/backend/rust-mangle.cc
@@ -0,0 +1,149 @@
+#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 {
+
+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