aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/backend
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2021-05-07 16:53:17 +0100
committerPhilip Herron <philip.herron@embecosm.com>2021-05-11 18:09:57 +0100
commit58e108c7c6d0fa3c9ebc7eeb681851924e22ddd5 (patch)
tree95c03868e9d05a84000e29187e2e5ccba431cd35 /gcc/rust/backend
parentc04343dbab902e5b8a5f047266645a5e7d40a5ed (diff)
downloadgcc-58e108c7c6d0fa3c9ebc7eeb681851924e22ddd5.zip
gcc-58e108c7c6d0fa3c9ebc7eeb681851924e22ddd5.tar.gz
gcc-58e108c7c6d0fa3c9ebc7eeb681851924e22ddd5.tar.bz2
Implement basic rustc legacy symbol mangling
Rust supports two different symbol mangling methods legacy and V0. V0 is the goal but its not yet stable. This implements the legacy method but with a dummy hash value since it requires a sip128 implementation to generate the apropriate hash which can be done in a sperate change. This change allows us to actually assemble generic functions and avoid bad symbol duplications. Addresses #305
Diffstat (limited to 'gcc/rust/backend')
-rw-r--r--gcc/rust/backend/rust-compile-context.h5
-rw-r--r--gcc/rust/backend/rust-compile-implitem.h16
-rw-r--r--gcc/rust/backend/rust-compile-item.h21
-rw-r--r--gcc/rust/backend/rust-compile.cc68
4 files changed, 88 insertions, 22 deletions
diff --git a/gcc/rust/backend/rust-compile-context.h b/gcc/rust/backend/rust-compile-context.h
index bdc9eca..7db4ea2 100644
--- a/gcc/rust/backend/rust-compile-context.h
+++ b/gcc/rust/backend/rust-compile-context.h
@@ -258,6 +258,11 @@ public:
return pop;
}
+ std::string mangle_item (const std::string &name) const;
+
+ std::string mangle_impl_item (const TyTy::BaseType *self,
+ const std::string &name) const;
+
private:
::Backend *backend;
Resolver::Resolver *resolver;
diff --git a/gcc/rust/backend/rust-compile-implitem.h b/gcc/rust/backend/rust-compile-implitem.h
index cee3a3b..f2caa2e 100644
--- a/gcc/rust/backend/rust-compile-implitem.h
+++ b/gcc/rust/backend/rust-compile-implitem.h
@@ -112,15 +112,17 @@ public:
::Btype *compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
unsigned int flags = 0;
- std::string fn_identifier
- = self->get_name () + "_" + function.get_function_name ();
// if its the main fn or pub visibility mark its as DECL_PUBLIC
// please see https://github.com/Rust-GCC/gccrs/pull/137
if (function.has_visibility ())
flags |= Backend::function_is_visible;
- std::string asm_name = fn_identifier;
+ std::string fn_identifier
+ = self->get_name () + "_" + function.get_function_name ();
+ std::string asm_name
+ = ctx->mangle_impl_item (self, function.get_function_name ());
+
Bfunction *fndecl
= ctx->get_backend ()->function (compiled_fn_type, fn_identifier,
asm_name, flags, function.get_locus ());
@@ -291,15 +293,17 @@ public:
::Btype *compiled_fn_type = TyTyResolveCompile::compile (ctx, fntype);
unsigned int flags = 0;
- std::string fn_identifier
- = self->get_name () + "_" + method.get_method_name ();
// if its the main fn or pub visibility mark its as DECL_PUBLIC
// please see https://github.com/Rust-GCC/gccrs/pull/137
if (method.has_visibility ())
flags |= Backend::function_is_visible;
- std::string asm_name = fn_identifier;
+ std::string fn_identifier
+ = self->get_name () + "_" + method.get_method_name ();
+ std::string asm_name
+ = ctx->mangle_impl_item (self, method.get_method_name ());
+
Bfunction *fndecl
= ctx->get_backend ()->function (compiled_fn_type, fn_identifier,
asm_name, flags, method.get_locus ());
diff --git a/gcc/rust/backend/rust-compile-item.h b/gcc/rust/backend/rust-compile-item.h
index 2bbfe4c..5a7d846 100644
--- a/gcc/rust/backend/rust-compile-item.h
+++ b/gcc/rust/backend/rust-compile-item.h
@@ -53,8 +53,7 @@ public:
Bexpression *value = CompileExpr::Compile (var.get_expr (), ctx);
std::string name = var.get_identifier ();
- // FIXME need name mangling
- std::string asm_name = "__" + var.get_identifier ();
+ std::string asm_name = ctx->mangle_item (name);
bool is_external = false;
bool is_hidden = false;
@@ -147,21 +146,11 @@ public:
std::string ir_symbol_name = function.get_function_name ();
std::string asm_name = function.get_function_name ();
- if (!is_main_fn)
- {
- // FIXME need name mangling
- if (concrete == nullptr)
- asm_name = "__" + function.get_function_name ();
- else
- {
- ir_symbol_name
- = function.get_function_name () + fntype->subst_as_string ();
- asm_name = "__" + function.get_function_name ();
- for (auto &sub : fntype->get_substs ())
- asm_name += "G" + sub.as_string ();
- }
- }
+ // we don't mangle the main fn since we haven't implemented the main shim
+ // yet
+ if (!is_main_fn)
+ asm_name = ctx->mangle_item (ir_symbol_name);
Bfunction *fndecl
= ctx->get_backend ()->function (compiled_fn_type, ir_symbol_name,
diff --git a/gcc/rust/backend/rust-compile.cc b/gcc/rust/backend/rust-compile.cc
index 4893541..9dd3b57 100644
--- a/gcc/rust/backend/rust-compile.cc
+++ b/gcc/rust/backend/rust-compile.cc
@@ -413,5 +413,73 @@ HIRCompileBase::compile_function_body (
}
}
+// 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
+dummy_hash ()
+{
+ return "h0123456789abcdef";
+}
+
+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 std::string &name) const
+{
+ const std::string &crate_name = mappings->get_current_crate_name ();
+ return kMangledSymbolPrefix + mangle_name (crate_name) + mangle_name (name)
+ + mangle_name (dummy_hash ()) + kMangledSymbolDelim;
+}
+
+std::string
+Context::mangle_impl_item (const TyTy::BaseType *self,
+ const std::string &name) const
+{
+ const std::string &crate_name = mappings->get_current_crate_name ();
+ return kMangledSymbolPrefix + mangle_name (crate_name) + mangle_self (self)
+ + mangle_name (name) + mangle_name (dummy_hash ())
+ + kMangledSymbolDelim;
+}
+
} // namespace Compile
} // namespace Rust