Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 56 additions & 11 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5501,11 +5501,14 @@ where
/// The `<template-param-decl>` production.
///
/// ```text
/// <template-param-decl> ::= Tn <type> # non-type parameter
/// <template-param-decl> ::= Ty # type parameter
/// ::= Tn <type> # non-type parameter
/// ::= Tp <template-param-decl> # parameter pack
/// ```
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum TemplateParamDecl {
/// A type parameter.
Type(u8),
/// A non-type parameter.
NonType(TypeHandle),
/// A parameter pack.
Expand All @@ -5521,6 +5524,10 @@ impl Parse for TemplateParamDecl {
try_begin_parse!("TemplateParamDecl", ctx, input);

let input = consume(b"T", input)?;
if let Ok(tail) = consume(b"y", input) {
return Ok((TemplateParamDecl::Type(0), tail));
}

if let Ok(tail) = consume(b"n", input) {
let (ty, tail) = TypeHandle::parse(ctx, subs, tail)?;
return Ok((TemplateParamDecl::NonType(ty), tail));
Expand All @@ -5547,6 +5554,13 @@ where
let ctx = try_begin_demangle!(self, ctx, scope);

match self {
TemplateParamDecl::Type(n) => {
write!(ctx, "typename $T")?;
if *n > 0 {
write!(ctx, "{}", n - 1)?;
}
Ok(())
}
TemplateParamDecl::NonType(ref ty) => ty.demangle(ctx, scope),
TemplateParamDecl::ParameterPack(ref pack) => pack.demangle(ctx, scope),
}
Expand Down Expand Up @@ -7588,10 +7602,10 @@ impl Parse for Discriminator {
/// The `<closure-type-name>` production.
///
/// ```text
/// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
/// <closure-type-name> ::= Ul <template-param-decl>* <lambda-sig> E [ <nonnegative number> ] _
/// ```
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ClosureTypeName(LambdaSig, Option<usize>);
pub struct ClosureTypeName(Vec<TemplateParamDecl>, LambdaSig, Option<usize>);

impl Parse for ClosureTypeName {
fn parse<'a, 'b>(
Expand All @@ -7601,7 +7615,13 @@ impl Parse for ClosureTypeName {
) -> Result<(ClosureTypeName, IndexStr<'b>)> {
try_begin_parse!("ClosureTypeName", ctx, input);

let tail = consume(b"Ul", input)?;
let mut tail = consume(b"Ul", input)?;
let mut params = vec![];
while tail.peek() == Some(b'T') && !matches!(tail.peek_second(), Some(b'_' | b'0'..=b'9')) {
let (decl, _tail) = TemplateParamDecl::parse(ctx, subs, tail)?;
params.push(decl);
tail = _tail;
}
let (sig, tail) = LambdaSig::parse(ctx, subs, tail)?;
let tail = consume(b"E", tail)?;
let (num, tail) = if let Ok((num, tail)) = parse_number(10, false, tail) {
Expand All @@ -7610,7 +7630,7 @@ impl Parse for ClosureTypeName {
(None, tail)
};
let tail = consume(b"_", tail)?;
Ok((ClosureTypeName(sig, num), tail))
Ok((ClosureTypeName(params, sig, num), tail))
}
}

Expand All @@ -7625,9 +7645,24 @@ where
) -> fmt::Result {
let ctx = try_begin_demangle!(self, ctx, scope);

write!(ctx, "{{lambda(")?;
self.0.demangle(ctx, scope)?;
write!(ctx, ")#{}}}", self.1.map_or(1, |n| n + 2))?;
// llvm tools format this as:
// `'lambda'<typename $T, typename $T0>`
write!(ctx, "{{lambda")?;
if !self.0.is_empty() {
write!(ctx, "<")?;
let mut need_comma = false;
for arg in &self.0 {
if need_comma {
write!(ctx, ", ")?;
}
arg.demangle(ctx, scope)?;
need_comma = true;
}
write!(ctx, ">")?;
}
write!(ctx, "(")?;
self.1.demangle(ctx, scope)?;
write!(ctx, ")#{}}}", self.2.map_or(1, |n| n + 2))?;
Ok(())
}
}
Expand Down Expand Up @@ -10275,17 +10310,25 @@ mod tests {
b"...",
[]
}
b"TyS_..." => {
TemplateArg::ParamDecl(
TemplateParamDecl::Type(0),
Box::new(TemplateArg::Type(TypeHandle::BackReference(0)))
),
b"...",
[]
}
}
Err => {
b"..." => Error::UnexpectedText,
b"X..." => Error::UnexpectedText,
b"J..." => Error::UnexpectedText,
b"JS_..." => Error::UnexpectedText,
// <template-param-decl>s that we don't implement yet.
b"Ty" => Error::UnexpectedText,
b"Tk" => Error::UnexpectedText,
b"Tt" => Error::UnexpectedText,
b"Tp" => Error::UnexpectedText,
b"Ty" => Error::UnexpectedEnd,
b"JS_" => Error::UnexpectedEnd,
b"X" => Error::UnexpectedEnd,
b"J" => Error::UnexpectedEnd,
Expand Down Expand Up @@ -11476,11 +11519,11 @@ mod tests {
assert_parse!(ClosureTypeName {
Ok => {
b"UlvE_..." => {
ClosureTypeName(LambdaSig(vec![]), None),
ClosureTypeName(vec![], LambdaSig(vec![]), None),
b"..."
}
b"UlvE36_..." => {
ClosureTypeName(LambdaSig(vec![]), Some(36)),
ClosureTypeName(vec![], LambdaSig(vec![]), Some(36)),
b"..."
}
}
Expand Down Expand Up @@ -12082,6 +12125,7 @@ mod tests {
b"UllE_..." => {
UnqualifiedName::ClosureType(
ClosureTypeName(
vec![],
LambdaSig(vec![
TypeHandle::Builtin(
BuiltinType::Standard(
Expand Down Expand Up @@ -12176,6 +12220,7 @@ mod tests {
b"UllE_B1Q..." => {
UnqualifiedName::ClosureType(
ClosureTypeName(
vec![],
LambdaSig(vec![
TypeHandle::Builtin(
BuiltinType::Standard(
Expand Down
18 changes: 18 additions & 0 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,11 @@ demangles!(
);

demangles!(_ZUlvE_, "{lambda()#1}");
demangles!(_ZUlT_E_, "{lambda(auto:1)#1}");
demangles!(_ZUlT0_E_, "{lambda(auto:2)#1}");
demangles!(_ZUlTyT_E_, "{lambda<typename $T>(auto:1)#1}");
demangles!(_ZUlTnivE_, "{lambda<int>()#1}");
demangles!(_ZUlTpTyvE_, "{lambda<typename $T>()#1}");
demangles!(_ZZ3aaavEUlvE_, "aaa()::{lambda()#1}");
demangles!(_ZZ3aaavENUlvE_3bbbE, "aaa()::{lambda()#1}::bbb");
demangles!(_ZN3aaaUlvE_D1Ev, "aaa::{lambda()#1}::~{lambda()#1}()");
Expand Down Expand Up @@ -733,3 +738,16 @@ fn test_pathological_recursion() {
}
}
}
demangles!(
_ZNSt6__ndk110__function6__funcIZN10xxxxxxxxxx20xxxxxxxxxxxxxxxxxxxx11xxxxxxxxxxxIN8xxxxxxxx14xxxxxxxxxxxxxxINS6_INS6_INS5_10xxxxxxxxxxEN14xxxxxxxxxxxxxx23xxxxxxxxxxxxxxxxxxxxxxxEEENS8_21xxxxxxxxxxxxxxxxxxxxxI18xxxxxxxxxxxxxxxxxxEEEE15xxxxxxxxxxxxxxxEESF_EEvRNS5_20xxxxxxxxxxxxxxxxxxxxIT_T0_EENS_8functionIFRS3_PSJ_EEEEUlTyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev,
"std::__ndk1::__function::__func<void xxxxxxxxxx::xxxxxxxxxxxxxxxxxxxx::xxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxxxx>, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxx<xxxxxxxxxxxxxxxxxx> >, xxxxxxxxxxxxxxx>, xxxxxxxxxxxxxxx>(xxxxxxxx::xxxxxxxxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxxxx>, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxx<xxxxxxxxxxxxxxxxxx> >, xxxxxxxxxxxxxxx>, xxxxxxxxxxxxxxx>&, std::__ndk1::function<xxxxxxxxxx::xxxxxxxxxxxxxxxxxxxx& (xxxxxxxxxxxxxxx*)>)::{lambda<typename $T>(auto:1&, int)#1}, std::__ndk1::allocator<void xxxxxxxxxx::xxxxxxxxxxxxxxxxxxxx::xxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxxxx>, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxx<xxxxxxxxxxxxxxxxxx> >, xxxxxxxxxxxxxxx>, xxxxxxxxxxxxxxx>(xxxxxxxx::xxxxxxxxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxxxx>, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxx<xxxxxxxxxxxxxxxxxx> >, xxxxxxxxxxxxxxx>, xxxxxxxxxxxxxxx>&, std::__ndk1::function<xxxxxxxxxx::xxxxxxxxxxxxxxxxxxxx& (xxxxxxxxxxxxxxx*)>)::{lambda<typename $T>(auto:1&, int)#1}>, void (xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxxxx>, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxx<xxxxxxxxxxxxxxxxxx> >, xxxxxxxxxxxxxxx>, xxxxxxxxxxxxxxx>, int>&, int const&)>::~__func()"
// This does not match llvm-cxxfilt, it should be:
// "std::__ndk1::__function::__func<void xxxxxxxxxx::xxxxxxxxxxxxxxxxxxxx::xxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxxxx>, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxx<xxxxxxxxxxxxxxxxxx> >, xxxxxxxxxxxxxxx>, xxxxxxxxxxxxxxx>(xxxxxxxx::xxxxxxxxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxxxx>, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxx<xxxxxxxxxxxxxxxxxx> >, xxxxxxxxxxxxxxx>, xxxxxxxxxxxxxxx>&, std::__ndk1::function<xxxxxxxxxx::xxxxxxxxxxxxxxxxxxxx& (xxxxxxxxxxxxxxx*)>)::'lambda'<typename $T>(xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxxxx>, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxx<xxxxxxxxxxxxxxxxxx> >, xxxxxxxxxxxxxxx>&, int), std::__ndk1::allocator<void xxxxxxxxxx::xxxxxxxxxxxxxxxxxxxx::xxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxxxx>, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxx<xxxxxxxxxxxxxxxxxx> >, xxxxxxxxxxxxxxx>, xxxxxxxxxxxxxxx>(xxxxxxxx::xxxxxxxxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxxxx>, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxx<xxxxxxxxxxxxxxxxxx> >, xxxxxxxxxxxxxxx>, xxxxxxxxxxxxxxx>&, std::__ndk1::function<xxxxxxxxxx::xxxxxxxxxxxxxxxxxxxx& (xxxxxxxxxxxxxxx*)>)::'lambda'<typename $T>(xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxxxx>, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxx<xxxxxxxxxxxxxxxxxx> >, xxxxxxxxxxxxxxx>&, int)>, void (xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxxxx>, xxxxxxxxxxxxxx::xxxxxxxxxxxxxxxxxxxxx<xxxxxxxxxxxxxxxxxx> >, xxxxxxxxxxxxxxx>, xxxxxxxxxxxxxxx>, int>&, int const&)>::~__func()"
);

demangles!(
_ZNKSt6__ndk110__function6__funcIZN8xxxxxxxx9xxxxxxxxxINS_10shared_ptrINS2_20xxxxxxxxxxxxxxxxxxxxINS2_10xxxxxxxxxxE15xxxxxxxxxxxxxxxEEEES7_bEEODaT_MT0_T1_PKcEUlTyTyRSB_RSC_E_NS_9allocatorISJ_EEFvRNS2_14xxxxxxxxxxxxxxINSM_IS6_S7_EEbEERKbEE7__cloneEPNS0_6__baseISS_EE,
"std::__ndk1::__function::__func<auto&& xxxxxxxx::xxxxxxxxx<std::__ndk1::shared_ptr<xxxxxxxx::xxxxxxxxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxxx> >, xxxxxxxxxxxxxxx, bool>(std::__ndk1::shared_ptr<xxxxxxxx::xxxxxxxxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxxx> >, bool xxxxxxxxxxxxxxx::*, char const*)::{lambda<typename $T, typename $T>(auto:1&, auto:2&)#1}, std::__ndk1::allocator<auto&& xxxxxxxx::xxxxxxxxx<std::__ndk1::shared_ptr<xxxxxxxx::xxxxxxxxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxxx> >, xxxxxxxxxxxxxxx, bool>(std::__ndk1::shared_ptr<xxxxxxxx::xxxxxxxxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxxx> >, bool xxxxxxxxxxxxxxx::*, char const*)::{lambda<typename $T, typename $T>(auto:1&, auto:2&)#1}>, void (xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxxx>, bool>&, bool const&)>::__clone(std::__ndk1::__function::__base<void (xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxxx>, bool>&, bool const&)>*) const"
// This does not match llvm-cxxfilt, it should be:
// "std::__ndk1::__function::__func<auto&& xxxxxxxx::xxxxxxxxx<std::__ndk1::shared_ptr<xxxxxxxx::xxxxxxxxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxxx> >, xxxxxxxxxxxxxxx, bool>(std::__ndk1::shared_ptr<xxxxxxxx::xxxxxxxxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxxx> >, bool xxxxxxxxxxxxxxx::*, char const*)::'lambda'<typename $T, typename $T0>(std::__ndk1::shared_ptr<xxxxxxxx::xxxxxxxxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxxx> >&, xxxxxxxxxxxxxxx&), std::__ndk1::allocator<auto&& xxxxxxxx::xxxxxxxxx<std::__ndk1::shared_ptr<xxxxxxxx::xxxxxxxxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxxx> >, xxxxxxxxxxxxxxx, bool>(std::__ndk1::shared_ptr<xxxxxxxx::xxxxxxxxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxxx> >, bool xxxxxxxxxxxxxxx::*, char const*)::'lambda'<typename $T, typename $T0>(std::__ndk1::shared_ptr<xxxxxxxx::xxxxxxxxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxxx> >&, xxxxxxxxxxxxxxx&)>, void (xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxxx>, bool>&, bool const&)>::__clone(std::__ndk1::__function::__base<void (xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxxxxxx<xxxxxxxx::xxxxxxxxxx, xxxxxxxxxxxxxxx>, bool>&, bool const&)>*) const"
);