summaryrefslogtreecommitdiff
path: root/source/Plugins/Language/CPlusPlus
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Language/CPlusPlus')
-rw-r--r--source/Plugins/Language/CPlusPlus/BlockPointer.cpp14
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp59
-rw-r--r--source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp51
-rw-r--r--source/Plugins/Language/CPlusPlus/CxxStringTypes.h6
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp15
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp1
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp11
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp39
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp1
-rw-r--r--source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp13
-rw-r--r--source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp29
11 files changed, 167 insertions, 72 deletions
diff --git a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
index 87b5b5947f358..5cfd978774fd0 100644
--- a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
+++ b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
@@ -17,6 +17,7 @@
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBAssert.h"
+#include "lldb/Utility/Log.h"
using namespace lldb;
using namespace lldb_private;
@@ -39,16 +40,17 @@ public:
return;
}
- Status err;
- TypeSystem *type_system = target_sp->GetScratchTypeSystemForLanguage(
- &err, lldb::eLanguageTypeC_plus_plus);
-
- if (!err.Success() || !type_system) {
+ auto type_system_or_err = target_sp->GetScratchTypeSystemForLanguage(
+ lldb::eLanguageTypeC_plus_plus);
+ if (auto err = type_system_or_err.takeError()) {
+ LLDB_LOG_ERROR(
+ lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DATAFORMATTERS),
+ std::move(err), "Failed to get scratch ClangASTContext");
return;
}
ClangASTContext *clang_ast_context =
- llvm::dyn_cast<ClangASTContext>(type_system);
+ llvm::dyn_cast<ClangASTContext>(&type_system_or_err.get());
if (!clang_ast_context) {
return;
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 44b9e5e24ccd9..489fa7d0ad918 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -486,8 +486,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
cpp_category_sp,
lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator,
"libc++ std::list synthetic children",
- ConstString("^std::__[[:alnum:]]+::list<.+>(( )?&)?$"), stl_deref_flags,
- true);
+ // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>(( )?&)?$"
+ // so that it does not clash with: "^std::(__cxx11::)?list<.+>(( )?&)?$"
+ ConstString("^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|"
+ "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$"),
+ stl_deref_flags, true);
AddCXXSynthetic(
cpp_category_sp,
lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
@@ -547,8 +550,8 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
ConstString("^std::__[[:alnum:]]+::atomic<.+>$"), stl_synth_flags, true);
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpressionSP(new RegularExpression(
- llvm::StringRef("^(std::__[[:alnum:]]+::)deque<.+>(( )?&)?$"))),
+ RegularExpression(
+ llvm::StringRef("^(std::__[[:alnum:]]+::)deque<.+>(( )?&)?$")),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.libcxx.stddeque_SynthProvider")));
@@ -566,12 +569,6 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
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);
AddCXXSummary(cpp_category_sp,
@@ -589,11 +586,14 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
"libc++ std::list summary provider",
ConstString("^std::__[[:alnum:]]+::forward_list<.+>(( )?&)?$"),
stl_summary_flags, true);
- AddCXXSummary(cpp_category_sp,
- lldb_private::formatters::LibcxxContainerSummaryProvider,
- "libc++ std::list summary provider",
- ConstString("^std::__[[:alnum:]]+::list<.+>(( )?&)?$"),
- stl_summary_flags, true);
+ AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider,
+ "libc++ std::list summary provider",
+ // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>(( )?&)?$"
+ // so that it does not clash with: "^std::(__cxx11::)?list<.+>(( )?&)?$"
+ ConstString("^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|"
+ "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$"),
+ stl_summary_flags, true);
AddCXXSummary(cpp_category_sp,
lldb_private::formatters::LibcxxContainerSummaryProvider,
"libc++ std::map summary provider",
@@ -750,38 +750,32 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
false);
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpressionSP(
- new RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$")),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdVectorSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpressionSP(
- new RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$")),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdMapSynthProvider")));
cpp_category_sp->GetRegexTypeSyntheticsContainer()->Add(
- RegularExpressionSP(new RegularExpression(
- llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$")),
SyntheticChildrenSP(new ScriptedSyntheticChildren(
stl_synth_flags,
"lldb.formatters.cpp.gnu_libstdcpp.StdListSynthProvider")));
stl_summary_flags.SetDontShowChildren(false);
stl_summary_flags.SetSkipPointers(true);
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpressionSP(
- new RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::vector<.+>(( )?&)?$")),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpressionSP(
- new RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::map<.+> >(( )?&)?$")),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
cpp_category_sp->GetRegexTypeSummariesContainer()->Add(
- RegularExpressionSP(new RegularExpression(
- llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$"))),
+ RegularExpression(llvm::StringRef("^std::(__cxx11::)?list<.+>(( )?&)?$")),
TypeSummaryImplSP(
new StringSummaryFormat(stl_summary_flags, "size=${svar%#}")));
@@ -860,6 +854,14 @@ static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
// FIXME because of a bug in the FormattersContainer we need to add a summary
// for both X* and const X* (<rdar://problem/12717717>)
AddCXXSummary(
+ cpp_category_sp, lldb_private::formatters::Char8StringSummaryProvider,
+ "char8_t * summary provider", ConstString("char8_t *"), string_flags);
+ AddCXXSummary(cpp_category_sp,
+ lldb_private::formatters::Char8StringSummaryProvider,
+ "char8_t [] summary provider",
+ ConstString("char8_t \\[[0-9]+\\]"), string_array_flags, true);
+
+ AddCXXSummary(
cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider,
"char16_t * summary provider", ConstString("char16_t *"), string_flags);
AddCXXSummary(cpp_category_sp,
@@ -896,6 +898,9 @@ static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
.SetHideItemNames(true)
.SetShowMembersOneLiner(false);
+ AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char8SummaryProvider,
+ "char8_t summary provider", ConstString("char8_t"),
+ widechar_flags);
AddCXXSummary(
cpp_category_sp, lldb_private::formatters::Char16SummaryProvider,
"char16_t summary provider", ConstString("char16_t"), widechar_flags);
diff --git a/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
index 959079070accc..3ea7589d8e4a8 100644
--- a/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
+++ b/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp
@@ -32,6 +32,31 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
+bool lldb_private::formatters::Char8StringSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
+ ProcessSP process_sp = valobj.GetProcessSP();
+ if (!process_sp)
+ return false;
+
+ lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj);
+ if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
+ options.SetLocation(valobj_addr);
+ options.SetProcessSP(process_sp);
+ options.SetStream(&stream);
+ options.SetPrefixToken("u8");
+
+ if (!StringPrinter::ReadStringAndDumpToStream<
+ StringPrinter::StringElementType::UTF8>(options)) {
+ stream.Printf("Summary Unavailable");
+ return true;
+ }
+
+ return true;
+}
+
bool lldb_private::formatters::Char16StringSummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
ProcessSP process_sp = valobj.GetProcessSP();
@@ -128,6 +153,32 @@ bool lldb_private::formatters::WCharStringSummaryProvider(
return true;
}
+bool lldb_private::formatters::Char8SummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
+ DataExtractor data;
+ Status error;
+ valobj.GetData(data, error);
+
+ if (error.Fail())
+ return false;
+
+ std::string value;
+ valobj.GetValueAsCString(lldb::eFormatUnicode8, value);
+ if (!value.empty())
+ stream.Printf("%s ", value.c_str());
+
+ StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj);
+ options.SetData(data);
+ options.SetStream(&stream);
+ options.SetPrefixToken("u8");
+ options.SetQuote('\'');
+ options.SetSourceSize(1);
+ options.SetBinaryZeroIsTerminator(false);
+
+ return StringPrinter::ReadBufferAndDumpToStream<
+ StringPrinter::StringElementType::UTF8>(options);
+}
+
bool lldb_private::formatters::Char16SummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) {
DataExtractor data;
diff --git a/source/Plugins/Language/CPlusPlus/CxxStringTypes.h b/source/Plugins/Language/CPlusPlus/CxxStringTypes.h
index 92bef2382eac1..35498b3b568f7 100644
--- a/source/Plugins/Language/CPlusPlus/CxxStringTypes.h
+++ b/source/Plugins/Language/CPlusPlus/CxxStringTypes.h
@@ -16,6 +16,9 @@
namespace lldb_private {
namespace formatters {
+bool Char8StringSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // char8_t*
+
bool Char16StringSummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // char16_t* and unichar*
@@ -27,6 +30,9 @@ bool Char32StringSummaryProvider(
bool WCharStringSummaryProvider(ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // wchar_t*
+bool Char8SummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &options); // char8_t
+
bool Char16SummaryProvider(
ValueObject &valobj, Stream &stream,
const TypeSummaryOptions &options); // char16_t and unichar
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
index 815dafb6c7242..78c453cd1b3c7 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp
@@ -30,8 +30,15 @@ public:
ValueObjectSP GetChildAtIndex(size_t idx) override;
private:
+ // The lifetime of a ValueObject and all its derivative ValueObjects
+ // (children, clones, etc.) is managed by a ClusterManager. These
+ // objects are only destroyed when every shared pointer to any of them
+ // is destroyed, so we must not store a shared pointer to any ValueObject
+ // derived from our backend ValueObject (since we're in the same cluster).
+ // Value objects created from raw data (i.e. in a different cluster) must
+ // be referenced via shared pointer to keep them alive, however.
std::vector<ValueObjectSP> m_elements;
- ValueObjectSP m_first;
+ ValueObject* m_first = nullptr;
CompilerType m_bool_type;
ByteOrder m_byte_order = eByteOrderInvalid;
uint8_t m_byte_size = 0;
@@ -50,7 +57,7 @@ BitsetFrontEnd::BitsetFrontEnd(ValueObject &valobj)
bool BitsetFrontEnd::Update() {
m_elements.clear();
- m_first.reset();
+ m_first = nullptr;
TargetSP target_sp = m_backend.GetTargetSP();
if (!target_sp)
@@ -63,7 +70,7 @@ bool BitsetFrontEnd::Update() {
m_elements.assign(size, ValueObjectSP());
- m_first = m_backend.GetChildMemberWithName(ConstString("__first_"), true);
+ m_first = m_backend.GetChildMemberWithName(ConstString("__first_"), true).get();
return false;
}
@@ -86,7 +93,7 @@ ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) {
chunk = m_first->GetChildAtIndex(idx / *bit_size, true);
} else {
type = m_first->GetCompilerType();
- chunk = m_first;
+ chunk = m_first->GetSP();
}
if (!type || !chunk)
return {};
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
index 116021588848c..b1ad171d0b0c6 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp
@@ -31,7 +31,6 @@ public:
private:
size_t m_size = 0;
- ValueObjectSP m_base_sp;
};
} // namespace
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp b/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
index 4b72089c6ba2e..2f06d684f953c 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp
@@ -38,16 +38,21 @@ public:
}
private:
- ValueObjectSP m_container_sp;
+ // The lifetime of a ValueObject and all its derivative ValueObjects
+ // (children, clones, etc.) is managed by a ClusterManager. These
+ // objects are only destroyed when every shared pointer to any of them
+ // is destroyed, so we must not store a shared pointer to any ValueObject
+ // derived from our backend ValueObject (since we're in the same cluster).
+ ValueObject* m_container_sp = nullptr;
};
} // namespace
bool QueueFrontEnd::Update() {
- m_container_sp.reset();
+ m_container_sp = nullptr;
ValueObjectSP c_sp = m_backend.GetChildMemberWithName(ConstString("c"), true);
if (!c_sp)
return false;
- m_container_sp = c_sp->GetSyntheticValue();
+ m_container_sp = c_sp->GetSyntheticValue().get();
return false;
}
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp b/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp
index 8da7460f2275f..45294e25f0f5d 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp
@@ -30,47 +30,58 @@ public:
ValueObjectSP GetChildAtIndex(size_t idx) override;
private:
- std::vector<ValueObjectSP> m_elements;
- ValueObjectSP m_base_sp;
+ // The lifetime of a ValueObject and all its derivative ValueObjects
+ // (children, clones, etc.) is managed by a ClusterManager. These
+ // objects are only destroyed when every shared pointer to any of them
+ // is destroyed, so we must not store a shared pointer to any ValueObject
+ // derived from our backend ValueObject (since we're in the same cluster).
+ std::vector<ValueObject*> m_elements;
+ ValueObject* m_base = nullptr;
};
}
bool TupleFrontEnd::Update() {
m_elements.clear();
- m_base_sp = m_backend.GetChildMemberWithName(ConstString("__base_"), true);
- if (! m_base_sp) {
+ m_base = nullptr;
+
+ ValueObjectSP base_sp;
+ base_sp = m_backend.GetChildMemberWithName(ConstString("__base_"), true);
+ if (!base_sp) {
// Pre r304382 name of the base element.
- m_base_sp = m_backend.GetChildMemberWithName(ConstString("base_"), true);
+ base_sp = m_backend.GetChildMemberWithName(ConstString("base_"), true);
}
- if (! m_base_sp)
+ if (!base_sp)
return false;
- m_elements.assign(m_base_sp->GetCompilerType().GetNumDirectBaseClasses(),
- ValueObjectSP());
+ m_base = base_sp.get();
+ m_elements.assign(base_sp->GetCompilerType().GetNumDirectBaseClasses(),
+ nullptr);
return false;
}
ValueObjectSP TupleFrontEnd::GetChildAtIndex(size_t idx) {
if (idx >= m_elements.size())
return ValueObjectSP();
- if (!m_base_sp)
+ if (!m_base)
return ValueObjectSP();
if (m_elements[idx])
- return m_elements[idx];
+ return m_elements[idx]->GetSP();
CompilerType holder_type =
- m_base_sp->GetCompilerType().GetDirectBaseClassAtIndex(idx, nullptr);
+ m_base->GetCompilerType().GetDirectBaseClassAtIndex(idx, nullptr);
if (!holder_type)
return ValueObjectSP();
- ValueObjectSP holder_sp = m_base_sp->GetChildAtIndex(idx, true);
+ ValueObjectSP holder_sp = m_base->GetChildAtIndex(idx, true);
if (!holder_sp)
return ValueObjectSP();
ValueObjectSP elem_sp = holder_sp->GetChildAtIndex(0, true);
if (elem_sp)
m_elements[idx] =
- elem_sp->Clone(ConstString(llvm::formatv("[{0}]", idx).str()));
+ elem_sp->Clone(ConstString(llvm::formatv("[{0}]", idx).str())).get();
- return m_elements[idx];
+ if (m_elements[idx])
+ return m_elements[idx]->GetSP();
+ return ValueObjectSP();
}
SyntheticChildrenFrontEnd *
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp b/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp
index 491cf048e4592..62945bd3ce80b 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp
@@ -184,7 +184,6 @@ public:
private:
size_t m_size = 0;
- ValueObjectSP m_base_sp;
};
} // namespace
diff --git a/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp b/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
index 66624e5beb6dc..0ac7b8f8e02b0 100644
--- a/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp
@@ -37,7 +37,12 @@ public:
size_t GetIndexOfChildWithName(ConstString name) override;
private:
- std::vector<ValueObjectSP> m_members;
+ // The lifetime of a ValueObject and all its derivative ValueObjects
+ // (children, clones, etc.) is managed by a ClusterManager. These
+ // objects are only destroyed when every shared pointer to any of them
+ // is destroyed, so we must not store a shared pointer to any ValueObject
+ // derived from our backend ValueObject (since we're in the same cluster).
+ std::vector<ValueObject*> m_members;
};
} // end of anonymous namespace
@@ -72,7 +77,7 @@ bool LibStdcppTupleSyntheticFrontEnd::Update() {
if (value_sp) {
StreamString name;
name.Printf("[%zd]", m_members.size());
- m_members.push_back(value_sp->Clone(ConstString(name.GetString())));
+ m_members.push_back(value_sp->Clone(ConstString(name.GetString())).get());
}
}
}
@@ -85,8 +90,8 @@ bool LibStdcppTupleSyntheticFrontEnd::MightHaveChildren() { return true; }
lldb::ValueObjectSP
LibStdcppTupleSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
- if (idx < m_members.size())
- return m_members[idx];
+ if (idx < m_members.size() && m_members[idx])
+ return m_members[idx]->GetSP();
return lldb::ValueObjectSP();
}
diff --git a/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
index 3860f960cb3de..cceb511cdc465 100644
--- a/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
@@ -39,9 +39,14 @@ public:
bool GetSummary(Stream &stream, const TypeSummaryOptions &options);
private:
- ValueObjectSP m_ptr_obj;
- ValueObjectSP m_obj_obj;
- ValueObjectSP m_del_obj;
+ // The lifetime of a ValueObject and all its derivative ValueObjects
+ // (children, clones, etc.) is managed by a ClusterManager. These
+ // objects are only destroyed when every shared pointer to any of them
+ // is destroyed, so we must not store a shared pointer to any ValueObject
+ // derived from our backend ValueObject (since we're in the same cluster).
+ ValueObject* m_ptr_obj = nullptr;
+ ValueObject* m_obj_obj = nullptr;
+ ValueObject* m_del_obj = nullptr;
ValueObjectSP GetTuple();
};
@@ -92,17 +97,17 @@ bool LibStdcppUniquePtrSyntheticFrontEnd::Update() {
ValueObjectSP ptr_obj = tuple_frontend->GetChildAtIndex(0);
if (ptr_obj)
- m_ptr_obj = ptr_obj->Clone(ConstString("pointer"));
+ m_ptr_obj = ptr_obj->Clone(ConstString("pointer")).get();
ValueObjectSP del_obj = tuple_frontend->GetChildAtIndex(1);
if (del_obj)
- m_del_obj = del_obj->Clone(ConstString("deleter"));
+ m_del_obj = del_obj->Clone(ConstString("deleter")).get();
if (m_ptr_obj) {
Status error;
ValueObjectSP obj_obj = m_ptr_obj->Dereference(error);
if (error.Success()) {
- m_obj_obj = obj_obj->Clone(ConstString("object"));
+ m_obj_obj = obj_obj->Clone(ConstString("object")).get();
}
}
@@ -113,12 +118,12 @@ bool LibStdcppUniquePtrSyntheticFrontEnd::MightHaveChildren() { return true; }
lldb::ValueObjectSP
LibStdcppUniquePtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) {
- if (idx == 0)
- return m_ptr_obj;
- if (idx == 1)
- return m_del_obj;
- if (idx == 2)
- return m_obj_obj;
+ if (idx == 0 && m_ptr_obj)
+ return m_ptr_obj->GetSP();
+ if (idx == 1 && m_del_obj)
+ return m_del_obj->GetSP();
+ if (idx == 2 && m_obj_obj)
+ return m_obj_obj->GetSP();
return lldb::ValueObjectSP();
}