forked from OSchip/llvm-project
In cxa_demangle.cpp, rewrite __parse_unresolved_name to reflect updated understanding and sync with updated clang mangling. Also fix think-o in __parse_encoding enabling the parsing of trailing .eh and .b.
llvm-svn: 133632
This commit is contained in:
parent
6208a2fd66
commit
471e111324
|
|
@ -127,6 +127,7 @@ private:
|
|||
const char* __parse_pack_expansion(const char*, const char*);
|
||||
const char* __parse_sizeof_function_param_pack_expr(const char*, const char*);
|
||||
const char* __parse_dot_suffix(const char*, const char*);
|
||||
const char* __parse_unresolved_qualifier_level(const char*, const char*);
|
||||
const char* __parse_hex_number(const char*, const char*, unsigned long long&);
|
||||
|
||||
template <class _Tp> bool __make();
|
||||
|
|
|
|||
|
|
@ -11308,34 +11308,33 @@ __demangle_tree::__parse_unresolved_type(const char* first, const char* last)
|
|||
return first;
|
||||
}
|
||||
|
||||
// <unresolved-qualifier-level> ::= <source-name> [ <template-args> ]
|
||||
|
||||
const char*
|
||||
__demangle_tree::__parse_unresolved_qualifier_level(const char* first, const char* last)
|
||||
{
|
||||
if (first != last)
|
||||
{
|
||||
const char* t = __parse_source_name(first, last);
|
||||
if (t != first)
|
||||
first = __parse_template_args(t, last);
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
// <unresolved-name>
|
||||
// ::= sr <name> <base-unresolved-name> # extension, subtly different than srN ...
|
||||
// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
|
||||
// # T::N::x /decltype(p)::N::x
|
||||
// extension ::= srN <unresolved-type> [<template-args>] <unresolved-qualifier-level>* E <base-unresolved-name>
|
||||
// ::= [gs] <base-unresolved-name> # x or (with "gs") ::x
|
||||
// ::= [gs] sr <unresolved-qualifier-level>+ E <base-unresolved-name>
|
||||
// # A::x, N::y, A<T>::z; "gs" means leading "::"
|
||||
// ::= sr <unresolved-type> <base-unresolved-name> # T::x / decltype(p)::x
|
||||
// # T::N::x /decltype(p)::N::x
|
||||
// (ignored) ::= srN <unresolved-type> <unresolved-qualifier-level>+ E <base-unresolved-name>
|
||||
|
||||
const char*
|
||||
__demangle_tree::__parse_unresolved_name(const char* first, const char* last)
|
||||
{
|
||||
if (last - first > 2)
|
||||
{
|
||||
if (first[0] == 's' && first[1] == 'r')
|
||||
{
|
||||
const char* t = __parse_name(first+2, last);
|
||||
if (t == first+2)
|
||||
t = __parse_unresolved_type(first+2, last);
|
||||
if (t != first+2)
|
||||
{
|
||||
__node* name = __root_;
|
||||
const char* t2 = __parse_base_unresolved_name(t, last);
|
||||
if (t2 != t && __make<__unresolved_name>(name, __root_))
|
||||
first = t2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* t = first;
|
||||
bool global = false;
|
||||
|
|
@ -11344,35 +11343,75 @@ __demangle_tree::__parse_unresolved_name(const char* first, const char* last)
|
|||
global = true;
|
||||
t += 2;
|
||||
}
|
||||
if (last - t > 2)
|
||||
const char* t2 = __parse_base_unresolved_name(t, last);
|
||||
if (t2 != t)
|
||||
{
|
||||
const char* t2;
|
||||
__node* name = NULL;
|
||||
if (t[0] == 's' && t[1] == 'r')
|
||||
if (__make<__unresolved_name>(global, (__node*)0, __root_))
|
||||
first = t2;
|
||||
}
|
||||
else if (last - t > 2 && t[0] == 's' && t[1] == 'r')
|
||||
{
|
||||
t += 2;
|
||||
t2 = __parse_simple_id(t, last);
|
||||
if (t2 == t || t2 == last)
|
||||
if (!global && t[2] == 'N')
|
||||
{
|
||||
t2 = __parse_unresolved_type(t+3, last);
|
||||
if (t2 != t+3 && t2 != last)
|
||||
{
|
||||
t = __parse_template_args(t2, last);
|
||||
if (t == last)
|
||||
return first;
|
||||
name = __root_;
|
||||
while (*t2 != 'E')
|
||||
__node* name = __root_;
|
||||
while (*t != 'E')
|
||||
{
|
||||
t = t2;
|
||||
t2 = __parse_simple_id(t, last);
|
||||
if (t2 == t)
|
||||
t2 = __parse_unresolved_qualifier_level(t, last);
|
||||
if (t2 == t || t2 == last)
|
||||
return first;
|
||||
if (!__make<__nested_delimeter>(name, __root_))
|
||||
return first;
|
||||
name = __root_;
|
||||
t = t2;
|
||||
}
|
||||
t = t2+1;
|
||||
t2 = __parse_base_unresolved_name(++t, last);
|
||||
if (t2 != t && __make<__unresolved_name>(false, name, __root_))
|
||||
first = t2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!global)
|
||||
{
|
||||
t2 = __parse_unresolved_type(t+2, last);
|
||||
if (t2 != t+2)
|
||||
{
|
||||
t = t2;
|
||||
__node* name = __root_;
|
||||
t2 = __parse_base_unresolved_name(t, last);
|
||||
if (t2 != t && __make<__unresolved_name>(false, name, __root_))
|
||||
return t2;
|
||||
return first;
|
||||
}
|
||||
}
|
||||
t2 = __parse_unresolved_qualifier_level(t+2, last);
|
||||
if (t2 != t+2 && t2 != last)
|
||||
{
|
||||
__node* name = __root_;
|
||||
t = t2;
|
||||
while (*t != 'E')
|
||||
{
|
||||
t2 = __parse_unresolved_qualifier_level(t, last);
|
||||
if (t2 == t || t2 == last)
|
||||
return first;
|
||||
if (!__make<__nested_delimeter>(name, __root_))
|
||||
return first;
|
||||
name = __root_;
|
||||
t = t2;
|
||||
}
|
||||
t2 = __parse_base_unresolved_name(++t, last);
|
||||
if (t2 != t && __make<__unresolved_name>(global, name, __root_))
|
||||
first = t2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
|
|
@ -14696,7 +14735,7 @@ __demangle_tree::__parse_encoding(const char* first, const char* last)
|
|||
const char* t = __parse_name(first, last);
|
||||
if (t != first)
|
||||
{
|
||||
if (t != last && *t != 'E')
|
||||
if (t != last && *t != 'E' && *t != '.')
|
||||
{
|
||||
__node* name = __root_;
|
||||
bool has_return = name->ends_with_template() &&
|
||||
|
|
|
|||
|
|
@ -29500,8 +29500,8 @@ const char* cases[][2] =
|
|||
{"_ZplRK1YRA100_P1X", "operator+(Y const&, X* (&) [100])"},
|
||||
{"_Z1fno", "f(__int128, unsigned __int128)"},
|
||||
{"_Z1fM1SKFvvE", "f(void (S::*)() const)"},
|
||||
{"_Z3ft7IiEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv", "__enable_if<__is_scalar<int>::__value, void>::__type ft7<int>()"},
|
||||
{"_Z3ft7IPvEN11__enable_ifIXsr11__is_scalarIT_E7__valueEvE6__typeEv", "__enable_if<__is_scalar<void*>::__value, void>::__type ft7<void*>()"},
|
||||
{"_Z3ft7IiEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv", "__enable_if<__is_scalar_type<int>::__value, void>::__type ft7<int>()"},
|
||||
{"_Z3ft7IPvEN11__enable_ifIXsr16__is_scalar_typeIT_EE7__valueEvE6__typeEv", "__enable_if<__is_scalar_type<void*>::__value, void>::__type ft7<void*>()"},
|
||||
{"_ZN6PR57968__fill_aIiEENS_11__enable_ifIXntsrNS_11__is_scalarIT_EE7__valueEvE6__typeEv", "PR5796::__enable_if<!(PR5796::__is_scalar<int>::__value), void>::__type PR5796::__fill_a<int>()"},
|
||||
{"_ZN11Expressions2f1ILi1EEEvPAplngT_Li2E_i", "void Expressions::f1<1>(int (*) [(-(1)) + (2)])"},
|
||||
{"_ZN11Expressions2f2ILi1EEEvPApsT__i", "void Expressions::f2<1>(int (*) [+(1)])"},
|
||||
|
|
|
|||
Loading…
Reference in New Issue