1 //===-- GoFormatterFunctions.cpp---------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
14 // Other libraries and framework includes
16 #include "GoFormatterFunctions.h"
17 #include "lldb/DataFormatters/FormattersHelpers.h"
18 #include "lldb/DataFormatters/StringPrinter.h"
21 using namespace lldb_private;
22 using namespace lldb_private::formatters;
25 class GoSliceSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
27 GoSliceSyntheticFrontEnd(ValueObject &valobj)
28 : SyntheticChildrenFrontEnd(valobj) {
32 ~GoSliceSyntheticFrontEnd() override = default;
34 size_t CalculateNumChildren() override { return m_len; }
36 lldb::ValueObjectSP GetChildAtIndex(size_t idx) override {
38 ValueObjectSP &cached = m_children[idx];
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(
45 idx_name.GetString(), object_at_idx,
46 m_backend.GetExecutionContextRef(), m_type);
50 return ValueObjectSP();
53 bool Update() override {
54 size_t old_count = m_len;
56 ConstString array_const_str("array");
57 ValueObjectSP array_sp =
58 m_backend.GetChildMemberWithName(array_const_str, true);
61 return old_count == 0;
63 m_type = array_sp->GetCompilerType().GetPointeeType();
64 m_base_data_address = array_sp->GetPointerValue();
66 ConstString len_const_str("len");
67 ValueObjectSP len_sp =
68 m_backend.GetChildMemberWithName(len_const_str, true);
70 m_len = len_sp->GetValueAsUnsigned(0);
74 return old_count == m_len;
77 bool MightHaveChildren() override { return true; }
79 size_t GetIndexOfChildWithName(const ConstString &name) override {
80 return ExtractIndexFromString(name.AsCString());
85 lldb::addr_t m_base_data_address;
87 std::map<size_t, lldb::ValueObjectSP> m_children;
90 } // anonymous namespace
92 bool lldb_private::formatters::GoStringSummaryProvider(
93 ValueObject &valobj, Stream &stream, const TypeSummaryOptions &opts) {
94 ProcessSP process_sp = valobj.GetProcessSP();
98 if (valobj.IsPointerType()) {
100 ValueObjectSP deref = valobj.Dereference(err);
103 return GoStringSummaryProvider(*deref, stream, opts);
106 ConstString str_name("str");
107 ConstString len_name("len");
109 ValueObjectSP data_sp = valobj.GetChildMemberWithName(str_name, true);
110 ValueObjectSP len_sp = valobj.GetChildMemberWithName(len_name, true);
111 if (!data_sp || !len_sp)
114 lldb::addr_t valobj_addr = data_sp->GetValueAsUnsigned(0, &success);
119 uint64_t length = len_sp->GetValueAsUnsigned(0);
121 stream.Printf("\"\"");
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);
133 if (!StringPrinter::ReadStringAndDumpToStream<
134 StringPrinter::StringElementType::UTF8>(options)) {
135 stream.Printf("Summary Unavailable");
142 SyntheticChildrenFrontEnd *
143 lldb_private::formatters::GoSliceSyntheticFrontEndCreator(
144 CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
148 lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
151 return new GoSliceSyntheticFrontEnd(*valobj_sp);