Index: lldb/include/lldb/Core/Mangled.h =================================================================== --- lldb/include/lldb/Core/Mangled.h +++ lldb/include/lldb/Core/Mangled.h @@ -261,6 +261,15 @@ 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 Index: lldb/source/Core/Mangled.cpp =================================================================== --- lldb/source/Core/Mangled.cpp +++ lldb/source/Core/Mangled.cpp @@ -32,18 +32,8 @@ #include 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 @@ #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 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 @@ 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 @@ // 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 @@ // within those targets. lldb::LanguageType Mangled::GuessLanguage() const { ConstString mangled = GetMangledName(); + if (mangled) { const char *mangled_name = mangled.GetCString(); if (CPlusPlusLanguage::IsCPPMangledName(mangled_name)) Index: lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h =================================================================== --- lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h +++ lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h @@ -101,7 +101,7 @@ 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 Index: lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp =================================================================== --- lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -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 @@ 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) - return false; + Mangled::ManglingScheme scheme = Mangled::GetManglingScheme(name); - // MSVC style mangling - if (name[0] == '?') - return true; + if (scheme == Mangled::eManglingSchemeNone) + return false; - return (name[0] != '\0' && name[0] == '_' && name[1] == 'Z'); + return true; } bool CPlusPlusLanguage::ExtractContextAndIdentifier( Index: lldb/unittests/Core/MangledTest.cpp =================================================================== --- lldb/unittests/Core/MangledTest.cpp +++ lldb/unittests/Core/MangledTest.cpp @@ -37,6 +37,17 @@ 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);