summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp')
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp152
1 files changed, 104 insertions, 48 deletions
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 489fa7d0ad918..4385a60f58623 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<TypeSubstitutor,
+template <typename Derived>
+class ManglingSubstitutor
+ : public llvm::itanium_demangle::AbstractManglingParser<Derived,
NodeAllocator> {
- /// Input character until which we have constructed the respective output
- /// already
- const char *Written;
+ using Base =
+ llvm::itanium_demangle::AbstractManglingParser<Derived, NodeAllocator>;
- llvm::StringRef Search;
- llvm::StringRef Replace;
- llvm::SmallString<128> Result;
+public:
+ ManglingSubstitutor() : Base(nullptr, nullptr) {}
- /// Whether we have performed any substitutions.
- bool Substituted;
+ template<typename... Ts>
+ ConstString substitute(llvm::StringRef Mangled, Ts &&... Vals) {
+ this->getDerived().reset(Mangled, std::forward<Ts>(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<TypeSubstitutor> {
+ 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<CtorDtorSubstitutor> {
+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<ConstString> &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<char>, "
"std::__[[:alnum:]]+::allocator<char> >$"),
stl_summary_flags, true);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::LibcxxStringSummaryProviderASCII,
+ "std::string summary provider",
+ ConstString("^std::__[[:alnum:]]+::basic_string<unsigned char, "
+ "std::__[[:alnum:]]+::char_traits<unsigned char>, "
+ "std::__[[:alnum:]]+::allocator<unsigned char> >$"),
+ 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<char, std::char_traits<char>, "
"std::allocator<char> >"),
cxx11_string_summary_sp);
+ cpp_category_sp->GetTypeSummariesContainer()->Add(
+ ConstString("std::__cxx11::basic_string<unsigned char, std::char_traits<unsigned char>, "
+ "std::allocator<unsigned char> >"),
+ cxx11_string_summary_sp);
// making sure we force-pick the summary for printing wstring (_M_p is a
// wchar_t*)