Skip to content

Commit

Permalink
Add support for displaying Java array types on Andorid
Browse files Browse the repository at this point in the history
Differential revision: http://reviews.llvm.org/D19540

llvm-svn: 268622
  • Loading branch information
Tamas Berghammer committed May 5, 2016
1 parent d00698f commit 2ff8330
Show file tree
Hide file tree
Showing 7 changed files with 258 additions and 70 deletions.
10 changes: 8 additions & 2 deletions lldb/include/lldb/Symbol/JavaASTContext.h
Expand Up @@ -335,8 +335,8 @@ class JavaASTContext : public TypeSystem
CreateObjectType(const ConstString &name, const ConstString &linkage_name, uint32_t byte_size);

CompilerType
CreateArrayType(const CompilerType &element_type, const DWARFExpression &length_expression,
const lldb::addr_t data_offset);
CreateArrayType(const ConstString &linkage_name, const CompilerType &element_type,
const DWARFExpression &length_expression, const lldb::addr_t data_offset);

CompilerType
CreateReferenceType(const CompilerType &pointee_type);
Expand All @@ -360,6 +360,12 @@ class JavaASTContext : public TypeSystem
static ConstString
GetLinkageName(const CompilerType &type);

static uint32_t
CalculateArraySize(const CompilerType &type, ValueObject &in_value);

static uint64_t
CalculateArrayElementOffset(const CompilerType &type, size_t index);

//------------------------------------------------------------------
// llvm casting support
//------------------------------------------------------------------
Expand Down
115 changes: 115 additions & 0 deletions lldb/source/Plugins/Language/Java/JavaFormatterFunctions.cpp
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
}
6 changes: 6 additions & 0 deletions lldb/source/Plugins/Language/Java/JavaFormatterFunctions.h
Expand Up @@ -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

Expand Down
13 changes: 12 additions & 1 deletion lldb/source/Plugins/Language/Java/JavaLanguage.cpp
Expand Up @@ -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;
Expand Down
Expand Up @@ -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,
Expand Down
18 changes: 10 additions & 8 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
Expand Up @@ -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:
Expand Down Expand Up @@ -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()));
Expand Down

0 comments on commit 2ff8330

Please sign in to comment.