SBTypeCategory.cpp revision 263363
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
26using namespace lldb;
27using namespace lldb_private;
28
29typedef std::pair<lldb::TypeCategoryImplSP,user_id_t> ImplType;
30
31SBTypeCategory::SBTypeCategory() :
32m_opaque_sp()
33{
34}
35
36SBTypeCategory::SBTypeCategory (const char* name) :
37m_opaque_sp()
38{
39    DataVisualization::Categories::GetCategory(ConstString(name), m_opaque_sp);
40}
41
42SBTypeCategory::SBTypeCategory (const lldb::SBTypeCategory &rhs) :
43m_opaque_sp(rhs.m_opaque_sp)
44{
45}
46
47SBTypeCategory::~SBTypeCategory ()
48{
49}
50
51bool
52SBTypeCategory::IsValid() const
53{
54    return (m_opaque_sp.get() != NULL);
55}
56
57bool
58SBTypeCategory::GetEnabled ()
59{
60    if (!IsValid())
61        return false;
62    return m_opaque_sp->IsEnabled();
63}
64
65void
66SBTypeCategory::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
76const char*
77SBTypeCategory::GetName()
78{
79    if (!IsValid())
80        return NULL;
81    return m_opaque_sp->GetName();
82}
83
84uint32_t
85SBTypeCategory::GetNumFormats ()
86{
87    if (!IsValid())
88        return 0;
89
90    return m_opaque_sp->GetValueNavigator()->GetCount() + m_opaque_sp->GetRegexValueNavigator()->GetCount();
91}
92
93uint32_t
94SBTypeCategory::GetNumSummaries ()
95{
96    if (!IsValid())
97        return 0;
98    return m_opaque_sp->GetSummaryNavigator()->GetCount() + m_opaque_sp->GetRegexSummaryNavigator()->GetCount();
99}
100
101uint32_t
102SBTypeCategory::GetNumFilters ()
103{
104    if (!IsValid())
105        return 0;
106    return m_opaque_sp->GetFilterNavigator()->GetCount() + m_opaque_sp->GetRegexFilterNavigator()->GetCount();
107}
108
109#ifndef LLDB_DISABLE_PYTHON
110uint32_t
111SBTypeCategory::GetNumSynthetics ()
112{
113    if (!IsValid())
114        return 0;
115    return m_opaque_sp->GetSyntheticNavigator()->GetCount() + m_opaque_sp->GetRegexSyntheticNavigator()->GetCount();
116}
117#endif
118
119lldb::SBTypeNameSpecifier
120SBTypeCategory::GetTypeNameSpecifierForFilterAtIndex (uint32_t index)
121{
122    if (!IsValid())
123        return SBTypeNameSpecifier();
124    return SBTypeNameSpecifier(m_opaque_sp->GetTypeNameSpecifierForFilterAtIndex(index));
125}
126
127lldb::SBTypeNameSpecifier
128SBTypeCategory::GetTypeNameSpecifierForFormatAtIndex (uint32_t index)
129{
130    if (!IsValid())
131        return SBTypeNameSpecifier();
132    return SBTypeNameSpecifier(m_opaque_sp->GetTypeNameSpecifierForFormatAtIndex(index));
133}
134
135lldb::SBTypeNameSpecifier
136SBTypeCategory::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
144lldb::SBTypeNameSpecifier
145SBTypeCategory::GetTypeNameSpecifierForSyntheticAtIndex (uint32_t index)
146{
147    if (!IsValid())
148        return SBTypeNameSpecifier();
149    return SBTypeNameSpecifier(m_opaque_sp->GetTypeNameSpecifierForSyntheticAtIndex(index));
150}
151#endif
152
153SBTypeFilter
154SBTypeCategory::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->GetRegexFilterNavigator()->GetExact(ConstString(spec.GetName()), children_sp);
166    else
167        m_opaque_sp->GetFilterNavigator()->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}
177SBTypeFormat
178SBTypeCategory::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->GetRegexValueNavigator()->GetExact(ConstString(spec.GetName()), format_sp);
190    else
191        m_opaque_sp->GetValueNavigator()->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
200SBTypeSummary
201SBTypeCategory::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->GetRegexSummaryNavigator()->GetExact(ConstString(spec.GetName()), summary_sp);
213    else
214        m_opaque_sp->GetSummaryNavigator()->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
224SBTypeSynthetic
225SBTypeCategory::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->GetRegexSyntheticNavigator()->GetExact(ConstString(spec.GetName()), children_sp);
237    else
238        m_opaque_sp->GetSyntheticNavigator()->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
250SBTypeFilter
251SBTypeCategory::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
266SBTypeFormat
267SBTypeCategory::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
275SBTypeSummary
276SBTypeCategory::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
285SBTypeSynthetic
286SBTypeCategory::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
301bool
302SBTypeCategory::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->GetRegexValueNavigator()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), format.GetSP());
316    else
317        m_opaque_sp->GetValueNavigator()->Add(ConstString(type_name.GetName()), format.GetSP());
318
319    return true;
320}
321
322bool
323SBTypeCategory::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->GetRegexValueNavigator()->Delete(ConstString(type_name.GetName()));
333    else
334        return m_opaque_sp->GetValueNavigator()->Delete(ConstString(type_name.GetName()));
335}
336
337#ifndef LLDB_DISABLE_PYTHON
338bool
339SBTypeCategory::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->GetRegexSummaryNavigator()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), summary.GetSP());
387    else
388        m_opaque_sp->GetSummaryNavigator()->Add(ConstString(type_name.GetName()), summary.GetSP());
389
390    return true;
391}
392#endif
393
394bool
395SBTypeCategory::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->GetRegexSummaryNavigator()->Delete(ConstString(type_name.GetName()));
405    else
406        return m_opaque_sp->GetSummaryNavigator()->Delete(ConstString(type_name.GetName()));
407}
408
409bool
410SBTypeCategory::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->GetRegexFilterNavigator()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), filter.GetSP());
424    else
425        m_opaque_sp->GetFilterNavigator()->Add(ConstString(type_name.GetName()), filter.GetSP());
426
427    return true;
428}
429
430bool
431SBTypeCategory::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->GetRegexFilterNavigator()->Delete(ConstString(type_name.GetName()));
441    else
442        return m_opaque_sp->GetFilterNavigator()->Delete(ConstString(type_name.GetName()));
443}
444
445#ifndef LLDB_DISABLE_PYTHON
446bool
447SBTypeCategory::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->GetRegexSyntheticNavigator()->Add(lldb::RegularExpressionSP(new RegularExpression(type_name.GetName())), synth.GetSP());
495    else
496        m_opaque_sp->GetSyntheticNavigator()->Add(ConstString(type_name.GetName()), synth.GetSP());
497
498    return true;
499}
500
501bool
502SBTypeCategory::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->GetRegexSyntheticNavigator()->Delete(ConstString(type_name.GetName()));
512    else
513        return m_opaque_sp->GetSyntheticNavigator()->Delete(ConstString(type_name.GetName()));
514}
515#endif // LLDB_DISABLE_PYTHON
516
517bool
518SBTypeCategory::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
527lldb::SBTypeCategory &
528SBTypeCategory::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
537bool
538SBTypeCategory::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
547bool
548SBTypeCategory::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
556lldb::TypeCategoryImplSP
557SBTypeCategory::GetSP ()
558{
559    if (!IsValid())
560        return lldb::TypeCategoryImplSP();
561    return m_opaque_sp;
562}
563
564void
565SBTypeCategory::SetSP (const lldb::TypeCategoryImplSP &typecategory_impl_sp)
566{
567    m_opaque_sp = typecategory_impl_sp;
568}
569
570SBTypeCategory::SBTypeCategory (const lldb::TypeCategoryImplSP &typecategory_impl_sp) :
571m_opaque_sp(typecategory_impl_sp)
572{
573}
574
575bool
576SBTypeCategory::IsDefaultCategory()
577{
578    if (!IsValid())
579        return false;
580
581    return (strcmp(m_opaque_sp->GetName(),"default") == 0);
582}
583
584