]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/API/SBTypeSummary.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / API / SBTypeSummary.cpp
1 //===-- SBTypeSummary.cpp -----------------------------------------*- C++
2 //-*-===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 #include "lldb/API/SBTypeSummary.h"
12 #include "lldb/API/SBStream.h"
13 #include "lldb/API/SBValue.h"
14 #include "lldb/DataFormatters/DataVisualization.h"
15
16 #include "llvm/Support/Casting.h"
17
18 using namespace lldb;
19 using namespace lldb_private;
20
21 SBTypeSummaryOptions::SBTypeSummaryOptions() {
22   m_opaque_ap.reset(new TypeSummaryOptions());
23 }
24
25 SBTypeSummaryOptions::SBTypeSummaryOptions(
26     const lldb::SBTypeSummaryOptions &rhs) {
27   if (rhs.m_opaque_ap)
28     m_opaque_ap.reset(new TypeSummaryOptions(*rhs.m_opaque_ap));
29   else
30     m_opaque_ap.reset(new TypeSummaryOptions());
31 }
32
33 SBTypeSummaryOptions::~SBTypeSummaryOptions() {}
34
35 bool SBTypeSummaryOptions::IsValid() { return m_opaque_ap.get(); }
36
37 lldb::LanguageType SBTypeSummaryOptions::GetLanguage() {
38   if (IsValid())
39     return m_opaque_ap->GetLanguage();
40   return lldb::eLanguageTypeUnknown;
41 }
42
43 lldb::TypeSummaryCapping SBTypeSummaryOptions::GetCapping() {
44   if (IsValid())
45     return m_opaque_ap->GetCapping();
46   return eTypeSummaryCapped;
47 }
48
49 void SBTypeSummaryOptions::SetLanguage(lldb::LanguageType l) {
50   if (IsValid())
51     m_opaque_ap->SetLanguage(l);
52 }
53
54 void SBTypeSummaryOptions::SetCapping(lldb::TypeSummaryCapping c) {
55   if (IsValid())
56     m_opaque_ap->SetCapping(c);
57 }
58
59 lldb_private::TypeSummaryOptions *SBTypeSummaryOptions::operator->() {
60   return m_opaque_ap.get();
61 }
62
63 const lldb_private::TypeSummaryOptions *SBTypeSummaryOptions::
64 operator->() const {
65   return m_opaque_ap.get();
66 }
67
68 lldb_private::TypeSummaryOptions *SBTypeSummaryOptions::get() {
69   return m_opaque_ap.get();
70 }
71
72 lldb_private::TypeSummaryOptions &SBTypeSummaryOptions::ref() {
73   return *m_opaque_ap;
74 }
75
76 const lldb_private::TypeSummaryOptions &SBTypeSummaryOptions::ref() const {
77   return *m_opaque_ap;
78 }
79
80 SBTypeSummaryOptions::SBTypeSummaryOptions(
81     const lldb_private::TypeSummaryOptions *lldb_object_ptr) {
82   SetOptions(lldb_object_ptr);
83 }
84
85 void SBTypeSummaryOptions::SetOptions(
86     const lldb_private::TypeSummaryOptions *lldb_object_ptr) {
87   if (lldb_object_ptr)
88     m_opaque_ap.reset(new TypeSummaryOptions(*lldb_object_ptr));
89   else
90     m_opaque_ap.reset(new TypeSummaryOptions());
91 }
92
93 SBTypeSummary::SBTypeSummary() : m_opaque_sp() {}
94
95 SBTypeSummary SBTypeSummary::CreateWithSummaryString(const char *data,
96                                                      uint32_t options) {
97   if (!data || data[0] == 0)
98     return SBTypeSummary();
99
100   return SBTypeSummary(
101       TypeSummaryImplSP(new StringSummaryFormat(options, data)));
102 }
103
104 SBTypeSummary SBTypeSummary::CreateWithFunctionName(const char *data,
105                                                     uint32_t options) {
106   if (!data || data[0] == 0)
107     return SBTypeSummary();
108
109   return SBTypeSummary(
110       TypeSummaryImplSP(new ScriptSummaryFormat(options, data)));
111 }
112
113 SBTypeSummary SBTypeSummary::CreateWithScriptCode(const char *data,
114                                                   uint32_t options) {
115   if (!data || data[0] == 0)
116     return SBTypeSummary();
117
118   return SBTypeSummary(
119       TypeSummaryImplSP(new ScriptSummaryFormat(options, "", data)));
120 }
121
122 SBTypeSummary SBTypeSummary::CreateWithCallback(FormatCallback cb,
123                                                 uint32_t options,
124                                                 const char *description) {
125   SBTypeSummary retval;
126   if (cb) {
127     retval.SetSP(TypeSummaryImplSP(new CXXFunctionSummaryFormat(
128         options,
129         [cb](ValueObject &valobj, Stream &stm,
130              const TypeSummaryOptions &opt) -> bool {
131           SBStream stream;
132           SBValue sb_value(valobj.GetSP());
133           SBTypeSummaryOptions options(&opt);
134           if (!cb(sb_value, options, stream))
135             return false;
136           stm.Write(stream.GetData(), stream.GetSize());
137           return true;
138         },
139         description ? description : "callback summary formatter")));
140   }
141
142   return retval;
143 }
144
145 SBTypeSummary::SBTypeSummary(const lldb::SBTypeSummary &rhs)
146     : m_opaque_sp(rhs.m_opaque_sp) {}
147
148 SBTypeSummary::~SBTypeSummary() {}
149
150 bool SBTypeSummary::IsValid() const { return m_opaque_sp.get() != NULL; }
151
152 bool SBTypeSummary::IsFunctionCode() {
153   if (!IsValid())
154     return false;
155   if (ScriptSummaryFormat *script_summary_ptr =
156           llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) {
157     const char *ftext = script_summary_ptr->GetPythonScript();
158     return (ftext && *ftext != 0);
159   }
160   return false;
161 }
162
163 bool SBTypeSummary::IsFunctionName() {
164   if (!IsValid())
165     return false;
166   if (ScriptSummaryFormat *script_summary_ptr =
167           llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) {
168     const char *ftext = script_summary_ptr->GetPythonScript();
169     return (!ftext || *ftext == 0);
170   }
171   return false;
172 }
173
174 bool SBTypeSummary::IsSummaryString() {
175   if (!IsValid())
176     return false;
177
178   return m_opaque_sp->GetKind() == TypeSummaryImpl::Kind::eSummaryString;
179 }
180
181 const char *SBTypeSummary::GetData() {
182   if (!IsValid())
183     return NULL;
184   if (ScriptSummaryFormat *script_summary_ptr =
185           llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) {
186     const char *fname = script_summary_ptr->GetFunctionName();
187     const char *ftext = script_summary_ptr->GetPythonScript();
188     if (ftext && *ftext)
189       return ftext;
190     return fname;
191   } else if (StringSummaryFormat *string_summary_ptr =
192                  llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get()))
193     return string_summary_ptr->GetSummaryString();
194   return nullptr;
195 }
196
197 uint32_t SBTypeSummary::GetOptions() {
198   if (!IsValid())
199     return lldb::eTypeOptionNone;
200   return m_opaque_sp->GetOptions();
201 }
202
203 void SBTypeSummary::SetOptions(uint32_t value) {
204   if (!CopyOnWrite_Impl())
205     return;
206   m_opaque_sp->SetOptions(value);
207 }
208
209 void SBTypeSummary::SetSummaryString(const char *data) {
210   if (!IsValid())
211     return;
212   if (!llvm::isa<StringSummaryFormat>(m_opaque_sp.get()))
213     ChangeSummaryType(false);
214   if (StringSummaryFormat *string_summary_ptr =
215           llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get()))
216     string_summary_ptr->SetSummaryString(data);
217 }
218
219 void SBTypeSummary::SetFunctionName(const char *data) {
220   if (!IsValid())
221     return;
222   if (!llvm::isa<ScriptSummaryFormat>(m_opaque_sp.get()))
223     ChangeSummaryType(true);
224   if (ScriptSummaryFormat *script_summary_ptr =
225           llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get()))
226     script_summary_ptr->SetFunctionName(data);
227 }
228
229 void SBTypeSummary::SetFunctionCode(const char *data) {
230   if (!IsValid())
231     return;
232   if (!llvm::isa<ScriptSummaryFormat>(m_opaque_sp.get()))
233     ChangeSummaryType(true);
234   if (ScriptSummaryFormat *script_summary_ptr =
235           llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get()))
236     script_summary_ptr->SetPythonScript(data);
237 }
238
239 bool SBTypeSummary::GetDescription(lldb::SBStream &description,
240                                    lldb::DescriptionLevel description_level) {
241   if (!CopyOnWrite_Impl())
242     return false;
243   else {
244     description.Printf("%s\n", m_opaque_sp->GetDescription().c_str());
245     return true;
246   }
247 }
248
249 bool SBTypeSummary::DoesPrintValue(lldb::SBValue value) {
250   if (!IsValid())
251     return false;
252   lldb::ValueObjectSP value_sp = value.GetSP();
253   return m_opaque_sp->DoesPrintValue(value_sp.get());
254 }
255
256 lldb::SBTypeSummary &SBTypeSummary::operator=(const lldb::SBTypeSummary &rhs) {
257   if (this != &rhs) {
258     m_opaque_sp = rhs.m_opaque_sp;
259   }
260   return *this;
261 }
262
263 bool SBTypeSummary::operator==(lldb::SBTypeSummary &rhs) {
264   if (!IsValid())
265     return !rhs.IsValid();
266   return m_opaque_sp == rhs.m_opaque_sp;
267 }
268
269 bool SBTypeSummary::IsEqualTo(lldb::SBTypeSummary &rhs) {
270   if (IsValid()) {
271     // valid and invalid are different
272     if (!rhs.IsValid())
273       return false;
274   } else {
275     // invalid and valid are different
276     if (rhs.IsValid())
277       return false;
278     else
279       // both invalid are the same
280       return true;
281   }
282
283   if (m_opaque_sp->GetKind() != rhs.m_opaque_sp->GetKind())
284     return false;
285
286   switch (m_opaque_sp->GetKind()) {
287   case TypeSummaryImpl::Kind::eCallback:
288     return llvm::dyn_cast<CXXFunctionSummaryFormat>(m_opaque_sp.get()) ==
289            llvm::dyn_cast<CXXFunctionSummaryFormat>(rhs.m_opaque_sp.get());
290   case TypeSummaryImpl::Kind::eScript:
291     if (IsFunctionCode() != rhs.IsFunctionCode())
292       return false;
293     if (IsFunctionName() != rhs.IsFunctionName())
294       return false;
295     return GetOptions() == rhs.GetOptions();
296   case TypeSummaryImpl::Kind::eSummaryString:
297     if (IsSummaryString() != rhs.IsSummaryString())
298       return false;
299     return GetOptions() == rhs.GetOptions();
300   case TypeSummaryImpl::Kind::eInternal:
301     return (m_opaque_sp.get() == rhs.m_opaque_sp.get());
302   }
303
304   return false;
305 }
306
307 bool SBTypeSummary::operator!=(lldb::SBTypeSummary &rhs) {
308   if (!IsValid())
309     return !rhs.IsValid();
310   return m_opaque_sp != rhs.m_opaque_sp;
311 }
312
313 lldb::TypeSummaryImplSP SBTypeSummary::GetSP() { return m_opaque_sp; }
314
315 void SBTypeSummary::SetSP(const lldb::TypeSummaryImplSP &typesummary_impl_sp) {
316   m_opaque_sp = typesummary_impl_sp;
317 }
318
319 SBTypeSummary::SBTypeSummary(const lldb::TypeSummaryImplSP &typesummary_impl_sp)
320     : m_opaque_sp(typesummary_impl_sp) {}
321
322 bool SBTypeSummary::CopyOnWrite_Impl() {
323   if (!IsValid())
324     return false;
325
326   if (m_opaque_sp.unique())
327     return true;
328
329   TypeSummaryImplSP new_sp;
330
331   if (CXXFunctionSummaryFormat *current_summary_ptr =
332           llvm::dyn_cast<CXXFunctionSummaryFormat>(m_opaque_sp.get())) {
333     new_sp = TypeSummaryImplSP(new CXXFunctionSummaryFormat(
334         GetOptions(), current_summary_ptr->m_impl,
335         current_summary_ptr->m_description.c_str()));
336   } else if (ScriptSummaryFormat *current_summary_ptr =
337                  llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) {
338     new_sp = TypeSummaryImplSP(new ScriptSummaryFormat(
339         GetOptions(), current_summary_ptr->GetFunctionName(),
340         current_summary_ptr->GetPythonScript()));
341   } else if (StringSummaryFormat *current_summary_ptr =
342                  llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get())) {
343     new_sp = TypeSummaryImplSP(new StringSummaryFormat(
344         GetOptions(), current_summary_ptr->GetSummaryString()));
345   }
346
347   SetSP(new_sp);
348
349   return nullptr != new_sp.get();
350 }
351
352 bool SBTypeSummary::ChangeSummaryType(bool want_script) {
353   if (!IsValid())
354     return false;
355
356   TypeSummaryImplSP new_sp;
357
358   if (want_script ==
359       (m_opaque_sp->GetKind() == TypeSummaryImpl::Kind::eScript)) {
360     if (m_opaque_sp->GetKind() ==
361             lldb_private::TypeSummaryImpl::Kind::eCallback &&
362         !want_script)
363       new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), ""));
364     else
365       return CopyOnWrite_Impl();
366   }
367
368   if (!new_sp) {
369     if (want_script)
370       new_sp = TypeSummaryImplSP(new ScriptSummaryFormat(GetOptions(), "", ""));
371     else
372       new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), ""));
373   }
374
375   SetSP(new_sp);
376
377   return true;
378 }