Skip to content

Commit

Permalink
gccrs: split rust-mangle.cc into two files
Browse files Browse the repository at this point in the history
gcc/rust/ChangeLog:

	* Make-lang.in: Add .o files
	* backend/rust-mangle.cc (struct V0Path): moved to splitted files
	(v0_path): Likewise.
	(legacy_mangle_name): Likewise.
	(legacy_mangle_canonical_path): Likewise.
	(legacy_hash): Likewise.
	(v0_tuple_prefix): Likewise.
	(v0_numeric_prefix): Likewise.
	(v0_simple_type_prefix): Likewise.
	(v0_complex_type_prefix): Likewise.
	(v0_integer_62): Likewise.
	(v0_opt_integer_62): Likewise.
	(v0_disambiguator): Likewise.
	(v0_type_prefix): Likewise.
	(v0_generic_args): Likewise.
	(v0_identifier): Likewise.
	(v0_type_path): Likewise.
	(v0_function_path): Likewise.
	(v0_scope_path): Likewise.
	(v0_crate_path): Likewise.
	(v0_inherent_or_trait_impl_path): Likewise.
	(v0_closure): Likewise.
	(legacy_mangle_item): Likewise.
	(v0_mangle_item): Likewise.
	* backend/rust-mangle.h (legacy_mangle_item): Likewise.
	(v0_mangle_item): Likewise.
	* backend/rust-mangle-legacy.cc: New file.
	* backend/rust-mangle-v0.cc: New file.

Signed-off-by: Raiki Tamura <[email protected]>
  • Loading branch information
tamaroning authored and CohenArthur committed Dec 26, 2023
1 parent 03a38a4 commit d8c5cf1
Show file tree
Hide file tree
Showing 5 changed files with 700 additions and 630 deletions.
2 changes: 2 additions & 0 deletions gcc/rust/Make-lang.in
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ GRS_OBJS = \
rust/rust-session-manager.o \
rust/rust-compile.o \
rust/rust-mangle.o \
rust/rust-mangle-v0.o \
rust/rust-mangle-legacy.o \
rust/rust-compile-resolve-path.o \
rust/rust-macro-expand.o \
rust/rust-cfg-strip.o \
Expand Down
164 changes: 164 additions & 0 deletions gcc/rust/backend/rust-mangle-legacy.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
// Copyright (C) 2020-2023 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/>.

#include "rust-mangle.h"
#include "fnv-hash.h"
#include "rust-unicode.h"
#include "rust-diagnostics.h"
#include "rust-system.h"
#include <sstream>

namespace Rust {
namespace Compile {

const std::string kLegacySymbolPrefix = "_ZN";
static const std::string kLegacySymbolDelim = "E";
static const std::string kLegacyGenericDelim = "$C$";
static const std::string kLegacySubstBegin = "$LT$";
static const std::string kLegacySubstEnd = "$GT$";
static const std::string kLegacySpace = "$u20$";
static const std::string kLegacyRef = "$RF$";
static const std::string kLegacyPtr = "$BP$";
static const std::string kLegacyLeftSqParen = "$u5b$"; // [
static const std::string kLegacyRightSqParen = "$u5d$"; // ]
static const std::string kLegacyLeftBrace = "$u7b$"; // {
static const std::string kLegacyRightBrace = "$u7d$"; // }
static const std::string kQualPathBegin = "_" + kLegacySubstBegin;
static const std::string kLegacyComma = "$C$";

static std::string
legacy_mangle_name (const std::string &name)
{
// example
// <&T as core::fmt::Debug>::fmt:
// _ZN42_$LT$$RF$T$u20$as$u20$core..fmt..Debug$GT$3fmt17h6dac924c0051eef7E
// replace all white space with $ and & with RF
//
// <example::Bar as example::A>::fooA:
// _ZN43_$LT$example..Bar$u20$as$u20$example..A$GT$4fooA17hfc615fa76c7db7a0E:
//
// core::ptr::const_ptr::<impl *const T>::cast:
// _ZN4core3ptr9const_ptr33_$LT$impl$u20$$BP$const$u20$T$GT$4cast17hb79f4617226f1d55E:
//
// core::ptr::const_ptr::<impl *const [T]>::as_ptr:
// _ZN4core3ptr9const_ptr43_$LT$impl$u20$$BP$const$u20$$u5b$T$u5d$$GT$6as_ptr17he16e0dcd9473b04fE:
//
// example::Foo<T>::new:
// _ZN7example12Foo$LT$T$GT$3new17h9a2aacb7fd783515E:
//
// <example::Identity as example::FnLike<&T,&T>>::call
// _ZN74_$LT$example..Identity$u20$as$u20$example..FnLike$LT$$RF$T$C$$RF$T$GT$$GT$4call17ha9ee58935895acb3E

tl::optional<Utf8String> utf8_name = Utf8String::make_utf8_string (name);
rust_assert (utf8_name.has_value ());
std::vector<Codepoint> chars = utf8_name.value ().get_chars ();
std::string buffer;
for (size_t i = 0; i < chars.size (); i++)
{
std::string m;
Codepoint c = chars.at (i);

if (c == ' ')
m = kLegacySpace;
else if (c == '&')
m = kLegacyRef;
else if (i == 0 && c == '<')
m = kQualPathBegin;
else if (c == '<')
m = kLegacySubstBegin;
else if (c == '>')
m = kLegacySubstEnd;
else if (c == '*')
m = kLegacyPtr;
else if (c == '[')
m = kLegacyLeftSqParen;
else if (c == ']')
m = kLegacyRightSqParen;
else if (c == '{')
m = kLegacyLeftBrace;
else if (c == '}')
m = kLegacyRightBrace;
else if (c == ',')
m = kLegacyComma;
else if (c == ':')
{
rust_assert (i + 1 < chars.size ());
rust_assert (chars.at (i + 1) == ':');
i++;
m = "..";
}
else if (c.is_ascii ())
// ASCII
m.push_back (c.value);
else
{
// Non-ASCII
std::stringstream escaped;
escaped << std::hex << "$u" << c.value << "$";
m += escaped.str ();
}
buffer += m;
}

return std::to_string (buffer.size ()) + buffer;
}

static std::string
legacy_mangle_canonical_path (const Resolver::CanonicalPath &path)
{
std::string buffer;
for (size_t i = 0; i < path.size (); i++)
{
auto &seg = path.get_seg_at (i);
buffer += legacy_mangle_name (seg.second);
}
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);
}

std::string
legacy_mangle_item (const TyTy::BaseType *ty,
const Resolver::CanonicalPath &path)
{
const std::string hash = legacy_hash (ty->mangle_string ());
const std::string hash_sig = legacy_mangle_name (hash);

return kLegacySymbolPrefix + legacy_mangle_canonical_path (path) + hash_sig
+ kLegacySymbolDelim;
}

} // namespace Compile
} // namespace Rust
Loading

0 comments on commit d8c5cf1

Please sign in to comment.