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