Home | History | Annotate | Download | only in DataFormatters
      1 //===-- TypeCategory.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/DataFormatters/TypeCategory.h"
     13 
     14 // C Includes
     15 // C++ Includes
     16 // Other libraries and framework includes
     17 // Project includes
     18 
     19 using namespace lldb;
     20 using namespace lldb_private;
     21 
     22 TypeCategoryImpl::TypeCategoryImpl(IFormatChangeListener* clist,
     23                                    ConstString name) :
     24 m_summary_nav(new SummaryNavigator("summary",clist)),
     25 m_regex_summary_nav(new RegexSummaryNavigator("regex-summary",clist)),
     26 m_filter_nav(new FilterNavigator("filter",clist)),
     27 m_regex_filter_nav(new RegexFilterNavigator("regex-filter",clist)),
     28 #ifndef LLDB_DISABLE_PYTHON
     29 m_synth_nav(new SynthNavigator("synth",clist)),
     30 m_regex_synth_nav(new RegexSynthNavigator("regex-synth",clist)),
     31 #endif
     32 m_enabled(false),
     33 m_change_listener(clist),
     34 m_mutex(Mutex::eMutexTypeRecursive),
     35 m_name(name)
     36 {}
     37 
     38 bool
     39 TypeCategoryImpl::Get (ValueObject& valobj,
     40                        lldb::TypeSummaryImplSP& entry,
     41                        lldb::DynamicValueType use_dynamic,
     42                        uint32_t* reason)
     43 {
     44     if (!IsEnabled())
     45         return false;
     46     if (GetSummaryNavigator()->Get(valobj, entry, use_dynamic, reason))
     47         return true;
     48     bool regex = GetRegexSummaryNavigator()->Get(valobj, entry, use_dynamic, reason);
     49     if (regex && reason)
     50         *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
     51     return regex;
     52 }
     53 
     54 bool
     55 TypeCategoryImpl::Get(ValueObject& valobj,
     56                       lldb::SyntheticChildrenSP& entry_sp,
     57                       lldb::DynamicValueType use_dynamic,
     58                       uint32_t* reason)
     59 {
     60     if (!IsEnabled())
     61         return false;
     62     TypeFilterImpl::SharedPointer filter_sp;
     63     uint32_t reason_filter = 0;
     64     bool regex_filter = false;
     65     // first find both Filter and Synth, and then check which is most recent
     66 
     67     if (!GetFilterNavigator()->Get(valobj, filter_sp, use_dynamic, &reason_filter))
     68         regex_filter = GetRegexFilterNavigator()->Get (valobj, filter_sp, use_dynamic, &reason_filter);
     69 
     70 #ifndef LLDB_DISABLE_PYTHON
     71     bool regex_synth = false;
     72     uint32_t reason_synth = 0;
     73     bool pick_synth = false;
     74     ScriptedSyntheticChildren::SharedPointer synth;
     75     if (!GetSyntheticNavigator()->Get(valobj, synth, use_dynamic, &reason_synth))
     76         regex_synth = GetRegexSyntheticNavigator()->Get (valobj, synth, use_dynamic, &reason_synth);
     77     if (!filter_sp.get() && !synth.get())
     78         return false;
     79     else if (!filter_sp.get() && synth.get())
     80         pick_synth = true;
     81 
     82     else if (filter_sp.get() && !synth.get())
     83         pick_synth = false;
     84 
     85     else /*if (filter_sp.get() && synth.get())*/
     86     {
     87         if (filter_sp->GetRevision() > synth->GetRevision())
     88             pick_synth = false;
     89         else
     90             pick_synth = true;
     91     }
     92     if (pick_synth)
     93     {
     94         if (regex_synth && reason)
     95             *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
     96         entry_sp = synth;
     97         return true;
     98     }
     99     else
    100     {
    101         if (regex_filter && reason)
    102             *reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
    103         entry_sp = filter_sp;
    104         return true;
    105     }
    106 
    107 #else
    108     if (filter_sp)
    109     {
    110         entry_sp = filter_sp;
    111         return true;
    112     }
    113 #endif
    114 
    115     return false;
    116 
    117 }
    118 
    119 void
    120 TypeCategoryImpl::Clear (FormatCategoryItems items)
    121 {
    122     if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
    123         m_summary_nav->Clear();
    124     if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
    125         m_regex_summary_nav->Clear();
    126     if ( (items & eFormatCategoryItemFilter)  == eFormatCategoryItemFilter )
    127         m_filter_nav->Clear();
    128     if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
    129         m_regex_filter_nav->Clear();
    130 #ifndef LLDB_DISABLE_PYTHON
    131     if ( (items & eFormatCategoryItemSynth)  == eFormatCategoryItemSynth )
    132         m_synth_nav->Clear();
    133     if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
    134         m_regex_synth_nav->Clear();
    135 #endif
    136 }
    137 
    138 bool
    139 TypeCategoryImpl::Delete (ConstString name,
    140                           FormatCategoryItems items)
    141 {
    142     bool success = false;
    143     if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
    144         success = m_summary_nav->Delete(name) || success;
    145     if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
    146         success = m_regex_summary_nav->Delete(name) || success;
    147     if ( (items & eFormatCategoryItemFilter)  == eFormatCategoryItemFilter )
    148         success = m_filter_nav->Delete(name) || success;
    149     if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
    150         success = m_regex_filter_nav->Delete(name) || success;
    151 #ifndef LLDB_DISABLE_PYTHON
    152     if ( (items & eFormatCategoryItemSynth)  == eFormatCategoryItemSynth )
    153         success = m_synth_nav->Delete(name) || success;
    154     if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
    155         success = m_regex_synth_nav->Delete(name) || success;
    156 #endif
    157     return success;
    158 }
    159 
    160 uint32_t
    161 TypeCategoryImpl::GetCount (FormatCategoryItems items)
    162 {
    163     uint32_t count = 0;
    164     if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
    165         count += m_summary_nav->GetCount();
    166     if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
    167         count += m_regex_summary_nav->GetCount();
    168     if ( (items & eFormatCategoryItemFilter)  == eFormatCategoryItemFilter )
    169         count += m_filter_nav->GetCount();
    170     if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
    171         count += m_regex_filter_nav->GetCount();
    172 #ifndef LLDB_DISABLE_PYTHON
    173     if ( (items & eFormatCategoryItemSynth)  == eFormatCategoryItemSynth )
    174         count += m_synth_nav->GetCount();
    175     if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
    176         count += m_regex_synth_nav->GetCount();
    177 #endif
    178     return count;
    179 }
    180 
    181 bool
    182 TypeCategoryImpl::AnyMatches(ConstString type_name,
    183                              FormatCategoryItems items,
    184                              bool only_enabled,
    185                              const char** matching_category,
    186                              FormatCategoryItems* matching_type)
    187 {
    188     if (!IsEnabled() && only_enabled)
    189         return false;
    190 
    191     lldb::TypeSummaryImplSP summary;
    192     TypeFilterImpl::SharedPointer filter;
    193 #ifndef LLDB_DISABLE_PYTHON
    194     ScriptedSyntheticChildren::SharedPointer synth;
    195 #endif
    196 
    197     if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
    198     {
    199         if (m_summary_nav->Get(type_name, summary))
    200         {
    201             if (matching_category)
    202                 *matching_category = m_name.GetCString();
    203             if (matching_type)
    204                 *matching_type = eFormatCategoryItemSummary;
    205             return true;
    206         }
    207     }
    208     if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
    209     {
    210         if (m_regex_summary_nav->Get(type_name, summary))
    211         {
    212             if (matching_category)
    213                 *matching_category = m_name.GetCString();
    214             if (matching_type)
    215                 *matching_type = eFormatCategoryItemRegexSummary;
    216             return true;
    217         }
    218     }
    219     if ( (items & eFormatCategoryItemFilter)  == eFormatCategoryItemFilter )
    220     {
    221         if (m_filter_nav->Get(type_name, filter))
    222         {
    223             if (matching_category)
    224                 *matching_category = m_name.GetCString();
    225             if (matching_type)
    226                 *matching_type = eFormatCategoryItemFilter;
    227             return true;
    228         }
    229     }
    230     if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
    231     {
    232         if (m_regex_filter_nav->Get(type_name, filter))
    233         {
    234             if (matching_category)
    235                 *matching_category = m_name.GetCString();
    236             if (matching_type)
    237                 *matching_type = eFormatCategoryItemRegexFilter;
    238             return true;
    239         }
    240     }
    241 #ifndef LLDB_DISABLE_PYTHON
    242     if ( (items & eFormatCategoryItemSynth)  == eFormatCategoryItemSynth )
    243     {
    244         if (m_synth_nav->Get(type_name, synth))
    245         {
    246             if (matching_category)
    247                 *matching_category = m_name.GetCString();
    248             if (matching_type)
    249                 *matching_type = eFormatCategoryItemSynth;
    250             return true;
    251         }
    252     }
    253     if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
    254     {
    255         if (m_regex_synth_nav->Get(type_name, synth))
    256         {
    257             if (matching_category)
    258                 *matching_category = m_name.GetCString();
    259             if (matching_type)
    260                 *matching_type = eFormatCategoryItemRegexSynth;
    261             return true;
    262         }
    263     }
    264 #endif
    265     return false;
    266 }
    267 
    268 TypeCategoryImpl::SummaryNavigator::MapValueType
    269 TypeCategoryImpl::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
    270 {
    271     SummaryNavigator::MapValueType retval;
    272 
    273     if (type_sp)
    274     {
    275         if (type_sp->IsRegex())
    276             m_regex_summary_nav->GetExact(ConstString(type_sp->GetName()),retval);
    277         else
    278             m_summary_nav->GetExact(ConstString(type_sp->GetName()),retval);
    279     }
    280 
    281     return retval;
    282 }
    283 
    284 TypeCategoryImpl::FilterNavigator::MapValueType
    285 TypeCategoryImpl::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
    286 {
    287     FilterNavigator::MapValueType retval;
    288 
    289     if (type_sp)
    290     {
    291         if (type_sp->IsRegex())
    292             m_regex_filter_nav->GetExact(ConstString(type_sp->GetName()),retval);
    293         else
    294             m_filter_nav->GetExact(ConstString(type_sp->GetName()),retval);
    295     }
    296 
    297     return retval;
    298 }
    299 
    300 #ifndef LLDB_DISABLE_PYTHON
    301 TypeCategoryImpl::SynthNavigator::MapValueType
    302 TypeCategoryImpl::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
    303 {
    304     SynthNavigator::MapValueType retval;
    305 
    306     if (type_sp)
    307     {
    308         if (type_sp->IsRegex())
    309             m_regex_synth_nav->GetExact(ConstString(type_sp->GetName()),retval);
    310         else
    311             m_synth_nav->GetExact(ConstString(type_sp->GetName()),retval);
    312     }
    313 
    314     return retval;
    315 }
    316 #endif
    317 
    318 lldb::TypeNameSpecifierImplSP
    319 TypeCategoryImpl::GetTypeNameSpecifierForSummaryAtIndex (size_t index)
    320 {
    321     if (index < m_summary_nav->GetCount())
    322         return m_summary_nav->GetTypeNameSpecifierAtIndex(index);
    323     else
    324         return m_regex_summary_nav->GetTypeNameSpecifierAtIndex(index-m_summary_nav->GetCount());
    325 }
    326 
    327 TypeCategoryImpl::SummaryNavigator::MapValueType
    328 TypeCategoryImpl::GetSummaryAtIndex (size_t index)
    329 {
    330     if (index < m_summary_nav->GetCount())
    331         return m_summary_nav->GetAtIndex(index);
    332     else
    333         return m_regex_summary_nav->GetAtIndex(index-m_summary_nav->GetCount());
    334 }
    335 
    336 TypeCategoryImpl::FilterNavigator::MapValueType
    337 TypeCategoryImpl::GetFilterAtIndex (size_t index)
    338 {
    339     if (index < m_filter_nav->GetCount())
    340         return m_filter_nav->GetAtIndex(index);
    341     else
    342         return m_regex_filter_nav->GetAtIndex(index-m_filter_nav->GetCount());
    343 }
    344 
    345 lldb::TypeNameSpecifierImplSP
    346 TypeCategoryImpl::GetTypeNameSpecifierForFilterAtIndex (size_t index)
    347 {
    348     if (index < m_filter_nav->GetCount())
    349         return m_filter_nav->GetTypeNameSpecifierAtIndex(index);
    350     else
    351         return m_regex_filter_nav->GetTypeNameSpecifierAtIndex(index-m_filter_nav->GetCount());
    352 }
    353 
    354 #ifndef LLDB_DISABLE_PYTHON
    355 TypeCategoryImpl::SynthNavigator::MapValueType
    356 TypeCategoryImpl::GetSyntheticAtIndex (size_t index)
    357 {
    358     if (index < m_synth_nav->GetCount())
    359         return m_synth_nav->GetAtIndex(index);
    360     else
    361         return m_regex_synth_nav->GetAtIndex(index-m_synth_nav->GetCount());
    362 }
    363 
    364 lldb::TypeNameSpecifierImplSP
    365 TypeCategoryImpl::GetTypeNameSpecifierForSyntheticAtIndex (size_t index)
    366 {
    367     if (index < m_synth_nav->GetCount())
    368         return m_synth_nav->GetTypeNameSpecifierAtIndex(index);
    369     else
    370         return m_regex_synth_nav->GetTypeNameSpecifierAtIndex(index - m_synth_nav->GetCount());
    371 }
    372 #endif
    373 
    374 void
    375 TypeCategoryImpl::Enable (bool value, uint32_t position)
    376 {
    377     Mutex::Locker locker(m_mutex);
    378     m_enabled = value;
    379     m_enabled_position = position;
    380     if (m_change_listener)
    381         m_change_listener->Changed();
    382 }
    383