From 706b4fc47bbc608932d3b491ae19a3b9cde9497b Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Fri, 17 Jan 2020 20:45:01 +0000 Subject: Vendor import of llvm-project master e26a78e70, the last commit before the llvmorg-11-init tag, from which release/10.x was branched. --- .../Language/CPlusPlus/CPlusPlusLanguage.cpp | 152 ++++++++++++++------- 1 file changed, 104 insertions(+), 48 deletions(-) (limited to 'lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp') diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 489fa7d0ad91..4385a60f5862 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/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 @@ 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) - 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( @@ -285,46 +284,34 @@ public: } }; -/// Given a mangled function `Mangled`, replace all the primitive function type -/// arguments of `Search` with type `Replace`. -class TypeSubstitutor - : public llvm::itanium_demangle::AbstractManglingParser +class ManglingSubstitutor + : public llvm::itanium_demangle::AbstractManglingParser { - /// Input character until which we have constructed the respective output - /// already - const char *Written; + using Base = + llvm::itanium_demangle::AbstractManglingParser; - llvm::StringRef Search; - llvm::StringRef Replace; - llvm::SmallString<128> Result; +public: + ManglingSubstitutor() : Base(nullptr, nullptr) {} - /// Whether we have performed any substitutions. - bool Substituted; + template + ConstString substitute(llvm::StringRef Mangled, Ts &&... Vals) { + this->getDerived().reset(Mangled, std::forward(Vals)...); + return substituteImpl(Mangled); + } - void reset(llvm::StringRef Mangled, llvm::StringRef Search, - llvm::StringRef Replace) { - AbstractManglingParser::reset(Mangled.begin(), Mangled.end()); + +protected: + void reset(llvm::StringRef Mangled) { + Base::reset(Mangled.begin(), Mangled.end()); Written = Mangled.begin(); - this->Search = Search; - this->Replace = Replace; Result.clear(); Substituted = false; } - void appendUnchangedInput() { - Result += llvm::StringRef(Written, First - Written); - Written = First; - } - -public: - TypeSubstitutor() : AbstractManglingParser(nullptr, nullptr) {} - - ConstString substitute(llvm::StringRef Mangled, llvm::StringRef From, - llvm::StringRef To) { + ConstString substituteImpl(llvm::StringRef Mangled) { Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE); - - reset(Mangled, From, To); - if (parse() == nullptr) { + if (this->parse() == nullptr) { LLDB_LOG(log, "Failed to substitute mangling in {0}", Mangled); return ConstString(); } @@ -337,20 +324,69 @@ public: return ConstString(Result); } + void trySubstitute(llvm::StringRef From, llvm::StringRef To) { + if (!llvm::StringRef(currentParserPos(), this->numLeft()).startswith(From)) + return; + + // We found a match. Append unmodified input up to this point. + appendUnchangedInput(); + + // And then perform the replacement. + Result += To; + Written += From.size(); + Substituted = true; + } + +private: + /// Input character until which we have constructed the respective output + /// already. + const char *Written; + + llvm::SmallString<128> Result; + + /// Whether we have performed any substitutions. + bool Substituted; + + const char *currentParserPos() const { return this->First; } + + void appendUnchangedInput() { + Result += + llvm::StringRef(Written, std::distance(Written, currentParserPos())); + Written = currentParserPos(); + } + +}; + +/// Given a mangled function `Mangled`, replace all the primitive function type +/// arguments of `Search` with type `Replace`. +class TypeSubstitutor : public ManglingSubstitutor { + llvm::StringRef Search; + llvm::StringRef Replace; + +public: + void reset(llvm::StringRef Mangled, llvm::StringRef Search, + llvm::StringRef Replace) { + ManglingSubstitutor::reset(Mangled); + this->Search = Search; + this->Replace = Replace; + } + llvm::itanium_demangle::Node *parseType() { - if (llvm::StringRef(First, numLeft()).startswith(Search)) { - // We found a match. Append unmodified input up to this point. - appendUnchangedInput(); - - // And then perform the replacement. - Result += Replace; - Written += Search.size(); - Substituted = true; - } - return AbstractManglingParser::parseType(); + trySubstitute(Search, Replace); + return ManglingSubstitutor::parseType(); } }; -} + +class CtorDtorSubstitutor : public ManglingSubstitutor { +public: + llvm::itanium_demangle::Node * + parseCtorDtorName(llvm::itanium_demangle::Node *&SoFar, NameState *State) { + trySubstitute("C1", "C2"); + trySubstitute("D1", "D2"); + return ManglingSubstitutor::parseCtorDtorName(SoFar, State); + } +}; +} // namespace uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings( const ConstString mangled_name, std::set &alternates) { @@ -398,6 +434,10 @@ uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings( TS.substitute(mangled_name.GetStringRef(), "y", "m")) alternates.insert(ulong_fixup); + if (ConstString ctor_fixup = + CtorDtorSubstitutor().substitute(mangled_name.GetStringRef())) + alternates.insert(ctor_fixup); + return alternates.size() - start_size; } @@ -426,6 +466,13 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { "std::__[[:alnum:]]+::char_traits, " "std::__[[:alnum:]]+::allocator >$"), stl_summary_flags, true); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::LibcxxStringSummaryProviderASCII, + "std::string summary provider", + ConstString("^std::__[[:alnum:]]+::basic_string, " + "std::__[[:alnum:]]+::allocator >$"), + stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxStringSummaryProviderUTF16, @@ -568,6 +615,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { "weak_ptr synthetic children", ConstString("^(std::__[[:alnum:]]+::)weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::LibcxxFunctionSummaryProvider, + "libc++ std::function summary provider", + ConstString("^std::__[[:alnum:]]+::function<.+>$"), + stl_summary_flags, true); stl_summary_flags.SetDontShowChildren(false); stl_summary_flags.SetSkipPointers(false); @@ -719,6 +771,10 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { ConstString("std::__cxx11::basic_string, " "std::allocator >"), cxx11_string_summary_sp); + cpp_category_sp->GetTypeSummariesContainer()->Add( + ConstString("std::__cxx11::basic_string, " + "std::allocator >"), + cxx11_string_summary_sp); // making sure we force-pick the summary for printing wstring (_M_p is a // wchar_t*) -- cgit v1.2.3