[Lldb-commits] [lldb] r268622 - Add support for displaying Java array types on Andorid

Tamas Berghammer via lldb-commits lldb-commits at lists.llvm.org
Thu May 5 04:18:22 PDT 2016


Author: tberghammer
Date: Thu May  5 06:18:21 2016
New Revision: 268622

URL: http://llvm.org/viewvc/llvm-project?rev=268622&view=rev
Log:
Add support for displaying Java array types on Andorid

Differential revision: http://reviews.llvm.org/D19540

Modified:
    lldb/trunk/include/lldb/Symbol/JavaASTContext.h
    lldb/trunk/source/Plugins/Language/Java/JavaFormatterFunctions.cpp
    lldb/trunk/source/Plugins/Language/Java/JavaFormatterFunctions.h
    lldb/trunk/source/Plugins/Language/Java/JavaLanguage.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
    lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
    lldb/trunk/source/Symbol/JavaASTContext.cpp

Modified: lldb/trunk/include/lldb/Symbol/JavaASTContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/JavaASTContext.h?rev=268622&r1=268621&r2=268622&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/JavaASTContext.h (original)
+++ lldb/trunk/include/lldb/Symbol/JavaASTContext.h Thu May  5 06:18:21 2016
@@ -335,8 +335,8 @@ public:
     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);
@@ -360,6 +360,12 @@ public:
     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
     //------------------------------------------------------------------

Modified: lldb/trunk/source/Plugins/Language/Java/JavaFormatterFunctions.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/Java/JavaFormatterFunctions.cpp?rev=268622&r1=268621&r2=268622&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/Java/JavaFormatterFunctions.cpp (original)
+++ lldb/trunk/source/Plugins/Language/Java/JavaFormatterFunctions.cpp Thu May  5 06:18:21 2016
@@ -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::JavaStringSumm
     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;
+}

Modified: lldb/trunk/source/Plugins/Language/Java/JavaFormatterFunctions.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/Java/JavaFormatterFunctions.h?rev=268622&r1=268621&r2=268622&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/Java/JavaFormatterFunctions.h (original)
+++ lldb/trunk/source/Plugins/Language/Java/JavaFormatterFunctions.h Thu May  5 06:18:21 2016
@@ -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
 

Modified: lldb/trunk/source/Plugins/Language/Java/JavaLanguage.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/Java/JavaLanguage.cpp?rev=268622&r1=268621&r2=268622&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Language/Java/JavaLanguage.cpp (original)
+++ lldb/trunk/source/Plugins/Language/Java/JavaLanguage.cpp Thu May  5 06:18:21 2016
@@ -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;

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp?rev=268622&r1=268621&r2=268622&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp Thu May  5 06:18:21 2016
@@ -147,7 +147,7 @@ DWARFASTParserJava::ParseArrayTypeFromDI
 
     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,

Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp?rev=268622&r1=268621&r2=268622&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp Thu May  5 06:18:21 2016
@@ -755,20 +755,21 @@ DWARFCompileUnit::IndexPrivate (DWARFCom
     
         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 (DWARFCom
             }
             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()));

Modified: lldb/trunk/source/Symbol/JavaASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/JavaASTContext.cpp?rev=268622&r1=268621&r2=268622&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/JavaASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/JavaASTContext.cpp Thu May  5 06:18:21 2016
@@ -141,7 +141,60 @@ private:
     const TypeKind m_type_kind;
 };
 
-class JavaObjectType : public JavaASTContext::JavaType
+class JavaDynamicType : public JavaASTContext::JavaType
+{
+public:
+    JavaDynamicType(LLVMCastKind kind, const ConstString &linkage_name) :
+        JavaType(kind),
+        m_linkage_name(linkage_name),
+        m_dynamic_type_id(nullptr)
+    {
+    }
+
+    ConstString
+    GetLinkageName() const
+    {
+        return m_linkage_name;
+    }
+
+    void
+    SetDynamicTypeId(const DWARFExpression &type_id)
+    {
+        m_dynamic_type_id = type_id;
+    }
+
+    uint64_t
+    CalculateDynamicTypeId(ExecutionContext *exe_ctx, ValueObject &value_obj)
+    {
+        if (!m_dynamic_type_id.IsValid())
+            return UINT64_MAX;
+
+        Value obj_load_address = value_obj.GetValue();
+        obj_load_address.ResolveValue(exe_ctx);
+        obj_load_address.SetValueType(Value::eValueTypeLoadAddress);
+
+        Value result;
+        if (m_dynamic_type_id.Evaluate(exe_ctx->GetBestExecutionContextScope(), nullptr, nullptr, 0, &obj_load_address,
+                                       nullptr, result, nullptr))
+        {
+            Error error;
+
+            lldb::addr_t type_id_addr = result.GetScalar().UInt();
+            lldb::ProcessSP process_sp = exe_ctx->GetProcessSP();
+            if (process_sp)
+                return process_sp->ReadUnsignedIntegerFromMemory(type_id_addr, process_sp->GetAddressByteSize(),
+                                                                 UINT64_MAX, error);
+        }
+
+        return UINT64_MAX;
+    }
+
+public:
+    ConstString m_linkage_name;
+    DWARFExpression m_dynamic_type_id;
+};
+
+class JavaObjectType : public JavaDynamicType
 {
 public:
     struct Field
@@ -152,13 +205,11 @@ public:
     };
 
     JavaObjectType(const ConstString &name, const ConstString &linkage_name, uint32_t byte_size)
-        : JavaType(JavaType::eKindObject),
+        : JavaDynamicType(JavaType::eKindObject, linkage_name),
           m_name(name),
-          m_linkage_name(linkage_name),
           m_byte_size(byte_size),
           m_base_class_offset(0),
-          m_is_complete(false),
-          m_dynamic_type_id(nullptr)
+          m_is_complete(false)
     {
     }
 
@@ -168,12 +219,6 @@ public:
         return m_name;
     }
 
-    ConstString
-    GetLinkageName() const
-    {
-        return m_linkage_name;
-    }
-
     uint32_t
     GetByteSize() const
     {
@@ -270,38 +315,6 @@ public:
         m_fields.push_back({name, type, offset});
     }
 
-    void
-    SetDynamicTypeId(const DWARFExpression &type_id)
-    {
-        m_dynamic_type_id = type_id;
-    }
-
-    uint64_t
-    CalculateDynamicTypeId(ExecutionContext *exe_ctx, ValueObject &value_obj)
-    {
-        if (!m_dynamic_type_id.IsValid())
-            return UINT64_MAX;
-
-        Value obj_load_address = value_obj.GetValue();
-        obj_load_address.ResolveValue(exe_ctx);
-        obj_load_address.SetValueType(Value::eValueTypeLoadAddress);
-
-        Value result;
-        if (m_dynamic_type_id.Evaluate(exe_ctx->GetBestExecutionContextScope(), nullptr, nullptr, 0, &obj_load_address,
-                                       nullptr, result, nullptr))
-        {
-            Error error;
-
-            lldb::addr_t type_id_addr = result.GetScalar().UInt();
-            lldb::ProcessSP process_sp = exe_ctx->GetProcessSP();
-            if (process_sp)
-                return process_sp->ReadUnsignedIntegerFromMemory(type_id_addr, process_sp->GetAddressByteSize(),
-                                                                 UINT64_MAX, error);
-        }
-
-        return UINT64_MAX;
-    }
-
     static bool
     classof(const JavaType *jt)
     {
@@ -310,14 +323,12 @@ public:
 
 private:
     ConstString m_name;
-    ConstString m_linkage_name;
     uint32_t m_byte_size;
     CompilerType m_base_class;
     uint32_t m_base_class_offset;
     std::vector<CompilerType> m_interfaces;
     std::vector<Field> m_fields;
     bool m_is_complete;
-    DWARFExpression m_dynamic_type_id;
 };
 
 class JavaReferenceType : public JavaASTContext::JavaType
@@ -360,13 +371,15 @@ private:
     CompilerType m_pointee_type;
 };
 
-class JavaArrayType : public JavaASTContext::JavaType
+class JavaArrayType : public JavaDynamicType
 {
 public:
-    JavaArrayType(CompilerType element_type, const DWARFExpression &length_expression, const lldb::addr_t data_offset)
-        : JavaType(JavaType::eKindArray),
+    JavaArrayType(const ConstString& linkage_name, CompilerType element_type, const DWARFExpression &length_expression,
+                  lldb::addr_t data_offset)
+        : JavaDynamicType(JavaType::eKindArray, linkage_name),
           m_element_type(element_type),
-          m_length_expression(length_expression)
+          m_length_expression(length_expression),
+          m_data_offset(data_offset)
     {
     }
 
@@ -402,25 +415,37 @@ public:
     }
 
     uint32_t
-    GetNumElements(const ValueObject *value_obj)
+    GetNumElements(ValueObject *value_obj)
     {
         if (!m_length_expression.IsValid())
-            return false;
+            return UINT32_MAX;
+
+        Error error;
+        ValueObjectSP address_obj = value_obj->AddressOf(error);
+        if (error.Fail())
+            return UINT32_MAX;
 
-        Value obj_load_address = value_obj->GetValue();
+        Value obj_load_address = address_obj->GetValue();
         obj_load_address.SetValueType(Value::eValueTypeLoadAddress);
 
         Value result;
-        if (m_length_expression.Evaluate(nullptr, nullptr, nullptr, nullptr, 0, nullptr, &obj_load_address, result,
-                                         nullptr))
+        ExecutionContextScope* exec_ctx_scope = value_obj->GetExecutionContextRef().Lock(true).GetBestExecutionContextScope();
+        if (m_length_expression.Evaluate(exec_ctx_scope, nullptr, nullptr, 0, nullptr, &obj_load_address, result, nullptr))
             return result.GetScalar().UInt();
 
-        return 0;
+        return UINT32_MAX;
+    }
+
+    uint64_t
+    GetElementOffset(size_t idx)
+    {
+        return m_data_offset + idx * m_element_type.GetByteSize(nullptr);
     }
 
 private:
     CompilerType m_element_type;
     DWARFExpression m_length_expression;
+    lldb::addr_t m_data_offset;
 };
 
 } // end of anonymous namespace
@@ -998,6 +1023,10 @@ JavaASTContext::GetBitSize(lldb::opaque_
     {
         return 32; // References are always 4 byte long in java
     }
+    else if (llvm::isa<JavaArrayType>(static_cast<JavaType *>(type)))
+    {
+        return 64;
+    }
     else if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type)))
     {
         return obj->GetByteSize() * 8;
@@ -1450,14 +1479,15 @@ JavaASTContext::CreateObjectType(const C
 }
 
 CompilerType
-JavaASTContext::CreateArrayType(const CompilerType &element_type, const DWARFExpression &length_expression,
-                                const lldb::addr_t data_offset)
+JavaASTContext::CreateArrayType(const ConstString &linkage_name, const CompilerType &element_type,
+                                const DWARFExpression &length_expression, const lldb::addr_t data_offset)
 {
     ConstString name = element_type.GetTypeName();
     auto it = m_array_type_map.find(name);
     if (it == m_array_type_map.end())
     {
-        std::unique_ptr<JavaType> array_type(new JavaArrayType(element_type, length_expression, data_offset));
+        std::unique_ptr<JavaType> array_type(new JavaArrayType(linkage_name, element_type, length_expression,
+                                                               data_offset));
         it = m_array_type_map.emplace(name, std::move(array_type)).first;
     }
     return CompilerType(this, it->second.get());
@@ -1512,6 +1542,24 @@ JavaASTContext::CalculateDynamicTypeId(E
 {
     if (JavaObjectType *obj = llvm::dyn_cast<JavaObjectType>(static_cast<JavaType *>(type.GetOpaqueQualType())))
         return obj->CalculateDynamicTypeId(exe_ctx, in_value);
+    if (JavaArrayType *arr = llvm::dyn_cast<JavaArrayType>(static_cast<JavaType *>(type.GetOpaqueQualType())))
+        return arr->CalculateDynamicTypeId(exe_ctx, in_value);
+    return UINT64_MAX;
+}
+
+uint32_t
+JavaASTContext::CalculateArraySize(const CompilerType &type, ValueObject &in_value)
+{
+    if (JavaArrayType *arr = llvm::dyn_cast<JavaArrayType>(static_cast<JavaType *>(type.GetOpaqueQualType())))
+        return arr->GetNumElements(&in_value);
+    return UINT32_MAX;
+}
+
+uint64_t
+JavaASTContext::CalculateArrayElementOffset(const CompilerType &type, size_t index)
+{
+    if (JavaArrayType *arr = llvm::dyn_cast<JavaArrayType>(static_cast<JavaType *>(type.GetOpaqueQualType())))
+        return arr->GetElementOffset(index);
     return UINT64_MAX;
 }
 




More information about the lldb-commits mailing list