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