| //===-- JavaFormatterFunctions.cpp-------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| // C Includes |
| // C++ Includes |
| // Other libraries and framework includes |
| // Project includes |
| #include "JavaFormatterFunctions.h" |
| #include "lldb/DataFormatters/FormattersHelpers.h" |
| #include "lldb/DataFormatters/StringPrinter.h" |
| #include "lldb/Symbol/JavaASTContext.h" |
| |
| using namespace lldb; |
| using namespace lldb_private; |
| using namespace lldb_private::formatters; |
| |
| namespace { |
| |
| class JavaArraySyntheticFrontEnd : public SyntheticChildrenFrontEnd { |
| public: |
| JavaArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) |
| : SyntheticChildrenFrontEnd(*valobj_sp) { |
| if (valobj_sp) |
| Update(); |
| } |
| |
| size_t CalculateNumChildren() override { |
| ValueObjectSP valobj = GetDereferencedValueObject(); |
| if (!valobj) |
| return 0; |
| |
| CompilerType type = valobj->GetCompilerType(); |
| uint32_t size = JavaASTContext::CalculateArraySize(type, *valobj); |
| if (size == UINT32_MAX) |
| return 0; |
| return size; |
| } |
| |
| lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { |
| ValueObjectSP valobj = GetDereferencedValueObject(); |
| if (!valobj) |
| return nullptr; |
| |
| ProcessSP process_sp = valobj->GetProcessSP(); |
| if (!process_sp) |
| return nullptr; |
| |
| CompilerType type = valobj->GetCompilerType(); |
| CompilerType element_type = type.GetArrayElementType(); |
| lldb::addr_t address = |
| valobj->GetAddressOf() + |
| JavaASTContext::CalculateArrayElementOffset(type, idx); |
| |
| Status error; |
| size_t byte_size = element_type.GetByteSize(nullptr); |
| DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0)); |
| size_t bytes_read = process_sp->ReadMemory(address, buffer_sp->GetBytes(), |
| byte_size, error); |
| if (error.Fail() || byte_size != bytes_read) |
| return nullptr; |
| |
| StreamString name; |
| name.Printf("[%" PRIu64 "]", (uint64_t)idx); |
| DataExtractor data(buffer_sp, process_sp->GetByteOrder(), |
| process_sp->GetAddressByteSize()); |
| return CreateValueObjectFromData( |
| name.GetString(), data, valobj->GetExecutionContextRef(), element_type); |
| } |
| |
| bool Update() override { return false; } |
| |
| bool MightHaveChildren() override { return true; } |
| |
| size_t GetIndexOfChildWithName(const ConstString &name) override { |
| return ExtractIndexFromString(name.GetCString()); |
| } |
| |
| private: |
| ValueObjectSP GetDereferencedValueObject() { |
| if (!m_backend.IsPointerOrReferenceType()) |
| return m_backend.GetSP(); |
| |
| Status error; |
| return m_backend.Dereference(error); |
| } |
| }; |
| |
| } // end of anonymous namespace |
| |
| bool lldb_private::formatters::JavaStringSummaryProvider( |
| ValueObject &valobj, Stream &stream, const TypeSummaryOptions &opts) { |
| if (valobj.IsPointerOrReferenceType()) { |
| Status error; |
| ValueObjectSP deref = valobj.Dereference(error); |
| if (error.Fail()) |
| return false; |
| return JavaStringSummaryProvider(*deref, stream, opts); |
| } |
| |
| ProcessSP process_sp = valobj.GetProcessSP(); |
| if (!process_sp) |
| return false; |
| |
| ConstString data_name("value"); |
| ConstString length_name("count"); |
| |
| ValueObjectSP length_sp = valobj.GetChildMemberWithName(length_name, true); |
| ValueObjectSP data_sp = valobj.GetChildMemberWithName(data_name, true); |
| if (!data_sp || !length_sp) |
| return false; |
| |
| bool success = false; |
| uint64_t length = length_sp->GetValueAsUnsigned(0, &success); |
| if (!success) |
| return false; |
| |
| if (length == 0) { |
| stream.Printf("\"\""); |
| return true; |
| } |
| lldb::addr_t valobj_addr = data_sp->GetAddressOf(); |
| |
| StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); |
| options.SetLocation(valobj_addr); |
| options.SetProcessSP(process_sp); |
| options.SetStream(&stream); |
| options.SetSourceSize(length); |
| options.SetNeedsZeroTermination(false); |
| options.SetLanguage(eLanguageTypeJava); |
| |
| if (StringPrinter::ReadStringAndDumpToStream< |
| StringPrinter::StringElementType::UTF16>(options)) |
| return true; |
| |
| stream.Printf("Summary Unavailable"); |
| return true; |
| } |
| |
| bool lldb_private::formatters::JavaArraySummaryProvider( |
| ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { |
| if (valobj.IsPointerOrReferenceType()) { |
| Status error; |
| ValueObjectSP deref = valobj.Dereference(error); |
| if (error.Fail()) |
| return false; |
| return JavaArraySummaryProvider(*deref, stream, options); |
| } |
| |
| CompilerType type = valobj.GetCompilerType(); |
| uint32_t size = JavaASTContext::CalculateArraySize(type, valobj); |
| if (size == UINT32_MAX) |
| return false; |
| stream.Printf("[%u]{...}", size); |
| return true; |
| } |
| |
| SyntheticChildrenFrontEnd * |
| lldb_private::formatters::JavaArraySyntheticFrontEndCreator( |
| CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { |
| return valobj_sp ? new JavaArraySyntheticFrontEnd(valobj_sp) : nullptr; |
| } |