[libcxx-commits] [libcxxabi] df4522f - [demangler] Fix undocumented Local encoding
Nathan Sidwell via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Apr 6 10:13:20 PDT 2022
Author: Nathan Sidwell
Date: 2022-04-06T10:12:36-07:00
New Revision: df4522feb790ea574f470e45e473aac1f6483b93
URL: https://github.com/llvm/llvm-project/commit/df4522feb790ea574f470e45e473aac1f6483b93
DIFF: https://github.com/llvm/llvm-project/commit/df4522feb790ea574f470e45e473aac1f6483b93.diff
LOG: [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
Added:
Modified:
libcxxabi/src/demangle/ItaniumDemangle.h
libcxxabi/test/test_demangle.pass.cpp
llvm/include/llvm/Demangle/ItaniumDemangle.h
Removed:
################################################################################
diff --git a/libcxxabi/src/demangle/ItaniumDemangle.h b/libcxxabi/src/demangle/ItaniumDemangle.h
index 9a0b9bfdea623..fd6835ab9aba4 100644
--- a/libcxxabi/src/demangle/ItaniumDemangle.h
+++ b/libcxxabi/src/demangle/ItaniumDemangle.h
@@ -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;
diff --git a/libcxxabi/test/test_demangle.pass.cpp b/libcxxabi/test/test_demangle.pass.cpp
index 1ba6170a2b7a8..5282b0161fe64 100644
--- a/libcxxabi/test/test_demangle.pass.cpp
+++ b/libcxxabi/test/test_demangle.pass.cpp
@@ -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 at M"},
+ {"_ZW1ML1fi", "f at M(int)"},
};
const unsigned N = sizeof(cases) / sizeof(cases[0]);
diff --git a/llvm/include/llvm/Demangle/ItaniumDemangle.h b/llvm/include/llvm/Demangle/ItaniumDemangle.h
index d969b48068716..f293fbce5aae5 100644
--- a/llvm/include/llvm/Demangle/ItaniumDemangle.h
+++ b/llvm/include/llvm/Demangle/ItaniumDemangle.h
@@ -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;
More information about the libcxx-commits
mailing list