[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:
shafik 2019-11-06 14:06:56 -08:00
parent 007d173e2e
commit 83393d27af
5 changed files with 50 additions and 23 deletions

View File

@ -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

View File

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

View File

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

View File

@ -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

View File

@ -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);