summaryrefslogtreecommitdiff
path: root/source/Plugins/Language/CPlusPlus/LibCxx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/Plugins/Language/CPlusPlus/LibCxx.cpp')
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxx.cpp186
1 files changed, 140 insertions, 46 deletions
diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 95e02a473cd7..7e8c06bd4c75 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -9,10 +9,7 @@
#include "LibCxx.h"
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-// Project includes
+#include "llvm/ADT/ScopeExit.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/FormatEntity.h"
#include "lldb/Core/ValueObject.h"
@@ -22,7 +19,9 @@
#include "lldb/DataFormatters/TypeSummary.h"
#include "lldb/DataFormatters/VectorIterator.h"
#include "lldb/Symbol/ClangASTContext.h"
+#include "lldb/Target/CPPLanguageRuntime.h"
#include "lldb/Target/ProcessStructReader.h"
+#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/Endian.h"
@@ -33,6 +32,76 @@ using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::formatters;
+bool lldb_private::formatters::LibcxxOptionalSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+ ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
+ if (!valobj_sp)
+ return false;
+
+ // An optional either contains a value or not, the member __engaged_ is
+ // a bool flag, it is true if the optional has a value and false otherwise.
+ ValueObjectSP engaged_sp(
+ valobj_sp->GetChildMemberWithName(ConstString("__engaged_"), true));
+
+ if (!engaged_sp)
+ return false;
+
+ llvm::StringRef engaged_as_cstring(
+ engaged_sp->GetValueAsUnsigned(0) == 1 ? "true" : "false");
+
+ stream.Printf(" Has Value=%s ", engaged_as_cstring.data());
+
+ return true;
+}
+
+bool lldb_private::formatters::LibcxxFunctionSummaryProvider(
+ ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
+
+ ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
+
+ if (!valobj_sp)
+ return false;
+
+ ExecutionContext exe_ctx(valobj_sp->GetExecutionContextRef());
+ Process *process = exe_ctx.GetProcessPtr();
+
+ if (process == nullptr)
+ return false;
+
+ CPPLanguageRuntime *cpp_runtime = process->GetCPPLanguageRuntime();
+
+ if (!cpp_runtime)
+ return false;
+
+ CPPLanguageRuntime::LibCppStdFunctionCallableInfo callable_info =
+ cpp_runtime->FindLibCppStdFunctionCallableInfo(valobj_sp);
+
+ switch (callable_info.callable_case) {
+ case CPPLanguageRuntime::LibCppStdFunctionCallableCase::Invalid:
+ stream.Printf(" __f_ = %" PRIu64, callable_info.member__f_pointer_value);
+ return false;
+ break;
+ case CPPLanguageRuntime::LibCppStdFunctionCallableCase::Lambda:
+ stream.Printf(
+ " Lambda in File %s at Line %u",
+ callable_info.callable_line_entry.file.GetFilename().GetCString(),
+ callable_info.callable_line_entry.line);
+ break;
+ case CPPLanguageRuntime::LibCppStdFunctionCallableCase::CallableObject:
+ stream.Printf(
+ " Function in File %s at Line %u",
+ callable_info.callable_line_entry.file.GetFilename().GetCString(),
+ callable_info.callable_line_entry.line);
+ break;
+ case CPPLanguageRuntime::LibCppStdFunctionCallableCase::FreeOrMemberFunction:
+ stream.Printf(" Function = %s ",
+ callable_info.callable_symbol.GetName().GetCString());
+ break;
+ }
+
+ return true;
+}
+
bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider(
ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue());
@@ -120,9 +189,9 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
if (!valobj_sp)
return false;
-
+
static ConstString g___i_("__i_");
-
+
// this must be a ValueObject* because it is a child of the ValueObject we
// are producing children for it if were a ValueObjectSP, we would end up
// with a loop (iterator -> synthetic -> child -> parent == iterator) and
@@ -156,37 +225,53 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
m_pair_ptr = nullptr;
return false;
}
- CompilerType pair_type(__i_->GetCompilerType().GetTypeTemplateArgument(0));
- std::string name; uint64_t bit_offset_ptr; uint32_t bitfield_bit_size_ptr; bool is_bitfield_ptr;
- pair_type = pair_type.GetFieldAtIndex(0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr);
+ CompilerType pair_type(
+ __i_->GetCompilerType().GetTypeTemplateArgument(0));
+ std::string name;
+ uint64_t bit_offset_ptr;
+ uint32_t bitfield_bit_size_ptr;
+ bool is_bitfield_ptr;
+ pair_type = pair_type.GetFieldAtIndex(
+ 0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr);
if (!pair_type) {
m_pair_ptr = nullptr;
return false;
}
-
+
auto addr(m_pair_ptr->GetValueAsUnsigned(LLDB_INVALID_ADDRESS));
m_pair_ptr = nullptr;
- if (addr && addr!=LLDB_INVALID_ADDRESS) {
- ClangASTContext *ast_ctx = llvm::dyn_cast_or_null<ClangASTContext>(pair_type.GetTypeSystem());
+ if (addr && addr != LLDB_INVALID_ADDRESS) {
+ ClangASTContext *ast_ctx =
+ llvm::dyn_cast_or_null<ClangASTContext>(pair_type.GetTypeSystem());
if (!ast_ctx)
return false;
- CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(ConstString(), {
- {"ptr0",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
- {"ptr1",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
- {"ptr2",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
- {"cw",ast_ctx->GetBasicType(lldb::eBasicTypeBool)},
- {"payload",pair_type}
- });
- DataBufferSP buffer_sp(new DataBufferHeap(tree_node_type.GetByteSize(nullptr),0));
+ CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(
+ ConstString(),
+ {{"ptr0",
+ ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
+ {"ptr1",
+ ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
+ {"ptr2",
+ ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()},
+ {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)},
+ {"payload", pair_type}});
+ llvm::Optional<uint64_t> size = tree_node_type.GetByteSize(nullptr);
+ if (!size)
+ return false;
+ DataBufferSP buffer_sp(new DataBufferHeap(*size, 0));
ProcessSP process_sp(target_sp->GetProcessSP());
Status error;
- process_sp->ReadMemory(addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), error);
+ process_sp->ReadMemory(addr, buffer_sp->GetBytes(),
+ buffer_sp->GetByteSize(), error);
if (error.Fail())
return false;
- DataExtractor extractor(buffer_sp, process_sp->GetByteOrder(), process_sp->GetAddressByteSize());
- auto pair_sp = CreateValueObjectFromData("pair", extractor, valobj_sp->GetExecutionContextRef(), tree_node_type);
+ DataExtractor extractor(buffer_sp, process_sp->GetByteOrder(),
+ process_sp->GetAddressByteSize());
+ auto pair_sp = CreateValueObjectFromData(
+ "pair", extractor, valobj_sp->GetExecutionContextRef(),
+ tree_node_type);
if (pair_sp)
- m_pair_sp = pair_sp->GetChildAtIndex(4,true);
+ m_pair_sp = pair_sp->GetChildAtIndex(4, true);
}
}
}
@@ -491,6 +576,8 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(
->GetScratchClangASTContext()
->GetBasicType(lldb::eBasicTypeWChar)
.GetByteSize(nullptr);
+ if (!wchar_t_size)
+ return false;
options.SetData(extractor);
options.SetStream(&stream);
@@ -499,7 +586,7 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(
options.SetSourceSize(size);
options.SetBinaryZeroIsTerminator(false);
- switch (wchar_t_size) {
+ switch (*wchar_t_size) {
case 1:
StringPrinter::ReadBufferAndDumpToStream<
lldb_private::formatters::StringPrinter::StringElementType::UTF8>(
@@ -526,9 +613,10 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider(
return true;
}
-bool lldb_private::formatters::LibcxxStringSummaryProvider(
- ValueObject &valobj, Stream &stream,
- const TypeSummaryOptions &summary_options) {
+template <StringPrinter::StringElementType element_type>
+bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options,
+ std::string prefix_token = "") {
uint64_t size = 0;
ValueObjectSP location_sp;
@@ -557,31 +645,37 @@ bool lldb_private::formatters::LibcxxStringSummaryProvider(
options.SetData(extractor);
options.SetStream(&stream);
- options.SetPrefixToken(nullptr);
+
+ if (prefix_token.empty())
+ options.SetPrefixToken(nullptr);
+ else
+ options.SetPrefixToken(prefix_token);
+
options.SetQuote('"');
options.SetSourceSize(size);
options.SetBinaryZeroIsTerminator(false);
- StringPrinter::ReadBufferAndDumpToStream<
- StringPrinter::StringElementType::ASCII>(options);
+ StringPrinter::ReadBufferAndDumpToStream<element_type>(options);
return true;
}
-class LibcxxFunctionFrontEnd : public SyntheticValueProviderFrontEnd {
-public:
- LibcxxFunctionFrontEnd(ValueObject &backend)
- : SyntheticValueProviderFrontEnd(backend) {}
+bool lldb_private::formatters::LibcxxStringSummaryProviderASCII(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options) {
+ return LibcxxStringSummaryProvider<StringPrinter::StringElementType::ASCII>(
+ valobj, stream, summary_options);
+}
- lldb::ValueObjectSP GetSyntheticValue() override {
- static ConstString g___f_("__f_");
- return m_backend.GetChildMemberWithName(g___f_, true);
- }
-};
+bool lldb_private::formatters::LibcxxStringSummaryProviderUTF16(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options) {
+ return LibcxxStringSummaryProvider<StringPrinter::StringElementType::UTF16>(
+ valobj, stream, summary_options, "u");
+}
-SyntheticChildrenFrontEnd *
-lldb_private::formatters::LibcxxFunctionFrontEndCreator(
- CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
- if (valobj_sp)
- return new LibcxxFunctionFrontEnd(*valobj_sp);
- return nullptr;
+bool lldb_private::formatters::LibcxxStringSummaryProviderUTF32(
+ ValueObject &valobj, Stream &stream,
+ const TypeSummaryOptions &summary_options) {
+ return LibcxxStringSummaryProvider<StringPrinter::StringElementType::UTF32>(
+ valobj, stream, summary_options, "U");
}