Allow the language plugins a say in how the function name is rendered as part of frame formatting

llvm-svn: 253531
This commit is contained in:
Enrico Granata 2015-11-19 01:11:53 +00:00
parent 4029426b17
commit d4129b47d0
3 changed files with 226 additions and 144 deletions

View File

@ -32,7 +32,6 @@ class Language :
public PluginInterface public PluginInterface
{ {
public: public:
class TypeScavenger class TypeScavenger
{ {
public: public:
@ -67,6 +66,13 @@ public:
const char *key, const char *key,
ResultSet &results) = 0; ResultSet &results) = 0;
}; };
enum class FunctionNameRepresentation
{
eName,
eNameWithArgs,
eNameWithNoArgs
};
~Language() override; ~Language() override;
@ -134,6 +140,11 @@ public:
virtual bool virtual bool
IsUninitializedReference (ValueObject& valobj); IsUninitializedReference (ValueObject& valobj);
virtual bool
GetFunctionDisplayName (const SymbolContext *sc,
FunctionNameRepresentation representation,
Stream& s);
// These are accessors for general information about the Languages lldb knows about: // These are accessors for general information about the Languages lldb knows about:
static lldb::LanguageType static lldb::LanguageType

View File

@ -1653,201 +1653,264 @@ FormatEntity::Format (const Entry &entry,
case Entry::Type::FunctionName: case Entry::Type::FunctionName:
{ {
const char *name = NULL; Language *language_plugin = nullptr;
bool language_plugin_handled = false;
StreamString ss;
if (sc->function) if (sc->function)
name = sc->function->GetName().AsCString (NULL); language_plugin = Language::FindPlugin(sc->function->GetLanguage());
else if (sc->symbol) else if (sc->symbol)
name = sc->symbol->GetName().AsCString (NULL); language_plugin = Language::FindPlugin(sc->symbol->GetLanguage());
if (name) if (language_plugin)
{ {
s.PutCString(name); language_plugin_handled = language_plugin->GetFunctionDisplayName(sc,
Language::FunctionNameRepresentation::eName,
if (sc->block) ss);
}
if (language_plugin_handled)
{
s.PutCString(ss.GetData());
return true;
}
else
{
const char *name = NULL;
if (sc->function)
name = sc->function->GetName().AsCString (NULL);
else if (sc->symbol)
name = sc->symbol->GetName().AsCString (NULL);
if (name)
{ {
Block *inline_block = sc->block->GetContainingInlinedBlock (); s.PutCString(name);
if (inline_block)
if (sc->block)
{ {
const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo(); Block *inline_block = sc->block->GetContainingInlinedBlock ();
if (inline_info) if (inline_block)
{ {
s.PutCString(" [inlined] "); const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo();
inline_info->GetName(sc->function->GetLanguage()).Dump(&s); if (inline_info)
{
s.PutCString(" [inlined] ");
inline_info->GetName(sc->function->GetLanguage()).Dump(&s);
}
} }
} }
return true;
} }
return true;
} }
} }
return false; return false;
case Entry::Type::FunctionNameNoArgs: case Entry::Type::FunctionNameNoArgs:
{ {
ConstString name; Language *language_plugin = nullptr;
bool language_plugin_handled = false;
StreamString ss;
if (sc->function) if (sc->function)
name = sc->function->GetNameNoArguments(); language_plugin = Language::FindPlugin(sc->function->GetLanguage());
else if (sc->symbol) else if (sc->symbol)
name = sc->symbol->GetNameNoArguments(); language_plugin = Language::FindPlugin(sc->symbol->GetLanguage());
if (name) if (language_plugin)
{ {
s.PutCString(name.GetCString()); language_plugin_handled = language_plugin->GetFunctionDisplayName(sc,
Language::FunctionNameRepresentation::eNameWithNoArgs,
ss);
}
if (language_plugin_handled)
{
s.PutCString(ss.GetData());
return true; return true;
} }
else
{
ConstString name;
if (sc->function)
name = sc->function->GetNameNoArguments();
else if (sc->symbol)
name = sc->symbol->GetNameNoArguments();
if (name)
{
s.PutCString(name.GetCString());
return true;
}
}
} }
return false; return false;
case Entry::Type::FunctionNameWithArgs: case Entry::Type::FunctionNameWithArgs:
{ {
// Print the function name with arguments in it Language *language_plugin = nullptr;
bool language_plugin_handled = false;
StreamString ss;
if (sc->function) if (sc->function)
language_plugin = Language::FindPlugin(sc->function->GetLanguage());
else if (sc->symbol)
language_plugin = Language::FindPlugin(sc->symbol->GetLanguage());
if (language_plugin)
{ {
ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL; language_plugin_handled = language_plugin->GetFunctionDisplayName(sc,
const char *cstr = sc->function->GetName().AsCString (NULL); Language::FunctionNameRepresentation::eNameWithArgs,
if (cstr) ss);
}
if (language_plugin_handled)
{
s.PutCString(ss.GetData());
return true;
}
else
{
// Print the function name with arguments in it
if (sc->function)
{ {
const InlineFunctionInfo *inline_info = NULL; ExecutionContextScope *exe_scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL;
VariableListSP variable_list_sp; const char *cstr = sc->function->GetName().AsCString (NULL);
bool get_function_vars = true; if (cstr)
if (sc->block)
{ {
Block *inline_block = sc->block->GetContainingInlinedBlock (); const InlineFunctionInfo *inline_info = NULL;
VariableListSP variable_list_sp;
if (inline_block) bool get_function_vars = true;
if (sc->block)
{ {
get_function_vars = false; Block *inline_block = sc->block->GetContainingInlinedBlock ();
inline_info = sc->block->GetInlinedFunctionInfo();
if (inline_info) if (inline_block)
variable_list_sp = inline_block->GetBlockVariableList (true);
}
}
if (get_function_vars)
{
variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
}
if (inline_info)
{
s.PutCString (cstr);
s.PutCString (" [inlined] ");
cstr = inline_info->GetName(sc->function->GetLanguage()).GetCString();
}
VariableList args;
if (variable_list_sp)
variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
if (args.GetSize() > 0)
{
const char *open_paren = strchr (cstr, '(');
const char *close_paren = nullptr;
const char *generic = strchr(cstr, '<');
// if before the arguments list begins there is a template sign
// then scan to the end of the generic args before you try to find
// the arguments list
if (generic && open_paren && generic < open_paren)
{
int generic_depth = 1;
++generic;
for (;
*generic && generic_depth > 0;
generic++)
{ {
if (*generic == '<') get_function_vars = false;
generic_depth++; inline_info = sc->block->GetInlinedFunctionInfo();
if (*generic == '>') if (inline_info)
generic_depth--; variable_list_sp = inline_block->GetBlockVariableList (true);
} }
if (*generic)
open_paren = strchr(generic, '(');
else
open_paren = nullptr;
} }
if (open_paren)
if (get_function_vars)
{ {
if (IsToken (open_paren, "(anonymous namespace)")) variable_list_sp = sc->function->GetBlock(true).GetBlockVariableList (true);
{
open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
if (open_paren)
close_paren = strchr (open_paren, ')');
}
else
close_paren = strchr (open_paren, ')');
} }
if (open_paren) if (inline_info)
s.Write(cstr, open_paren - cstr + 1);
else
{ {
s.PutCString (cstr); s.PutCString (cstr);
s.PutChar ('('); s.PutCString (" [inlined] ");
cstr = inline_info->GetName(sc->function->GetLanguage()).GetCString();
} }
const size_t num_args = args.GetSize();
for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx) VariableList args;
if (variable_list_sp)
variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, args);
if (args.GetSize() > 0)
{ {
std::string buffer; const char *open_paren = strchr (cstr, '(');
const char *close_paren = nullptr;
VariableSP var_sp (args.GetVariableAtIndex (arg_idx)); const char *generic = strchr(cstr, '<');
ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp)); // if before the arguments list begins there is a template sign
StreamString ss; // then scan to the end of the generic args before you try to find
const char *var_representation = nullptr; // the arguments list
const char *var_name = var_value_sp->GetName().GetCString(); if (generic && open_paren && generic < open_paren)
if (var_value_sp->GetCompilerType().IsValid())
{ {
if (var_value_sp && exe_scope->CalculateTarget()) int generic_depth = 1;
var_value_sp = var_value_sp->GetQualifiedRepresentationIfAvailable(exe_scope->CalculateTarget()->TargetProperties::GetPreferDynamicValue(), ++generic;
exe_scope->CalculateTarget()->TargetProperties::GetEnableSyntheticValue()); for (;
if (var_value_sp->GetCompilerType().IsAggregateType() && *generic && generic_depth > 0;
DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get())) generic++)
{ {
static StringSummaryFormat format(TypeSummaryImpl::Flags() if (*generic == '<')
.SetHideItemNames(false) generic_depth++;
.SetShowMembersOneLiner(true), if (*generic == '>')
""); generic_depth--;
format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions()); }
var_representation = buffer.c_str(); if (*generic)
open_paren = strchr(generic, '(');
else
open_paren = nullptr;
}
if (open_paren)
{
if (IsToken (open_paren, "(anonymous namespace)"))
{
open_paren = strchr (open_paren + strlen("(anonymous namespace)"), '(');
if (open_paren)
close_paren = strchr (open_paren, ')');
} }
else else
var_value_sp->DumpPrintableRepresentation(ss, close_paren = strchr (open_paren, ')');
ValueObject::ValueObjectRepresentationStyle::eValueObjectRepresentationStyleSummary,
eFormatDefault,
ValueObject::PrintableRepresentationSpecialCases::ePrintableRepresentationSpecialCasesAllow,
false);
} }
if (ss.GetData() && ss.GetSize()) if (open_paren)
var_representation = ss.GetData(); s.Write(cstr, open_paren - cstr + 1);
if (arg_idx > 0)
s.PutCString (", ");
if (var_value_sp->GetError().Success())
{
if (var_representation)
s.Printf ("%s=%s", var_name, var_representation);
else
s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
}
else else
s.Printf ("%s=<unavailable>", var_name); {
s.PutCString (cstr);
s.PutChar ('(');
}
const size_t num_args = args.GetSize();
for (size_t arg_idx = 0; arg_idx < num_args; ++arg_idx)
{
std::string buffer;
VariableSP var_sp (args.GetVariableAtIndex (arg_idx));
ValueObjectSP var_value_sp (ValueObjectVariable::Create (exe_scope, var_sp));
StreamString ss;
const char *var_representation = nullptr;
const char *var_name = var_value_sp->GetName().GetCString();
if (var_value_sp->GetCompilerType().IsValid())
{
if (var_value_sp && exe_scope->CalculateTarget())
var_value_sp = var_value_sp->GetQualifiedRepresentationIfAvailable(exe_scope->CalculateTarget()->TargetProperties::GetPreferDynamicValue(),
exe_scope->CalculateTarget()->TargetProperties::GetEnableSyntheticValue());
if (var_value_sp->GetCompilerType().IsAggregateType() &&
DataVisualization::ShouldPrintAsOneLiner(*var_value_sp.get()))
{
static StringSummaryFormat format(TypeSummaryImpl::Flags()
.SetHideItemNames(false)
.SetShowMembersOneLiner(true),
"");
format.FormatObject(var_value_sp.get(), buffer, TypeSummaryOptions());
var_representation = buffer.c_str();
}
else
var_value_sp->DumpPrintableRepresentation(ss,
ValueObject::ValueObjectRepresentationStyle::eValueObjectRepresentationStyleSummary,
eFormatDefault,
ValueObject::PrintableRepresentationSpecialCases::ePrintableRepresentationSpecialCasesAllow,
false);
}
if (ss.GetData() && ss.GetSize())
var_representation = ss.GetData();
if (arg_idx > 0)
s.PutCString (", ");
if (var_value_sp->GetError().Success())
{
if (var_representation)
s.Printf ("%s=%s", var_name, var_representation);
else
s.Printf ("%s=%s at %s", var_name, var_value_sp->GetTypeName().GetCString(), var_value_sp->GetLocationAsCString());
}
else
s.Printf ("%s=<unavailable>", var_name);
}
if (close_paren)
s.PutCString (close_paren);
else
s.PutChar(')');
} }
if (close_paren)
s.PutCString (close_paren);
else else
s.PutChar(')'); {
s.PutCString(cstr);
}
return true;
} }
else }
else if (sc->symbol)
{
const char *cstr = sc->symbol->GetName().AsCString (NULL);
if (cstr)
{ {
s.PutCString(cstr); s.PutCString(cstr);
return true;
} }
return true;
}
}
else if (sc->symbol)
{
const char *cstr = sc->symbol->GetName().AsCString (NULL);
if (cstr)
{
s.PutCString(cstr);
return true;
} }
} }
} }

View File

@ -370,6 +370,14 @@ Language::IsUninitializedReference (ValueObject& valobj)
return false; return false;
} }
bool
Language::GetFunctionDisplayName (const SymbolContext *sc,
FunctionNameRepresentation representation,
Stream& s)
{
return false;
}
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Constructor // Constructor
//---------------------------------------------------------------------- //----------------------------------------------------------------------