blob: 322d1cf55437eeca35d44457e68b070e0170a903 [file] [log] [blame]
//===-- TypeCategory.cpp -------------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "lldb/lldb-python.h"
#include "lldb/DataFormatters/TypeCategory.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
using namespace lldb;
using namespace lldb_private;
TypeCategoryImpl::TypeCategoryImpl(IFormatChangeListener* clist,
ConstString name) :
m_format_cont("format","regex-format",clist),
m_summary_cont("summary","regex-summary",clist),
m_filter_cont("filter","regex-filter",clist),
#ifndef LLDB_DISABLE_PYTHON
m_synth_cont("synth","regex-synth",clist),
#endif
m_enabled(false),
m_change_listener(clist),
m_mutex(Mutex::eMutexTypeRecursive),
m_name(name)
{}
bool
TypeCategoryImpl::Get (ValueObject& valobj,
const FormattersMatchVector& candidates,
lldb::TypeFormatImplSP& entry,
uint32_t* reason)
{
if (!IsEnabled())
return false;
if (GetTypeFormatsContainer()->Get(candidates, entry, reason))
return true;
bool regex = GetRegexTypeFormatsContainer()->Get(candidates, entry, reason);
if (regex && reason)
*reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
return regex;
}
bool
TypeCategoryImpl::Get (ValueObject& valobj,
const FormattersMatchVector& candidates,
lldb::TypeSummaryImplSP& entry,
uint32_t* reason)
{
if (!IsEnabled())
return false;
if (GetTypeSummariesContainer()->Get(candidates, entry, reason))
return true;
bool regex = GetRegexTypeSummariesContainer()->Get(candidates, entry, reason);
if (regex && reason)
*reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
return regex;
}
bool
TypeCategoryImpl::Get (ValueObject& valobj,
const FormattersMatchVector& candidates,
lldb::SyntheticChildrenSP& entry,
uint32_t* reason)
{
if (!IsEnabled())
return false;
TypeFilterImpl::SharedPointer filter_sp;
uint32_t reason_filter = 0;
bool regex_filter = false;
// first find both Filter and Synth, and then check which is most recent
if (!GetTypeFiltersContainer()->Get(candidates, filter_sp, &reason_filter))
regex_filter = GetRegexTypeFiltersContainer()->Get (candidates, filter_sp, &reason_filter);
#ifndef LLDB_DISABLE_PYTHON
bool regex_synth = false;
uint32_t reason_synth = 0;
bool pick_synth = false;
ScriptedSyntheticChildren::SharedPointer synth;
if (!GetTypeSyntheticsContainer()->Get(candidates, synth, &reason_synth))
regex_synth = GetRegexTypeSyntheticsContainer()->Get (candidates, synth, &reason_synth);
if (!filter_sp.get() && !synth.get())
return false;
else if (!filter_sp.get() && synth.get())
pick_synth = true;
else if (filter_sp.get() && !synth.get())
pick_synth = false;
else /*if (filter_sp.get() && synth.get())*/
{
if (filter_sp->GetRevision() > synth->GetRevision())
pick_synth = false;
else
pick_synth = true;
}
if (pick_synth)
{
if (regex_synth && reason)
*reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
entry = synth;
return true;
}
else
{
if (regex_filter && reason)
*reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
entry = filter_sp;
return true;
}
#else
if (filter_sp)
{
entry = filter_sp;
return true;
}
#endif
return false;
}
void
TypeCategoryImpl::Clear (FormatCategoryItems items)
{
if ( (items & eFormatCategoryItemValue) == eFormatCategoryItemValue )
GetTypeFormatsContainer()->Clear();
if ( (items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue )
GetRegexTypeFormatsContainer()->Clear();
if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
GetTypeSummariesContainer()->Clear();
if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
GetRegexTypeSummariesContainer()->Clear();
if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
GetTypeFiltersContainer()->Clear();
if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
GetRegexTypeFiltersContainer()->Clear();
#ifndef LLDB_DISABLE_PYTHON
if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
GetTypeSyntheticsContainer()->Clear();
if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
GetRegexTypeSyntheticsContainer()->Clear();
#endif
}
bool
TypeCategoryImpl::Delete (ConstString name,
FormatCategoryItems items)
{
bool success = false;
if ( (items & eFormatCategoryItemValue) == eFormatCategoryItemValue )
success = GetTypeFormatsContainer()->Delete(name) || success;
if ( (items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue )
success = GetRegexTypeFormatsContainer()->Delete(name) || success;
if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
success = GetTypeSummariesContainer()->Delete(name) || success;
if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
success = GetRegexTypeSummariesContainer()->Delete(name) || success;
if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
success = GetTypeFiltersContainer()->Delete(name) || success;
if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
success = GetRegexTypeFiltersContainer()->Delete(name) || success;
#ifndef LLDB_DISABLE_PYTHON
if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
success = GetTypeSyntheticsContainer()->Delete(name) || success;
if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
success = GetRegexTypeSyntheticsContainer()->Delete(name) || success;
#endif
return success;
}
uint32_t
TypeCategoryImpl::GetCount (FormatCategoryItems items)
{
uint32_t count = 0;
if ( (items & eFormatCategoryItemValue) == eFormatCategoryItemValue )
count += GetTypeFormatsContainer()->GetCount();
if ( (items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue )
count += GetRegexTypeFormatsContainer()->GetCount();
if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
count += GetTypeSummariesContainer()->GetCount();
if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
count += GetRegexTypeSummariesContainer()->GetCount();
if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
count += GetTypeFiltersContainer()->GetCount();
if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
count += GetRegexTypeFiltersContainer()->GetCount();
#ifndef LLDB_DISABLE_PYTHON
if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
count += GetTypeSyntheticsContainer()->GetCount();
if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
count += GetRegexTypeSyntheticsContainer()->GetCount();
#endif
return count;
}
bool
TypeCategoryImpl::AnyMatches(ConstString type_name,
FormatCategoryItems items,
bool only_enabled,
const char** matching_category,
FormatCategoryItems* matching_type)
{
if (!IsEnabled() && only_enabled)
return false;
lldb::TypeFormatImplSP format_sp;
lldb::TypeSummaryImplSP summary_sp;
TypeFilterImpl::SharedPointer filter_sp;
#ifndef LLDB_DISABLE_PYTHON
ScriptedSyntheticChildren::SharedPointer synth_sp;
#endif
if ( (items & eFormatCategoryItemValue) == eFormatCategoryItemValue )
{
if (GetTypeFormatsContainer()->Get(type_name, format_sp))
{
if (matching_category)
*matching_category = m_name.GetCString();
if (matching_type)
*matching_type = eFormatCategoryItemValue;
return true;
}
}
if ( (items & eFormatCategoryItemRegexValue) == eFormatCategoryItemRegexValue )
{
if (GetRegexTypeFormatsContainer()->Get(type_name, format_sp))
{
if (matching_category)
*matching_category = m_name.GetCString();
if (matching_type)
*matching_type = eFormatCategoryItemRegexValue;
return true;
}
}
if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
{
if (GetTypeSummariesContainer()->Get(type_name, summary_sp))
{
if (matching_category)
*matching_category = m_name.GetCString();
if (matching_type)
*matching_type = eFormatCategoryItemSummary;
return true;
}
}
if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
{
if (GetRegexTypeSummariesContainer()->Get(type_name, summary_sp))
{
if (matching_category)
*matching_category = m_name.GetCString();
if (matching_type)
*matching_type = eFormatCategoryItemRegexSummary;
return true;
}
}
if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
{
if (GetTypeFiltersContainer()->Get(type_name, filter_sp))
{
if (matching_category)
*matching_category = m_name.GetCString();
if (matching_type)
*matching_type = eFormatCategoryItemFilter;
return true;
}
}
if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
{
if (GetRegexTypeFiltersContainer()->Get(type_name, filter_sp))
{
if (matching_category)
*matching_category = m_name.GetCString();
if (matching_type)
*matching_type = eFormatCategoryItemRegexFilter;
return true;
}
}
#ifndef LLDB_DISABLE_PYTHON
if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
{
if (GetTypeSyntheticsContainer()->Get(type_name, synth_sp))
{
if (matching_category)
*matching_category = m_name.GetCString();
if (matching_type)
*matching_type = eFormatCategoryItemSynth;
return true;
}
}
if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
{
if (GetRegexTypeSyntheticsContainer()->Get(type_name, synth_sp))
{
if (matching_category)
*matching_category = m_name.GetCString();
if (matching_type)
*matching_type = eFormatCategoryItemRegexSynth;
return true;
}
}
#endif
return false;
}
TypeCategoryImpl::FormatContainer::MapValueType
TypeCategoryImpl::GetFormatForType (lldb::TypeNameSpecifierImplSP type_sp)
{
FormatContainer::MapValueType retval;
if (type_sp)
{
if (type_sp->IsRegex())
GetRegexTypeFormatsContainer()->GetExact(ConstString(type_sp->GetName()),retval);
else
GetTypeFormatsContainer()->GetExact(ConstString(type_sp->GetName()),retval);
}
return retval;
}
TypeCategoryImpl::SummaryContainer::MapValueType
TypeCategoryImpl::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
{
SummaryContainer::MapValueType retval;
if (type_sp)
{
if (type_sp->IsRegex())
GetRegexTypeSummariesContainer()->GetExact(ConstString(type_sp->GetName()),retval);
else
GetTypeSummariesContainer()->GetExact(ConstString(type_sp->GetName()),retval);
}
return retval;
}
TypeCategoryImpl::FilterContainer::MapValueType
TypeCategoryImpl::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
{
FilterContainer::MapValueType retval;
if (type_sp)
{
if (type_sp->IsRegex())
GetRegexTypeFiltersContainer()->GetExact(ConstString(type_sp->GetName()),retval);
else
GetTypeFiltersContainer()->GetExact(ConstString(type_sp->GetName()),retval);
}
return retval;
}
#ifndef LLDB_DISABLE_PYTHON
TypeCategoryImpl::SynthContainer::MapValueType
TypeCategoryImpl::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
{
SynthContainer::MapValueType retval;
if (type_sp)
{
if (type_sp->IsRegex())
GetRegexTypeSyntheticsContainer()->GetExact(ConstString(type_sp->GetName()),retval);
else
GetTypeSyntheticsContainer()->GetExact(ConstString(type_sp->GetName()),retval);
}
return retval;
}
#endif
lldb::TypeNameSpecifierImplSP
TypeCategoryImpl::GetTypeNameSpecifierForSummaryAtIndex (size_t index)
{
if (index < GetTypeSummariesContainer()->GetCount())
return GetTypeSummariesContainer()->GetTypeNameSpecifierAtIndex(index);
else
return GetRegexTypeSummariesContainer()->GetTypeNameSpecifierAtIndex(index-GetTypeSummariesContainer()->GetCount());
}
TypeCategoryImpl::FormatContainer::MapValueType
TypeCategoryImpl::GetFormatAtIndex (size_t index)
{
if (index < GetTypeFormatsContainer()->GetCount())
return GetTypeFormatsContainer()->GetAtIndex(index);
else
return GetRegexTypeFormatsContainer()->GetAtIndex(index-GetTypeFormatsContainer()->GetCount());
}
TypeCategoryImpl::SummaryContainer::MapValueType
TypeCategoryImpl::GetSummaryAtIndex (size_t index)
{
if (index < GetTypeSummariesContainer()->GetCount())
return GetTypeSummariesContainer()->GetAtIndex(index);
else
return GetRegexTypeSummariesContainer()->GetAtIndex(index-GetTypeSummariesContainer()->GetCount());
}
TypeCategoryImpl::FilterContainer::MapValueType
TypeCategoryImpl::GetFilterAtIndex (size_t index)
{
if (index < GetTypeFiltersContainer()->GetCount())
return GetTypeFiltersContainer()->GetAtIndex(index);
else
return GetRegexTypeFiltersContainer()->GetAtIndex(index-GetTypeFiltersContainer()->GetCount());
}
lldb::TypeNameSpecifierImplSP
TypeCategoryImpl::GetTypeNameSpecifierForFormatAtIndex (size_t index)
{
if (index < GetTypeFormatsContainer()->GetCount())
return GetTypeFormatsContainer()->GetTypeNameSpecifierAtIndex(index);
else
return GetRegexTypeFormatsContainer()->GetTypeNameSpecifierAtIndex(index-GetTypeFormatsContainer()->GetCount());
}
lldb::TypeNameSpecifierImplSP
TypeCategoryImpl::GetTypeNameSpecifierForFilterAtIndex (size_t index)
{
if (index < GetTypeFiltersContainer()->GetCount())
return GetTypeFiltersContainer()->GetTypeNameSpecifierAtIndex(index);
else
return GetRegexTypeFiltersContainer()->GetTypeNameSpecifierAtIndex(index-GetTypeFiltersContainer()->GetCount());
}
#ifndef LLDB_DISABLE_PYTHON
TypeCategoryImpl::SynthContainer::MapValueType
TypeCategoryImpl::GetSyntheticAtIndex (size_t index)
{
if (index < GetTypeSyntheticsContainer()->GetCount())
return GetTypeSyntheticsContainer()->GetAtIndex(index);
else
return GetRegexTypeSyntheticsContainer()->GetAtIndex(index-GetTypeSyntheticsContainer()->GetCount());
}
lldb::TypeNameSpecifierImplSP
TypeCategoryImpl::GetTypeNameSpecifierForSyntheticAtIndex (size_t index)
{
if (index < GetTypeSyntheticsContainer()->GetCount())
return GetTypeSyntheticsContainer()->GetTypeNameSpecifierAtIndex(index);
else
return GetRegexTypeSyntheticsContainer()->GetTypeNameSpecifierAtIndex(index - GetTypeSyntheticsContainer()->GetCount());
}
#endif
void
TypeCategoryImpl::Enable (bool value, uint32_t position)
{
Mutex::Locker locker(m_mutex);
m_enabled = value;
m_enabled_position = position;
if (m_change_listener)
m_change_listener->Changed();
}