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 
SBTypeSummary()23 SBTypeSummary::SBTypeSummary() :
24 m_opaque_sp()
25 {
26 }
27 
28 SBTypeSummary
CreateWithSummaryString(const char * data,uint32_t options)29 SBTypeSummary::CreateWithSummaryString (const char* data, uint32_t options)
30 {
31     if (!data || data[0] == 0)
32         return SBTypeSummary();
33 
34     return SBTypeSummary(TypeSummaryImplSP(new StringSummaryFormat(options, data)));
35 }
36 
37 SBTypeSummary
CreateWithFunctionName(const char * data,uint32_t options)38 SBTypeSummary::CreateWithFunctionName (const char* data, uint32_t options)
39 {
40     if (!data || data[0] == 0)
41         return SBTypeSummary();
42 
43     return SBTypeSummary(TypeSummaryImplSP(new ScriptSummaryFormat(options, data)));
44 }
45 
46 SBTypeSummary
CreateWithScriptCode(const char * data,uint32_t options)47 SBTypeSummary::CreateWithScriptCode (const char* data, uint32_t options)
48 {
49     if (!data || data[0] == 0)
50         return SBTypeSummary();
51 
52     return SBTypeSummary(TypeSummaryImplSP(new ScriptSummaryFormat(options, "", data)));
53 }
54 
SBTypeSummary(const lldb::SBTypeSummary & rhs)55 SBTypeSummary::SBTypeSummary (const lldb::SBTypeSummary &rhs) :
56 m_opaque_sp(rhs.m_opaque_sp)
57 {
58 }
59 
~SBTypeSummary()60 SBTypeSummary::~SBTypeSummary ()
61 {
62 }
63 
64 bool
IsValid() const65 SBTypeSummary::IsValid() const
66 {
67     return m_opaque_sp.get() != NULL;
68 }
69 
70 bool
IsFunctionCode()71 SBTypeSummary::IsFunctionCode()
72 {
73     if (!IsValid())
74         return false;
75     if (m_opaque_sp->IsScripted())
76     {
77         ScriptSummaryFormat* script_summary_ptr = (ScriptSummaryFormat*)m_opaque_sp.get();
78         const char* ftext = script_summary_ptr->GetPythonScript();
79         return (ftext && *ftext != 0);
80     }
81     return false;
82 }
83 
84 bool
IsFunctionName()85 SBTypeSummary::IsFunctionName()
86 {
87     if (!IsValid())
88         return false;
89     if (m_opaque_sp->IsScripted())
90     {
91         ScriptSummaryFormat* script_summary_ptr = (ScriptSummaryFormat*)m_opaque_sp.get();
92         const char* ftext = script_summary_ptr->GetPythonScript();
93         return (!ftext || *ftext == 0);
94     }
95     return false;
96 }
97 
98 bool
IsSummaryString()99 SBTypeSummary::IsSummaryString()
100 {
101     if (!IsValid())
102         return false;
103 
104     if (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback)
105         return false;
106 
107     return !m_opaque_sp->IsScripted();
108 }
109 
110 const char*
GetData()111 SBTypeSummary::GetData ()
112 {
113     if (!IsValid())
114         return NULL;
115     if (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback)
116         return NULL;
117     if (m_opaque_sp->IsScripted())
118     {
119         ScriptSummaryFormat* script_summary_ptr = (ScriptSummaryFormat*)m_opaque_sp.get();
120         const char* fname = script_summary_ptr->GetFunctionName();
121         const char* ftext = script_summary_ptr->GetPythonScript();
122         if (ftext && *ftext)
123             return ftext;
124         return fname;
125     }
126     else
127     {
128         StringSummaryFormat* string_summary_ptr = (StringSummaryFormat*)m_opaque_sp.get();
129         return string_summary_ptr->GetSummaryString();
130     }
131 }
132 
133 uint32_t
GetOptions()134 SBTypeSummary::GetOptions ()
135 {
136     if (!IsValid())
137         return lldb::eTypeOptionNone;
138     return m_opaque_sp->GetOptions();
139 }
140 
141 void
SetOptions(uint32_t value)142 SBTypeSummary::SetOptions (uint32_t value)
143 {
144     if (!CopyOnWrite_Impl())
145         return;
146     m_opaque_sp->SetOptions(value);
147 }
148 
149 void
SetSummaryString(const char * data)150 SBTypeSummary::SetSummaryString (const char* data)
151 {
152     if (!IsValid())
153         return;
154     if (m_opaque_sp->IsScripted() || (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback))
155         ChangeSummaryType(false);
156     ((StringSummaryFormat*)m_opaque_sp.get())->SetSummaryString(data);
157 }
158 
159 void
SetFunctionName(const char * data)160 SBTypeSummary::SetFunctionName (const char* data)
161 {
162     if (!IsValid())
163         return;
164     if (!m_opaque_sp->IsScripted())
165         ChangeSummaryType(true);
166     ((ScriptSummaryFormat*)m_opaque_sp.get())->SetFunctionName(data);
167 }
168 
169 void
SetFunctionCode(const char * data)170 SBTypeSummary::SetFunctionCode (const char* data)
171 {
172     if (!IsValid())
173         return;
174     if (!m_opaque_sp->IsScripted())
175         ChangeSummaryType(true);
176     ((ScriptSummaryFormat*)m_opaque_sp.get())->SetPythonScript(data);
177 }
178 
179 bool
GetDescription(lldb::SBStream & description,lldb::DescriptionLevel description_level)180 SBTypeSummary::GetDescription (lldb::SBStream &description,
181                               lldb::DescriptionLevel description_level)
182 {
183     if (!CopyOnWrite_Impl())
184         return false;
185     else {
186         description.Printf("%s\n",
187                            m_opaque_sp->GetDescription().c_str());
188         return true;
189     }
190 }
191 
192 lldb::SBTypeSummary &
operator =(const lldb::SBTypeSummary & rhs)193 SBTypeSummary::operator = (const lldb::SBTypeSummary &rhs)
194 {
195     if (this != &rhs)
196     {
197         m_opaque_sp = rhs.m_opaque_sp;
198     }
199     return *this;
200 }
201 
202 bool
operator ==(lldb::SBTypeSummary & rhs)203 SBTypeSummary::operator == (lldb::SBTypeSummary &rhs)
204 {
205     if (IsValid() == false)
206         return !rhs.IsValid();
207     return m_opaque_sp == rhs.m_opaque_sp;
208 }
209 
210 bool
IsEqualTo(lldb::SBTypeSummary & rhs)211 SBTypeSummary::IsEqualTo (lldb::SBTypeSummary &rhs)
212 {
213     if (IsValid() == false)
214         return !rhs.IsValid();
215 
216     if (m_opaque_sp->GetType() != rhs.m_opaque_sp->GetType())
217         return false;
218 
219     if (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback)
220     {
221         lldb_private::CXXFunctionSummaryFormat *self_cxx = (lldb_private::CXXFunctionSummaryFormat*)m_opaque_sp.get();
222         lldb_private::CXXFunctionSummaryFormat *other_cxx = (lldb_private::CXXFunctionSummaryFormat*)rhs.m_opaque_sp.get();
223         return (self_cxx->m_impl == other_cxx->m_impl);
224     }
225 
226     if (m_opaque_sp->IsScripted() != rhs.m_opaque_sp->IsScripted())
227         return false;
228 
229     if (IsFunctionCode() != rhs.IsFunctionCode())
230         return false;
231 
232     if (IsSummaryString() != rhs.IsSummaryString())
233         return false;
234 
235     if (IsFunctionName() != rhs.IsFunctionName())
236         return false;
237 
238     if ( GetData() == NULL || rhs.GetData() == NULL || strcmp(GetData(), rhs.GetData()) )
239         return false;
240 
241     return GetOptions() == rhs.GetOptions();
242 
243 }
244 
245 bool
operator !=(lldb::SBTypeSummary & rhs)246 SBTypeSummary::operator != (lldb::SBTypeSummary &rhs)
247 {
248     if (IsValid() == false)
249         return !rhs.IsValid();
250     return m_opaque_sp != rhs.m_opaque_sp;
251 }
252 
253 lldb::TypeSummaryImplSP
GetSP()254 SBTypeSummary::GetSP ()
255 {
256     return m_opaque_sp;
257 }
258 
259 void
SetSP(const lldb::TypeSummaryImplSP & typesummary_impl_sp)260 SBTypeSummary::SetSP (const lldb::TypeSummaryImplSP &typesummary_impl_sp)
261 {
262     m_opaque_sp = typesummary_impl_sp;
263 }
264 
SBTypeSummary(const lldb::TypeSummaryImplSP & typesummary_impl_sp)265 SBTypeSummary::SBTypeSummary (const lldb::TypeSummaryImplSP &typesummary_impl_sp) :
266 m_opaque_sp(typesummary_impl_sp)
267 {
268 }
269 
270 bool
CopyOnWrite_Impl()271 SBTypeSummary::CopyOnWrite_Impl()
272 {
273     if (!IsValid())
274         return false;
275 
276     if (m_opaque_sp.unique())
277         return true;
278 
279     TypeSummaryImplSP new_sp;
280 
281     if (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback)
282     {
283         CXXFunctionSummaryFormat* current_summary_ptr = (CXXFunctionSummaryFormat*)m_opaque_sp.get();
284         new_sp = TypeSummaryImplSP(new CXXFunctionSummaryFormat(GetOptions(),
285                                                                 current_summary_ptr->m_impl,
286                                                                 current_summary_ptr->m_description.c_str()));
287     }
288     else if (m_opaque_sp->IsScripted())
289     {
290         ScriptSummaryFormat* current_summary_ptr = (ScriptSummaryFormat*)m_opaque_sp.get();
291         new_sp = TypeSummaryImplSP(new ScriptSummaryFormat(GetOptions(),
292                                                            current_summary_ptr->GetFunctionName(),
293                                                            current_summary_ptr->GetPythonScript()));
294     }
295     else {
296         StringSummaryFormat* current_summary_ptr = (StringSummaryFormat*)m_opaque_sp.get();
297         new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(),
298                                                            current_summary_ptr->GetSummaryString()));
299     }
300 
301     SetSP(new_sp);
302 
303     return true;
304 }
305 
306 bool
ChangeSummaryType(bool want_script)307 SBTypeSummary::ChangeSummaryType (bool want_script)
308 {
309     if (!IsValid())
310         return false;
311 
312     TypeSummaryImplSP new_sp;
313 
314     if (want_script == m_opaque_sp->IsScripted())
315     {
316         if (m_opaque_sp->GetType() == lldb_private::TypeSummaryImpl::eTypeCallback && !want_script)
317             new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), ""));
318         else
319             return CopyOnWrite_Impl();
320     }
321 
322     if (!new_sp)
323     {
324         if (want_script)
325             new_sp = TypeSummaryImplSP(new ScriptSummaryFormat(GetOptions(), "", ""));
326         else
327             new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), ""));
328     }
329 
330     SetSP(new_sp);
331 
332     return true;
333 }
334 
335 #endif // LLDB_DISABLE_PYTHON
336