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
18using namespace lldb;
19using namespace lldb_private;
20
21#ifndef LLDB_DISABLE_PYTHON
22
23SBTypeSummary::SBTypeSummary() :
24m_opaque_sp()
25{
26}
27
28SBTypeSummary
29SBTypeSummary::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
37SBTypeSummary
38SBTypeSummary::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
46SBTypeSummary
47SBTypeSummary::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
55SBTypeSummary::SBTypeSummary (const lldb::SBTypeSummary &rhs) :
56m_opaque_sp(rhs.m_opaque_sp)
57{
58}
59
60SBTypeSummary::~SBTypeSummary ()
61{
62}
63
64bool
65SBTypeSummary::IsValid() const
66{
67    return m_opaque_sp.get() != NULL;
68}
69
70bool
71SBTypeSummary::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
84bool
85SBTypeSummary::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
98bool
99SBTypeSummary::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
110const char*
111SBTypeSummary::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
133uint32_t
134SBTypeSummary::GetOptions ()
135{
136    if (!IsValid())
137        return lldb::eTypeOptionNone;
138    return m_opaque_sp->GetOptions();
139}
140
141void
142SBTypeSummary::SetOptions (uint32_t value)
143{
144    if (!CopyOnWrite_Impl())
145        return;
146    m_opaque_sp->SetOptions(value);
147}
148
149void
150SBTypeSummary::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
159void
160SBTypeSummary::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
169void
170SBTypeSummary::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
179bool
180SBTypeSummary::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
192lldb::SBTypeSummary &
193SBTypeSummary::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
202bool
203SBTypeSummary::operator == (lldb::SBTypeSummary &rhs)
204{
205    if (IsValid() == false)
206        return !rhs.IsValid();
207    return m_opaque_sp == rhs.m_opaque_sp;
208}
209
210bool
211SBTypeSummary::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
245bool
246SBTypeSummary::operator != (lldb::SBTypeSummary &rhs)
247{
248    if (IsValid() == false)
249        return !rhs.IsValid();
250    return m_opaque_sp != rhs.m_opaque_sp;
251}
252
253lldb::TypeSummaryImplSP
254SBTypeSummary::GetSP ()
255{
256    return m_opaque_sp;
257}
258
259void
260SBTypeSummary::SetSP (const lldb::TypeSummaryImplSP &typesummary_impl_sp)
261{
262    m_opaque_sp = typesummary_impl_sp;
263}
264
265SBTypeSummary::SBTypeSummary (const lldb::TypeSummaryImplSP &typesummary_impl_sp) :
266m_opaque_sp(typesummary_impl_sp)
267{
268}
269
270bool
271SBTypeSummary::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
306bool
307SBTypeSummary::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