]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Language/Java/JavaFormatterFunctions.cpp
MFC r345703:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Language / Java / JavaFormatterFunctions.cpp
1 //===-- JavaFormatterFunctions.cpp-------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 // C Includes
11 // C++ Includes
12 // Other libraries and framework includes
13 // Project includes
14 #include "JavaFormatterFunctions.h"
15 #include "lldb/DataFormatters/FormattersHelpers.h"
16 #include "lldb/DataFormatters/StringPrinter.h"
17 #include "lldb/Symbol/JavaASTContext.h"
18
19 using namespace lldb;
20 using namespace lldb_private;
21 using namespace lldb_private::formatters;
22
23 namespace {
24
25 class JavaArraySyntheticFrontEnd : public SyntheticChildrenFrontEnd {
26 public:
27   JavaArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
28       : SyntheticChildrenFrontEnd(*valobj_sp) {
29     if (valobj_sp)
30       Update();
31   }
32
33   size_t CalculateNumChildren() override {
34     ValueObjectSP valobj = GetDereferencedValueObject();
35     if (!valobj)
36       return 0;
37
38     CompilerType type = valobj->GetCompilerType();
39     uint32_t size = JavaASTContext::CalculateArraySize(type, *valobj);
40     if (size == UINT32_MAX)
41       return 0;
42     return size;
43   }
44
45   lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
46     ValueObjectSP valobj = GetDereferencedValueObject();
47     if (!valobj)
48       return nullptr;
49
50     ProcessSP process_sp = valobj->GetProcessSP();
51     if (!process_sp)
52       return nullptr;
53
54     CompilerType type = valobj->GetCompilerType();
55     CompilerType element_type = type.GetArrayElementType();
56     lldb::addr_t address =
57         valobj->GetAddressOf() +
58         JavaASTContext::CalculateArrayElementOffset(type, idx);
59
60     Status error;
61     size_t byte_size = element_type.GetByteSize(nullptr);
62     DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0));
63     size_t bytes_read = process_sp->ReadMemory(address, buffer_sp->GetBytes(),
64                                                byte_size, error);
65     if (error.Fail() || byte_size != bytes_read)
66       return nullptr;
67
68     StreamString name;
69     name.Printf("[%" PRIu64 "]", (uint64_t)idx);
70     DataExtractor data(buffer_sp, process_sp->GetByteOrder(),
71                        process_sp->GetAddressByteSize());
72     return CreateValueObjectFromData(
73         name.GetString(), data, valobj->GetExecutionContextRef(), element_type);
74   }
75
76   bool Update() override { return false; }
77
78   bool MightHaveChildren() override { return true; }
79
80   size_t GetIndexOfChildWithName(const ConstString &name) override {
81     return ExtractIndexFromString(name.GetCString());
82   }
83
84 private:
85   ValueObjectSP GetDereferencedValueObject() {
86     if (!m_backend.IsPointerOrReferenceType())
87       return m_backend.GetSP();
88
89     Status error;
90     return m_backend.Dereference(error);
91   }
92 };
93
94 } // end of anonymous namespace
95
96 bool lldb_private::formatters::JavaStringSummaryProvider(
97     ValueObject &valobj, Stream &stream, const TypeSummaryOptions &opts) {
98   if (valobj.IsPointerOrReferenceType()) {
99     Status error;
100     ValueObjectSP deref = valobj.Dereference(error);
101     if (error.Fail())
102       return false;
103     return JavaStringSummaryProvider(*deref, stream, opts);
104   }
105
106   ProcessSP process_sp = valobj.GetProcessSP();
107   if (!process_sp)
108     return false;
109
110   ConstString data_name("value");
111   ConstString length_name("count");
112
113   ValueObjectSP length_sp = valobj.GetChildMemberWithName(length_name, true);
114   ValueObjectSP data_sp = valobj.GetChildMemberWithName(data_name, true);
115   if (!data_sp || !length_sp)
116     return false;
117
118   bool success = false;
119   uint64_t length = length_sp->GetValueAsUnsigned(0, &success);
120   if (!success)
121     return false;
122
123   if (length == 0) {
124     stream.Printf("\"\"");
125     return true;
126   }
127   lldb::addr_t valobj_addr = data_sp->GetAddressOf();
128
129   StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
130   options.SetLocation(valobj_addr);
131   options.SetProcessSP(process_sp);
132   options.SetStream(&stream);
133   options.SetSourceSize(length);
134   options.SetNeedsZeroTermination(false);
135   options.SetLanguage(eLanguageTypeJava);
136
137   if (StringPrinter::ReadStringAndDumpToStream<
138           StringPrinter::StringElementType::UTF16>(options))
139     return true;
140
141   stream.Printf("Summary Unavailable");
142   return true;
143 }
144
145 bool lldb_private::formatters::JavaArraySummaryProvider(
146     ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) {
147   if (valobj.IsPointerOrReferenceType()) {
148     Status error;
149     ValueObjectSP deref = valobj.Dereference(error);
150     if (error.Fail())
151       return false;
152     return JavaArraySummaryProvider(*deref, stream, options);
153   }
154
155   CompilerType type = valobj.GetCompilerType();
156   uint32_t size = JavaASTContext::CalculateArraySize(type, valobj);
157   if (size == UINT32_MAX)
158     return false;
159   stream.Printf("[%u]{...}", size);
160   return true;
161 }
162
163 SyntheticChildrenFrontEnd *
164 lldb_private::formatters::JavaArraySyntheticFrontEndCreator(
165     CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
166   return valobj_sp ? new JavaArraySyntheticFrontEnd(valobj_sp) : nullptr;
167 }