1 //===-- SBTypeCategory.cpp ------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "lldb/API/SBTypeCategory.h"
10 #include "lldb/Utility/Instrumentation.h"
11
12 #include "lldb/API/SBStream.h"
13 #include "lldb/API/SBTypeFilter.h"
14 #include "lldb/API/SBTypeFormat.h"
15 #include "lldb/API/SBTypeNameSpecifier.h"
16 #include "lldb/API/SBTypeSummary.h"
17 #include "lldb/API/SBTypeSynthetic.h"
18
19 #include "lldb/Core/Debugger.h"
20 #include "lldb/DataFormatters/DataVisualization.h"
21 #include "lldb/Interpreter/CommandInterpreter.h"
22 #include "lldb/Interpreter/ScriptInterpreter.h"
23
24 using namespace lldb;
25 using namespace lldb_private;
26
27 typedef std::pair<lldb::TypeCategoryImplSP, user_id_t> ImplType;
28
SBTypeCategory()29 SBTypeCategory::SBTypeCategory() { LLDB_INSTRUMENT_VA(this); }
30
SBTypeCategory(const char * name)31 SBTypeCategory::SBTypeCategory(const char *name) {
32 DataVisualization::Categories::GetCategory(ConstString(name), m_opaque_sp);
33 }
34
SBTypeCategory(const lldb::SBTypeCategory & rhs)35 SBTypeCategory::SBTypeCategory(const lldb::SBTypeCategory &rhs)
36 : m_opaque_sp(rhs.m_opaque_sp) {
37 LLDB_INSTRUMENT_VA(this, rhs);
38 }
39
40 SBTypeCategory::~SBTypeCategory() = default;
41
IsValid() const42 bool SBTypeCategory::IsValid() const {
43 LLDB_INSTRUMENT_VA(this);
44 return this->operator bool();
45 }
operator bool() const46 SBTypeCategory::operator bool() const {
47 LLDB_INSTRUMENT_VA(this);
48
49 return (m_opaque_sp.get() != nullptr);
50 }
51
GetEnabled()52 bool SBTypeCategory::GetEnabled() {
53 LLDB_INSTRUMENT_VA(this);
54
55 if (!IsValid())
56 return false;
57 return m_opaque_sp->IsEnabled();
58 }
59
SetEnabled(bool enabled)60 void SBTypeCategory::SetEnabled(bool enabled) {
61 LLDB_INSTRUMENT_VA(this, enabled);
62
63 if (!IsValid())
64 return;
65 if (enabled)
66 DataVisualization::Categories::Enable(m_opaque_sp);
67 else
68 DataVisualization::Categories::Disable(m_opaque_sp);
69 }
70
GetName()71 const char *SBTypeCategory::GetName() {
72 LLDB_INSTRUMENT_VA(this);
73
74 if (!IsValid())
75 return nullptr;
76 return ConstString(m_opaque_sp->GetName()).GetCString();
77 }
78
GetLanguageAtIndex(uint32_t idx)79 lldb::LanguageType SBTypeCategory::GetLanguageAtIndex(uint32_t idx) {
80 LLDB_INSTRUMENT_VA(this, idx);
81
82 if (IsValid())
83 return m_opaque_sp->GetLanguageAtIndex(idx);
84 return lldb::eLanguageTypeUnknown;
85 }
86
GetNumLanguages()87 uint32_t SBTypeCategory::GetNumLanguages() {
88 LLDB_INSTRUMENT_VA(this);
89
90 if (IsValid())
91 return m_opaque_sp->GetNumLanguages();
92 return 0;
93 }
94
AddLanguage(lldb::LanguageType language)95 void SBTypeCategory::AddLanguage(lldb::LanguageType language) {
96 LLDB_INSTRUMENT_VA(this, language);
97
98 if (IsValid())
99 m_opaque_sp->AddLanguage(language);
100 }
101
GetNumFormats()102 uint32_t SBTypeCategory::GetNumFormats() {
103 LLDB_INSTRUMENT_VA(this);
104
105 if (!IsValid())
106 return 0;
107
108 return m_opaque_sp->GetNumFormats();
109 }
110
GetNumSummaries()111 uint32_t SBTypeCategory::GetNumSummaries() {
112 LLDB_INSTRUMENT_VA(this);
113
114 if (!IsValid())
115 return 0;
116 return m_opaque_sp->GetNumSummaries();
117 }
118
GetNumFilters()119 uint32_t SBTypeCategory::GetNumFilters() {
120 LLDB_INSTRUMENT_VA(this);
121
122 if (!IsValid())
123 return 0;
124 return m_opaque_sp->GetNumFilters();
125 }
126
GetNumSynthetics()127 uint32_t SBTypeCategory::GetNumSynthetics() {
128 LLDB_INSTRUMENT_VA(this);
129
130 if (!IsValid())
131 return 0;
132 return m_opaque_sp->GetNumSynthetics();
133 }
134
135 lldb::SBTypeNameSpecifier
GetTypeNameSpecifierForFilterAtIndex(uint32_t index)136 SBTypeCategory::GetTypeNameSpecifierForFilterAtIndex(uint32_t index) {
137 LLDB_INSTRUMENT_VA(this, index);
138
139 if (!IsValid())
140 return SBTypeNameSpecifier();
141 return SBTypeNameSpecifier(
142 m_opaque_sp->GetTypeNameSpecifierForFilterAtIndex(index));
143 }
144
145 lldb::SBTypeNameSpecifier
GetTypeNameSpecifierForFormatAtIndex(uint32_t index)146 SBTypeCategory::GetTypeNameSpecifierForFormatAtIndex(uint32_t index) {
147 LLDB_INSTRUMENT_VA(this, index);
148
149 if (!IsValid())
150 return SBTypeNameSpecifier();
151 return SBTypeNameSpecifier(
152 m_opaque_sp->GetTypeNameSpecifierForFormatAtIndex(index));
153 }
154
155 lldb::SBTypeNameSpecifier
GetTypeNameSpecifierForSummaryAtIndex(uint32_t index)156 SBTypeCategory::GetTypeNameSpecifierForSummaryAtIndex(uint32_t index) {
157 LLDB_INSTRUMENT_VA(this, index);
158
159 if (!IsValid())
160 return SBTypeNameSpecifier();
161 return SBTypeNameSpecifier(
162 m_opaque_sp->GetTypeNameSpecifierForSummaryAtIndex(index));
163 }
164
165 lldb::SBTypeNameSpecifier
GetTypeNameSpecifierForSyntheticAtIndex(uint32_t index)166 SBTypeCategory::GetTypeNameSpecifierForSyntheticAtIndex(uint32_t index) {
167 LLDB_INSTRUMENT_VA(this, index);
168
169 if (!IsValid())
170 return SBTypeNameSpecifier();
171 return SBTypeNameSpecifier(
172 m_opaque_sp->GetTypeNameSpecifierForSyntheticAtIndex(index));
173 }
174
GetFilterForType(SBTypeNameSpecifier spec)175 SBTypeFilter SBTypeCategory::GetFilterForType(SBTypeNameSpecifier spec) {
176 LLDB_INSTRUMENT_VA(this, spec);
177
178 if (!IsValid())
179 return SBTypeFilter();
180
181 if (!spec.IsValid())
182 return SBTypeFilter();
183
184 lldb::TypeFilterImplSP children_sp =
185 m_opaque_sp->GetFilterForType(spec.GetSP());
186
187 if (!children_sp)
188 return lldb::SBTypeFilter();
189
190 TypeFilterImplSP filter_sp =
191 std::static_pointer_cast<TypeFilterImpl>(children_sp);
192
193 return lldb::SBTypeFilter(filter_sp);
194 }
GetFormatForType(SBTypeNameSpecifier spec)195 SBTypeFormat SBTypeCategory::GetFormatForType(SBTypeNameSpecifier spec) {
196 LLDB_INSTRUMENT_VA(this, spec);
197
198 if (!IsValid())
199 return SBTypeFormat();
200
201 if (!spec.IsValid())
202 return SBTypeFormat();
203
204 lldb::TypeFormatImplSP format_sp =
205 m_opaque_sp->GetFormatForType(spec.GetSP());
206
207 if (!format_sp)
208 return lldb::SBTypeFormat();
209
210 return lldb::SBTypeFormat(format_sp);
211 }
212
GetSummaryForType(SBTypeNameSpecifier spec)213 SBTypeSummary SBTypeCategory::GetSummaryForType(SBTypeNameSpecifier spec) {
214 LLDB_INSTRUMENT_VA(this, spec);
215
216 if (!IsValid())
217 return SBTypeSummary();
218
219 if (!spec.IsValid())
220 return SBTypeSummary();
221
222 lldb::TypeSummaryImplSP summary_sp =
223 m_opaque_sp->GetSummaryForType(spec.GetSP());
224
225 if (!summary_sp)
226 return lldb::SBTypeSummary();
227
228 return lldb::SBTypeSummary(summary_sp);
229 }
230
GetSyntheticForType(SBTypeNameSpecifier spec)231 SBTypeSynthetic SBTypeCategory::GetSyntheticForType(SBTypeNameSpecifier spec) {
232 LLDB_INSTRUMENT_VA(this, spec);
233
234 if (!IsValid())
235 return SBTypeSynthetic();
236
237 if (!spec.IsValid())
238 return SBTypeSynthetic();
239
240 lldb::SyntheticChildrenSP children_sp =
241 m_opaque_sp->GetSyntheticForType(spec.GetSP());
242
243 if (!children_sp)
244 return lldb::SBTypeSynthetic();
245
246 ScriptedSyntheticChildrenSP synth_sp =
247 std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp);
248
249 return lldb::SBTypeSynthetic(synth_sp);
250 }
251
GetFilterAtIndex(uint32_t index)252 SBTypeFilter SBTypeCategory::GetFilterAtIndex(uint32_t index) {
253 LLDB_INSTRUMENT_VA(this, index);
254
255 if (!IsValid())
256 return SBTypeFilter();
257 lldb::SyntheticChildrenSP children_sp =
258 m_opaque_sp->GetSyntheticAtIndex((index));
259
260 if (!children_sp.get())
261 return lldb::SBTypeFilter();
262
263 TypeFilterImplSP filter_sp =
264 std::static_pointer_cast<TypeFilterImpl>(children_sp);
265
266 return lldb::SBTypeFilter(filter_sp);
267 }
268
GetFormatAtIndex(uint32_t index)269 SBTypeFormat SBTypeCategory::GetFormatAtIndex(uint32_t index) {
270 LLDB_INSTRUMENT_VA(this, index);
271
272 if (!IsValid())
273 return SBTypeFormat();
274 return SBTypeFormat(m_opaque_sp->GetFormatAtIndex((index)));
275 }
276
GetSummaryAtIndex(uint32_t index)277 SBTypeSummary SBTypeCategory::GetSummaryAtIndex(uint32_t index) {
278 LLDB_INSTRUMENT_VA(this, index);
279
280 if (!IsValid())
281 return SBTypeSummary();
282 return SBTypeSummary(m_opaque_sp->GetSummaryAtIndex((index)));
283 }
284
GetSyntheticAtIndex(uint32_t index)285 SBTypeSynthetic SBTypeCategory::GetSyntheticAtIndex(uint32_t index) {
286 LLDB_INSTRUMENT_VA(this, index);
287
288 if (!IsValid())
289 return SBTypeSynthetic();
290 lldb::SyntheticChildrenSP children_sp =
291 m_opaque_sp->GetSyntheticAtIndex((index));
292
293 if (!children_sp.get())
294 return lldb::SBTypeSynthetic();
295
296 ScriptedSyntheticChildrenSP synth_sp =
297 std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp);
298
299 return lldb::SBTypeSynthetic(synth_sp);
300 }
301
AddTypeFormat(SBTypeNameSpecifier type_name,SBTypeFormat format)302 bool SBTypeCategory::AddTypeFormat(SBTypeNameSpecifier type_name,
303 SBTypeFormat format) {
304 LLDB_INSTRUMENT_VA(this, type_name, format);
305
306 if (!IsValid())
307 return false;
308
309 if (!type_name.IsValid())
310 return false;
311
312 if (!format.IsValid())
313 return false;
314
315 m_opaque_sp->AddTypeFormat(type_name.GetSP(), format.GetSP());
316 return true;
317 }
318
DeleteTypeFormat(SBTypeNameSpecifier type_name)319 bool SBTypeCategory::DeleteTypeFormat(SBTypeNameSpecifier type_name) {
320 LLDB_INSTRUMENT_VA(this, type_name);
321
322 if (!IsValid())
323 return false;
324
325 if (!type_name.IsValid())
326 return false;
327
328 return m_opaque_sp->DeleteTypeFormat(type_name.GetSP());
329 }
330
AddTypeSummary(SBTypeNameSpecifier type_name,SBTypeSummary summary)331 bool SBTypeCategory::AddTypeSummary(SBTypeNameSpecifier type_name,
332 SBTypeSummary summary) {
333 LLDB_INSTRUMENT_VA(this, type_name, summary);
334
335 if (!IsValid())
336 return false;
337
338 if (!type_name.IsValid())
339 return false;
340
341 if (!summary.IsValid())
342 return false;
343
344 // FIXME: we need to iterate over all the Debugger objects and have each of
345 // them contain a copy of the function
346 // since we currently have formatters live in a global space, while Python
347 // code lives in a specific Debugger-related environment this should
348 // eventually be fixed by deciding a final location in the LLDB object space
349 // for formatters
350 if (summary.IsFunctionCode()) {
351 const void *name_token =
352 (const void *)ConstString(type_name.GetName()).GetCString();
353 const char *script = summary.GetData();
354 StringList input;
355 input.SplitIntoLines(script, strlen(script));
356 uint32_t num_debuggers = lldb_private::Debugger::GetNumDebuggers();
357 bool need_set = true;
358 for (uint32_t j = 0; j < num_debuggers; j++) {
359 DebuggerSP debugger_sp = lldb_private::Debugger::GetDebuggerAtIndex(j);
360 if (debugger_sp) {
361 ScriptInterpreter *interpreter_ptr =
362 debugger_sp->GetScriptInterpreter();
363 if (interpreter_ptr) {
364 std::string output;
365 if (interpreter_ptr->GenerateTypeScriptFunction(input, output,
366 name_token) &&
367 !output.empty()) {
368 if (need_set) {
369 need_set = false;
370 summary.SetFunctionName(output.c_str());
371 }
372 }
373 }
374 }
375 }
376 }
377
378 m_opaque_sp->AddTypeSummary(type_name.GetSP(), summary.GetSP());
379 return true;
380 }
381
DeleteTypeSummary(SBTypeNameSpecifier type_name)382 bool SBTypeCategory::DeleteTypeSummary(SBTypeNameSpecifier type_name) {
383 LLDB_INSTRUMENT_VA(this, type_name);
384
385 if (!IsValid())
386 return false;
387
388 if (!type_name.IsValid())
389 return false;
390
391 return m_opaque_sp->DeleteTypeSummary(type_name.GetSP());
392 }
393
AddTypeFilter(SBTypeNameSpecifier type_name,SBTypeFilter filter)394 bool SBTypeCategory::AddTypeFilter(SBTypeNameSpecifier type_name,
395 SBTypeFilter filter) {
396 LLDB_INSTRUMENT_VA(this, type_name, filter);
397
398 if (!IsValid())
399 return false;
400
401 if (!type_name.IsValid())
402 return false;
403
404 if (!filter.IsValid())
405 return false;
406
407 m_opaque_sp->AddTypeFilter(type_name.GetSP(), filter.GetSP());
408 return true;
409 }
410
DeleteTypeFilter(SBTypeNameSpecifier type_name)411 bool SBTypeCategory::DeleteTypeFilter(SBTypeNameSpecifier type_name) {
412 LLDB_INSTRUMENT_VA(this, type_name);
413
414 if (!IsValid())
415 return false;
416
417 if (!type_name.IsValid())
418 return false;
419
420 return m_opaque_sp->DeleteTypeFilter(type_name.GetSP());
421 }
422
AddTypeSynthetic(SBTypeNameSpecifier type_name,SBTypeSynthetic synth)423 bool SBTypeCategory::AddTypeSynthetic(SBTypeNameSpecifier type_name,
424 SBTypeSynthetic synth) {
425 LLDB_INSTRUMENT_VA(this, type_name, synth);
426
427 if (!IsValid())
428 return false;
429
430 if (!type_name.IsValid())
431 return false;
432
433 if (!synth.IsValid())
434 return false;
435
436 // FIXME: we need to iterate over all the Debugger objects and have each of
437 // them contain a copy of the function
438 // since we currently have formatters live in a global space, while Python
439 // code lives in a specific Debugger-related environment this should
440 // eventually be fixed by deciding a final location in the LLDB object space
441 // for formatters
442 if (synth.IsClassCode()) {
443 const void *name_token =
444 (const void *)ConstString(type_name.GetName()).GetCString();
445 const char *script = synth.GetData();
446 StringList input;
447 input.SplitIntoLines(script, strlen(script));
448 uint32_t num_debuggers = lldb_private::Debugger::GetNumDebuggers();
449 bool need_set = true;
450 for (uint32_t j = 0; j < num_debuggers; j++) {
451 DebuggerSP debugger_sp = lldb_private::Debugger::GetDebuggerAtIndex(j);
452 if (debugger_sp) {
453 ScriptInterpreter *interpreter_ptr =
454 debugger_sp->GetScriptInterpreter();
455 if (interpreter_ptr) {
456 std::string output;
457 if (interpreter_ptr->GenerateTypeSynthClass(input, output,
458 name_token) &&
459 !output.empty()) {
460 if (need_set) {
461 need_set = false;
462 synth.SetClassName(output.c_str());
463 }
464 }
465 }
466 }
467 }
468 }
469
470 m_opaque_sp->AddTypeSynthetic(type_name.GetSP(), synth.GetSP());
471 return true;
472 }
473
DeleteTypeSynthetic(SBTypeNameSpecifier type_name)474 bool SBTypeCategory::DeleteTypeSynthetic(SBTypeNameSpecifier type_name) {
475 LLDB_INSTRUMENT_VA(this, type_name);
476
477 if (!IsValid())
478 return false;
479
480 if (!type_name.IsValid())
481 return false;
482
483 return m_opaque_sp->DeleteTypeSynthetic(type_name.GetSP());
484 }
485
GetDescription(lldb::SBStream & description,lldb::DescriptionLevel description_level)486 bool SBTypeCategory::GetDescription(lldb::SBStream &description,
487 lldb::DescriptionLevel description_level) {
488 LLDB_INSTRUMENT_VA(this, description, description_level);
489
490 if (!IsValid())
491 return false;
492 description.Printf("Category name: %s\n", GetName());
493 return true;
494 }
495
496 lldb::SBTypeCategory &SBTypeCategory::
operator =(const lldb::SBTypeCategory & rhs)497 operator=(const lldb::SBTypeCategory &rhs) {
498 LLDB_INSTRUMENT_VA(this, rhs);
499
500 if (this != &rhs) {
501 m_opaque_sp = rhs.m_opaque_sp;
502 }
503 return *this;
504 }
505
operator ==(lldb::SBTypeCategory & rhs)506 bool SBTypeCategory::operator==(lldb::SBTypeCategory &rhs) {
507 LLDB_INSTRUMENT_VA(this, rhs);
508
509 if (!IsValid())
510 return !rhs.IsValid();
511
512 return m_opaque_sp.get() == rhs.m_opaque_sp.get();
513 }
514
operator !=(lldb::SBTypeCategory & rhs)515 bool SBTypeCategory::operator!=(lldb::SBTypeCategory &rhs) {
516 LLDB_INSTRUMENT_VA(this, rhs);
517
518 if (!IsValid())
519 return rhs.IsValid();
520
521 return m_opaque_sp.get() != rhs.m_opaque_sp.get();
522 }
523
GetSP()524 lldb::TypeCategoryImplSP SBTypeCategory::GetSP() {
525 if (!IsValid())
526 return lldb::TypeCategoryImplSP();
527 return m_opaque_sp;
528 }
529
SetSP(const lldb::TypeCategoryImplSP & typecategory_impl_sp)530 void SBTypeCategory::SetSP(
531 const lldb::TypeCategoryImplSP &typecategory_impl_sp) {
532 m_opaque_sp = typecategory_impl_sp;
533 }
534
SBTypeCategory(const lldb::TypeCategoryImplSP & typecategory_impl_sp)535 SBTypeCategory::SBTypeCategory(
536 const lldb::TypeCategoryImplSP &typecategory_impl_sp)
537 : m_opaque_sp(typecategory_impl_sp) {}
538
IsDefaultCategory()539 bool SBTypeCategory::IsDefaultCategory() {
540 if (!IsValid())
541 return false;
542
543 return (strcmp(m_opaque_sp->GetName(), "default") == 0);
544 }
545