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