diff options
author | Philip Herron <philip.herron@embecosm.com> | 2022-06-29 12:01:05 +0100 |
---|---|---|
committer | Philip Herron <philip.herron@embecosm.com> | 2022-06-29 12:10:08 +0100 |
commit | 1282974cf899f9486c62054bcbadf41346915dd5 (patch) | |
tree | b556162c6cb759c387191527ea6f001c300c3ab3 /gcc | |
parent | c88cc0aa644836c361ce5d8ff5225a9c12333dea (diff) | |
download | gcc-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.cc | 6 | ||||
-rw-r--r-- | gcc/rust/resolve/rust-ast-resolve-type.cc | 47 |
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 > : 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; + } } } |