diff options
Diffstat (limited to 'lldb/source/Plugins')
5 files changed, 144 insertions, 10 deletions
diff --git a/lldb/source/Plugins/Language/Java/JavaFormatterFunctions.cpp b/lldb/source/Plugins/Language/Java/JavaFormatterFunctions.cpp index ab368b33fbc..09f45d6a853 100644 --- a/lldb/source/Plugins/Language/Java/JavaFormatterFunctions.cpp +++ b/lldb/source/Plugins/Language/Java/JavaFormatterFunctions.cpp @@ -14,11 +14,100 @@ #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); + + Error 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.GetData(), 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()) + m_backend.GetSP(); + + Error error; + return m_backend.Dereference(error); + } +}; + +} // end of anonymous namespace + bool lldb_private::formatters::JavaStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &opts) { @@ -69,3 +158,29 @@ lldb_private::formatters::JavaStringSummaryProvider(ValueObject &valobj, Stream stream.Printf("Summary Unavailable"); return true; } + +bool +lldb_private::formatters::JavaArraySummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) +{ + if (valobj.IsPointerOrReferenceType()) + { + Error 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; +} diff --git a/lldb/source/Plugins/Language/Java/JavaFormatterFunctions.h b/lldb/source/Plugins/Language/Java/JavaFormatterFunctions.h index 3fe7cf10141..f9588c5590a 100644 --- a/lldb/source/Plugins/Language/Java/JavaFormatterFunctions.h +++ b/lldb/source/Plugins/Language/Java/JavaFormatterFunctions.h @@ -24,6 +24,12 @@ namespace formatters bool JavaStringSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); +bool +JavaArraySummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); + +SyntheticChildrenFrontEnd* +JavaArraySyntheticFrontEndCreator (CXXSyntheticChildren*, lldb::ValueObjectSP valobj_sp); + } // namespace formatters } // namespace lldb_private diff --git a/lldb/source/Plugins/Language/Java/JavaLanguage.cpp b/lldb/source/Plugins/Language/Java/JavaLanguage.cpp index eefc2efb718..7bd5f8a5463 100644 --- a/lldb/source/Plugins/Language/Java/JavaLanguage.cpp +++ b/lldb/source/Plugins/Language/Java/JavaLanguage.cpp @@ -88,11 +88,22 @@ JavaLanguage::GetFormatters() DataVisualization::Categories::GetCategory(GetPluginName(), g_category); if (g_category) { + const char* array_regexp = "^.*\\[\\]&?$"; + lldb::TypeSummaryImplSP string_summary_sp(new CXXFunctionSummaryFormat( TypeSummaryImpl::Flags().SetDontShowChildren(true), lldb_private::formatters::JavaStringSummaryProvider, "java.lang.String summary provider")); - g_category->GetTypeSummariesContainer()->Add(ConstString("java::lang::String"), string_summary_sp); + + lldb::TypeSummaryImplSP array_summary_sp(new CXXFunctionSummaryFormat( + TypeSummaryImpl::Flags().SetDontShowChildren(true), lldb_private::formatters::JavaArraySummaryProvider, + "Java array summary provider")); + g_category->GetRegexTypeSummariesContainer()->Add(RegularExpressionSP(new RegularExpression(array_regexp)), + array_summary_sp); + + AddCXXSynthetic(g_category, lldb_private::formatters::JavaArraySyntheticFrontEndCreator, + "Java array synthetic children", ConstString(array_regexp), + SyntheticChildren::Flags().SetCascades(true), true); } }); return g_category; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp index 1bb107966a9..71290f2f879 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp @@ -147,7 +147,7 @@ DWARFASTParserJava::ParseArrayTypeFromDIE(const DWARFDIE &die) CompilerType element_compiler_type = element_type->GetForwardCompilerType(); CompilerType array_compiler_type = - m_ast.CreateArrayType(element_compiler_type, length_expression, data_offset); + m_ast.CreateArrayType(linkage_name, element_compiler_type, length_expression, data_offset); Declaration decl; TypeSP type_sp(new Type(die.GetID(), dwarf, array_compiler_type.GetTypeName(), -1, nullptr, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index f1074921060..c5d7568b527 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -755,20 +755,21 @@ DWARFCompileUnit::IndexPrivate (DWARFCompileUnit* dwarf_cu, switch (tag) { - case DW_TAG_subprogram: - case DW_TAG_inlined_subroutine: + case DW_TAG_array_type: case DW_TAG_base_type: case DW_TAG_class_type: case DW_TAG_constant: case DW_TAG_enumeration_type: + case DW_TAG_inlined_subroutine: + case DW_TAG_namespace: case DW_TAG_string_type: - case DW_TAG_subroutine_type: case DW_TAG_structure_type: - case DW_TAG_union_type: + case DW_TAG_subprogram: + case DW_TAG_subroutine_type: case DW_TAG_typedef: - case DW_TAG_namespace: - case DW_TAG_variable: + case DW_TAG_union_type: case DW_TAG_unspecified_type: + case DW_TAG_variable: break; default: @@ -980,15 +981,16 @@ DWARFCompileUnit::IndexPrivate (DWARFCompileUnit* dwarf_cu, } break; + case DW_TAG_array_type: case DW_TAG_base_type: case DW_TAG_class_type: case DW_TAG_constant: case DW_TAG_enumeration_type: case DW_TAG_string_type: - case DW_TAG_subroutine_type: case DW_TAG_structure_type: - case DW_TAG_union_type: + case DW_TAG_subroutine_type: case DW_TAG_typedef: + case DW_TAG_union_type: case DW_TAG_unspecified_type: if (name && !is_declaration) types.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset())); |