- If you download and build the sources in the Xcode project, x86_64 builds by default using the "llvm.zip" checkpointed LLVM. - If you delete the "lldb/llvm.zip" and the "lldb/llvm" folder, and build the Xcode project will download the right LLVM sources and build them from scratch - If you have a "lldb/llvm" folder already that contains a "lldb/llvm/lib" directory, we will use the sources you have placed in the LLDB directory. Python can now be disabled for platforms that don't support it. Changed the way the libllvmclang.a files get used. They now all get built into arch specific directories and never get merged into universal binaries as this was causing issues where you would have to go and delete the file if you wanted to build an extra architecture slice. llvm-svn: 143678
643 lines
24 KiB
C++
643 lines
24 KiB
C++
//===-- FormatManager.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/Core/FormatManager.h"
|
|
|
|
// C Includes
|
|
// C++ Includes
|
|
// Other libraries and framework includes
|
|
// Project includes
|
|
|
|
#include "lldb/Core/Debugger.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
|
|
|
|
struct FormatInfo
|
|
{
|
|
Format format;
|
|
const char format_char; // One or more format characters that can be used for this format.
|
|
const char *format_name; // Long format name that can be used to specify the current format
|
|
};
|
|
|
|
static FormatInfo
|
|
g_format_infos[] =
|
|
{
|
|
{ eFormatDefault , '\0' , "default" },
|
|
{ eFormatBoolean , 'B' , "boolean" },
|
|
{ eFormatBinary , 'b' , "binary" },
|
|
{ eFormatBytes , 'y' , "bytes" },
|
|
{ eFormatBytesWithASCII , 'Y' , "bytes with ASCII" },
|
|
{ eFormatChar , 'c' , "character" },
|
|
{ eFormatCharPrintable , 'C' , "printable character" },
|
|
{ eFormatComplexFloat , 'F' , "complex float" },
|
|
{ eFormatCString , 's' , "c-string" },
|
|
{ eFormatDecimal , 'd' , "decimal" },
|
|
{ eFormatEnum , 'E' , "enumeration" },
|
|
{ eFormatHex , 'x' , "hex" },
|
|
{ eFormatFloat , 'f' , "float" },
|
|
{ eFormatOctal , 'o' , "octal" },
|
|
{ eFormatOSType , 'O' , "OSType" },
|
|
{ eFormatUnicode16 , 'U' , "unicode16" },
|
|
{ eFormatUnicode32 , '\0' , "unicode32" },
|
|
{ eFormatUnsigned , 'u' , "unsigned decimal" },
|
|
{ eFormatPointer , 'p' , "pointer" },
|
|
{ eFormatVectorOfChar , '\0' , "char[]" },
|
|
{ eFormatVectorOfSInt8 , '\0' , "int8_t[]" },
|
|
{ eFormatVectorOfUInt8 , '\0' , "uint8_t[]" },
|
|
{ eFormatVectorOfSInt16 , '\0' , "int16_t[]" },
|
|
{ eFormatVectorOfUInt16 , '\0' , "uint16_t[]" },
|
|
{ eFormatVectorOfSInt32 , '\0' , "int32_t[]" },
|
|
{ eFormatVectorOfUInt32 , '\0' , "uint32_t[]" },
|
|
{ eFormatVectorOfSInt64 , '\0' , "int64_t[]" },
|
|
{ eFormatVectorOfUInt64 , '\0' , "uint64_t[]" },
|
|
{ eFormatVectorOfFloat32, '\0' , "float32[]" },
|
|
{ eFormatVectorOfFloat64, '\0' , "float64[]" },
|
|
{ eFormatVectorOfUInt128, '\0' , "uint128_t[]" },
|
|
{ eFormatComplexInteger , 'I' , "complex integer" },
|
|
{ eFormatCharArray , 'a' , "character array" },
|
|
{ eFormatAddressInfo , 'A' , "address" },
|
|
{ eFormatHexFloat , 'X' , "hex float" },
|
|
{ eFormatInstruction , 'i' , "instruction" }
|
|
};
|
|
|
|
static uint32_t
|
|
g_num_format_infos = sizeof(g_format_infos)/sizeof(FormatInfo);
|
|
|
|
static bool
|
|
GetFormatFromFormatChar (char format_char, Format &format)
|
|
{
|
|
for (uint32_t i=0; i<g_num_format_infos; ++i)
|
|
{
|
|
if (g_format_infos[i].format_char == format_char)
|
|
{
|
|
format = g_format_infos[i].format;
|
|
return true;
|
|
}
|
|
}
|
|
format = eFormatInvalid;
|
|
return false;
|
|
}
|
|
|
|
static bool
|
|
GetFormatFromFormatName (const char *format_name, bool partial_match_ok, Format &format)
|
|
{
|
|
uint32_t i;
|
|
for (i=0; i<g_num_format_infos; ++i)
|
|
{
|
|
if (strcasecmp (g_format_infos[i].format_name, format_name) == 0)
|
|
{
|
|
format = g_format_infos[i].format;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (partial_match_ok)
|
|
{
|
|
for (i=0; i<g_num_format_infos; ++i)
|
|
{
|
|
if (strcasestr (g_format_infos[i].format_name, format_name) == g_format_infos[i].format_name)
|
|
{
|
|
format = g_format_infos[i].format;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
format = eFormatInvalid;
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
FormatManager::GetFormatFromCString (const char *format_cstr,
|
|
bool partial_match_ok,
|
|
lldb::Format &format)
|
|
{
|
|
bool success = false;
|
|
if (format_cstr && format_cstr[0])
|
|
{
|
|
if (format_cstr[1] == '\0')
|
|
{
|
|
success = GetFormatFromFormatChar (format_cstr[0], format);
|
|
if (success)
|
|
return true;
|
|
}
|
|
|
|
success = GetFormatFromFormatName (format_cstr, partial_match_ok, format);
|
|
}
|
|
if (!success)
|
|
format = eFormatInvalid;
|
|
return success;
|
|
}
|
|
|
|
char
|
|
FormatManager::GetFormatAsFormatChar (lldb::Format format)
|
|
{
|
|
for (uint32_t i=0; i<g_num_format_infos; ++i)
|
|
{
|
|
if (g_format_infos[i].format == format)
|
|
return g_format_infos[i].format_char;
|
|
}
|
|
return '\0';
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
FormatManager::GetFormatAsCString (Format format)
|
|
{
|
|
if (format >= eFormatDefault && format < kNumFormats)
|
|
return g_format_infos[format].format_name;
|
|
return NULL;
|
|
}
|
|
|
|
FormatCategory::FormatCategory(IFormatChangeListener* clist,
|
|
std::string name) :
|
|
m_summary_nav(new SummaryNavigator("summary",clist)),
|
|
m_regex_summary_nav(new RegexSummaryNavigator("regex-summary",clist)),
|
|
m_filter_nav(new FilterNavigator("filter",clist)),
|
|
m_regex_filter_nav(new RegexFilterNavigator("regex-filter",clist)),
|
|
#ifndef LLDB_DISABLE_PYTHON
|
|
m_synth_nav(new SynthNavigator("synth",clist)),
|
|
m_regex_synth_nav(new RegexSynthNavigator("regex-synth",clist)),
|
|
#endif
|
|
m_enabled(false),
|
|
m_change_listener(clist),
|
|
m_mutex(Mutex::eMutexTypeRecursive),
|
|
m_name(name)
|
|
{}
|
|
|
|
bool
|
|
FormatCategory::Get (ValueObject& valobj,
|
|
lldb::SummaryFormatSP& entry,
|
|
lldb::DynamicValueType use_dynamic,
|
|
uint32_t* reason)
|
|
{
|
|
if (!IsEnabled())
|
|
return false;
|
|
if (GetSummaryNavigator()->Get(valobj, entry, use_dynamic, reason))
|
|
return true;
|
|
bool regex = GetRegexSummaryNavigator()->Get(valobj, entry, use_dynamic, reason);
|
|
if (regex && reason)
|
|
*reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionSummary;
|
|
return regex;
|
|
}
|
|
|
|
bool
|
|
FormatCategory::Get(ValueObject& valobj,
|
|
lldb::SyntheticChildrenSP& entry_sp,
|
|
lldb::DynamicValueType use_dynamic,
|
|
uint32_t* reason)
|
|
{
|
|
if (!IsEnabled())
|
|
return false;
|
|
SyntheticFilter::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 (!GetFilterNavigator()->Get(valobj, filter_sp, use_dynamic, &reason_filter))
|
|
regex_filter = GetRegexFilterNavigator()->Get (valobj, filter_sp, use_dynamic, &reason_filter);
|
|
|
|
#ifndef LLDB_DISABLE_PYTHON
|
|
bool regex_synth = false;
|
|
uint32_t reason_synth = 0;
|
|
bool pick_synth = false;
|
|
SyntheticScriptProvider::SharedPointer synth;
|
|
if (!GetSyntheticNavigator()->Get(valobj, synth, use_dynamic, &reason_synth))
|
|
regex_synth = GetRegexSyntheticNavigator()->Get (valobj, synth, use_dynamic, &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->m_my_revision > synth->m_my_revision)
|
|
pick_synth = false;
|
|
else
|
|
pick_synth = true;
|
|
}
|
|
if (pick_synth)
|
|
{
|
|
if (regex_synth && reason)
|
|
*reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
|
|
entry_sp = synth;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
if (regex_filter && reason)
|
|
*reason |= lldb_private::eFormatterChoiceCriterionRegularExpressionFilter;
|
|
entry_sp = filter_sp;
|
|
return true;
|
|
}
|
|
|
|
#else
|
|
if (filter_sp)
|
|
{
|
|
entry_sp = filter_sp;
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
void
|
|
FormatCategory::Clear (FormatCategoryItems items)
|
|
{
|
|
if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
|
|
m_summary_nav->Clear();
|
|
if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
|
|
m_regex_summary_nav->Clear();
|
|
if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
|
|
m_filter_nav->Clear();
|
|
if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
|
|
m_regex_filter_nav->Clear();
|
|
#ifndef LLDB_DISABLE_PYTHON
|
|
if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
|
|
m_synth_nav->Clear();
|
|
if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
|
|
m_regex_synth_nav->Clear();
|
|
#endif
|
|
}
|
|
|
|
bool
|
|
FormatCategory::Delete (ConstString name,
|
|
FormatCategoryItems items)
|
|
{
|
|
bool success = false;
|
|
if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
|
|
success = m_summary_nav->Delete(name) || success;
|
|
if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
|
|
success = m_regex_summary_nav->Delete(name) || success;
|
|
if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
|
|
success = m_filter_nav->Delete(name) || success;
|
|
if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
|
|
success = m_regex_filter_nav->Delete(name) || success;
|
|
#ifndef LLDB_DISABLE_PYTHON
|
|
if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
|
|
success = m_synth_nav->Delete(name) || success;
|
|
if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
|
|
success = m_regex_synth_nav->Delete(name) || success;
|
|
#endif
|
|
return success;
|
|
}
|
|
|
|
uint32_t
|
|
FormatCategory::GetCount (FormatCategoryItems items)
|
|
{
|
|
uint32_t count = 0;
|
|
if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
|
|
count += m_summary_nav->GetCount();
|
|
if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
|
|
count += m_regex_summary_nav->GetCount();
|
|
if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
|
|
count += m_filter_nav->GetCount();
|
|
if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
|
|
count += m_regex_filter_nav->GetCount();
|
|
#ifndef LLDB_DISABLE_PYTHON
|
|
if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
|
|
count += m_synth_nav->GetCount();
|
|
if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
|
|
count += m_regex_synth_nav->GetCount();
|
|
#endif
|
|
return count;
|
|
}
|
|
|
|
bool
|
|
FormatCategory::AnyMatches(ConstString type_name,
|
|
FormatCategoryItems items,
|
|
bool only_enabled,
|
|
const char** matching_category,
|
|
FormatCategoryItems* matching_type)
|
|
{
|
|
if (!IsEnabled() && only_enabled)
|
|
return false;
|
|
|
|
lldb::SummaryFormatSP summary;
|
|
SyntheticFilter::SharedPointer filter;
|
|
#ifndef LLDB_DISABLE_PYTHON
|
|
SyntheticScriptProvider::SharedPointer synth;
|
|
#endif
|
|
|
|
if ( (items & eFormatCategoryItemSummary) == eFormatCategoryItemSummary )
|
|
{
|
|
if (m_summary_nav->Get(type_name, summary))
|
|
{
|
|
if (matching_category)
|
|
*matching_category = m_name.c_str();
|
|
if (matching_type)
|
|
*matching_type = eFormatCategoryItemSummary;
|
|
return true;
|
|
}
|
|
}
|
|
if ( (items & eFormatCategoryItemRegexSummary) == eFormatCategoryItemRegexSummary )
|
|
{
|
|
if (m_regex_summary_nav->Get(type_name, summary))
|
|
{
|
|
if (matching_category)
|
|
*matching_category = m_name.c_str();
|
|
if (matching_type)
|
|
*matching_type = eFormatCategoryItemRegexSummary;
|
|
return true;
|
|
}
|
|
}
|
|
if ( (items & eFormatCategoryItemFilter) == eFormatCategoryItemFilter )
|
|
{
|
|
if (m_filter_nav->Get(type_name, filter))
|
|
{
|
|
if (matching_category)
|
|
*matching_category = m_name.c_str();
|
|
if (matching_type)
|
|
*matching_type = eFormatCategoryItemFilter;
|
|
return true;
|
|
}
|
|
}
|
|
if ( (items & eFormatCategoryItemRegexFilter) == eFormatCategoryItemRegexFilter )
|
|
{
|
|
if (m_regex_filter_nav->Get(type_name, filter))
|
|
{
|
|
if (matching_category)
|
|
*matching_category = m_name.c_str();
|
|
if (matching_type)
|
|
*matching_type = eFormatCategoryItemRegexFilter;
|
|
return true;
|
|
}
|
|
}
|
|
#ifndef LLDB_DISABLE_PYTHON
|
|
if ( (items & eFormatCategoryItemSynth) == eFormatCategoryItemSynth )
|
|
{
|
|
if (m_synth_nav->Get(type_name, synth))
|
|
{
|
|
if (matching_category)
|
|
*matching_category = m_name.c_str();
|
|
if (matching_type)
|
|
*matching_type = eFormatCategoryItemSynth;
|
|
return true;
|
|
}
|
|
}
|
|
if ( (items & eFormatCategoryItemRegexSynth) == eFormatCategoryItemRegexSynth )
|
|
{
|
|
if (m_regex_synth_nav->Get(type_name, synth))
|
|
{
|
|
if (matching_category)
|
|
*matching_category = m_name.c_str();
|
|
if (matching_type)
|
|
*matching_type = eFormatCategoryItemRegexSynth;
|
|
return true;
|
|
}
|
|
}
|
|
#endif
|
|
return false;
|
|
}
|
|
|
|
bool
|
|
CategoryMap::AnyMatches (ConstString type_name,
|
|
FormatCategory::FormatCategoryItems items,
|
|
bool only_enabled,
|
|
const char** matching_category,
|
|
FormatCategory::FormatCategoryItems* matching_type)
|
|
{
|
|
Mutex::Locker(m_map_mutex);
|
|
|
|
MapIterator pos, end = m_map.end();
|
|
for (pos = m_map.begin(); pos != end; pos++)
|
|
{
|
|
if (pos->second->AnyMatches(type_name,
|
|
items,
|
|
only_enabled,
|
|
matching_category,
|
|
matching_type))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
lldb::SummaryFormatSP
|
|
CategoryMap::GetSummaryFormat (ValueObject& valobj,
|
|
lldb::DynamicValueType use_dynamic)
|
|
{
|
|
Mutex::Locker(m_map_mutex);
|
|
|
|
uint32_t reason_why;
|
|
ActiveCategoriesIterator begin, end = m_active_categories.end();
|
|
|
|
for (begin = m_active_categories.begin(); begin != end; begin++)
|
|
{
|
|
lldb::FormatCategorySP category = *begin;
|
|
lldb::SummaryFormatSP current_format;
|
|
if (!category->Get(valobj, current_format, use_dynamic, &reason_why))
|
|
continue;
|
|
return current_format;
|
|
}
|
|
return lldb::SummaryFormatSP();
|
|
}
|
|
|
|
lldb::SyntheticChildrenSP
|
|
CategoryMap::GetSyntheticChildren (ValueObject& valobj,
|
|
lldb::DynamicValueType use_dynamic)
|
|
{
|
|
Mutex::Locker(m_map_mutex);
|
|
|
|
uint32_t reason_why;
|
|
|
|
ActiveCategoriesIterator begin, end = m_active_categories.end();
|
|
|
|
for (begin = m_active_categories.begin(); begin != end; begin++)
|
|
{
|
|
lldb::FormatCategorySP category = *begin;
|
|
lldb::SyntheticChildrenSP current_format;
|
|
if (!category->Get(valobj, current_format, use_dynamic, &reason_why))
|
|
continue;
|
|
return current_format;
|
|
}
|
|
return lldb::SyntheticChildrenSP();
|
|
}
|
|
|
|
void
|
|
CategoryMap::LoopThrough(CallbackType callback, void* param)
|
|
{
|
|
if (callback)
|
|
{
|
|
Mutex::Locker(m_map_mutex);
|
|
|
|
// loop through enabled categories in respective order
|
|
{
|
|
ActiveCategoriesIterator begin, end = m_active_categories.end();
|
|
for (begin = m_active_categories.begin(); begin != end; begin++)
|
|
{
|
|
lldb::FormatCategorySP category = *begin;
|
|
ConstString type = ConstString(category->GetName().c_str());
|
|
if (!callback(param, category))
|
|
break;
|
|
}
|
|
}
|
|
|
|
// loop through disabled categories in just any order
|
|
{
|
|
MapIterator pos, end = m_map.end();
|
|
for (pos = m_map.begin(); pos != end; pos++)
|
|
{
|
|
if (pos->second->IsEnabled())
|
|
continue;
|
|
KeyType type = pos->first;
|
|
if (!callback(param, pos->second))
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
lldb::FormatCategorySP
|
|
FormatManager::GetCategory (const ConstString& category_name,
|
|
bool can_create)
|
|
{
|
|
if (!category_name)
|
|
return GetCategory(m_default_category_name);
|
|
lldb::FormatCategorySP category;
|
|
if (m_categories_map.Get(category_name, category))
|
|
return category;
|
|
|
|
if (!can_create)
|
|
return lldb::FormatCategorySP();
|
|
|
|
m_categories_map.Add(category_name,lldb::FormatCategorySP(new FormatCategory(this, category_name.AsCString())));
|
|
return GetCategory(category_name);
|
|
}
|
|
|
|
lldb::Format
|
|
FormatManager::GetSingleItemFormat(lldb::Format vector_format)
|
|
{
|
|
switch(vector_format)
|
|
{
|
|
case eFormatVectorOfChar:
|
|
return eFormatCharArray;
|
|
|
|
case eFormatVectorOfSInt8:
|
|
case eFormatVectorOfSInt16:
|
|
case eFormatVectorOfSInt32:
|
|
case eFormatVectorOfSInt64:
|
|
return eFormatDecimal;
|
|
|
|
case eFormatVectorOfUInt8:
|
|
case eFormatVectorOfUInt16:
|
|
case eFormatVectorOfUInt32:
|
|
case eFormatVectorOfUInt64:
|
|
case eFormatVectorOfUInt128:
|
|
return eFormatHex;
|
|
|
|
case eFormatVectorOfFloat32:
|
|
case eFormatVectorOfFloat64:
|
|
return eFormatFloat;
|
|
|
|
default:
|
|
return lldb::eFormatInvalid;
|
|
}
|
|
}
|
|
|
|
ConstString
|
|
FormatManager::GetValidTypeName (const ConstString& type)
|
|
{
|
|
return ::GetValidTypeName_Impl(type);
|
|
}
|
|
|
|
FormatManager::FormatManager() :
|
|
m_value_nav("format",this),
|
|
m_named_summaries_map(this),
|
|
m_last_revision(0),
|
|
m_categories_map(this),
|
|
m_default_category_name(ConstString("default")),
|
|
m_system_category_name(ConstString("system")),
|
|
m_gnu_cpp_category_name(ConstString("gnu-libstdc++"))
|
|
{
|
|
|
|
// add some default stuff
|
|
// most formats, summaries, ... actually belong to the users' lldbinit file rather than here
|
|
lldb::SummaryFormatSP string_format(new StringSummaryFormat(false,
|
|
true,
|
|
false,
|
|
true,
|
|
false,
|
|
false,
|
|
"${var%s}"));
|
|
|
|
|
|
lldb::SummaryFormatSP string_array_format(new StringSummaryFormat(false,
|
|
true,
|
|
false,
|
|
false,
|
|
false,
|
|
false,
|
|
"${var%s}"));
|
|
|
|
lldb::RegularExpressionSP any_size_char_arr(new RegularExpression("char \\[[0-9]+\\]"));
|
|
|
|
|
|
FormatCategory::SharedPointer sys_category_sp = GetCategory(m_system_category_name);
|
|
|
|
sys_category_sp->GetSummaryNavigator()->Add(ConstString("char *"), string_format);
|
|
sys_category_sp->GetSummaryNavigator()->Add(ConstString("const char *"), string_format);
|
|
sys_category_sp->GetRegexSummaryNavigator()->Add(any_size_char_arr, string_array_format);
|
|
|
|
GetCategory(m_default_category_name); // this call is there to force LLDB into creating an empty "default" category
|
|
|
|
// WARNING: temporary code!!
|
|
// The platform should be responsible for initializing its own formatters
|
|
// (e.g. to handle versioning, different runtime libraries, ...)
|
|
// Currently, basic formatters for std:: objects as implemented by
|
|
// the GNU libstdc++ are defined regardless, and enabled by default
|
|
// This is going to be moved to some platform-dependent location
|
|
// (in the meanwhile, these formatters should work for Mac OS X & Linux)
|
|
lldb::SummaryFormatSP std_string_summary_sp(new StringSummaryFormat(true,
|
|
false,
|
|
false,
|
|
true,
|
|
true,
|
|
false,
|
|
"${var._M_dataplus._M_p}"));
|
|
|
|
FormatCategory::SharedPointer gnu_category_sp = GetCategory(m_gnu_cpp_category_name);
|
|
|
|
gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::string"),
|
|
std_string_summary_sp);
|
|
gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::basic_string<char>"),
|
|
std_string_summary_sp);
|
|
gnu_category_sp->GetSummaryNavigator()->Add(ConstString("std::basic_string<char,std::char_traits<char>,std::allocator<char> >"),
|
|
std_string_summary_sp);
|
|
|
|
#ifndef LLDB_DISABLE_PYTHON
|
|
gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?vector<.+>$")),
|
|
SyntheticChildrenSP(new SyntheticScriptProvider(true,
|
|
false,
|
|
false,
|
|
"gnu_libstdcpp.StdVectorSynthProvider")));
|
|
gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?map<.+> >$")),
|
|
SyntheticChildrenSP(new SyntheticScriptProvider(true,
|
|
false,
|
|
false,
|
|
"gnu_libstdcpp.StdMapSynthProvider")));
|
|
gnu_category_sp->GetRegexSyntheticNavigator()->Add(RegularExpressionSP(new RegularExpression("^(std::)?list<.+>$")),
|
|
SyntheticChildrenSP(new SyntheticScriptProvider(true,
|
|
false,
|
|
false,
|
|
"gnu_libstdcpp.StdListSynthProvider")));
|
|
#endif
|
|
// DO NOT change the order of these calls, unless you WANT a change in the priority of these categories
|
|
EnableCategory(m_system_category_name);
|
|
EnableCategory(m_gnu_cpp_category_name);
|
|
EnableCategory(m_default_category_name);
|
|
|
|
}
|