]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Plugins/Language/Go/GoFormatterFunctions.cpp
Vendor import of lldb trunk r290819:
[FreeBSD/FreeBSD.git] / source / Plugins / Language / Go / GoFormatterFunctions.cpp
1 //===-- 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>
13
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
20 using namespace lldb;
21 using namespace lldb_private;
22 using namespace lldb_private::formatters;
23
24 namespace {
25 class GoSliceSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
26 public:
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(
45             idx_name.GetString(), object_at_idx,
46             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();
72     }
73
74     return old_count == m_len;
75   }
76
77   bool MightHaveChildren() override { return true; }
78
79   size_t GetIndexOfChildWithName(const ConstString &name) override {
80     return ExtractIndexFromString(name.AsCString());
81   }
82
83 private:
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;
88 };
89
90 } // anonymous namespace
91
92 bool 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;
97
98   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   }
105
106   ConstString str_name("str");
107   ConstString len_name("len");
108
109   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);
115
116   if (!success)
117     return false;
118
119   uint64_t length = len_sp->GetValueAsUnsigned(0);
120   if (length == 0) {
121     stream.Printf("\"\"");
122     return true;
123   }
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;
140 }
141
142 SyntheticChildrenFrontEnd *
143 lldb_private::formatters::GoSliceSyntheticFrontEndCreator(
144     CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
145   if (!valobj_sp)
146     return nullptr;
147
148   lldb::ProcessSP process_sp(valobj_sp->GetProcessSP());
149   if (!process_sp)
150     return nullptr;
151   return new GoSliceSyntheticFrontEnd(*valobj_sp);
152 }