blob: 0f78f643321bbfe56c173e47f29c41381690e766 [file] [log] [blame]
Ryan Brown2dd84882015-11-05 00:24:36 +00001//===-- GoFormatterFunctions.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#include <map>
Ryan Brown2dd84882015-11-05 00:24:36 +000013
14// Other libraries and framework includes
15// Project includes
16#include "GoFormatterFunctions.h"
17#include "lldb/DataFormatters/FormattersHelpers.h"
18#include "lldb/DataFormatters/StringPrinter.h"
19
20using namespace lldb;
21using namespace lldb_private;
22using namespace lldb_private::formatters;
23
Kate Stoneb9c1b512016-09-06 20:57:50 +000024namespace {
25class GoSliceSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
26public:
27 GoSliceSyntheticFrontEnd(ValueObject &valobj)
28 : SyntheticChildrenFrontEnd(valobj) {
29 Update();
30 }
31
32 ~GoSliceSyntheticFrontEnd() override = default;
33
34 size_t CalculateNumChildren() override { return m_len; }
35
36 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
37 if (idx < m_len) {
38 ValueObjectSP &cached = m_children[idx];
39 if (!cached) {
40 StreamString idx_name;
41 idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx);
42 lldb::addr_t object_at_idx = m_base_data_address;
43 object_at_idx += idx * m_type.GetByteSize(nullptr);
44 cached = CreateValueObjectFromAddress(
Zachary Turnerc1564272016-11-16 21:15:24 +000045 idx_name.GetString(), object_at_idx,
Kate Stoneb9c1b512016-09-06 20:57:50 +000046 m_backend.GetExecutionContextRef(), m_type);
47 }
48 return cached;
49 }
50 return ValueObjectSP();
51 }
52
53 bool Update() override {
54 size_t old_count = m_len;
55
56 ConstString array_const_str("array");
57 ValueObjectSP array_sp =
58 m_backend.GetChildMemberWithName(array_const_str, true);
59 if (!array_sp) {
60 m_children.clear();
61 return old_count == 0;
62 }
63 m_type = array_sp->GetCompilerType().GetPointeeType();
64 m_base_data_address = array_sp->GetPointerValue();
65
66 ConstString len_const_str("len");
67 ValueObjectSP len_sp =
68 m_backend.GetChildMemberWithName(len_const_str, true);
69 if (len_sp) {
70 m_len = len_sp->GetValueAsUnsigned(0);
71 m_children.clear();
Ryan Brown2dd84882015-11-05 00:24:36 +000072 }
73
Kate Stoneb9c1b512016-09-06 20:57:50 +000074 return old_count == m_len;
75 }
Ryan Brown2dd84882015-11-05 00:24:36 +000076
Kate Stoneb9c1b512016-09-06 20:57:50 +000077 bool MightHaveChildren() override { return true; }
Ryan Brown2dd84882015-11-05 00:24:36 +000078
Kate Stoneb9c1b512016-09-06 20:57:50 +000079 size_t GetIndexOfChildWithName(const ConstString &name) override {
80 return ExtractIndexFromString(name.AsCString());
81 }
Ryan Brown2dd84882015-11-05 00:24:36 +000082
Kate Stoneb9c1b512016-09-06 20:57:50 +000083private:
84 CompilerType m_type;
85 lldb::addr_t m_base_data_address;
86 size_t m_len;
87 std::map<size_t, lldb::ValueObjectSP> m_children;
Ryan Brown2dd84882015-11-05 00:24:36 +000088};
89
90} // anonymous namespace
91
Kate Stoneb9c1b512016-09-06 20:57:50 +000092bool lldb_private::formatters::GoStringSummaryProvider(
93 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &opts) {
94 ProcessSP process_sp = valobj.GetProcessSP();
95 if (!process_sp)
96 return false;
Ryan Brown2dd84882015-11-05 00:24:36 +000097
Kate Stoneb9c1b512016-09-06 20:57:50 +000098 if (valobj.IsPointerType()) {
99 Error err;
100 ValueObjectSP deref = valobj.Dereference(err);
101 if (!err.Success())
102 return false;
103 return GoStringSummaryProvider(*deref, stream, opts);
104 }
Ryan Brown2dd84882015-11-05 00:24:36 +0000105
Kate Stoneb9c1b512016-09-06 20:57:50 +0000106 ConstString str_name("str");
107 ConstString len_name("len");
Ryan Brown2dd84882015-11-05 00:24:36 +0000108
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109 ValueObjectSP data_sp = valobj.GetChildMemberWithName(str_name, true);
110 ValueObjectSP len_sp = valobj.GetChildMemberWithName(len_name, true);
111 if (!data_sp || !len_sp)
112 return false;
113 bool success;
114 lldb::addr_t valobj_addr = data_sp->GetValueAsUnsigned(0, &success);
Ryan Brown2dd84882015-11-05 00:24:36 +0000115
Kate Stoneb9c1b512016-09-06 20:57:50 +0000116 if (!success)
117 return false;
Ryan Brown2dd84882015-11-05 00:24:36 +0000118
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119 uint64_t length = len_sp->GetValueAsUnsigned(0);
120 if (length == 0) {
121 stream.Printf("\"\"");
Ryan Brown2dd84882015-11-05 00:24:36 +0000122 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000123 }
124
125 StringPrinter::ReadStringAndDumpToStreamOptions options(valobj);
126 options.SetLocation(valobj_addr);
127 options.SetProcessSP(process_sp);
128 options.SetStream(&stream);
129 options.SetSourceSize(length);
130 options.SetNeedsZeroTermination(false);
131 options.SetLanguage(eLanguageTypeGo);
132
133 if (!StringPrinter::ReadStringAndDumpToStream<
134 StringPrinter::StringElementType::UTF8>(options)) {
135 stream.Printf("Summary Unavailable");
136 return true;
137 }
138
139 return true;
Ryan Brown2dd84882015-11-05 00:24:36 +0000140}
141
142SyntheticChildrenFrontEnd *
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143lldb_private::formatters::GoSliceSyntheticFrontEndCreator(
144 CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
145 if (!valobj_sp)
146 return nullptr;
Ryan Brown2dd84882015-11-05 00:24:36 +0000147
Kate Stoneb9c1b512016-09-06 20:57:50 +0000148 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
149 if (!process_sp)
150 return nullptr;
151 return new GoSliceSyntheticFrontEnd(*valobj_sp);
Ryan Brown2dd84882015-11-05 00:24:36 +0000152}