aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPhilip Herron <philip.herron@embecosm.com>2022-06-29 12:01:05 +0100
committerPhilip Herron <philip.herron@embecosm.com>2022-06-29 12:10:08 +0100
commit1282974cf899f9486c62054bcbadf41346915dd5 (patch)
treeb556162c6cb759c387191527ea6f001c300c3ab3 /gcc
parentc88cc0aa644836c361ce5d8ff5225a9c12333dea (diff)
downloadgcc-1282974cf899f9486c62054bcbadf41346915dd5.zip
gcc-1282974cf899f9486c62054bcbadf41346915dd5.tar.gz
gcc-1282974cf899f9486c62054bcbadf41346915dd5.tar.bz2
Ensure we support generic arguments on mangled type-paths
This allows us to have the generic arguments within type paths for mangled symbols such as those in impl-blocks. This also updates our symbol managling to mangle comma's to $C$.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rust/backend/rust-mangle.cc6
-rw-r--r--gcc/rust/resolve/rust-ast-resolve-type.cc47
2 files changed, 52 insertions, 1 deletions
diff --git a/gcc/rust/backend/rust-mangle.cc b/gcc/rust/backend/rust-mangle.cc
index c0aea02..4d20207 100644
--- a/gcc/rust/backend/rust-mangle.cc
+++ b/gcc/rust/backend/rust-mangle.cc
@@ -14,6 +14,7 @@ static const std::string kMangledPtr = "$BP$";
static const std::string kMangledLeftSqParen = "$u5b$"; // [
static const std::string kMangledRightSqParen = "$u5d$"; // ]
static const std::string kQualPathBegin = "_" + kMangledSubstBegin;
+static const std::string kMangledComma = "$C$";
namespace Rust {
namespace Compile {
@@ -39,6 +40,9 @@ legacy_mangle_name (const std::string &name)
//
// 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
std::string buffer;
for (size_t i = 0; i < name.size (); i++)
@@ -62,6 +66,8 @@ legacy_mangle_name (const std::string &name)
m = kMangledLeftSqParen;
else if (c == ']')
m = kMangledRightSqParen;
+ else if (c == ',')
+ m = kMangledComma;
else if (c == ':')
{
rust_assert (i + 1 < name.size ());
diff --git a/gcc/rust/resolve/rust-ast-resolve-type.cc b/gcc/rust/resolve/rust-ast-resolve-type.cc
index 5d0ceb5..a823543 100644
--- a/gcc/rust/resolve/rust-ast-resolve-type.cc
+++ b/gcc/rust/resolve/rust-ast-resolve-type.cc
@@ -356,7 +356,52 @@ ResolveTypeToCanonicalPath::visit (AST::TypePath &path)
if (mappings->lookup_canonical_path (mappings->get_current_crate (),
resolved_node, &type_path))
{
- result = *type_path;
+ auto &final_seg = path.get_segments ().back ();
+ switch (final_seg->get_type ())
+ {
+ case AST::TypePathSegment::SegmentType::GENERIC: {
+ AST::TypePathSegmentGeneric *s
+ = static_cast<AST::TypePathSegmentGeneric *> (final_seg.get ());
+
+ std::vector<CanonicalPath> args;
+ if (s->has_generic_args ())
+ {
+ for (auto &gt : s->get_generic_args ().get_type_args ())
+ {
+ CanonicalPath arg = CanonicalPath::create_empty ();
+ bool ok = ResolveTypeToCanonicalPath::go (gt.get (), arg);
+ if (ok)
+ args.push_back (std::move (arg));
+ }
+ }
+
+ result = *type_path;
+ if (!args.empty ())
+ {
+ // append this onto the path
+ std::string buf;
+ for (size_t i = 0; i < args.size (); i++)
+ {
+ bool has_next = (i + 1) < args.size ();
+ const auto &arg = args.at (i);
+
+ buf += arg.get ();
+ if (has_next)
+ buf += ", ";
+ }
+
+ std::string arg_seg = "<" + buf + ">";
+ CanonicalPath argument_seg
+ = CanonicalPath::new_seg (s->get_node_id (), arg_seg);
+ result = result.append (argument_seg);
+ }
+ }
+ break;
+
+ default:
+ result = *type_path;
+ break;
+ }
}
}