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
SBTypeSummaryOptions()21 SBTypeSummaryOptions::SBTypeSummaryOptions() {
22 m_opaque_ap.reset(new TypeSummaryOptions());
23 }
24
SBTypeSummaryOptions(const lldb::SBTypeSummaryOptions & rhs)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
~SBTypeSummaryOptions()33 SBTypeSummaryOptions::~SBTypeSummaryOptions() {}
34
IsValid()35 bool SBTypeSummaryOptions::IsValid() { return m_opaque_ap.get(); }
36
GetLanguage()37 lldb::LanguageType SBTypeSummaryOptions::GetLanguage() {
38 if (IsValid())
39 return m_opaque_ap->GetLanguage();
40 return lldb::eLanguageTypeUnknown;
41 }
42
GetCapping()43 lldb::TypeSummaryCapping SBTypeSummaryOptions::GetCapping() {
44 if (IsValid())
45 return m_opaque_ap->GetCapping();
46 return eTypeSummaryCapped;
47 }
48
SetLanguage(lldb::LanguageType l)49 void SBTypeSummaryOptions::SetLanguage(lldb::LanguageType l) {
50 if (IsValid())
51 m_opaque_ap->SetLanguage(l);
52 }
53
SetCapping(lldb::TypeSummaryCapping c)54 void SBTypeSummaryOptions::SetCapping(lldb::TypeSummaryCapping c) {
55 if (IsValid())
56 m_opaque_ap->SetCapping(c);
57 }
58
operator ->()59 lldb_private::TypeSummaryOptions *SBTypeSummaryOptions::operator->() {
60 return m_opaque_ap.get();
61 }
62
63 const lldb_private::TypeSummaryOptions *SBTypeSummaryOptions::
operator ->() const64 operator->() const {
65 return m_opaque_ap.get();
66 }
67
get()68 lldb_private::TypeSummaryOptions *SBTypeSummaryOptions::get() {
69 return m_opaque_ap.get();
70 }
71
ref()72 lldb_private::TypeSummaryOptions &SBTypeSummaryOptions::ref() {
73 return *m_opaque_ap;
74 }
75
ref() const76 const lldb_private::TypeSummaryOptions &SBTypeSummaryOptions::ref() const {
77 return *m_opaque_ap;
78 }
79
SBTypeSummaryOptions(const lldb_private::TypeSummaryOptions * lldb_object_ptr)80 SBTypeSummaryOptions::SBTypeSummaryOptions(
81 const lldb_private::TypeSummaryOptions *lldb_object_ptr) {
82 SetOptions(lldb_object_ptr);
83 }
84
SetOptions(const lldb_private::TypeSummaryOptions * lldb_object_ptr)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
SBTypeSummary()93 SBTypeSummary::SBTypeSummary() : m_opaque_sp() {}
94
CreateWithSummaryString(const char * data,uint32_t options)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
CreateWithFunctionName(const char * data,uint32_t options)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
CreateWithScriptCode(const char * data,uint32_t options)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
CreateWithCallback(FormatCallback cb,uint32_t options,const char * description)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
SBTypeSummary(const lldb::SBTypeSummary & rhs)145 SBTypeSummary::SBTypeSummary(const lldb::SBTypeSummary &rhs)
146 : m_opaque_sp(rhs.m_opaque_sp) {}
147
~SBTypeSummary()148 SBTypeSummary::~SBTypeSummary() {}
149
IsValid() const150 bool SBTypeSummary::IsValid() const { return m_opaque_sp.get() != NULL; }
151
IsFunctionCode()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
IsFunctionName()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
IsSummaryString()174 bool SBTypeSummary::IsSummaryString() {
175 if (!IsValid())
176 return false;
177
178 return m_opaque_sp->GetKind() == TypeSummaryImpl::Kind::eSummaryString;
179 }
180
GetData()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
GetOptions()197 uint32_t SBTypeSummary::GetOptions() {
198 if (!IsValid())
199 return lldb::eTypeOptionNone;
200 return m_opaque_sp->GetOptions();
201 }
202
SetOptions(uint32_t value)203 void SBTypeSummary::SetOptions(uint32_t value) {
204 if (!CopyOnWrite_Impl())
205 return;
206 m_opaque_sp->SetOptions(value);
207 }
208
SetSummaryString(const char * data)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
SetFunctionName(const char * data)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
SetFunctionCode(const char * data)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
GetDescription(lldb::SBStream & description,lldb::DescriptionLevel description_level)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
DoesPrintValue(lldb::SBValue value)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
operator =(const lldb::SBTypeSummary & rhs)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
operator ==(lldb::SBTypeSummary & rhs)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
IsEqualTo(lldb::SBTypeSummary & rhs)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
operator !=(lldb::SBTypeSummary & rhs)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
GetSP()313 lldb::TypeSummaryImplSP SBTypeSummary::GetSP() { return m_opaque_sp; }
314
SetSP(const lldb::TypeSummaryImplSP & typesummary_impl_sp)315 void SBTypeSummary::SetSP(const lldb::TypeSummaryImplSP &typesummary_impl_sp) {
316 m_opaque_sp = typesummary_impl_sp;
317 }
318
SBTypeSummary(const lldb::TypeSummaryImplSP & typesummary_impl_sp)319 SBTypeSummary::SBTypeSummary(const lldb::TypeSummaryImplSP &typesummary_impl_sp)
320 : m_opaque_sp(typesummary_impl_sp) {}
321
CopyOnWrite_Impl()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
ChangeSummaryType(bool want_script)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 }
379