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