diff options
Diffstat (limited to 'lldb/source')
-rw-r--r-- | lldb/source/API/SBValue.cpp | 4 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectExpression.cpp | 3 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectFrame.cpp | 9 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectMemory.cpp | 3 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectTarget.cpp | 3 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectType.cpp | 887 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectType.h | 17 | ||||
-rw-r--r-- | lldb/source/Core/Debugger.cpp | 8 | ||||
-rw-r--r-- | lldb/source/Core/FormatManager.cpp | 38 | ||||
-rw-r--r-- | lldb/source/Core/ValueObject.cpp | 19 | ||||
-rw-r--r-- | lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp | 23 | ||||
-rw-r--r-- | lldb/source/Target/Target.cpp | 28 |
12 files changed, 911 insertions, 131 deletions
diff --git a/lldb/source/API/SBValue.cpp b/lldb/source/API/SBValue.cpp index 1bfe211ec8f..58eb9794729 100644 --- a/lldb/source/API/SBValue.cpp +++ b/lldb/source/API/SBValue.cpp @@ -934,6 +934,7 @@ SBValue::GetDescription (SBStream &description) bool flat_output = false; bool use_synthetic = true; uint32_t no_summary_depth = 0; + bool ignore_cap = false; ValueObject::DumpValueObject (description.ref(), m_opaque_sp.get(), m_opaque_sp->GetName().GetCString(), @@ -946,7 +947,8 @@ SBValue::GetDescription (SBStream &description) use_synthetic, scope_already_checked, flat_output, - no_summary_depth); + no_summary_depth, + ignore_cap); } else description.Printf ("No value"); diff --git a/lldb/source/Commands/CommandObjectExpression.cpp b/lldb/source/Commands/CommandObjectExpression.cpp index 86c2fd7d9a9..ca5ca1520f1 100644 --- a/lldb/source/Commands/CommandObjectExpression.cpp +++ b/lldb/source/Commands/CommandObjectExpression.cpp @@ -340,7 +340,8 @@ CommandObjectExpression::EvaluateExpression true, // Use synthetic children if available true, // Scope is already checked. Const results are always in scope. false, // Don't flatten output - 0); // Always use summaries (you might want an option --no-summary like there is for frame variable) + 0, // Always use summaries (you might want an option --no-summary like there is for frame variable) + false); // Do not show more children than settings allow if (result) result->SetStatus (eReturnStatusSuccessFinishResult); } diff --git a/lldb/source/Commands/CommandObjectFrame.cpp b/lldb/source/Commands/CommandObjectFrame.cpp index 12b4b1b1f3b..d03d3bb18a0 100644 --- a/lldb/source/Commands/CommandObjectFrame.cpp +++ b/lldb/source/Commands/CommandObjectFrame.cpp @@ -502,7 +502,8 @@ public: m_varobj_options.be_raw ? false : m_varobj_options.use_synth, false, m_varobj_options.flat_output, - m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth); + m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth, + m_varobj_options.be_raw ? true : m_varobj_options.ignore_cap); } } } @@ -555,7 +556,8 @@ public: m_varobj_options.be_raw ? false : m_varobj_options.use_synth, false, m_varobj_options.flat_output, - m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth); + m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth, + m_varobj_options.be_raw ? true : m_varobj_options.ignore_cap); } else { @@ -647,7 +649,8 @@ public: m_varobj_options.be_raw ? false : m_varobj_options.use_synth, false, m_varobj_options.flat_output, - m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth); + m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth, + m_varobj_options.be_raw ? true : m_varobj_options.ignore_cap); } } } diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp index fb0bb9412fa..32ac9a24aa5 100644 --- a/lldb/source/Commands/CommandObjectMemory.cpp +++ b/lldb/source/Commands/CommandObjectMemory.cpp @@ -660,7 +660,8 @@ public: m_varobj_options.be_raw ? false : m_varobj_options.use_synth, scope_already_checked, m_varobj_options.flat_output, - m_varobj_options.be_raw ? UINT32_MAX : 0); + m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth, + m_varobj_options.be_raw ? true : m_varobj_options.ignore_cap); } else { diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp index a17cfc88a64..1da39a5f4cc 100644 --- a/lldb/source/Commands/CommandObjectTarget.cpp +++ b/lldb/source/Commands/CommandObjectTarget.cpp @@ -607,7 +607,8 @@ public: m_varobj_options.be_raw ? false : m_varobj_options.use_synth, false, m_varobj_options.flat_output, - m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth); + m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth, + m_varobj_options.be_raw ? true : m_varobj_options.ignore_cap); } diff --git a/lldb/source/Commands/CommandObjectType.cpp b/lldb/source/Commands/CommandObjectType.cpp index 0983b16cc5f..4fa34eb625b 100644 --- a/lldb/source/Commands/CommandObjectType.cpp +++ b/lldb/source/Commands/CommandObjectType.cpp @@ -1121,7 +1121,7 @@ private: m_delete_all = true; break; case 'w': - m_category = ConstString(option_arg).GetCString(); + m_category = std::string(option_arg); break; default: error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); @@ -1135,7 +1135,7 @@ private: OptionParsingStarting () { m_delete_all = false; - m_category = NULL; + m_category = "default"; } const OptionDefinition* @@ -1151,7 +1151,7 @@ private: // Instance variables to hold the values for command options. bool m_delete_all; - const char* m_category; + std::string m_category; }; @@ -1226,7 +1226,7 @@ public: } lldb::FormatCategorySP category; - Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category); + Debugger::Formatting::Categories::Get(ConstString(m_options.m_category.c_str()), category); bool delete_category = category->DeleteSummaries(typeCS.GetCString()); bool delete_named = Debugger::Formatting::NamedSummaryFormats::Delete(typeCS); @@ -1888,11 +1888,219 @@ public: }; //------------------------------------------------------------------------- +// CommandObjectTypeFilterList +//------------------------------------------------------------------------- + +bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, const char* type, const SyntheticChildren::SharedPointer& entry); +bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); + +class CommandObjectTypeFilterList; + +struct CommandObjectTypeFilterList_LoopCallbackParam { + CommandObjectTypeFilterList* self; + CommandReturnObject* result; + RegularExpression* regex; + RegularExpression* cate_regex; + CommandObjectTypeFilterList_LoopCallbackParam(CommandObjectTypeFilterList* S, CommandReturnObject* R, + RegularExpression* X = NULL, + RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {} +}; + +class CommandObjectTypeFilterList : public CommandObject +{ + + 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; + char short_option = (char) m_getopt_table[option_idx].val; + + switch (short_option) + { + case 'w': + m_category_regex = std::string(option_arg); + break; + default: + error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); + break; + } + + return error; + } + + void + OptionParsingStarting () + { + m_category_regex = ""; + } + + 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. + + std::string m_category_regex; + + }; + + CommandOptions m_options; + + virtual Options * + GetOptions () + { + return &m_options; + } + +public: + CommandObjectTypeFilterList (CommandInterpreter &interpreter) : + CommandObject (interpreter, + "type filter list", + "Show a list of current filters.", + NULL), m_options(interpreter) + { + CommandArgumentEntry type_arg; + CommandArgumentData type_style_arg; + + type_style_arg.arg_type = eArgTypeName; + type_style_arg.arg_repetition = eArgRepeatOptional; + + type_arg.push_back (type_style_arg); + + m_arguments.push_back (type_arg); + } + + ~CommandObjectTypeFilterList () + { + } + + bool + Execute (Args& command, CommandReturnObject &result) + { + const size_t argc = command.GetArgumentCount(); + + CommandObjectTypeFilterList_LoopCallbackParam *param; + RegularExpression* cate_regex = + m_options.m_category_regex.empty() ? NULL : + new RegularExpression(m_options.m_category_regex.c_str()); + + if (argc == 1) { + RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0)); + regex->Compile(command.GetArgumentAtIndex(0)); + param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,regex,cate_regex); + } + else + param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,NULL,cate_regex); + + Debugger::Formatting::Categories::LoopThrough(PerCategoryCallback,param); + + if (cate_regex) + delete cate_regex; + + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } + +private: + + static bool + PerCategoryCallback(void* param_vp, + const char* cate_name, + const FormatCategory::SharedPointer& cate) + { + + CommandObjectTypeFilterList_LoopCallbackParam* param = + (CommandObjectTypeFilterList_LoopCallbackParam*)param_vp; + CommandReturnObject* result = param->result; + + // if the category is disabled or empty and there is no regex, just skip it + if ((cate->IsEnabled() == false || cate->Filter()->GetCount() == 0) && param->cate_regex == NULL) + return true; + + // if we have a regex and this category does not match it, just skip it + if(param->cate_regex != NULL && param->cate_regex->Execute(cate_name) == false) + return true; + + result->GetOutputStream().Printf("-----------------------\nCategory: %s (%s)\n-----------------------\n", + cate_name, + (cate->IsEnabled() ? "enabled" : "disabled")); + + cate->Filter()->LoopThrough(CommandObjectTypeFilterList_LoopCallback, param_vp); + + if (cate->RegexFilter()->GetCount() > 0) + { + result->GetOutputStream().Printf("Regex-based filters (slower):\n"); + cate->RegexFilter()->LoopThrough(CommandObjectTypeFilterRXList_LoopCallback, param_vp); + } + + return true; + } + + bool + LoopCallback (const char* type, + const SyntheticChildren::SharedPointer& entry, + RegularExpression* regex, + CommandReturnObject *result) + { + if (regex == NULL || regex->Execute(type)) + result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str()); + return true; + } + + friend bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, const char* type, const SyntheticChildren::SharedPointer& entry); + friend bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); +}; + +bool +CommandObjectTypeFilterList_LoopCallback (void* pt2self, + const char* type, + const SyntheticChildren::SharedPointer& entry) +{ + CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self; + return param->self->LoopCallback(type, entry, param->regex, param->result); +} + +bool +CommandObjectTypeFilterRXList_LoopCallback (void* pt2self, + lldb::RegularExpressionSP regex, + const SyntheticChildren::SharedPointer& entry) +{ + CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self; + return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); +} + + +OptionDefinition +CommandObjectTypeFilterList::CommandOptions::g_option_table[] = +{ + { LLDB_OPT_SET_ALL, false, "category-regex", 'w', required_argument, NULL, 0, eArgTypeName, "Only show categories matching this filter."}, + { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +}; + +//------------------------------------------------------------------------- // CommandObjectTypeSynthList //------------------------------------------------------------------------- -bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, const char* type, const SyntheticFilter::SharedPointer& entry); -bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticFilter::SharedPointer& entry); +bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, const char* type, const SyntheticChildren::SharedPointer& entry); +bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); class CommandObjectTypeSynthList; @@ -2032,7 +2240,7 @@ private: CommandReturnObject* result = param->result; // if the category is disabled or empty and there is no regex, just skip it - if ((cate->IsEnabled() == false || cate->Filter()->GetCount() == 0) && param->cate_regex == NULL) + if ((cate->IsEnabled() == false || cate->Synth()->GetCount() == 0) && param->cate_regex == NULL) return true; // if we have a regex and this category does not match it, just skip it @@ -2043,12 +2251,12 @@ private: cate_name, (cate->IsEnabled() ? "enabled" : "disabled")); - cate->Filter()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp); + cate->Synth()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp); - if (cate->RegexFilter()->GetCount() > 0) + if (cate->RegexSynth()->GetCount() > 0) { - result->GetOutputStream().Printf("Regex-based filters (slower):\n"); - cate->RegexFilter()->LoopThrough(CommandObjectTypeSynthRXList_LoopCallback, param_vp); + result->GetOutputStream().Printf("Regex-based synthetic providers (slower):\n"); + cate->RegexSynth()->LoopThrough(CommandObjectTypeSynthRXList_LoopCallback, param_vp); } return true; @@ -2056,23 +2264,23 @@ private: bool LoopCallback (const char* type, - const SyntheticFilter::SharedPointer& entry, + const SyntheticChildren::SharedPointer& entry, RegularExpression* regex, CommandReturnObject *result) { - if (regex == NULL || regex->Execute(type)) + if (regex == NULL || regex->Execute(type)) result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str()); return true; } - friend bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, const char* type, const SyntheticFilter::SharedPointer& entry); - friend bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticFilter::SharedPointer& entry); + friend bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, const char* type, const SyntheticChildren::SharedPointer& entry); + friend bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry); }; bool CommandObjectTypeSynthList_LoopCallback (void* pt2self, const char* type, - const SyntheticFilter::SharedPointer& entry) + const SyntheticChildren::SharedPointer& entry) { CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self; return param->self->LoopCallback(type, entry, param->regex, param->result); @@ -2081,7 +2289,7 @@ CommandObjectTypeSynthList_LoopCallback (void* pt2self, bool CommandObjectTypeSynthRXList_LoopCallback (void* pt2self, lldb::RegularExpressionSP regex, - const SyntheticFilter::SharedPointer& entry) + const SyntheticChildren::SharedPointer& entry) { CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self; return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result); @@ -2096,6 +2304,169 @@ CommandObjectTypeSynthList::CommandOptions::g_option_table[] = }; //------------------------------------------------------------------------- +// CommandObjectTypeFilterDelete +//------------------------------------------------------------------------- + +class CommandObjectTypeFilterDelete : public CommandObject +{ +private: + 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; + char short_option = (char) m_getopt_table[option_idx].val; + + switch (short_option) + { + case 'a': + m_delete_all = true; + break; + case 'w': + m_category = std::string(option_arg); + break; + default: + error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); + break; + } + + return error; + } + + void + OptionParsingStarting () + { + m_delete_all = false; + m_category = "default"; + } + + 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. + + bool m_delete_all; + std::string m_category; + + }; + + CommandOptions m_options; + + virtual Options * + GetOptions () + { + return &m_options; + } + + static bool + PerCategoryCallback(void* param, + const char* cate_name, + const FormatCategory::SharedPointer& cate) + { + const char* name = (const char*)param; + return cate->Delete(name, FormatCategory::eFilter | FormatCategory::eRegexFilter); + } + +public: + CommandObjectTypeFilterDelete (CommandInterpreter &interpreter) : + CommandObject (interpreter, + "type filter delete", + "Delete an existing filter for a type.", + NULL), m_options(interpreter) + { + CommandArgumentEntry type_arg; + CommandArgumentData type_style_arg; + + type_style_arg.arg_type = eArgTypeName; + type_style_arg.arg_repetition = eArgRepeatPlain; + + type_arg.push_back (type_style_arg); + + m_arguments.push_back (type_arg); + + } + + ~CommandObjectTypeFilterDelete () + { + } + + bool + Execute (Args& command, CommandReturnObject &result) + { + const size_t argc = command.GetArgumentCount(); + + if (argc != 1) + { + result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + const char* typeA = command.GetArgumentAtIndex(0); + ConstString typeCS(typeA); + + if (!typeCS) + { + result.AppendError("empty typenames not allowed"); + result.SetStatus(eReturnStatusFailed); + return false; + } + + if (m_options.m_delete_all) + { + Debugger::Formatting::Categories::LoopThrough(PerCategoryCallback, (void*)typeCS.GetCString()); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return result.Succeeded(); + } + + lldb::FormatCategorySP category; + Debugger::Formatting::Categories::Get(ConstString(m_options.m_category.c_str()), category); + + bool delete_category = category->Filter()->Delete(typeCS.GetCString()); + delete_category = category->RegexFilter()->Delete(typeCS.GetCString()) || delete_category; + + if (delete_category) + { + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return result.Succeeded(); + } + else + { + result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA); + result.SetStatus(eReturnStatusFailed); + return false; + } + + } +}; + +OptionDefinition +CommandObjectTypeFilterDelete::CommandOptions::g_option_table[] = +{ + { LLDB_OPT_SET_1, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone, "Delete from every category."}, + { LLDB_OPT_SET_2, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Delete from given category."}, + { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +}; + +//------------------------------------------------------------------------- // CommandObjectTypeSynthDelete //------------------------------------------------------------------------- @@ -2126,7 +2497,7 @@ private: m_delete_all = true; break; case 'w': - m_category = ConstString(option_arg).GetCString(); + m_category = std::string(option_arg); break; default: error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); @@ -2140,7 +2511,7 @@ private: OptionParsingStarting () { m_delete_all = false; - m_category = NULL; + m_category = "default"; } const OptionDefinition* @@ -2156,7 +2527,7 @@ private: // Instance variables to hold the values for command options. bool m_delete_all; - const char* m_category; + std::string m_category; }; @@ -2174,7 +2545,7 @@ private: const FormatCategory::SharedPointer& cate) { const char* name = (const char*)param; - return cate->Delete(name, FormatCategory::eFilter | FormatCategory::eRegexFilter); + return cate->Delete(name, FormatCategory::eSynth | FormatCategory::eRegexSynth); } public: @@ -2230,10 +2601,10 @@ public: } lldb::FormatCategorySP category; - Debugger::Formatting::Categories::Get(ConstString(m_options.m_category), category); + Debugger::Formatting::Categories::Get(ConstString(m_options.m_category.c_str()), category); - bool delete_category = category->Filter()->Delete(typeCS.GetCString()); - delete_category = category->RegexFilter()->Delete(typeCS.GetCString()) || delete_category; + bool delete_category = category->Synth()->Delete(typeCS.GetCString()); + delete_category = category->RegexSynth()->Delete(typeCS.GetCString()) || delete_category; if (delete_category) { @@ -2259,6 +2630,133 @@ CommandObjectTypeSynthDelete::CommandOptions::g_option_table[] = }; //------------------------------------------------------------------------- +// CommandObjectTypeFilterClear +//------------------------------------------------------------------------- + +class CommandObjectTypeFilterClear : public CommandObject +{ +private: + + 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; + char short_option = (char) m_getopt_table[option_idx].val; + + switch (short_option) + { + case 'a': + m_delete_all = true; + break; + default: + error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); + break; + } + + return error; + } + + void + OptionParsingStarting () + { + m_delete_all = false; + } + + 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. + + bool m_delete_all; + bool m_delete_named; + }; + + CommandOptions m_options; + + virtual Options * + GetOptions () + { + return &m_options; + } + + static bool + PerCategoryCallback(void* param, + const char* cate_name, + const FormatCategory::SharedPointer& cate) + { + cate->Clear(FormatCategory::eFilter | FormatCategory::eRegexFilter); + return true; + + } + +public: + CommandObjectTypeFilterClear (CommandInterpreter &interpreter) : + CommandObject (interpreter, + "type filter clear", + "Delete all existing filters.", + NULL), m_options(interpreter) + { + } + + ~CommandObjectTypeFilterClear () + { + } + + bool + Execute (Args& command, CommandReturnObject &result) + { + + if (m_options.m_delete_all) + Debugger::Formatting::Categories::LoopThrough(PerCategoryCallback, NULL); + + else + { + lldb::FormatCategorySP category; + if (command.GetArgumentCount() > 0) + { + const char* cat_name = command.GetArgumentAtIndex(0); + ConstString cat_nameCS(cat_name); + Debugger::Formatting::Categories::Get(cat_nameCS, category); + } + else + Debugger::Formatting::Categories::Get(ConstString(NULL), category); + category->Filter()->Clear(); + category->RegexFilter()->Clear(); + } + + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } + +}; + +OptionDefinition +CommandObjectTypeFilterClear::CommandOptions::g_option_table[] = +{ + { LLDB_OPT_SET_ALL, false, "all", 'a', no_argument, NULL, 0, eArgTypeNone, "Clear every category."}, + { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +}; + +//------------------------------------------------------------------------- // CommandObjectTypeSynthClear //------------------------------------------------------------------------- @@ -2332,7 +2830,7 @@ private: const char* cate_name, const FormatCategory::SharedPointer& cate) { - cate->Clear(FormatCategory::eFilter | FormatCategory::eRegexFilter); + cate->Clear(FormatCategory::eSynth | FormatCategory::eRegexSynth); return true; } @@ -2368,8 +2866,8 @@ public: } else Debugger::Formatting::Categories::Get(ConstString(NULL), category); - category->Filter()->Clear(); - category->RegexFilter()->Clear(); + category->Synth()->Clear(); + category->RegexSynth()->Clear(); } result.SetStatus(eReturnStatusSuccessFinishResult); @@ -2594,67 +3092,7 @@ CommandObjectTypeSynthAdd::Execute_HandwritePython (Args& command, CommandReturn CollectPythonScript(options,result); return result.Succeeded(); } - -bool -CommandObjectTypeSynthAdd::Execute_ChildrenList (Args& command, CommandReturnObject &result) -{ - const size_t argc = command.GetArgumentCount(); - - if (argc < 1) - { - result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); - return false; - } - - if (m_options.m_expr_paths.size() == 0) - { - result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str()); - result.SetStatus(eReturnStatusFailed); - return false; - } - - SyntheticChildrenSP entry; - - SyntheticFilter* impl = new SyntheticFilter(m_options.m_cascade, - m_options.m_skip_pointers, - m_options.m_skip_references); - - entry.reset(impl); - - // go through the expression paths - CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end(); - - for (begin = m_options.m_expr_paths.begin(); begin != end; begin++) - impl->AddExpressionPath(*begin); - - - // now I have a valid provider, let's add it to every type - - lldb::FormatCategorySP category; - Debugger::Formatting::Categories::Get(ConstString(m_options.m_category.c_str()), category); - - for (size_t i = 0; i < argc; i++) { - const char* typeA = command.GetArgumentAtIndex(i); - ConstString typeCS(typeA); - if (typeCS) - AddSynth(typeCS, - entry, - m_options.m_regex ? eRegexSynth : eRegularSynth, - m_options.m_category, - NULL); - else - { - result.AppendError("empty typenames not allowed"); - result.SetStatus(eReturnStatusFailed); - return false; - } - } - - result.SetStatus(eReturnStatusSuccessFinishNoResult); - return result.Succeeded(); -} - + bool CommandObjectTypeSynthAdd::Execute_PythonClass (Args& command, CommandReturnObject &result) { @@ -2747,14 +3185,14 @@ CommandObjectTypeSynthAdd::AddSynth(const ConstString& type_name, return false; } - category->RegexFilter()->Delete(type_name.GetCString()); - category->RegexFilter()->Add(typeRX, entry); + category->RegexSynth()->Delete(type_name.GetCString()); + category->RegexSynth()->Add(typeRX, entry); return true; } else { - category->Filter()->Add(type_name.GetCString(), entry); + category->Synth()->Add(type_name.GetCString(), entry); return true; } } @@ -2766,8 +3204,6 @@ CommandObjectTypeSynthAdd::Execute (Args& command, CommandReturnObject &result) return Execute_HandwritePython(command, result); else if (m_options.is_class_based) return Execute_PythonClass(command, result); - else if (m_options.has_child_list) - return Execute_ChildrenList(command, result); else { result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line"); @@ -2783,13 +3219,252 @@ CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] = { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, { LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, - { LLDB_OPT_SET_1, false, "child", 'c', required_argument, NULL, 0, eArgTypeName, "Include this expression path in the synthetic view."}, { LLDB_OPT_SET_2, false, "python-class", 'l', required_argument, NULL, 0, eArgTypeName, "Use this Python class to produce synthetic children."}, { LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeNone, "Type Python code to generate a class that provides synthetic children."}, { LLDB_OPT_SET_ALL, false, "regex", 'x', no_argument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } }; +class CommandObjectTypeFilterAdd : public CommandObject +{ + +private: + + class CommandOptions : public Options + { + typedef std::vector<std::string> option_vector; + public: + + CommandOptions (CommandInterpreter &interpreter) : + Options (interpreter) + { + } + + virtual + ~CommandOptions (){} + + virtual Error + SetOptionValue (uint32_t option_idx, const char *option_arg) + { + Error error; + char short_option = (char) m_getopt_table[option_idx].val; + bool success; + + switch (short_option) + { + case 'C': + m_cascade = Args::StringToBoolean(option_arg, true, &success); + if (!success) + error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg); + break; + case 'c': + m_expr_paths.push_back(option_arg); + has_child_list = true; + break; + case 'p': + m_skip_pointers = true; + break; + case 'r': + m_skip_references = true; + break; + case 'w': + m_category = std::string(option_arg); + break; + case 'x': + m_regex = true; + break; + default: + error.SetErrorStringWithFormat ("Unrecognized option '%c'.\n", short_option); + break; + } + + return error; + } + + void + OptionParsingStarting () + { + m_cascade = true; + m_skip_pointers = false; + m_skip_references = false; + m_category = "default"; + m_expr_paths.clear(); + has_child_list = false; + m_regex = false; + } + + 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. + + bool m_cascade; + bool m_skip_references; + bool m_skip_pointers; + bool m_input_python; + option_vector m_expr_paths; + std::string m_category; + + bool has_child_list; + + bool m_regex; + + typedef option_vector::iterator ExpressionPathsIterator; + }; + + CommandOptions m_options; + + virtual Options * + GetOptions () + { + return &m_options; + } + + enum SynthFormatType + { + eRegularSynth, + eRegexSynth, + }; + + bool + AddSynth(const ConstString& type_name, + SyntheticChildrenSP entry, + SynthFormatType type, + std::string category_name, + Error* error) + { + lldb::FormatCategorySP category; + Debugger::Formatting::Categories::Get(ConstString(category_name.c_str()), category); + + if (type == eRegexSynth) + { + RegularExpressionSP typeRX(new RegularExpression()); + if (!typeRX->Compile(type_name.GetCString())) + { + if (error) + error->SetErrorString("regex format error (maybe this is not really a regex?)"); + return false; + } + + category->RegexFilter()->Delete(type_name.GetCString()); + category->RegexFilter()->Add(typeRX, entry); + + return true; + } + else + { + category->Filter()->Add(type_name.GetCString(), entry); + return true; + } + } + + +public: + + CommandObjectTypeFilterAdd (CommandInterpreter &interpreter) : + CommandObject (interpreter, + "type filter add", + "Add a new filter for a type.", + NULL), + m_options (interpreter) + { + CommandArgumentEntry type_arg; + CommandArgumentData type_style_arg; + + type_style_arg.arg_type = eArgTypeName; + type_style_arg.arg_repetition = eArgRepeatPlus; + + type_arg.push_back (type_style_arg); + + m_arguments.push_back (type_arg); + + } + + ~CommandObjectTypeFilterAdd () + { + } + + bool + Execute (Args& command, CommandReturnObject &result) + { + const size_t argc = command.GetArgumentCount(); + + if (argc < 1) + { + result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + if (m_options.m_expr_paths.size() == 0) + { + result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + SyntheticChildrenSP entry; + + SyntheticFilter* impl = new SyntheticFilter(m_options.m_cascade, + m_options.m_skip_pointers, + m_options.m_skip_references); + + entry.reset(impl); + + // go through the expression paths + CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end(); + + for (begin = m_options.m_expr_paths.begin(); begin != end; begin++) + impl->AddExpressionPath(*begin); + + + // now I have a valid provider, let's add it to every type + + lldb::FormatCategorySP category; + Debugger::Formatting::Categories::Get(ConstString(m_options.m_category.c_str()), category); + + for (size_t i = 0; i < argc; i++) { + const char* typeA = command.GetArgumentAtIndex(i); + ConstString typeCS(typeA); + if (typeCS) + AddSynth(typeCS, + entry, + m_options.m_regex ? eRegexSynth : eRegularSynth, + m_options.m_category, + NULL); + else + { + result.AppendError("empty typenames not allowed"); + result.SetStatus(eReturnStatusFailed); + return false; + } + } + + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return result.Succeeded(); + } + +}; + +OptionDefinition +CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] = +{ + { LLDB_OPT_SET_ALL, false, "cascade", 'C', required_argument, NULL, 0, eArgTypeBoolean, "If true, cascade to derived typedefs."}, + { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."}, + { LLDB_OPT_SET_ALL, false, "skip-references", 'r', no_argument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."}, + { LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."}, + { LLDB_OPT_SET_ALL, false, "child", 'c', required_argument, NULL, 0, eArgTypeName, "Include this expression path in the synthetic view."}, + { LLDB_OPT_SET_ALL, false, "regex", 'x', no_argument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."}, + { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } +}; + class CommandObjectTypeFormat : public CommandObjectMultiword { public: @@ -2832,6 +3507,27 @@ public: } }; +class CommandObjectTypeFilter : public CommandObjectMultiword +{ +public: + CommandObjectTypeFilter (CommandInterpreter &interpreter) : + CommandObjectMultiword (interpreter, + "type filter", + "A set of commands for operating on type filters", + "type synthetic [<sub-command-options>] ") + { + LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFilterAdd (interpreter))); + LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFilterClear (interpreter))); + LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFilterDelete (interpreter))); + LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFilterList (interpreter))); + } + + + ~CommandObjectTypeFilter () + { + } +}; + class CommandObjectTypeCategory : public CommandObjectMultiword { public: @@ -2885,9 +3581,10 @@ CommandObjectType::CommandObjectType (CommandInterpreter &interpreter) : "type [<sub-command-options>]") { LoadSubCommand ("category", CommandObjectSP (new CommandObjectTypeCategory (interpreter))); + LoadSubCommand ("filter", CommandObjectSP (new CommandObjectTypeFilter (interpreter))); LoadSubCommand ("format", CommandObjectSP (new CommandObjectTypeFormat (interpreter))); LoadSubCommand ("summary", CommandObjectSP (new CommandObjectTypeSummary (interpreter))); - LoadSubCommand ("synthetic", CommandObjectSP (new CommandObjectTypeSynth (interpreter))); + LoadSubCommand ("synthetic", CommandObjectSP (new CommandObjectTypeSynth (interpreter))); } diff --git a/lldb/source/Commands/CommandObjectType.h b/lldb/source/Commands/CommandObjectType.h index cdf3bea46ef..cb86f8e3e11 100644 --- a/lldb/source/Commands/CommandObjectType.h +++ b/lldb/source/Commands/CommandObjectType.h @@ -214,7 +214,6 @@ private: class CommandOptions : public Options { - typedef std::vector<std::string> option_vector; public: CommandOptions (CommandInterpreter &interpreter) : @@ -239,10 +238,6 @@ private: if (!success) error.SetErrorStringWithFormat("Invalid value for cascade: %s.\n", option_arg); break; - case 'c': - m_expr_paths.push_back(option_arg); - has_child_list = true; - break; case 'P': handwrite_python = true; break; @@ -278,10 +273,8 @@ private: m_skip_pointers = false; m_skip_references = false; m_category = "default"; - m_expr_paths.clear(); is_class_based = false; handwrite_python = false; - has_child_list = false; m_regex = false; } @@ -302,18 +295,14 @@ private: bool m_skip_pointers; std::string m_class_name; bool m_input_python; - option_vector m_expr_paths; std::string m_category; bool is_class_based; bool handwrite_python; - - bool has_child_list; - + bool m_regex; - typedef option_vector::iterator ExpressionPathsIterator; }; CommandOptions m_options; @@ -329,10 +318,10 @@ private: CommandReturnObject &result); bool Execute_HandwritePython (Args& command, CommandReturnObject &result); - bool - Execute_ChildrenList (Args& command, CommandReturnObject &result); + bool Execute_PythonClass (Args& command, CommandReturnObject &result); + bool Execute (Args& command, CommandReturnObject &result); diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 08cbb1c4755..0c62a4f8047 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -1200,6 +1200,8 @@ Debugger::FormatPrompt if (index_higher < 0) index_higher = vobj->GetNumChildren() - 1; + uint32_t max_num_children = target->GetUpdatePoint().GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); + for (;index_lower<=index_higher;index_lower++) { ValueObject* item = ExpandIndexedExpression(target, @@ -1223,6 +1225,12 @@ Debugger::FormatPrompt else var_success &= FormatPrompt(special_directions, sc, exe_ctx, addr, s, NULL, item); + if (--max_num_children == 0) + { + s.PutCString(", ..."); + break; + } + if (index_lower < index_higher) s.PutChar(','); } diff --git a/lldb/source/Core/FormatManager.cpp b/lldb/source/Core/FormatManager.cpp index c0242fef336..2210e37f111 100644 --- a/lldb/source/Core/FormatManager.cpp +++ b/lldb/source/Core/FormatManager.cpp @@ -230,6 +230,44 @@ FormatNavigator<lldb::RegularExpressionSP, SyntheticFilter>::Delete(const char* return false; } +template<> +bool +FormatNavigator<lldb::RegularExpressionSP, SyntheticScriptProvider>::Get(const char* key, SyntheticFilter::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, SyntheticScriptProvider>::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) { diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index fe27d712842..6d157be9775 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -2687,7 +2687,8 @@ ValueObject::DumpValueObject bool use_synth, bool scope_already_checked, bool flat_output, - uint32_t omit_summary_depth + uint32_t omit_summary_depth, + bool ignore_cap ) { if (valobj) @@ -2864,7 +2865,8 @@ ValueObject::DumpValueObject ValueObjectSP synth_vobj = valobj->GetSyntheticValue(use_synth ? lldb::eUseSyntheticFilter : lldb::eNoSyntheticFilter); - const uint32_t num_children = synth_vobj->GetNumChildren(); + uint32_t num_children = synth_vobj->GetNumChildren(); + bool print_dotdotdot = false; if (num_children) { if (flat_output) @@ -2878,6 +2880,14 @@ ValueObject::DumpValueObject s.PutCString(is_ref ? ": {\n" : " {\n"); s.IndentMore(); } + + uint32_t max_num_children = valobj->GetUpdatePoint().GetTargetSP()->GetMaximumNumberOfChildrenToDisplay(); + + if (num_children > max_num_children && !ignore_cap) + { + num_children = max_num_children; + print_dotdotdot = true; + } for (uint32_t idx=0; idx<num_children; ++idx) { @@ -2897,12 +2907,15 @@ ValueObject::DumpValueObject use_synth, true, flat_output, - omit_summary_depth > 1 ? omit_summary_depth - 1 : 0); + omit_summary_depth > 1 ? omit_summary_depth - 1 : 0, + ignore_cap); } } if (!flat_output) { + if (print_dotdotdot) + s.Indent("...\n"); s.IndentLess(); s.Indent("}\n"); } diff --git a/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp index b274521445b..5f540d60d06 100644 --- a/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp +++ b/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp @@ -30,17 +30,18 @@ OptionGroupValueObjectDisplay::~OptionGroupValueObjectDisplay () static OptionDefinition g_option_table[] = { - { LLDB_OPT_SET_1, false, "dynamic-type", 'd', required_argument, TargetInstanceSettings::g_dynamic_value_types, + { LLDB_OPT_SET_1, false, "dynamic-type", 'd', required_argument, TargetInstanceSettings::g_dynamic_value_types, 0, eArgTypeNone, "Show the object as its full dynamic type, not its static type, if available."}, - { LLDB_OPT_SET_1, false, "synthetic-type", 'S', required_argument, NULL, 0, eArgTypeBoolean, "Show the object obeying its synthetic provider, if available."}, - { LLDB_OPT_SET_1, false, "depth", 'D', required_argument, NULL, 0, eArgTypeCount, "Set the max recurse depth when dumping aggregate types (default is infinity)."}, - { LLDB_OPT_SET_1, false, "flat", 'F', no_argument, NULL, 0, eArgTypeNone, "Display results in a flat format that uses expression paths for each variable or member."}, - { LLDB_OPT_SET_1, false, "location", 'L', no_argument, NULL, 0, eArgTypeNone, "Show variable location information."}, - { LLDB_OPT_SET_1, false, "objc", 'O', no_argument, NULL, 0, eArgTypeNone, "Print as an Objective-C object."}, - { LLDB_OPT_SET_1, false, "ptr-depth", 'P', required_argument, NULL, 0, eArgTypeCount, "The number of pointers to be traversed when dumping values (default is zero)."}, - { LLDB_OPT_SET_1, false, "show-types", 'T', no_argument, NULL, 0, eArgTypeNone, "Show variable types when dumping values."}, - { LLDB_OPT_SET_1, false, "no-summary-depth",'Y', optional_argument, NULL, 0, eArgTypeCount, "Set a depth for omitting summary information (default is 1)."}, - { LLDB_OPT_SET_1, false, "raw-output", 'R', no_argument, NULL, 0, eArgTypeNone, "Don't use formatting options."}, + { LLDB_OPT_SET_1, false, "synthetic-type", 'S', required_argument, NULL, 0, eArgTypeBoolean, "Show the object obeying its synthetic provider, if available."}, + { LLDB_OPT_SET_1, false, "depth", 'D', required_argument, NULL, 0, eArgTypeCount, "Set the max recurse depth when dumping aggregate types (default is infinity)."}, + { LLDB_OPT_SET_1, false, "flat", 'F', no_argument, NULL, 0, eArgTypeNone, "Display results in a flat format that uses expression paths for each variable or member."}, + { LLDB_OPT_SET_1, false, "location", 'L', no_argument, NULL, 0, eArgTypeNone, "Show variable location information."}, + { LLDB_OPT_SET_1, false, "objc", 'O', no_argument, NULL, 0, eArgTypeNone, "Print as an Objective-C object."}, + { LLDB_OPT_SET_1, false, "ptr-depth", 'P', required_argument, NULL, 0, eArgTypeCount, "The number of pointers to be traversed when dumping values (default is zero)."}, + { LLDB_OPT_SET_1, false, "show-types", 'T', no_argument, NULL, 0, eArgTypeNone, "Show variable types when dumping values."}, + { LLDB_OPT_SET_1, false, "no-summary-depth", 'Y', optional_argument, NULL, 0, eArgTypeCount, "Set a depth for omitting summary information (default is 1)."}, + { LLDB_OPT_SET_1, false, "raw-output", 'R', no_argument, NULL, 0, eArgTypeNone, "Don't use formatting options."}, + { LLDB_OPT_SET_1, false, "show-all-children",'A', no_argument, NULL, 0, eArgTypeNone, "Ignore the upper bound on the number of children to show."}, { 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL } }; @@ -86,6 +87,7 @@ OptionGroupValueObjectDisplay::SetOptionValue (CommandInterpreter &interpreter, case 'F': flat_output = true; break; case 'O': use_objc = true; break; case 'R': be_raw = true; break; + case 'A': ignore_cap = true; break; case 'D': max_depth = Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success); @@ -135,6 +137,7 @@ OptionGroupValueObjectDisplay::OptionParsingStarting (CommandInterpreter &interp ptr_depth = 0; use_synth = true; be_raw = false; + ignore_cap = false; Target *target = interpreter.GetExecutionContext().target; if (target != NULL) diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 600a06bc137..25d37435ff6 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -1578,6 +1578,7 @@ Target::SettingsController::CreateInstanceSettings (const char *instance_name) #define TSC_PREFER_DYNAMIC "prefer-dynamic-value" #define TSC_SKIP_PROLOGUE "skip-prologue" #define TSC_SOURCE_MAP "source-map" +#define TSC_MAX_CHILDREN "max-children-count" static const ConstString & @@ -1615,6 +1616,12 @@ GetSettingNameForSkipPrologue () return g_const_string; } +static const ConstString & +GetSettingNameForMaxChildren () +{ + static ConstString g_const_string (TSC_MAX_CHILDREN); + return g_const_string; +} bool @@ -1668,7 +1675,8 @@ TargetInstanceSettings::TargetInstanceSettings m_expr_prefix_contents_sp (), m_prefer_dynamic_value (2), m_skip_prologue (true, true), - m_source_map (NULL, NULL) + m_source_map (NULL, NULL), + m_max_children_display(256) { // CopyInstanceSettings is a pure virtual function in InstanceSettings; it therefore cannot be called // until the vtables for TargetInstanceSettings are properly set up, i.e. AFTER all the initializers. @@ -1694,7 +1702,8 @@ TargetInstanceSettings::TargetInstanceSettings (const TargetInstanceSettings &rh m_expr_prefix_contents_sp (rhs.m_expr_prefix_contents_sp), m_prefer_dynamic_value (rhs.m_prefer_dynamic_value), m_skip_prologue (rhs.m_skip_prologue), - m_source_map (rhs.m_source_map) + m_source_map (rhs.m_source_map), + m_max_children_display(rhs.m_max_children_display) { if (m_instance_name != InstanceSettings::GetDefaultName()) { @@ -1771,6 +1780,13 @@ TargetInstanceSettings::UpdateInstanceSettingsVariable (const ConstString &var_n { err = UserSettingsController::UpdateBooleanOptionValue (value, op, m_skip_prologue); } + else if (var_name == GetSettingNameForMaxChildren()) + { + bool ok; + uint32_t new_value = Args::StringToUInt32(value, 0, 10, &ok); + if (ok) + m_max_children_display = new_value; + } else if (var_name == GetSettingNameForSourcePathMap ()) { switch (op) @@ -1841,6 +1857,7 @@ TargetInstanceSettings::CopyInstanceSettings (const lldb::InstanceSettingsSP &ne m_expr_prefix_contents_sp = new_settings_ptr->m_expr_prefix_contents_sp; m_prefer_dynamic_value = new_settings_ptr->m_prefer_dynamic_value; m_skip_prologue = new_settings_ptr->m_skip_prologue; + m_max_children_display = new_settings_ptr->m_max_children_display; } bool @@ -1870,6 +1887,12 @@ TargetInstanceSettings::GetInstanceSettingsValue (const SettingEntry &entry, else if (var_name == GetSettingNameForSourcePathMap ()) { } + else if (var_name == GetSettingNameForMaxChildren()) + { + StreamString count_str; + count_str.Printf ("%d", m_max_children_display); + value.AppendString (count_str.GetData()); + } else { if (err) @@ -1923,5 +1946,6 @@ Target::SettingsController::instance_settings_table[] = { TSC_PREFER_DYNAMIC, eSetVarTypeEnum , NULL , g_dynamic_value_types, false, false, "Should printed values be shown as their dynamic value." }, { TSC_SKIP_PROLOGUE , eSetVarTypeBoolean, "true" , NULL, false, false, "Skip function prologues when setting breakpoints by name." }, { TSC_SOURCE_MAP , eSetVarTypeArray , NULL , NULL, false, false, "Source path remappings to use when locating source files from debug information." }, + { TSC_MAX_CHILDREN , eSetVarTypeInt , "256" , NULL, true, false, "Maximum number of children to expand in any level of depth." }, { NULL , eSetVarTypeNone , NULL , NULL, false, false, NULL } }; |