forked from OSchip/llvm-project
<rdar://problem/11338654> Fixing a bug where having a summary for a bitfield without a format specified would in certain cases crash LLDB - This has also led to refactoring the by-type accessors for the data formatter subsystem. These now belong in our internal layer, and are just invoked by the public API stratum
llvm-svn: 156429
This commit is contained in:
parent
f534e91882
commit
a777dc2abe
|
@ -58,6 +58,7 @@ namespace lldb {
|
|||
operator != (lldb::SBTypeNameSpecifier &rhs);
|
||||
|
||||
protected:
|
||||
friend class SBDebugger;
|
||||
friend class SBTypeCategory;
|
||||
|
||||
lldb::TypeNameSpecifierImplSP
|
||||
|
|
|
@ -70,6 +70,18 @@ public:
|
|||
static lldb::TypeSummaryImplSP
|
||||
GetSummaryFormat(ValueObject& valobj,
|
||||
lldb::DynamicValueType use_dynamic);
|
||||
|
||||
static lldb::TypeSummaryImplSP
|
||||
GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp);
|
||||
|
||||
static lldb::SyntheticChildrenSP
|
||||
GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp);
|
||||
|
||||
static lldb::TypeFilterImplSP
|
||||
GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp);
|
||||
|
||||
static lldb::TypeSyntheticImplSP
|
||||
GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp);
|
||||
|
||||
static lldb::SyntheticChildrenSP
|
||||
GetSyntheticChildren(ValueObject& valobj,
|
||||
|
|
|
@ -99,6 +99,54 @@ public:
|
|||
return RegexFilterNavigatorSP(m_regex_filter_nav);
|
||||
}
|
||||
|
||||
SummaryNavigator::MapValueType
|
||||
GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
|
||||
{
|
||||
SummaryNavigator::MapValueType retval;
|
||||
|
||||
if (type_sp)
|
||||
{
|
||||
if (type_sp->IsRegex())
|
||||
m_regex_summary_nav->GetExact(ConstString(type_sp->GetName()),retval);
|
||||
else
|
||||
m_summary_nav->GetExact(ConstString(type_sp->GetName()),retval);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
FilterNavigator::MapValueType
|
||||
GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
|
||||
{
|
||||
FilterNavigator::MapValueType retval;
|
||||
|
||||
if (type_sp)
|
||||
{
|
||||
if (type_sp->IsRegex())
|
||||
m_regex_filter_nav->GetExact(ConstString(type_sp->GetName()),retval);
|
||||
else
|
||||
m_filter_nav->GetExact(ConstString(type_sp->GetName()),retval);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
SynthNavigator::MapValueType
|
||||
GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
|
||||
{
|
||||
SynthNavigator::MapValueType retval;
|
||||
|
||||
if (type_sp)
|
||||
{
|
||||
if (type_sp->IsRegex())
|
||||
m_regex_synth_nav->GetExact(ConstString(type_sp->GetName()),retval);
|
||||
else
|
||||
m_synth_nav->GetExact(ConstString(type_sp->GetName()),retval);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
lldb::TypeNameSpecifierImplSP
|
||||
GetTypeNameSpecifierForSummaryAtIndex (uint32_t index)
|
||||
{
|
||||
|
@ -601,6 +649,18 @@ public:
|
|||
return m_categories_map.GetSummaryFormat(valobj, use_dynamic);
|
||||
}
|
||||
|
||||
lldb::TypeSummaryImplSP
|
||||
GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp);
|
||||
|
||||
lldb::TypeFilterImplSP
|
||||
GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp);
|
||||
|
||||
lldb::TypeSyntheticImplSP
|
||||
GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp);
|
||||
|
||||
lldb::SyntheticChildrenSP
|
||||
GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp);
|
||||
|
||||
lldb::SyntheticChildrenSP
|
||||
GetSyntheticChildren (ValueObject& valobj,
|
||||
lldb::DynamicValueType use_dynamic)
|
||||
|
|
|
@ -1146,75 +1146,27 @@ SBDebugger::GetFormatForType (SBTypeNameSpecifier type_name)
|
|||
SBTypeSummary
|
||||
SBDebugger::GetSummaryForType (SBTypeNameSpecifier type_name)
|
||||
{
|
||||
SBTypeSummary summary_chosen;
|
||||
uint32_t num_categories = GetNumCategories();
|
||||
SBTypeCategory category_sb;
|
||||
uint32_t prio_category = UINT32_MAX;
|
||||
for (uint32_t category_id = 0;
|
||||
category_id < num_categories;
|
||||
category_id++)
|
||||
{
|
||||
category_sb = GetCategoryAtIndex(category_id);
|
||||
if (category_sb.GetEnabled() == false)
|
||||
continue;
|
||||
SBTypeSummary summary_current = category_sb.GetSummaryForType(type_name);
|
||||
if (summary_current.IsValid() && (summary_chosen.IsValid() == false || (prio_category > category_sb.m_opaque_sp->GetEnabledPosition())))
|
||||
{
|
||||
prio_category = category_sb.m_opaque_sp->GetEnabledPosition();
|
||||
summary_chosen = summary_current;
|
||||
}
|
||||
}
|
||||
return summary_chosen;
|
||||
if (type_name.IsValid() == false)
|
||||
return SBTypeSummary();
|
||||
return SBTypeSummary(DataVisualization::GetSummaryForType(type_name.GetSP()));
|
||||
}
|
||||
#endif // LLDB_DISABLE_PYTHON
|
||||
|
||||
SBTypeFilter
|
||||
SBDebugger::GetFilterForType (SBTypeNameSpecifier type_name)
|
||||
{
|
||||
SBTypeFilter filter_chosen;
|
||||
uint32_t num_categories = GetNumCategories();
|
||||
SBTypeCategory category_sb;
|
||||
uint32_t prio_category = UINT32_MAX;
|
||||
for (uint32_t category_id = 0;
|
||||
category_id < num_categories;
|
||||
category_id++)
|
||||
{
|
||||
category_sb = GetCategoryAtIndex(category_id);
|
||||
if (category_sb.GetEnabled() == false)
|
||||
continue;
|
||||
SBTypeFilter filter_current = category_sb.GetFilterForType(type_name);
|
||||
if (filter_current.IsValid() && (filter_chosen.IsValid() == false || (prio_category > category_sb.m_opaque_sp->GetEnabledPosition())))
|
||||
{
|
||||
prio_category = category_sb.m_opaque_sp->GetEnabledPosition();
|
||||
filter_chosen = filter_current;
|
||||
}
|
||||
}
|
||||
return filter_chosen;
|
||||
if (type_name.IsValid() == false)
|
||||
return SBTypeFilter();
|
||||
return SBTypeFilter(DataVisualization::GetFilterForType(type_name.GetSP()));
|
||||
}
|
||||
|
||||
#ifndef LLDB_DISABLE_PYTHON
|
||||
SBTypeSynthetic
|
||||
SBDebugger::GetSyntheticForType (SBTypeNameSpecifier type_name)
|
||||
{
|
||||
SBTypeSynthetic synth_chosen;
|
||||
uint32_t num_categories = GetNumCategories();
|
||||
SBTypeCategory category_sb;
|
||||
uint32_t prio_category = UINT32_MAX;
|
||||
for (uint32_t category_id = 0;
|
||||
category_id < num_categories;
|
||||
category_id++)
|
||||
{
|
||||
category_sb = GetCategoryAtIndex(category_id);
|
||||
if (category_sb.GetEnabled() == false)
|
||||
continue;
|
||||
SBTypeSynthetic synth_current = category_sb.GetSyntheticForType(type_name);
|
||||
if (synth_current.IsValid() && (synth_chosen.IsValid() == false || (prio_category > category_sb.m_opaque_sp->GetEnabledPosition())))
|
||||
{
|
||||
prio_category = category_sb.m_opaque_sp->GetEnabledPosition();
|
||||
synth_chosen = synth_current;
|
||||
}
|
||||
}
|
||||
return synth_chosen;
|
||||
if (type_name.IsValid() == false)
|
||||
return SBTypeSynthetic();
|
||||
return SBTypeSynthetic(DataVisualization::GetSyntheticForType(type_name.GetSP()));
|
||||
}
|
||||
#endif // LLDB_DISABLE_PYTHON
|
||||
|
||||
|
|
|
@ -103,6 +103,12 @@ DataVisualization::GetSummaryFormat (ValueObject& valobj,
|
|||
return GetFormatManager().GetSummaryFormat(valobj, use_dynamic);
|
||||
}
|
||||
|
||||
lldb::TypeSummaryImplSP
|
||||
DataVisualization::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
|
||||
{
|
||||
return GetFormatManager().GetSummaryForType(type_sp);
|
||||
}
|
||||
|
||||
lldb::SyntheticChildrenSP
|
||||
DataVisualization::GetSyntheticChildren (ValueObject& valobj,
|
||||
lldb::DynamicValueType use_dynamic)
|
||||
|
@ -110,6 +116,24 @@ DataVisualization::GetSyntheticChildren (ValueObject& valobj,
|
|||
return GetFormatManager().GetSyntheticChildren(valobj, use_dynamic);
|
||||
}
|
||||
|
||||
lldb::SyntheticChildrenSP
|
||||
DataVisualization::GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp)
|
||||
{
|
||||
return GetFormatManager().GetSyntheticChildrenForType(type_sp);
|
||||
}
|
||||
|
||||
lldb::TypeFilterImplSP
|
||||
DataVisualization::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
|
||||
{
|
||||
return GetFormatManager().GetFilterForType(type_sp);
|
||||
}
|
||||
|
||||
lldb::TypeSyntheticImplSP
|
||||
DataVisualization::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
|
||||
{
|
||||
return GetFormatManager().GetSyntheticForType(type_sp);
|
||||
}
|
||||
|
||||
bool
|
||||
DataVisualization::AnyMatches (ConstString type_name,
|
||||
TypeCategoryImpl::FormatCategoryItems items,
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "lldb/lldb-private.h"
|
||||
#include "lldb/Core/ConnectionFileDescriptor.h"
|
||||
#include "lldb/Core/DataVisualization.h"
|
||||
#include "lldb/Core/FormatManager.h"
|
||||
#include "lldb/Core/InputReader.h"
|
||||
#include "lldb/Core/RegisterValue.h"
|
||||
|
@ -1215,6 +1216,7 @@ Debugger::FormatPrompt
|
|||
const char* first_unparsed;
|
||||
bool was_plain_var = false;
|
||||
bool was_var_format = false;
|
||||
bool was_var_indexed = false;
|
||||
|
||||
if (!valobj) break;
|
||||
// simplest case ${var}, just print valobj's value
|
||||
|
@ -1241,7 +1243,8 @@ Debugger::FormatPrompt
|
|||
// this is ${var.something} or multiple .something nested
|
||||
else if (::strncmp (var_name_begin, "var", strlen("var")) == 0)
|
||||
{
|
||||
|
||||
if (::strncmp(var_name_begin, "var[", strlen("var[")) == 0)
|
||||
was_var_indexed = true;
|
||||
const char* percent_position;
|
||||
ScanFormatDescriptor (var_name_begin,
|
||||
var_name_end,
|
||||
|
@ -1318,6 +1321,20 @@ Debugger::FormatPrompt
|
|||
do_deref_pointer = false;
|
||||
}
|
||||
|
||||
// <rdar://problem/11338654>
|
||||
// we do not want to use the summary for a bitfield of type T:n
|
||||
// if we were originally dealing with just a T - that would get
|
||||
// us into an endless recursion
|
||||
if (target->IsBitfield() && was_var_indexed)
|
||||
{
|
||||
// TODO: check for a (T:n)-specific summary - we should still obey that
|
||||
StreamString bitfield_name;
|
||||
bitfield_name.Printf("%s:%d", target->GetTypeName().AsCString(), target->GetBitfieldBitSize());
|
||||
lldb::TypeNameSpecifierImplSP type_sp(new TypeNameSpecifierImpl(bitfield_name.GetData(),false));
|
||||
if (!DataVisualization::GetSummaryForType(type_sp))
|
||||
val_obj_display = ValueObject::eValueObjectRepresentationStyleValue;
|
||||
}
|
||||
|
||||
// TODO use flags for these
|
||||
bool is_array = ClangASTContext::IsArrayType(target->GetClangType());
|
||||
bool is_pointer = ClangASTContext::IsPointerType(target->GetClangType());
|
||||
|
|
|
@ -445,6 +445,97 @@ CategoryMap::GetSummaryFormat (ValueObject& valobj,
|
|||
return lldb::TypeSummaryImplSP();
|
||||
}
|
||||
|
||||
lldb::TypeSummaryImplSP
|
||||
FormatManager::GetSummaryForType (lldb::TypeNameSpecifierImplSP type_sp)
|
||||
{
|
||||
if (!type_sp)
|
||||
return lldb::TypeSummaryImplSP();
|
||||
lldb::TypeSummaryImplSP summary_chosen_sp;
|
||||
uint32_t num_categories = m_categories_map.GetCount();
|
||||
lldb::TypeCategoryImplSP category_sp;
|
||||
uint32_t prio_category = UINT32_MAX;
|
||||
for (uint32_t category_id = 0;
|
||||
category_id < num_categories;
|
||||
category_id++)
|
||||
{
|
||||
category_sp = GetCategoryAtIndex(category_id);
|
||||
if (category_sp->IsEnabled() == false)
|
||||
continue;
|
||||
lldb::TypeSummaryImplSP summary_current_sp = category_sp->GetSummaryForType(type_sp);
|
||||
if (summary_current_sp && (summary_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
|
||||
{
|
||||
prio_category = category_sp->GetEnabledPosition();
|
||||
summary_chosen_sp = summary_current_sp;
|
||||
}
|
||||
}
|
||||
return summary_chosen_sp;
|
||||
}
|
||||
|
||||
lldb::TypeFilterImplSP
|
||||
FormatManager::GetFilterForType (lldb::TypeNameSpecifierImplSP type_sp)
|
||||
{
|
||||
if (!type_sp)
|
||||
return lldb::TypeFilterImplSP();
|
||||
lldb::TypeFilterImplSP filter_chosen_sp;
|
||||
uint32_t num_categories = m_categories_map.GetCount();
|
||||
lldb::TypeCategoryImplSP category_sp;
|
||||
uint32_t prio_category = UINT32_MAX;
|
||||
for (uint32_t category_id = 0;
|
||||
category_id < num_categories;
|
||||
category_id++)
|
||||
{
|
||||
category_sp = GetCategoryAtIndex(category_id);
|
||||
if (category_sp->IsEnabled() == false)
|
||||
continue;
|
||||
lldb::TypeFilterImplSP filter_current_sp((TypeFilterImpl*)category_sp->GetFilterForType(type_sp).get());
|
||||
if (filter_current_sp && (filter_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
|
||||
{
|
||||
prio_category = category_sp->GetEnabledPosition();
|
||||
filter_chosen_sp = filter_current_sp;
|
||||
}
|
||||
}
|
||||
return filter_chosen_sp;
|
||||
}
|
||||
|
||||
lldb::TypeSyntheticImplSP
|
||||
FormatManager::GetSyntheticForType (lldb::TypeNameSpecifierImplSP type_sp)
|
||||
{
|
||||
if (!type_sp)
|
||||
return lldb::TypeSyntheticImplSP();
|
||||
lldb::TypeSyntheticImplSP synth_chosen_sp;
|
||||
uint32_t num_categories = m_categories_map.GetCount();
|
||||
lldb::TypeCategoryImplSP category_sp;
|
||||
uint32_t prio_category = UINT32_MAX;
|
||||
for (uint32_t category_id = 0;
|
||||
category_id < num_categories;
|
||||
category_id++)
|
||||
{
|
||||
category_sp = GetCategoryAtIndex(category_id);
|
||||
if (category_sp->IsEnabled() == false)
|
||||
continue;
|
||||
lldb::TypeSyntheticImplSP synth_current_sp((TypeSyntheticImpl*)category_sp->GetSyntheticForType(type_sp).get());
|
||||
if (synth_current_sp && (synth_chosen_sp.get() == NULL || (prio_category > category_sp->GetEnabledPosition())))
|
||||
{
|
||||
prio_category = category_sp->GetEnabledPosition();
|
||||
synth_chosen_sp = synth_current_sp;
|
||||
}
|
||||
}
|
||||
return synth_chosen_sp;
|
||||
}
|
||||
|
||||
lldb::SyntheticChildrenSP
|
||||
FormatManager::GetSyntheticChildrenForType (lldb::TypeNameSpecifierImplSP type_sp)
|
||||
{
|
||||
if (!type_sp)
|
||||
return lldb::SyntheticChildrenSP();
|
||||
lldb::TypeFilterImplSP filter_sp = GetFilterForType(type_sp);
|
||||
lldb::TypeSyntheticImplSP synth_sp = GetSyntheticForType(type_sp);
|
||||
if (filter_sp->GetRevision() > synth_sp->GetRevision())
|
||||
return lldb::SyntheticChildrenSP(filter_sp.get());
|
||||
else
|
||||
return lldb::SyntheticChildrenSP(synth_sp.get());
|
||||
}
|
||||
|
||||
lldb::SyntheticChildrenSP
|
||||
CategoryMap::GetSyntheticChildren (ValueObject& valobj,
|
||||
lldb::DynamicValueType use_dynamic)
|
||||
|
|
|
@ -105,6 +105,11 @@ class AdvDataFormatterTestCase(TestBase):
|
|||
substrs = ['0x',
|
||||
'2'])
|
||||
|
||||
# check fix for <rdar://problem/11338654> LLDB crashes when using a "type summary" that uses bitfields with no format
|
||||
self.runCmd("type summary add --summary-string \"${var[0-1]}\" int")
|
||||
self.expect("frame variable iAmInt",
|
||||
substrs = ['9 1'])
|
||||
|
||||
self.expect("frame variable cool_array[3].floating",
|
||||
substrs = ['0x'])
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ struct VeryLong
|
|||
int main (int argc, const char * argv[])
|
||||
{
|
||||
|
||||
int iAmInt = 1;
|
||||
int iAmInt = 9;
|
||||
|
||||
i_am_cool cool_boy(1,0.5,3);
|
||||
i_am_cooler cooler_boy(1,2,0.1,0.2,'A','B');
|
||||
|
|
Loading…
Reference in New Issue