forked from OSchip/llvm-project
[LLDB] Fix handling for the clang name mangling extension for block invocations
Add support for clangs mangling extension for block invocations. Differential Revision: https://reviews.llvm.org/D69738
This commit is contained in:
parent
007d173e2e
commit
83393d27af
|
@ -261,6 +261,15 @@ public:
|
|||
bool DemangleWithRichManglingInfo(RichManglingContext &context,
|
||||
SkipMangledNameFn *skip_mangled_name);
|
||||
|
||||
/// Try to identify the mangling scheme used.
|
||||
/// \param[in] name
|
||||
/// The name we are attempting to identify the mangling scheme for.
|
||||
///
|
||||
/// \return
|
||||
/// eManglingSchemeNone if no known mangling scheme could be identified
|
||||
/// for s, otherwise the enumerator for the mangling scheme detected.
|
||||
static Mangled::ManglingScheme GetManglingScheme(llvm::StringRef const name);
|
||||
|
||||
private:
|
||||
/// Mangled member variables.
|
||||
ConstString m_mangled; ///< The mangled version of the name
|
||||
|
|
|
@ -32,18 +32,8 @@
|
|||
#include <string.h>
|
||||
using namespace lldb_private;
|
||||
|
||||
static inline Mangled::ManglingScheme cstring_mangling_scheme(const char *s) {
|
||||
if (s) {
|
||||
if (s[0] == '?')
|
||||
return Mangled::eManglingSchemeMSVC;
|
||||
if (s[0] == '_' && s[1] == 'Z')
|
||||
return Mangled::eManglingSchemeItanium;
|
||||
}
|
||||
return Mangled::eManglingSchemeNone;
|
||||
}
|
||||
|
||||
static inline bool cstring_is_mangled(const char *s) {
|
||||
return cstring_mangling_scheme(s) != Mangled::eManglingSchemeNone;
|
||||
static inline bool cstring_is_mangled(llvm::StringRef s) {
|
||||
return Mangled::GetManglingScheme(s) != Mangled::eManglingSchemeNone;
|
||||
}
|
||||
|
||||
static ConstString
|
||||
|
@ -99,6 +89,23 @@ get_demangled_name_without_arguments(ConstString mangled,
|
|||
|
||||
#pragma mark Mangled
|
||||
|
||||
Mangled::ManglingScheme Mangled::GetManglingScheme(llvm::StringRef const name) {
|
||||
if (name.empty())
|
||||
return Mangled::eManglingSchemeNone;
|
||||
|
||||
if (name.startswith("?"))
|
||||
return Mangled::eManglingSchemeMSVC;
|
||||
|
||||
if (name.startswith("_Z"))
|
||||
return Mangled::eManglingSchemeItanium;
|
||||
|
||||
// ___Z is a clang extension of block invocations
|
||||
if (name.startswith("___Z"))
|
||||
return Mangled::eManglingSchemeItanium;
|
||||
|
||||
return Mangled::eManglingSchemeNone;
|
||||
}
|
||||
|
||||
Mangled::Mangled(ConstString s) : m_mangled(), m_demangled() {
|
||||
if (s)
|
||||
SetValue(s);
|
||||
|
@ -159,7 +166,7 @@ void Mangled::SetValue(ConstString s, bool mangled) {
|
|||
|
||||
void Mangled::SetValue(ConstString name) {
|
||||
if (name) {
|
||||
if (cstring_is_mangled(name.GetCString())) {
|
||||
if (cstring_is_mangled(name.GetStringRef())) {
|
||||
m_demangled.Clear();
|
||||
m_mangled = name;
|
||||
} else {
|
||||
|
@ -232,7 +239,7 @@ bool Mangled::DemangleWithRichManglingInfo(
|
|||
assert(m_mangled);
|
||||
|
||||
// Check whether or not we are interested in this name at all.
|
||||
ManglingScheme scheme = cstring_mangling_scheme(m_mangled.GetCString());
|
||||
ManglingScheme scheme = GetManglingScheme(m_mangled.GetStringRef());
|
||||
if (skip_mangled_name && skip_mangled_name(m_mangled.GetStringRef(), scheme))
|
||||
return false;
|
||||
|
||||
|
@ -300,7 +307,7 @@ Mangled::GetDemangledName(lldb::LanguageType language) const {
|
|||
|
||||
// Don't bother running anything that isn't mangled
|
||||
const char *mangled_name = m_mangled.GetCString();
|
||||
ManglingScheme mangling_scheme{cstring_mangling_scheme(mangled_name)};
|
||||
ManglingScheme mangling_scheme = GetManglingScheme(m_mangled.GetStringRef());
|
||||
if (mangling_scheme != eManglingSchemeNone &&
|
||||
!m_mangled.GetMangledCounterpart(m_demangled)) {
|
||||
// We didn't already mangle this name, demangle it and if all goes well
|
||||
|
@ -405,6 +412,7 @@ size_t Mangled::MemorySize() const {
|
|||
// within those targets.
|
||||
lldb::LanguageType Mangled::GuessLanguage() const {
|
||||
ConstString mangled = GetMangledName();
|
||||
|
||||
if (mangled) {
|
||||
const char *mangled_name = mangled.GetCString();
|
||||
if (CPlusPlusLanguage::IsCPPMangledName(mangled_name))
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Demangle/ItaniumDemangle.h"
|
||||
|
||||
#include "lldb/Core/Mangled.h"
|
||||
#include "lldb/Core/PluginManager.h"
|
||||
#include "lldb/Core/UniqueCStringMap.h"
|
||||
#include "lldb/DataFormatters/CXXFunctionPointer.h"
|
||||
|
@ -238,18 +239,16 @@ std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() {
|
|||
return res;
|
||||
}
|
||||
|
||||
bool CPlusPlusLanguage::IsCPPMangledName(const char *name) {
|
||||
bool CPlusPlusLanguage::IsCPPMangledName(llvm::StringRef name) {
|
||||
// FIXME!! we should really run through all the known C++ Language plugins
|
||||
// and ask each one if this is a C++ mangled name
|
||||
|
||||
if (name == nullptr)
|
||||
Mangled::ManglingScheme scheme = Mangled::GetManglingScheme(name);
|
||||
|
||||
if (scheme == Mangled::eManglingSchemeNone)
|
||||
return false;
|
||||
|
||||
// MSVC style mangling
|
||||
if (name[0] == '?')
|
||||
return true;
|
||||
|
||||
return (name[0] != '\0' && name[0] == '_' && name[1] == 'Z');
|
||||
}
|
||||
|
||||
bool CPlusPlusLanguage::ExtractContextAndIdentifier(
|
||||
|
|
|
@ -101,7 +101,7 @@ public:
|
|||
|
||||
static lldb_private::ConstString GetPluginNameStatic();
|
||||
|
||||
static bool IsCPPMangledName(const char *name);
|
||||
static bool IsCPPMangledName(llvm::StringRef name);
|
||||
|
||||
// Extract C++ context and identifier from a string using heuristic matching
|
||||
// (as opposed to
|
||||
|
|
|
@ -37,6 +37,17 @@ TEST(MangledTest, ResultForValidName) {
|
|||
EXPECT_STREQ(ExpectedResult.GetCString(), TheDemangled.GetCString());
|
||||
}
|
||||
|
||||
TEST(MangledTest, ResultForBlockInvocation) {
|
||||
ConstString MangledName("___Z1fU13block_pointerFviE_block_invoke");
|
||||
Mangled TheMangled(MangledName);
|
||||
ConstString TheDemangled =
|
||||
TheMangled.GetDemangledName(eLanguageTypeC_plus_plus);
|
||||
|
||||
ConstString ExpectedResult(
|
||||
"invocation function for block in f(void (int) block_pointer)");
|
||||
EXPECT_STREQ(ExpectedResult.GetCString(), TheDemangled.GetCString());
|
||||
}
|
||||
|
||||
TEST(MangledTest, EmptyForInvalidName) {
|
||||
ConstString MangledName("_ZN1a1b1cmxktpEEvm");
|
||||
Mangled TheMangled(MangledName);
|
||||
|
|
Loading…
Reference in New Issue