1 //===-- SBTypeSummary.cpp -----------------------------------------*- C++
4 // The LLVM Compiler Infrastructure
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 #include "lldb/API/SBTypeSummary.h"
12 #include "lldb/API/SBStream.h"
13 #include "lldb/API/SBValue.h"
14 #include "lldb/DataFormatters/DataVisualization.h"
16 #include "llvm/Support/Casting.h"
19 using namespace lldb_private;
21 SBTypeSummaryOptions::SBTypeSummaryOptions() {
22 m_opaque_ap.reset(new TypeSummaryOptions());
25 SBTypeSummaryOptions::SBTypeSummaryOptions(
26 const lldb::SBTypeSummaryOptions &rhs) {
28 m_opaque_ap.reset(new TypeSummaryOptions(*rhs.m_opaque_ap));
30 m_opaque_ap.reset(new TypeSummaryOptions());
33 SBTypeSummaryOptions::~SBTypeSummaryOptions() {}
35 bool SBTypeSummaryOptions::IsValid() { return m_opaque_ap.get(); }
37 lldb::LanguageType SBTypeSummaryOptions::GetLanguage() {
39 return m_opaque_ap->GetLanguage();
40 return lldb::eLanguageTypeUnknown;
43 lldb::TypeSummaryCapping SBTypeSummaryOptions::GetCapping() {
45 return m_opaque_ap->GetCapping();
46 return eTypeSummaryCapped;
49 void SBTypeSummaryOptions::SetLanguage(lldb::LanguageType l) {
51 m_opaque_ap->SetLanguage(l);
54 void SBTypeSummaryOptions::SetCapping(lldb::TypeSummaryCapping c) {
56 m_opaque_ap->SetCapping(c);
59 lldb_private::TypeSummaryOptions *SBTypeSummaryOptions::operator->() {
60 return m_opaque_ap.get();
63 const lldb_private::TypeSummaryOptions *SBTypeSummaryOptions::
65 return m_opaque_ap.get();
68 lldb_private::TypeSummaryOptions *SBTypeSummaryOptions::get() {
69 return m_opaque_ap.get();
72 lldb_private::TypeSummaryOptions &SBTypeSummaryOptions::ref() {
76 const lldb_private::TypeSummaryOptions &SBTypeSummaryOptions::ref() const {
80 SBTypeSummaryOptions::SBTypeSummaryOptions(
81 const lldb_private::TypeSummaryOptions *lldb_object_ptr) {
82 SetOptions(lldb_object_ptr);
85 void SBTypeSummaryOptions::SetOptions(
86 const lldb_private::TypeSummaryOptions *lldb_object_ptr) {
88 m_opaque_ap.reset(new TypeSummaryOptions(*lldb_object_ptr));
90 m_opaque_ap.reset(new TypeSummaryOptions());
93 SBTypeSummary::SBTypeSummary() : m_opaque_sp() {}
95 SBTypeSummary SBTypeSummary::CreateWithSummaryString(const char *data,
97 if (!data || data[0] == 0)
98 return SBTypeSummary();
100 return SBTypeSummary(
101 TypeSummaryImplSP(new StringSummaryFormat(options, data)));
104 SBTypeSummary SBTypeSummary::CreateWithFunctionName(const char *data,
106 if (!data || data[0] == 0)
107 return SBTypeSummary();
109 return SBTypeSummary(
110 TypeSummaryImplSP(new ScriptSummaryFormat(options, data)));
113 SBTypeSummary SBTypeSummary::CreateWithScriptCode(const char *data,
115 if (!data || data[0] == 0)
116 return SBTypeSummary();
118 return SBTypeSummary(
119 TypeSummaryImplSP(new ScriptSummaryFormat(options, "", data)));
122 SBTypeSummary SBTypeSummary::CreateWithCallback(FormatCallback cb,
124 const char *description) {
125 SBTypeSummary retval;
127 retval.SetSP(TypeSummaryImplSP(new CXXFunctionSummaryFormat(
129 [cb](ValueObject &valobj, Stream &stm,
130 const TypeSummaryOptions &opt) -> bool {
132 SBValue sb_value(valobj.GetSP());
133 SBTypeSummaryOptions options(&opt);
134 if (!cb(sb_value, options, stream))
136 stm.Write(stream.GetData(), stream.GetSize());
139 description ? description : "callback summary formatter")));
145 SBTypeSummary::SBTypeSummary(const lldb::SBTypeSummary &rhs)
146 : m_opaque_sp(rhs.m_opaque_sp) {}
148 SBTypeSummary::~SBTypeSummary() {}
150 bool SBTypeSummary::IsValid() const { return m_opaque_sp.get() != NULL; }
152 bool SBTypeSummary::IsFunctionCode() {
155 if (ScriptSummaryFormat *script_summary_ptr =
156 llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) {
157 const char *ftext = script_summary_ptr->GetPythonScript();
158 return (ftext && *ftext != 0);
163 bool SBTypeSummary::IsFunctionName() {
166 if (ScriptSummaryFormat *script_summary_ptr =
167 llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) {
168 const char *ftext = script_summary_ptr->GetPythonScript();
169 return (!ftext || *ftext == 0);
174 bool SBTypeSummary::IsSummaryString() {
178 return m_opaque_sp->GetKind() == TypeSummaryImpl::Kind::eSummaryString;
181 const char *SBTypeSummary::GetData() {
184 if (ScriptSummaryFormat *script_summary_ptr =
185 llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) {
186 const char *fname = script_summary_ptr->GetFunctionName();
187 const char *ftext = script_summary_ptr->GetPythonScript();
191 } else if (StringSummaryFormat *string_summary_ptr =
192 llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get()))
193 return string_summary_ptr->GetSummaryString();
197 uint32_t SBTypeSummary::GetOptions() {
199 return lldb::eTypeOptionNone;
200 return m_opaque_sp->GetOptions();
203 void SBTypeSummary::SetOptions(uint32_t value) {
204 if (!CopyOnWrite_Impl())
206 m_opaque_sp->SetOptions(value);
209 void SBTypeSummary::SetSummaryString(const char *data) {
212 if (!llvm::isa<StringSummaryFormat>(m_opaque_sp.get()))
213 ChangeSummaryType(false);
214 if (StringSummaryFormat *string_summary_ptr =
215 llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get()))
216 string_summary_ptr->SetSummaryString(data);
219 void SBTypeSummary::SetFunctionName(const char *data) {
222 if (!llvm::isa<ScriptSummaryFormat>(m_opaque_sp.get()))
223 ChangeSummaryType(true);
224 if (ScriptSummaryFormat *script_summary_ptr =
225 llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get()))
226 script_summary_ptr->SetFunctionName(data);
229 void SBTypeSummary::SetFunctionCode(const char *data) {
232 if (!llvm::isa<ScriptSummaryFormat>(m_opaque_sp.get()))
233 ChangeSummaryType(true);
234 if (ScriptSummaryFormat *script_summary_ptr =
235 llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get()))
236 script_summary_ptr->SetPythonScript(data);
239 bool SBTypeSummary::GetDescription(lldb::SBStream &description,
240 lldb::DescriptionLevel description_level) {
241 if (!CopyOnWrite_Impl())
244 description.Printf("%s\n", m_opaque_sp->GetDescription().c_str());
249 bool SBTypeSummary::DoesPrintValue(lldb::SBValue value) {
252 lldb::ValueObjectSP value_sp = value.GetSP();
253 return m_opaque_sp->DoesPrintValue(value_sp.get());
256 lldb::SBTypeSummary &SBTypeSummary::operator=(const lldb::SBTypeSummary &rhs) {
258 m_opaque_sp = rhs.m_opaque_sp;
263 bool SBTypeSummary::operator==(lldb::SBTypeSummary &rhs) {
265 return !rhs.IsValid();
266 return m_opaque_sp == rhs.m_opaque_sp;
269 bool SBTypeSummary::IsEqualTo(lldb::SBTypeSummary &rhs) {
271 // valid and invalid are different
275 // invalid and valid are different
279 // both invalid are the same
283 if (m_opaque_sp->GetKind() != rhs.m_opaque_sp->GetKind())
286 switch (m_opaque_sp->GetKind()) {
287 case TypeSummaryImpl::Kind::eCallback:
288 return llvm::dyn_cast<CXXFunctionSummaryFormat>(m_opaque_sp.get()) ==
289 llvm::dyn_cast<CXXFunctionSummaryFormat>(rhs.m_opaque_sp.get());
290 case TypeSummaryImpl::Kind::eScript:
291 if (IsFunctionCode() != rhs.IsFunctionCode())
293 if (IsFunctionName() != rhs.IsFunctionName())
295 return GetOptions() == rhs.GetOptions();
296 case TypeSummaryImpl::Kind::eSummaryString:
297 if (IsSummaryString() != rhs.IsSummaryString())
299 return GetOptions() == rhs.GetOptions();
300 case TypeSummaryImpl::Kind::eInternal:
301 return (m_opaque_sp.get() == rhs.m_opaque_sp.get());
307 bool SBTypeSummary::operator!=(lldb::SBTypeSummary &rhs) {
309 return !rhs.IsValid();
310 return m_opaque_sp != rhs.m_opaque_sp;
313 lldb::TypeSummaryImplSP SBTypeSummary::GetSP() { return m_opaque_sp; }
315 void SBTypeSummary::SetSP(const lldb::TypeSummaryImplSP &typesummary_impl_sp) {
316 m_opaque_sp = typesummary_impl_sp;
319 SBTypeSummary::SBTypeSummary(const lldb::TypeSummaryImplSP &typesummary_impl_sp)
320 : m_opaque_sp(typesummary_impl_sp) {}
322 bool SBTypeSummary::CopyOnWrite_Impl() {
326 if (m_opaque_sp.unique())
329 TypeSummaryImplSP new_sp;
331 if (CXXFunctionSummaryFormat *current_summary_ptr =
332 llvm::dyn_cast<CXXFunctionSummaryFormat>(m_opaque_sp.get())) {
333 new_sp = TypeSummaryImplSP(new CXXFunctionSummaryFormat(
334 GetOptions(), current_summary_ptr->m_impl,
335 current_summary_ptr->m_description.c_str()));
336 } else if (ScriptSummaryFormat *current_summary_ptr =
337 llvm::dyn_cast<ScriptSummaryFormat>(m_opaque_sp.get())) {
338 new_sp = TypeSummaryImplSP(new ScriptSummaryFormat(
339 GetOptions(), current_summary_ptr->GetFunctionName(),
340 current_summary_ptr->GetPythonScript()));
341 } else if (StringSummaryFormat *current_summary_ptr =
342 llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get())) {
343 new_sp = TypeSummaryImplSP(new StringSummaryFormat(
344 GetOptions(), current_summary_ptr->GetSummaryString()));
349 return nullptr != new_sp.get();
352 bool SBTypeSummary::ChangeSummaryType(bool want_script) {
356 TypeSummaryImplSP new_sp;
359 (m_opaque_sp->GetKind() == TypeSummaryImpl::Kind::eScript)) {
360 if (m_opaque_sp->GetKind() ==
361 lldb_private::TypeSummaryImpl::Kind::eCallback &&
363 new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), ""));
365 return CopyOnWrite_Impl();
370 new_sp = TypeSummaryImplSP(new ScriptSummaryFormat(GetOptions(), "", ""));
372 new_sp = TypeSummaryImplSP(new StringSummaryFormat(GetOptions(), ""));