Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++20 templated lambdas not yet supported #208

Open
Swatinem opened this issue Aug 12, 2020 · 1 comment
Open

C++20 templated lambdas not yet supported #208

Swatinem opened this issue Aug 12, 2020 · 1 comment

Comments

@Swatinem
Copy link
Contributor

I cam across the following identifiers:

_ZNSt6__ndk110__function6__funcIZN10xxxxxxxxxx20xxxxxxxxxxxxxxxxxxxx11xxxxxxxxxxxIN8xxxxxxxx14xxxxxxxxxxxxxxINS6_INS6_INS5_10xxxxxxxxxxEN14xxxxxxxxxxxxxx23xxxxxxxxxxxxxxxxxxxxxxxEEENS8_21xxxxxxxxxxxxxxxxxxxxxI18xxxxxxxxxxxxxxxxxxEEEE15xxxxxxxxxxxxxxxEESF_EEvRNS5_20xxxxxxxxxxxxxxxxxxxxIT_T0_EENS_8functionIFRS3_PSJ_EEEEUlTyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev

_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

They correctly demangle using macos c++filt as:

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()

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

So both have a …'lambda'<typename $T… in them, which is encoded as …UlTY….

I would like to work on this, still trying to figure out how all this fits together.
Since all the productions have bnf-like comments, is there a reference for all this somewhere? I didn’t really find anything.

From reading the code, I guess this has to go somewhere in the ClosureTypeName parser?

cpp_demangle/src/ast.rs

Lines 6909 to 6936 in 1e51bce

/// The `<closure-type-name>` production.
///
/// ```text
/// <closure-type-name> ::= Ul <lambda-sig> E [ <nonnegative number> ] _
/// ```
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ClosureTypeName(LambdaSig, Option<usize>);
impl Parse for ClosureTypeName {
fn parse<'a, 'b>(
ctx: &'a ParseContext,
subs: &'a mut SubstitutionTable,
input: IndexStr<'b>,
) -> Result<(ClosureTypeName, IndexStr<'b>)> {
try_begin_parse!("ClosureTypeName", ctx, input);
let tail = consume(b"Ul", input)?;
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) {
(Some(num as _), tail)
} else {
(None, tail)
};
let tail = consume(b"_", tail)?;
Ok((ClosureTypeName(sig, num), tail))
}
}

@khuey
Copy link
Collaborator

khuey commented Aug 12, 2020

The BNF is generally taken from libiberty. The actual cxx abi spec on Github doesn't seem to be updated in a timely fashion.

If you're trying to figure out why a symbol doesn't parse, it helps to build with the logging feature. Then you'll get output like this

                                                (Name "UlTyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev                                                             [532/1855]
"
                                                    (NestedName "UlTyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                    )
                                                    (UnscopedName "UlTyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                        (UnqualifiedName "UlTyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                            (OperatorName "UlTyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                                (SimpleOperatorName "UlTyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                                )
                                                            )
                                                            (CtorDtorName "UlTyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                            )
                                                            (SourceName "UlTyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                            )
                                                            (TaggedName "UlTyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                            )
                                                            (ClosureTypeName "UlTyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                                (LambdaSig "TyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                                    (TypeHandle "TyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                                        (BuiltinType "TyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                                            (StandardBuiltinType "TyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                                            )
                                                                        )
                                                                        (ClassEnumType "TyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                                            (Name "TyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                                                (NestedName "TyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                                                )
                                                                                (UnscopedName "TyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                                                    (UnqualifiedName "TyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev
"
                                                                                        (OperatorName "TyRSI_iE_NS_9allocatorISS_EEFvRNS6_INS6_ISG_SF_EEiEERKiEED0Ev

If you look at this log you'll see that we're recognizing "Ul" as a lambda signature, but we eventually get hung up on the "Ty" that follows it. binutils c++filter doesn't seem to understand this construct either, so I'd look at llvm's demangler to see what "Ty" is supposed to be to start with.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants