1 //===-- SBTypeSummary.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 #include "lldb/lldb-python.h"
11 
12 #include "lldb/API/SBTypeSummary.h"
13 
14 #include "lldb/API/SBStream.h"
15 
16 #include "lldb/DataFormatters/DataVisualization.h"
17 
18 using namespace lldb;
19 using namespace lldb_private;
20 
21 #ifndef LLDB_DISABLE_PYTHON
22 
23 SBTypeSummaryOptions::SBTypeSummaryOptions()
24 {
25     m_opaque_ap.reset(new TypeSummaryOptions());
26 }
27 
28 SBTypeSummaryOptions::SBTypeSummaryOptions (const lldb::SBTypeSummaryOptions &rhs)
29 {
30     if (rhs.m_opaque_ap)
31         m_opaque_ap.reset(new TypeSummaryOptions(*rhs.m_opaque_ap.get()));
32     else
33         m_opaque_ap.reset(new TypeSummaryOptions());
34 }
35 
36 SBTypeSummaryOptions::~SBTypeSummaryOptions ()
37 {
38 }
39 
40 bool
41 SBTypeSummaryOptions::IsValid()
42 {
43     return m_opaque_ap.get();
44 }
45 
46 lldb::LanguageType
47 SBTypeSummaryOptions::GetLanguage ()
48 {
49     if (IsValid())
50         return m_opaque_ap->GetLanguage();
51     return lldb::eLanguageTypeUnknown;
52 }
53 
54 lldb::TypeSummaryCapping
55 SBTypeSummaryOptions::GetCapping ()
56 {
57     if (IsValid())
58         return m_opaque_ap->GetCapping();
59     return eTypeSummaryCapped;
60 }
61 
62 void
63 SBTypeSummaryOptions::SetLanguage (lldb::LanguageType l)
64 {
65     if (IsValid())
66         m_opaque_ap->SetLanguage(l);
67 }
68 
69 void
70 SBTypeSummaryOptions::SetCapping (lldb::TypeSummaryCapping c)
71 {
72     if (IsValid())
73         m_opaque_ap->SetCapping(c);
74 }
75 
76 lldb_private::TypeSummaryOptions *
77 SBTypeSummaryOptions::operator->()
78 {
79     return m_opaque_ap.get();
80 }
81 
82 const lldb_private::TypeSummaryOptions *
83 SBTypeSummaryOptions::operator->() const
84 {
85     return m_opaque_ap.get();
86 }
87 
88 lldb_private::TypeSummaryOptions *
89 SBTypeSummaryOptions::get ()
90 {
91     return m_opaque_ap.get();
92 }
93 
94 lldb_private::TypeSummaryOptions &
95 SBTypeSummaryOptions::ref()
96 {
97     return *m_opaque_ap.get();
98 }
99 
100 const lldb_private::TypeSummaryOptions &
101 SBTypeSummaryOptions::ref() const
102 {
103     return *m_opaque_ap.get();
104 }
105 
106 SBTypeSummaryOptions::SBTypeSummaryOptions (const lldb_private::TypeSummaryOptions *lldb_object_ptr)
107 {
108     SetOptions(lldb_object_ptr);
109 }
110 
111 void
112 SBTypeSummaryOptions::SetOptions (const lldb_private::TypeSummaryOptions *lldb_object_ptr)
113 {
114     if (lldb_object_ptr)
115         m_opaque_ap.reset(new TypeSummaryOptions(*lldb_object_ptr));
116     else
117         m_opaque_ap.reset(new TypeSummaryOptions());
118 }
119 
120 SBTypeSummary::SBTypeSummary() :
121 m_opaque_sp()
122 {
123 }
124 
125 SBTypeSummary
126 SBTypeSummary::CreateWithSummaryString (const char* data, uint32_t options)
127 {
128     if (!data || data[0] == 0)
129         return SBTypeSummary();
130 
131     return SBTypeSummary(TypeSummaryImplSP(new StringSummaryFormat(options, data)));
132 }
133 
134 SBTypeSummary
135 SBTypeSummary::CreateWithFunctionName (const char* data, uint32_t options)
136 {
137     if (!data || data[0] == 0)
138         return SBTypeSummary();
139 
140     return SBTypeSummary(TypeSummaryImplSP(new ScriptSummaryFormat(options, data)));
141 }
142 
143 SBTypeSummary
144 SBTypeSummary::CreateWithScriptCode (const char* data, uint32_t options)
145 {
146     if (!data || data[0] == 0)
147         return SBTypeSummary();
148 
149     return SBTypeSummary(TypeSummaryImplSP(new ScriptSummaryFormat(options, "", data)));
150 }
151 
152 SBTypeSummary::SBTypeSummary (const lldb::SBTypeSummary &rhs) :
153 m_opaque_sp(rhs.m_opaque_sp)
154 {
155 }
156 
157 SBTypeSummary::~SBTypeSummary ()
158 {
159 }
160 
161 bool
162 SBTypeSummary::IsValid() const
163 {
164     return m_opaque_sp.get() != NULL;
165 }
166 
167 bool
168 SBTypeSummary::IsFunctionCode()
169 {
170     if (!IsValid())
171         return false;
172     if (m_opaque_sp->IsScripted())
173     {
174         ScriptSummaryFormat* script_summary_ptr = (ScriptSummaryFormat*)m_opaque_sp.get();
175         const char* ftext = script_summary_ptr->GetPythonScript();
176         return (ftext && *ftext != 0);
177     }
178     return false;
179 }
180 
181 bool
182 SBTypeSummary::IsFunctionName()
183 {
184     if (!IsValid())
185         return false;
186     if (m_opaque_sp->IsScripted())
187     {
188         ScriptSummaryFormat* script_summary_ptr = (ScriptSummaryFormat*)m_opaque_sp.get();
189         const char* ftext = script_summary_ptr->GetPythonScript();
190         return (!ftext || *ftext == 0);
191     }
192     return false;
193 }
194 
195 bool
196 SBTypeSummary::IsSummaryString()
197 {
198     if (!IsValid())
199         return false;
200 
201     if (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback)
202         return false;
203 
204     return !m_opaque_sp->IsScripted();
205 }
206 
207 const char*
208 SBTypeSummary::GetData ()
209 {
210     if (!IsValid())
211         return NULL;
212     if (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback)
213         return NULL;
214     if (m_opaque_sp->IsScripted())
215     {
216         ScriptSummaryFormat* script_summary_ptr = (ScriptSummaryFormat*)m_opaque_sp.get();
217         const char* fname = script_summary_ptr->GetFunctionName();
218         const char* ftext = script_summary_ptr->GetPythonScript();
219         if (ftext && *ftext)
220             return ftext;
221         return fname;
222     }
223     else
224     {
225         StringSummaryFormat* string_summary_ptr = (StringSummaryFormat*)m_opaque_sp.get();
226         return string_summary_ptr->GetSummaryString();
227     }
228 }
229 
230 uint32_t
231 SBTypeSummary::GetOptions ()
232 {
233     if (!IsValid())
234         return lldb::eTypeOptionNone;
235     return m_opaque_sp->GetOptions();
236 }
237 
238 void
239 SBTypeSummary::SetOptions (uint32_t value)
240 {
241     if (!CopyOnWrite_Impl())
242         return;
243     m_opaque_sp->SetOptions(value);
244 }
245 
246 void
247 SBTypeSummary::SetSummaryString (const char* data)
248 {
249     if (!IsValid())
250         return;
251     if (m_opaque_sp->IsScripted() || (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback))
252         ChangeSummaryType(false);
253     ((StringSummaryFormat*)m_opaque_sp.get())->SetSummaryString(data);
254 }
255 
256 void
257 SBTypeSummary::SetFunctionName (const char* data)
258 {
259     if (!IsValid())
260         return;
261     if (!m_opaque_sp->IsScripted())
262         ChangeSummaryType(true);
263     ((ScriptSummaryFormat*)m_opaque_sp.get())->SetFunctionName(data);
264 }
265 
266 void
267 SBTypeSummary::SetFunctionCode (const char* data)
268 {
269     if (!IsValid())
270         return;
271     if (!m_opaque_sp->IsScripted())
272         ChangeSummaryType(true);
273     ((ScriptSummaryFormat*)m_opaque_sp.get())->SetPythonScript(data);
274 }
275 
276 bool
277 SBTypeSummary::GetDescription (lldb::SBStream &description,
278                               lldb::DescriptionLevel description_level)
279 {
280     if (!CopyOnWrite_Impl())
281         return false;
282     else {
283         description.Printf("%s\n",
284                            m_opaque_sp->GetDescription().c_str());
285         return true;
286     }
287 }
288 
289 lldb::SBTypeSummary &
290 SBTypeSummary::operator = (const lldb::SBTypeSummary &rhs)
291 {
292     if (this != &rhs)
293     {
294         m_opaque_sp = rhs.m_opaque_sp;
295     }
296     return *this;
297 }
298 
299 bool
300 SBTypeSummary::operator == (lldb::SBTypeSummary &rhs)
301 {
302     if (IsValid() == false)
303         return !rhs.IsValid();
304     return m_opaque_sp == rhs.m_opaque_sp;
305 }
306 
307 bool
308 SBTypeSummary::IsEqualTo (lldb::SBTypeSummary &rhs)
309 {
310     if (IsValid() == false)
311         return !rhs.IsValid();
312 
313     if (m_opaque_sp->GetType() != rhs.m_opaque_sp->GetType())
314         return false;
315 
316     if (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback)
317     {
318         lldb_private::CXXFunctionSummaryFormat *self_cxx = (lldb_private::CXXFunctionSummaryFormat*)m_opaque_sp.get();
319         lldb_private::CXXFunctionSummaryFormat *other_cxx = (lldb_private::CXXFunctionSummaryFormat*)rhs.m_opaque_sp.get();
320         return (self_cxx->m_impl == other_cxx->m_impl);
321     }
322 
323     if (m_opaque_sp->IsScripted() != rhs.m_opaque_sp->IsScripted())
324         return false;
325 
326     if (IsFunctionCode() != rhs.IsFunctionCode())
327         return false;
328 
329     if (IsSummaryString() != rhs.IsSummaryString())
330         return false;
331 
332     if (IsFunctionName() != rhs.IsFunctionName())
333         return false;
334 
335     if ( GetData() == NULL || rhs.GetData() == NULL || strcmp(GetData(), rhs.GetData()) )
336         return false;
337 
338     return GetOptions() == rhs.GetOptions();
339 
340 }
341 
342 bool
343 SBTypeSummary::operator != (lldb::SBTypeSummary &rhs)
344 {
345     if (IsValid() == false)
346         return !rhs.IsValid();
347     return m_opaque_sp != rhs.m_opaque_sp;
348 }
349 
350 lldb::TypeSummaryImplSP
351 SBTypeSummary::GetSP ()
352 {
353     return m_opaque_sp;
354 }
355 
356 void
357 SBTypeSummary::SetSP (const lldb::TypeSummaryImplSP &typesummary_impl_sp)
358 {
359     m_opaque_sp = typesummary_impl_sp;
360 }
361 
362 SBTypeSummary::SBTypeSummary (const lldb::TypeSummaryImplSP &typesummary_impl_sp) :
363 m_opaque_sp(typesummary_impl_sp)
364 {
365 }
366 
367 bool
368 SBTypeSummary::CopyOnWrite_Impl()
369 {
370     if (!IsValid())
371         return false;
372 
373     if (m_opaque_sp.unique())
374         return true;
375 
376     TypeSummaryImplSP new_sp;
377 
378     if (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback)
379     {
380         CXXFunctionSummaryFormat* current_summary_ptr = (CXXFunctionSummaryFormat*)m_opaque_sp.get();
381         new_sp = TypeSummaryImplSP(new CXXFunctionSummaryFormat(GetOptions(),
382                                                                 current_summary_ptr->m_impl,
383                                                                 current_summary_ptr->m_description.c_str()));
384     }
385     else if (m_opaque_sp->IsScripted())
386     {
387         ScriptSummaryFormat* current_summary_ptr = (ScriptSummaryFormat*)m_opaque_sp.get();
388         new_sp = TypeSummaryImplSP(new ScriptSummaryFormat(GetOptions(),
389                                                            current_summary_ptr->GetFunctionName(),
390                                                            current_summary_ptr->GetPythonScript()));
391     }
392     else {
393         StringSummaryFormat* current_summary_ptr = (StringSummaryFormat*)m_opaque_sp.get();
394         new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(),
395                                                            current_summary_ptr->GetSummaryString()));
396     }
397 
398     SetSP(new_sp);
399 
400     return true;
401 }
402 
403 bool
404 SBTypeSummary::ChangeSummaryType (bool want_script)
405 {
406     if (!IsValid())
407         return false;
408 
409     TypeSummaryImplSP new_sp;
410 
411     if (want_script == m_opaque_sp->IsScripted())
412     {
413         if (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback && !want_script)
414             new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), ""));
415         else
416             return CopyOnWrite_Impl();
417     }
418 
419     if (!new_sp)
420     {
421         if (want_script)
422             new_sp = TypeSummaryImplSP(new ScriptSummaryFormat(GetOptions(), "", ""));
423         else
424             new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), ""));
425     }
426 
427     SetSP(new_sp);
428 
429     return true;
430 }
431 
432 #endif // LLDB_DISABLE_PYTHON
433