Add a --language (-l) option to type category {enable|disable} to allow people to turn on and off formatters for a given language

llvm-svn: 246884
This commit is contained in:
Enrico Granata 2015-09-04 22:07:48 +00:00
parent 0e2b975eb6
commit 964211f25f
5 changed files with 191 additions and 19 deletions

View File

@ -133,8 +133,14 @@ public:
Enable (const ConstString& category,
TypeCategoryMap::Position = TypeCategoryMap::Default);
static void
Enable (lldb::LanguageType lang_type);
static void
Disable (const ConstString& category);
static void
Disable (lldb::LanguageType lang_type);
static void
Enable (const lldb::TypeCategoryImplSP& category,

View File

@ -258,6 +258,9 @@ public:
static ConstString
GetTypeForCache (ValueObject&, lldb::DynamicValueType);
LanguageCategory*
GetCategoryForLanguage (lldb::LanguageType lang_type);
private:
@ -272,9 +275,6 @@ private:
bool did_strip_typedef,
bool root_level = false);
LanguageCategory*
GetCategoryForLanguage (lldb::LanguageType lang_type);
FormatCache m_format_cache;
NamedSummariesMap m_named_summaries_map;
std::atomic<uint32_t> m_last_revision;

View File

@ -30,6 +30,7 @@
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/OptionGroupFormat.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
@ -2460,12 +2461,79 @@ CommandObjectTypeSummaryList::CommandOptions::g_option_table[] =
class CommandObjectTypeCategoryEnable : public CommandObjectParsed
{
class CommandOptions : public Options
{
public:
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
}
virtual
~CommandOptions (){}
virtual Error
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
case 'l':
if (option_arg)
{
m_language = Language::GetLanguageTypeFromString(option_arg);
if (m_language == lldb::eLanguageTypeUnknown)
error.SetErrorStringWithFormat ("unrecognized language '%s'", option_arg);
}
break;
default:
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
break;
}
return error;
}
void
OptionParsingStarting ()
{
m_language = lldb::eLanguageTypeUnknown;
}
const OptionDefinition*
GetDefinitions ()
{
return g_option_table;
}
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table[];
// Instance variables to hold the values for command options.
lldb::LanguageType m_language;
};
CommandOptions m_options;
virtual Options *
GetOptions ()
{
return &m_options;
}
public:
CommandObjectTypeCategoryEnable (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
"type category enable",
"Enable a category as a source of formatters.",
NULL)
NULL),
m_options(interpreter)
{
CommandArgumentEntry type_arg;
CommandArgumentData type_style_arg;
@ -2489,9 +2557,10 @@ protected:
{
const size_t argc = command.GetArgumentCount();
if (argc < 1)
if (argc < 1 &&
m_options.m_language == lldb::eLanguageTypeUnknown)
{
result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str());
result.AppendErrorWithFormat ("%s takes arguments and/or a language", m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
@ -2500,7 +2569,7 @@ protected:
{
DataVisualization::Categories::EnableStar();
}
else
else if (argc > 0)
{
for (int i = argc - 1; i >= 0; i--)
{
@ -2525,12 +2594,22 @@ protected:
}
}
if (m_options.m_language != lldb::eLanguageTypeUnknown)
DataVisualization::Categories::Enable(m_options.m_language);
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
}
};
OptionDefinition
CommandObjectTypeCategoryEnable::CommandOptions::g_option_table[] =
{
{ LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Enable the category for this language."},
{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
};
//-------------------------------------------------------------------------
// CommandObjectTypeCategoryDelete
//-------------------------------------------------------------------------
@ -2610,12 +2689,79 @@ protected:
class CommandObjectTypeCategoryDisable : public CommandObjectParsed
{
class CommandOptions : public Options
{
public:
CommandOptions (CommandInterpreter &interpreter) :
Options (interpreter)
{
}
virtual
~CommandOptions (){}
virtual Error
SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
const int short_option = m_getopt_table[option_idx].val;
switch (short_option)
{
case 'l':
if (option_arg)
{
m_language = Language::GetLanguageTypeFromString(option_arg);
if (m_language == lldb::eLanguageTypeUnknown)
error.SetErrorStringWithFormat ("unrecognized language '%s'", option_arg);
}
break;
default:
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
break;
}
return error;
}
void
OptionParsingStarting ()
{
m_language = lldb::eLanguageTypeUnknown;
}
const OptionDefinition*
GetDefinitions ()
{
return g_option_table;
}
// Options table: Required for subclasses of Options.
static OptionDefinition g_option_table[];
// Instance variables to hold the values for command options.
lldb::LanguageType m_language;
};
CommandOptions m_options;
virtual Options *
GetOptions ()
{
return &m_options;
}
public:
CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
"type category disable",
"Disable a category as a source of formatters.",
NULL)
NULL),
m_options(interpreter)
{
CommandArgumentEntry type_arg;
CommandArgumentData type_style_arg;
@ -2639,9 +2785,10 @@ protected:
{
const size_t argc = command.GetArgumentCount();
if (argc < 1)
if (argc < 1 &&
m_options.m_language == lldb::eLanguageTypeUnknown)
{
result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str());
result.AppendErrorWithFormat ("%s takes arguments and/or a language", m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
return false;
}
@ -2650,7 +2797,7 @@ protected:
{
DataVisualization::Categories::DisableStar();
}
else
else if (argc > 0)
{
// the order is not relevant here
for (int i = argc - 1; i >= 0; i--)
@ -2667,6 +2814,9 @@ protected:
DataVisualization::Categories::Disable(typeCS);
}
}
if (m_options.m_language != lldb::eLanguageTypeUnknown)
DataVisualization::Categories::Disable(m_options.m_language);
result.SetStatus(eReturnStatusSuccessFinishResult);
return result.Succeeded();
@ -2674,6 +2824,13 @@ protected:
};
OptionDefinition
CommandObjectTypeCategoryDisable::CommandOptions::g_option_table[] =
{
{ LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Enable the category for this language."},
{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
};
//-------------------------------------------------------------------------
// CommandObjectTypeCategoryList
//-------------------------------------------------------------------------

View File

@ -167,6 +167,13 @@ DataVisualization::Categories::Enable (const ConstString& category,
GetFormatManager().EnableCategory(category, pos);
}
void
DataVisualization::Categories::Enable (lldb::LanguageType lang_type)
{
if (LanguageCategory* lang_category = GetFormatManager().GetCategoryForLanguage(lang_type))
lang_category->Enable();
}
void
DataVisualization::Categories::Disable (const ConstString& category)
{
@ -174,6 +181,13 @@ DataVisualization::Categories::Disable (const ConstString& category)
GetFormatManager().DisableCategory(category);
}
void
DataVisualization::Categories::Disable (lldb::LanguageType lang_type)
{
if (LanguageCategory* lang_category = GetFormatManager().GetCategoryForLanguage(lang_type))
lang_category->Disable();
}
void
DataVisualization::Categories::Enable (const lldb::TypeCategoryImplSP& category,
TypeCategoryMap::Position pos)

View File

@ -14,14 +14,12 @@ class TypeCompletionTestCase(TestBase):
@skipUnlessDarwin
@dsym_test
@unittest2.expectedFailure("xfail pending a way to disable language categories")
def test_with_dsym_and_run_command(self):
"""Check that types only get completed when necessary."""
self.buildDsym()
self.type_completion_commands()
@dwarf_test
@unittest2.expectedFailure("xfail pending a way to disable language categories")
@expectedFailureIcc # often fails with 'NameAndAddress should be valid'
# Fails with gcc 4.8.1 with llvm.org/pr15301 LLDB prints incorrect sizes of STL containers
def test_with_dwarf_and_run_command(self):
@ -49,11 +47,9 @@ class TypeCompletionTestCase(TestBase):
# This is the function to remove the custom formats in order to have a
# clean slate for the next test case.
def cleanup():
self.runCmd('type category enable gnu-libstdc++', check=False)
self.runCmd('type category enable libcxx', check=False)
self.runCmd('type category enable -l c++', check=False)
self.runCmd('type category disable gnu-libstdc++', check=False)
self.runCmd('type category disable libcxx', check=False)
self.runCmd('type category disable -l c++', check=False)
# Execute the cleanup function during test case tear down.
self.addTearDownHook(cleanup)
@ -117,8 +113,7 @@ class TypeCompletionTestCase(TestBase):
self.assertTrue(string.IsValid(), 'std::string should be valid')
self.assertFalse(string.IsTypeComplete(), 'std::string complete but it should not be')
self.runCmd('type category enable gnu-libstdc++', check=False)
self.runCmd('type category enable libcxx', check=False)
self.runCmd('type category enable -l c++', check=False)
self.runCmd('frame variable guy --show-types')
p_vector = self.dbg.GetSelectedTarget().GetProcess().GetSelectedThread().GetSelectedFrame().FindVariable('p')