mirror of
https://github.com/intel/llvm.git
synced 2026-01-17 23:45:25 +08:00
The "systemwide summaries" feature has been removed and replaced with a more general and powerful mechanism. Categories: - summaries can now be grouped into buckets, called "categories" (it is expected that categories correspond to libraries and/or runtime environments) - to add a summary to a category, you can use the -w option to type summary add and give a category name (e.g. type summary add -f "foo" foo_t -w foo_category) - categories are by default disabled, which means LLDB will not look into them for summaries, to enable a category use "type category enable". once a category is enabled, LLDB will look into that category for summaries. the rules are quite trivial: every enabled category is searched for an exact match. if an exact match is nowhere to be found, any match is searched for in every enabled category (whether it involves cascading, going to base classes, ...). categories are searched into the order in which they were enabled (the most recently enabled category first, then the second most and so on..) - by default, most commands that deal with summaries, use a category named "default" if no explicit -w parameter is given (the observable behavior of LLDB should not change when categories are not explicitly used) - the systemwide summaries are now part of a "system" category llvm-svn: 135463
295 lines
8.7 KiB
C++
295 lines
8.7 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 , 'i' , "signed 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" }
|
|
};
|
|
|
|
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;
|
|
}
|
|
|
|
template<>
|
|
bool
|
|
FormatNavigator<lldb::RegularExpressionSP, SummaryFormat>::Get(const char* key, SummaryFormat::SharedPointer& value)
|
|
{
|
|
Mutex::Locker(m_format_map.mutex());
|
|
MapIterator pos, end = m_format_map.map().end();
|
|
for (pos = m_format_map.map().begin(); pos != end; pos++)
|
|
{
|
|
lldb::RegularExpressionSP regex = pos->first;
|
|
if (regex->Execute(key))
|
|
{
|
|
value = pos->second;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
template<>
|
|
bool
|
|
FormatNavigator<lldb::RegularExpressionSP, SummaryFormat>::Delete(const char* type)
|
|
{
|
|
Mutex::Locker(m_format_map.mutex());
|
|
MapIterator pos, end = m_format_map.map().end();
|
|
for (pos = m_format_map.map().begin(); pos != end; pos++)
|
|
{
|
|
lldb::RegularExpressionSP regex = pos->first;
|
|
if ( ::strcmp(type,regex->GetText()) == 0)
|
|
{
|
|
m_format_map.map().erase(pos);
|
|
if(m_format_map.listener)
|
|
m_format_map.listener->Changed();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
std::string
|
|
StringSummaryFormat::FormatObject(lldb::ValueObjectSP object)
|
|
{
|
|
if (!object.get())
|
|
return "NULL";
|
|
|
|
StreamString s;
|
|
ExecutionContext exe_ctx;
|
|
object->GetExecutionContextScope()->CalculateExecutionContext(exe_ctx);
|
|
SymbolContext sc;
|
|
if (exe_ctx.frame)
|
|
sc = exe_ctx.frame->GetSymbolContext(lldb::eSymbolContextEverything);
|
|
|
|
if (m_show_members_oneliner)
|
|
{
|
|
const uint32_t num_children = object->GetNumChildren();
|
|
if (num_children)
|
|
{
|
|
s.PutChar('(');
|
|
|
|
for (uint32_t idx=0; idx<num_children; ++idx)
|
|
{
|
|
lldb::ValueObjectSP child_sp(object->GetChildAtIndex(idx, true));
|
|
if (child_sp.get())
|
|
{
|
|
if (idx)
|
|
s.PutCString(", ");
|
|
s.PutCString(child_sp.get()->GetName().AsCString());
|
|
s.PutChar('=');
|
|
s.PutCString(child_sp.get()->GetPrintableRepresentation());
|
|
}
|
|
}
|
|
|
|
s.PutChar(')');
|
|
|
|
return s.GetString();
|
|
}
|
|
else
|
|
return "";
|
|
|
|
}
|
|
else
|
|
{
|
|
if (Debugger::FormatPrompt(m_format.c_str(), &sc, &exe_ctx, &sc.line_entry.range.GetBaseAddress(), s, NULL, object.get()))
|
|
return s.GetString();
|
|
else
|
|
return "";
|
|
}
|
|
}
|
|
|
|
void
|
|
FormatCategory::ChooseAsPreferential(const char* name)
|
|
{
|
|
Mutex::Locker(m_mutex);
|
|
lldb::SummaryFormatSP format;
|
|
|
|
uint32_t revision = Debugger::Formatting::ValueFormats::GetCurrentRevision();
|
|
|
|
if ( Summary()->Get(name, format) )
|
|
format->SetPriority(revision);
|
|
|
|
format.reset();
|
|
|
|
if ( RegexSummary()->Get(name, format) )
|
|
format->SetPriority(revision);
|
|
|
|
if(m_change_listener)
|
|
m_change_listener->Changed();
|
|
|
|
}
|