diff options
author | Thomas Schwinge <thomas@codesourcery.com> | 2021-09-09 14:17:41 +0200 |
---|---|---|
committer | Thomas Schwinge <thomas@codesourcery.com> | 2021-09-09 14:17:41 +0200 |
commit | e17824d3c307376ac79041836dc3eea6ffcb6046 (patch) | |
tree | eb8033b46d5d9fe7fcae7542913b100552c0af75 /gcc | |
parent | a8fb0fd650712b91c7c18a493b56e10faa5a1fd0 (diff) | |
parent | bca1debe33bf477df850db5979e4206627b3790b (diff) | |
download | gcc-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.in | 1 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile-context.h | 16 | ||||
-rw-r--r-- | gcc/rust/backend/rust-compile.cc | 103 | ||||
-rw-r--r-- | gcc/rust/backend/rust-mangle.cc | 152 | ||||
-rw-r--r-- | gcc/rust/backend/rust-mangle.h | 54 | ||||
-rw-r--r-- | gcc/rust/lang.opt | 13 | ||||
-rw-r--r-- | gcc/rust/rust-gcc.cc | 1 | ||||
-rw-r--r-- | gcc/rust/rust-session-manager.cc | 2 |
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> ¶ms - = 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> ¶ms + = 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 |