forked from OSchip/llvm-project
[demangler] Fix undocumented Local encoding
GCC emits [some] static symbols with an 'L' mangling, which we attempt to demangle. But the module mangling changes have exposed that we were doing so at the wrong level. Such manglings are outside of the ABI as they are internal-linkage, so a bit of reverse engineering was needed. This adjusts the demangler along the same lines as the existing gcc demangler (which is not yet module-aware). 'L' is part of an unqualified name. As before we merely parse the 'L', and then ignore it. Reviewed By: iains Differential Revision: https://reviews.llvm.org/D123138
This commit is contained in:
parent
1ad36487e9
commit
df4522feb7
|
@ -2729,8 +2729,8 @@ Node *AbstractManglingParser<Derived, Alloc>::parseLocalName(NameState *State) {
|
|||
return make<LocalName>(Encoding, Entity);
|
||||
}
|
||||
|
||||
// <unscoped-name> ::= [L]* <unqualified-name>
|
||||
// ::= St [L]* <unqualified-name> # ::std::
|
||||
// <unscoped-name> ::= <unqualified-name>
|
||||
// ::= St <unqualified-name> # ::std::
|
||||
// [*] extension
|
||||
template <typename Derived, typename Alloc>
|
||||
Node *
|
||||
|
@ -2743,7 +2743,6 @@ AbstractManglingParser<Derived, Alloc>::parseUnscopedName(NameState *State,
|
|||
if (Std == nullptr)
|
||||
return nullptr;
|
||||
}
|
||||
consumeIf('L');
|
||||
|
||||
Node *Res = nullptr;
|
||||
ModuleName *Module = nullptr;
|
||||
|
@ -2761,29 +2760,32 @@ AbstractManglingParser<Derived, Alloc>::parseUnscopedName(NameState *State,
|
|||
}
|
||||
}
|
||||
|
||||
if (Res == nullptr)
|
||||
if (Res == nullptr || Std != nullptr) {
|
||||
Res = getDerived().parseUnqualifiedName(State, Std, Module);
|
||||
}
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
||||
// <unqualified-name> ::= [<module-name>] <operator-name> [<abi-tags>]
|
||||
// <unqualified-name> ::= [<module-name>] L? <operator-name> [<abi-tags>]
|
||||
// ::= [<module-name>] <ctor-dtor-name> [<abi-tags>]
|
||||
// ::= [<module-name>] <source-name> [<abi-tags>]
|
||||
// ::= [<module-name>] <unnamed-type-name> [<abi-tags>]
|
||||
// ::= [<module-name>] L? <source-name> [<abi-tags>]
|
||||
// ::= [<module-name>] L? <unnamed-type-name> [<abi-tags>]
|
||||
// # structured binding declaration
|
||||
// ::= [<module-name>] DC <source-name>+ E
|
||||
// ::= [<module-name>] L? DC <source-name>+ E
|
||||
template <typename Derived, typename Alloc>
|
||||
Node *AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName(
|
||||
NameState *State, Node *Scope, ModuleName *Module) {
|
||||
if (getDerived().parseModuleNameOpt(Module))
|
||||
return nullptr;
|
||||
|
||||
consumeIf('L');
|
||||
|
||||
Node *Result;
|
||||
if (look() == 'U') {
|
||||
Result = getDerived().parseUnnamedTypeName(State);
|
||||
} else if (look() >= '1' && look() <= '9') {
|
||||
if (look() >= '1' && look() <= '9') {
|
||||
Result = getDerived().parseSourceName(State);
|
||||
} else if (look() == 'U') {
|
||||
Result = getDerived().parseUnnamedTypeName(State);
|
||||
} else if (consumeIf("DC")) {
|
||||
// Structured binding
|
||||
size_t BindingsBegin = Names.size();
|
||||
|
@ -3163,10 +3165,12 @@ AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
|
||||
// ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
|
||||
// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix>
|
||||
// <unqualified-name> E
|
||||
// ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix>
|
||||
// <template-args> E
|
||||
//
|
||||
// <prefix> ::= <prefix> [L]* <unqualified-name>
|
||||
// <prefix> ::= <prefix> <unqualified-name>
|
||||
// ::= <template-prefix> <template-args>
|
||||
// ::= <template-param>
|
||||
// ::= <decltype>
|
||||
|
@ -3230,7 +3234,6 @@ AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
|
|||
SoFar = getDerived().parseDecltype();
|
||||
} else {
|
||||
ModuleName *Module = nullptr;
|
||||
bool IsLocal = consumeIf('L'); // extension
|
||||
|
||||
if (look() == 'S') {
|
||||
// ::= <substitution>
|
||||
|
@ -3245,7 +3248,7 @@ AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
|
|||
return nullptr;
|
||||
if (S->getKind() == Node::KModuleName) {
|
||||
Module = static_cast<ModuleName *>(S);
|
||||
} else if (SoFar != nullptr || IsLocal) {
|
||||
} else if (SoFar != nullptr) {
|
||||
return nullptr; // Cannot have a prefix.
|
||||
} else {
|
||||
SoFar = S;
|
||||
|
|
|
@ -30078,6 +30078,8 @@ const char* cases[][2] =
|
|||
{"_ZGIW3Foo", "initializer for module Foo"},
|
||||
{"_ZGIW3FooW3Bar", "initializer for module Foo.Bar"},
|
||||
{"_ZGIW3FooWP3BarW3Baz", "initializer for module Foo:Bar.Baz"},
|
||||
{"_ZW1ML4Oink", "Oink@M"},
|
||||
{"_ZW1ML1fi", "f@M(int)"},
|
||||
};
|
||||
|
||||
const unsigned N = sizeof(cases) / sizeof(cases[0]);
|
||||
|
|
|
@ -2729,8 +2729,8 @@ Node *AbstractManglingParser<Derived, Alloc>::parseLocalName(NameState *State) {
|
|||
return make<LocalName>(Encoding, Entity);
|
||||
}
|
||||
|
||||
// <unscoped-name> ::= [L]* <unqualified-name>
|
||||
// ::= St [L]* <unqualified-name> # ::std::
|
||||
// <unscoped-name> ::= <unqualified-name>
|
||||
// ::= St <unqualified-name> # ::std::
|
||||
// [*] extension
|
||||
template <typename Derived, typename Alloc>
|
||||
Node *
|
||||
|
@ -2743,7 +2743,6 @@ AbstractManglingParser<Derived, Alloc>::parseUnscopedName(NameState *State,
|
|||
if (Std == nullptr)
|
||||
return nullptr;
|
||||
}
|
||||
consumeIf('L');
|
||||
|
||||
Node *Res = nullptr;
|
||||
ModuleName *Module = nullptr;
|
||||
|
@ -2761,29 +2760,32 @@ AbstractManglingParser<Derived, Alloc>::parseUnscopedName(NameState *State,
|
|||
}
|
||||
}
|
||||
|
||||
if (Res == nullptr)
|
||||
if (Res == nullptr || Std != nullptr) {
|
||||
Res = getDerived().parseUnqualifiedName(State, Std, Module);
|
||||
}
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
||||
// <unqualified-name> ::= [<module-name>] <operator-name> [<abi-tags>]
|
||||
// <unqualified-name> ::= [<module-name>] L? <operator-name> [<abi-tags>]
|
||||
// ::= [<module-name>] <ctor-dtor-name> [<abi-tags>]
|
||||
// ::= [<module-name>] <source-name> [<abi-tags>]
|
||||
// ::= [<module-name>] <unnamed-type-name> [<abi-tags>]
|
||||
// ::= [<module-name>] L? <source-name> [<abi-tags>]
|
||||
// ::= [<module-name>] L? <unnamed-type-name> [<abi-tags>]
|
||||
// # structured binding declaration
|
||||
// ::= [<module-name>] DC <source-name>+ E
|
||||
// ::= [<module-name>] L? DC <source-name>+ E
|
||||
template <typename Derived, typename Alloc>
|
||||
Node *AbstractManglingParser<Derived, Alloc>::parseUnqualifiedName(
|
||||
NameState *State, Node *Scope, ModuleName *Module) {
|
||||
if (getDerived().parseModuleNameOpt(Module))
|
||||
return nullptr;
|
||||
|
||||
consumeIf('L');
|
||||
|
||||
Node *Result;
|
||||
if (look() == 'U') {
|
||||
Result = getDerived().parseUnnamedTypeName(State);
|
||||
} else if (look() >= '1' && look() <= '9') {
|
||||
if (look() >= '1' && look() <= '9') {
|
||||
Result = getDerived().parseSourceName(State);
|
||||
} else if (look() == 'U') {
|
||||
Result = getDerived().parseUnnamedTypeName(State);
|
||||
} else if (consumeIf("DC")) {
|
||||
// Structured binding
|
||||
size_t BindingsBegin = Names.size();
|
||||
|
@ -3163,10 +3165,12 @@ AbstractManglingParser<Derived, Alloc>::parseCtorDtorName(Node *&SoFar,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E
|
||||
// ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix> <template-args> E
|
||||
// <nested-name> ::= N [<CV-Qualifiers>] [<ref-qualifier>] <prefix>
|
||||
// <unqualified-name> E
|
||||
// ::= N [<CV-Qualifiers>] [<ref-qualifier>] <template-prefix>
|
||||
// <template-args> E
|
||||
//
|
||||
// <prefix> ::= <prefix> [L]* <unqualified-name>
|
||||
// <prefix> ::= <prefix> <unqualified-name>
|
||||
// ::= <template-prefix> <template-args>
|
||||
// ::= <template-param>
|
||||
// ::= <decltype>
|
||||
|
@ -3230,7 +3234,6 @@ AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
|
|||
SoFar = getDerived().parseDecltype();
|
||||
} else {
|
||||
ModuleName *Module = nullptr;
|
||||
bool IsLocal = consumeIf('L'); // extension
|
||||
|
||||
if (look() == 'S') {
|
||||
// ::= <substitution>
|
||||
|
@ -3245,7 +3248,7 @@ AbstractManglingParser<Derived, Alloc>::parseNestedName(NameState *State) {
|
|||
return nullptr;
|
||||
if (S->getKind() == Node::KModuleName) {
|
||||
Module = static_cast<ModuleName *>(S);
|
||||
} else if (SoFar != nullptr || IsLocal) {
|
||||
} else if (SoFar != nullptr) {
|
||||
return nullptr; // Cannot have a prefix.
|
||||
} else {
|
||||
SoFar = S;
|
||||
|
|
Loading…
Reference in New Issue