1 //===-- CommandObjectType.cpp ----------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "CommandObjectType.h"
19 #include "llvm/ADT/StringRef.h"
21 #include "lldb/Core/ConstString.h"
22 #include "lldb/Core/Debugger.h"
23 #include "lldb/Core/IOHandler.h"
24 #include "lldb/Core/RegularExpression.h"
25 #include "lldb/Core/State.h"
26 #include "lldb/Core/StringList.h"
27 #include "lldb/DataFormatters/DataVisualization.h"
28 #include "lldb/Interpreter/CommandInterpreter.h"
29 #include "lldb/Interpreter/CommandObject.h"
30 #include "lldb/Interpreter/CommandReturnObject.h"
31 #include "lldb/Interpreter/Options.h"
32 #include "lldb/Interpreter/OptionGroupFormat.h"
33 #include "lldb/Interpreter/OptionValueBoolean.h"
34 #include "lldb/Interpreter/OptionValueLanguage.h"
35 #include "lldb/Interpreter/OptionValueString.h"
36 #include "lldb/Target/Language.h"
37 #include "lldb/Target/Process.h"
38 #include "lldb/Target/StackFrame.h"
39 #include "lldb/Target/Target.h"
40 #include "lldb/Target/Thread.h"
41 #include "lldb/Target/ThreadList.h"
44 using namespace lldb_private;
47 class ScriptAddOptions
52 TypeSummaryImpl::Flags m_flags;
54 StringList m_target_types;
60 std::string m_category;
62 ScriptAddOptions(const TypeSummaryImpl::Flags& flags,
64 const ConstString& name,
73 typedef std::shared_ptr<ScriptAddOptions> SharedPointer;
83 bool m_skip_references;
86 StringList m_target_types;
88 std::string m_category;
90 SynthAddOptions(bool sptr,
95 m_skip_pointers(sptr),
96 m_skip_references(sref),
104 typedef std::shared_ptr<SynthAddOptions> SharedPointer;
109 WarnOnPotentialUnquotedUnsignedType (Args& command, CommandReturnObject &result)
111 for (unsigned idx = 0; idx < command.GetArgumentCount(); idx++)
113 const char* arg = command.GetArgumentAtIndex(idx);
114 if (idx+1 < command.GetArgumentCount())
116 if (arg && 0 == strcmp(arg,"unsigned"))
118 const char* next = command.GetArgumentAtIndex(idx+1);
120 (0 == strcmp(next, "int") ||
121 0 == strcmp(next, "short") ||
122 0 == strcmp(next, "char") ||
123 0 == strcmp(next, "long")))
125 result.AppendWarningWithFormat("%s %s being treated as two types. if you meant the combined type name use quotes, as in \"%s %s\"\n",
135 class CommandObjectTypeSummaryAdd :
136 public CommandObjectParsed,
137 public IOHandlerDelegateMultiline
142 class CommandOptions : public Options
146 CommandOptions (CommandInterpreter &interpreter) :
147 Options (interpreter)
151 ~CommandOptions () override {}
154 SetOptionValue (uint32_t option_idx, const char *option_arg) override;
157 OptionParsingStarting () override;
159 const OptionDefinition*
160 GetDefinitions () override
162 return g_option_table;
165 // Options table: Required for subclasses of Options.
167 static OptionDefinition g_option_table[];
169 // Instance variables to hold the values for command options.
171 TypeSummaryImpl::Flags m_flags;
173 std::string m_format_string;
175 std::string m_python_script;
176 std::string m_python_function;
177 bool m_is_add_script;
178 std::string m_category;
181 CommandOptions m_options;
184 GetOptions () override
190 Execute_ScriptSummary (Args& command, CommandReturnObject &result);
193 Execute_StringSummary (Args& command, CommandReturnObject &result);
197 enum SummaryFormatType
204 CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter);
206 ~CommandObjectTypeSummaryAdd () override
211 IOHandlerActivated (IOHandler &io_handler) override
213 static const char *g_summary_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
214 "def function (valobj,internal_dict):\n"
215 " \"\"\"valobj: an SBValue which you want to provide a summary for\n"
216 " internal_dict: an LLDB support object not to be used\"\"\"\n";
218 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
221 output_sp->PutCString(g_summary_addreader_instructions);
228 IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
230 StreamFileSP error_sp = io_handler.GetErrorStreamFile();
232 #ifndef LLDB_DISABLE_PYTHON
233 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
237 lines.SplitIntoLines(data);
238 if (lines.GetSize() > 0)
240 ScriptAddOptions *options_ptr = ((ScriptAddOptions*)io_handler.GetUserData());
243 ScriptAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
245 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
248 std::string funct_name_str;
249 if (interpreter->GenerateTypeScriptFunction (lines, funct_name_str))
251 if (funct_name_str.empty())
253 error_sp->Printf ("unable to obtain a valid function name from the script interpreter.\n");
258 // now I have a valid function name, let's add this as script for every type in the list
260 TypeSummaryImplSP script_format;
261 script_format.reset(new ScriptSummaryFormat(options->m_flags,
262 funct_name_str.c_str(),
263 lines.CopyList(" ").c_str()));
267 for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
269 const char *type_name = options->m_target_types.GetStringAtIndex(i);
270 CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
272 (options->m_regex ? CommandObjectTypeSummaryAdd::eRegexSummary : CommandObjectTypeSummaryAdd::eRegularSummary),
277 error_sp->Printf ("error: %s", error.AsCString());
284 CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
286 CommandObjectTypeSummaryAdd::eNamedSummary,
291 CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
293 CommandObjectTypeSummaryAdd::eNamedSummary,
298 error_sp->Printf ("error: %s", error.AsCString());
304 error_sp->Printf ("error: %s", error.AsCString());
310 if (error.AsCString())
312 error_sp->Printf ("error: %s", error.AsCString());
320 error_sp->Printf ("error: unable to generate a function.\n");
326 error_sp->Printf ("error: no script interpreter.\n");
332 error_sp->Printf ("error: internal synchronization information missing or invalid.\n");
338 error_sp->Printf ("error: empty function, didn't add python command.\n");
344 error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
347 #endif // #ifndef LLDB_DISABLE_PYTHON
348 io_handler.SetIsDone(true);
352 AddSummary(ConstString type_name,
353 lldb::TypeSummaryImplSP entry,
354 SummaryFormatType type,
355 std::string category,
356 Error* error = NULL);
359 DoExecute (Args& command, CommandReturnObject &result) override;
363 static const char *g_synth_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
364 "You must define a Python class with these methods:\n"
365 " def __init__(self, valobj, dict):\n"
366 " def num_children(self):\n"
367 " def get_child_at_index(self, index):\n"
368 " def get_child_index(self, name):\n"
369 " def update(self):\n"
371 "class synthProvider:\n";
373 class CommandObjectTypeSynthAdd :
374 public CommandObjectParsed,
375 public IOHandlerDelegateMultiline
380 class CommandOptions : public Options
384 CommandOptions (CommandInterpreter &interpreter) :
385 Options (interpreter)
389 ~CommandOptions () override {}
392 SetOptionValue (uint32_t option_idx, const char *option_arg) override
395 const int short_option = m_getopt_table[option_idx].val;
398 switch (short_option)
401 m_cascade = Args::StringToBoolean(option_arg, true, &success);
403 error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
406 handwrite_python = true;
409 m_class_name = std::string(option_arg);
410 is_class_based = true;
413 m_skip_pointers = true;
416 m_skip_references = true;
419 m_category = std::string(option_arg);
425 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
433 OptionParsingStarting () override
437 m_skip_pointers = false;
438 m_skip_references = false;
439 m_category = "default";
440 is_class_based = false;
441 handwrite_python = false;
445 const OptionDefinition*
446 GetDefinitions () override
448 return g_option_table;
451 // Options table: Required for subclasses of Options.
453 static OptionDefinition g_option_table[];
455 // Instance variables to hold the values for command options.
458 bool m_skip_references;
459 bool m_skip_pointers;
460 std::string m_class_name;
462 std::string m_category;
466 bool handwrite_python;
472 CommandOptions m_options;
475 GetOptions () override
481 Execute_HandwritePython (Args& command, CommandReturnObject &result);
484 Execute_PythonClass (Args& command, CommandReturnObject &result);
488 DoExecute (Args& command, CommandReturnObject &result) override
490 WarnOnPotentialUnquotedUnsignedType(command, result);
492 if (m_options.handwrite_python)
493 return Execute_HandwritePython(command, result);
494 else if (m_options.is_class_based)
495 return Execute_PythonClass(command, result);
498 result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line");
499 result.SetStatus(eReturnStatusFailed);
505 IOHandlerActivated (IOHandler &io_handler) override
507 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
510 output_sp->PutCString(g_synth_addreader_instructions);
517 IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
519 StreamFileSP error_sp = io_handler.GetErrorStreamFile();
521 #ifndef LLDB_DISABLE_PYTHON
522 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
526 lines.SplitIntoLines(data);
527 if (lines.GetSize() > 0)
529 SynthAddOptions *options_ptr = ((SynthAddOptions*)io_handler.GetUserData());
532 SynthAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
534 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
537 std::string class_name_str;
538 if (interpreter->GenerateTypeSynthClass (lines, class_name_str))
540 if (class_name_str.empty())
542 error_sp->Printf ("error: unable to obtain a proper name for the class.\n");
547 // everything should be fine now, let's add the synth provider class
549 SyntheticChildrenSP synth_provider;
550 synth_provider.reset(new ScriptedSyntheticChildren(SyntheticChildren::Flags().SetCascades(options->m_cascade).
551 SetSkipPointers(options->m_skip_pointers).
552 SetSkipReferences(options->m_skip_references),
553 class_name_str.c_str()));
556 lldb::TypeCategoryImplSP category;
557 DataVisualization::Categories::GetCategory(ConstString(options->m_category.c_str()), category);
561 for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
563 const char *type_name = options->m_target_types.GetStringAtIndex(i);
564 ConstString const_type_name(type_name);
567 if (!CommandObjectTypeSynthAdd::AddSynth(const_type_name,
569 options->m_regex ? CommandObjectTypeSynthAdd::eRegexSynth : CommandObjectTypeSynthAdd::eRegularSynth,
573 error_sp->Printf("error: %s\n", error.AsCString());
580 error_sp->Printf ("error: invalid type name.\n");
589 error_sp->Printf ("error: unable to generate a class.\n");
595 error_sp->Printf ("error: no script interpreter.\n");
601 error_sp->Printf ("error: internal synchronization data missing.\n");
607 error_sp->Printf ("error: empty function, didn't add python command.\n");
613 error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
617 #endif // #ifndef LLDB_DISABLE_PYTHON
618 io_handler.SetIsDone(true);
629 CommandObjectTypeSynthAdd (CommandInterpreter &interpreter);
631 ~CommandObjectTypeSynthAdd () override
636 AddSynth(ConstString type_name,
637 lldb::SyntheticChildrenSP entry,
638 SynthFormatType type,
639 std::string category_name,
643 //-------------------------------------------------------------------------
644 // CommandObjectTypeFormatAdd
645 //-------------------------------------------------------------------------
647 class CommandObjectTypeFormatAdd : public CommandObjectParsed
652 class CommandOptions : public OptionGroup
661 ~CommandOptions () override
666 GetNumDefinitions () override;
668 const OptionDefinition*
669 GetDefinitions () override
671 return g_option_table;
675 OptionParsingStarting (CommandInterpreter &interpreter) override
678 m_skip_pointers = false;
679 m_skip_references = false;
681 m_category.assign("default");
682 m_custom_type_name.clear();
685 SetOptionValue (CommandInterpreter &interpreter,
687 const char *option_value) override
690 const int short_option = g_option_table[option_idx].short_option;
693 switch (short_option)
696 m_cascade = Args::StringToBoolean(option_value, true, &success);
698 error.SetErrorStringWithFormat("invalid value for cascade: %s", option_value);
701 m_skip_pointers = true;
704 m_category.assign(option_value);
707 m_skip_references = true;
713 m_custom_type_name.assign(option_value);
716 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
723 // Options table: Required for subclasses of Options.
725 static OptionDefinition g_option_table[];
727 // Instance variables to hold the values for command options.
730 bool m_skip_references;
731 bool m_skip_pointers;
733 std::string m_category;
734 std::string m_custom_type_name;
737 OptionGroupOptions m_option_group;
738 OptionGroupFormat m_format_options;
739 CommandOptions m_command_options;
742 GetOptions () override
744 return &m_option_group;
748 CommandObjectTypeFormatAdd (CommandInterpreter &interpreter) :
749 CommandObjectParsed (interpreter,
751 "Add a new formatting style for a type.",
753 m_option_group (interpreter),
754 m_format_options (eFormatInvalid),
757 CommandArgumentEntry type_arg;
758 CommandArgumentData type_style_arg;
760 type_style_arg.arg_type = eArgTypeName;
761 type_style_arg.arg_repetition = eArgRepeatPlus;
763 type_arg.push_back (type_style_arg);
765 m_arguments.push_back (type_arg);
769 The following examples of 'type format add' refer to this code snippet for context:
772 typedef float Afloat;
774 typedef Afloat Bfloat;
782 Adding default formatting:
784 (lldb) type format add -f hex AInt
785 (lldb) frame variable iy
787 )" " Produces hexidecimal display of iy, because no formatter is available for Bint and \
788 the one for Aint is used instead." R"(
790 To prevent this use the cascade option '-C no' to prevent evaluation of typedef chains:
793 (lldb) type format add -f hex -C no AInt
795 Similar reasoning applies to this:
797 (lldb) type format add -f hex -C no float -p
799 )" " All float values and float references are now formatted as hexadecimal, but not \
800 pointers to floats. Nor will it change the default display for Afloat and Bfloat objects."
803 // Add the "--format" to all options groups
804 m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1);
805 m_option_group.Append (&m_command_options);
806 m_option_group.Finalize();
810 ~CommandObjectTypeFormatAdd () override
816 DoExecute (Args& command, CommandReturnObject &result) override
818 const size_t argc = command.GetArgumentCount();
822 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
823 result.SetStatus(eReturnStatusFailed);
827 const Format format = m_format_options.GetFormat();
828 if (format == eFormatInvalid && m_command_options.m_custom_type_name.empty())
830 result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str());
831 result.SetStatus(eReturnStatusFailed);
835 TypeFormatImplSP entry;
837 if (m_command_options.m_custom_type_name.empty())
838 entry.reset(new TypeFormatImpl_Format(format,
839 TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
840 SetSkipPointers(m_command_options.m_skip_pointers).
841 SetSkipReferences(m_command_options.m_skip_references)));
843 entry.reset(new TypeFormatImpl_EnumType(ConstString(m_command_options.m_custom_type_name.c_str()),
844 TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
845 SetSkipPointers(m_command_options.m_skip_pointers).
846 SetSkipReferences(m_command_options.m_skip_references)));
848 // now I have a valid format, let's add it to every type
850 TypeCategoryImplSP category_sp;
851 DataVisualization::Categories::GetCategory(ConstString(m_command_options.m_category), category_sp);
855 WarnOnPotentialUnquotedUnsignedType(command, result);
857 for (size_t i = 0; i < argc; i++)
859 const char* typeA = command.GetArgumentAtIndex(i);
860 ConstString typeCS(typeA);
863 if (m_command_options.m_regex)
865 RegularExpressionSP typeRX(new RegularExpression());
866 if (!typeRX->Compile(typeCS.GetCString()))
868 result.AppendError("regex format error (maybe this is not really a regex?)");
869 result.SetStatus(eReturnStatusFailed);
872 category_sp->GetRegexTypeSummariesContainer()->Delete(typeCS);
873 category_sp->GetRegexTypeFormatsContainer()->Add(typeRX, entry);
876 category_sp->GetTypeFormatsContainer()->Add(typeCS, entry);
880 result.AppendError("empty typenames not allowed");
881 result.SetStatus(eReturnStatusFailed);
886 result.SetStatus(eReturnStatusSuccessFinishNoResult);
887 return result.Succeeded();
892 CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] =
894 { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
895 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
896 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
897 { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
898 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."},
899 { LLDB_OPT_SET_2, false, "type", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Format variables as if they were of this type."},
900 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
905 CommandObjectTypeFormatAdd::CommandOptions::GetNumDefinitions ()
907 return sizeof(g_option_table) / sizeof (OptionDefinition);
910 class CommandObjectTypeFormatterDelete : public CommandObjectParsed
913 class CommandOptions : public Options
917 CommandOptions (CommandInterpreter &interpreter) :
918 Options (interpreter)
922 ~CommandOptions () override {}
925 SetOptionValue (uint32_t option_idx, const char *option_arg) override
928 const int short_option = m_getopt_table[option_idx].val;
930 switch (short_option)
936 m_category = std::string(option_arg);
939 m_language = Language::GetLanguageTypeFromString(option_arg);
942 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
950 OptionParsingStarting () override
952 m_delete_all = false;
953 m_category = "default";
954 m_language = lldb::eLanguageTypeUnknown;
957 const OptionDefinition*
958 GetDefinitions () override
960 return g_option_table;
963 // Options table: Required for subclasses of Options.
965 static OptionDefinition g_option_table[];
967 // Instance variables to hold the values for command options.
970 std::string m_category;
971 lldb::LanguageType m_language;
974 CommandOptions m_options;
975 uint32_t m_formatter_kind_mask;
978 GetOptions () override
984 CommandObjectTypeFormatterDelete (CommandInterpreter &interpreter,
985 uint32_t formatter_kind_mask,
988 CommandObjectParsed (interpreter,
992 m_options(interpreter),
993 m_formatter_kind_mask(formatter_kind_mask)
995 CommandArgumentEntry type_arg;
996 CommandArgumentData type_style_arg;
998 type_style_arg.arg_type = eArgTypeName;
999 type_style_arg.arg_repetition = eArgRepeatPlain;
1001 type_arg.push_back (type_style_arg);
1003 m_arguments.push_back (type_arg);
1007 ~CommandObjectTypeFormatterDelete () override = default;
1011 FormatterSpecificDeletion (ConstString typeCS)
1017 DoExecute (Args& command, CommandReturnObject &result) override
1019 const size_t argc = command.GetArgumentCount();
1023 result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
1024 result.SetStatus(eReturnStatusFailed);
1028 const char* typeA = command.GetArgumentAtIndex(0);
1029 ConstString typeCS(typeA);
1033 result.AppendError("empty typenames not allowed");
1034 result.SetStatus(eReturnStatusFailed);
1038 if (m_options.m_delete_all)
1040 DataVisualization::Categories::ForEach( [this, typeCS] (const lldb::TypeCategoryImplSP& category_sp) -> bool {
1041 category_sp->Delete(typeCS, m_formatter_kind_mask);
1044 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1045 return result.Succeeded();
1048 bool delete_category = false;
1049 bool extra_deletion = false;
1051 if (m_options.m_language != lldb::eLanguageTypeUnknown)
1053 lldb::TypeCategoryImplSP category;
1054 DataVisualization::Categories::GetCategory(m_options.m_language, category);
1056 delete_category = category->Delete(typeCS, m_formatter_kind_mask);
1057 extra_deletion = FormatterSpecificDeletion(typeCS);
1061 lldb::TypeCategoryImplSP category;
1062 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
1064 delete_category = category->Delete(typeCS, m_formatter_kind_mask);
1065 extra_deletion = FormatterSpecificDeletion(typeCS);
1068 if (delete_category || extra_deletion)
1070 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1071 return result.Succeeded();
1075 result.AppendErrorWithFormat ("no custom formatter for %s.\n", typeA);
1076 result.SetStatus(eReturnStatusFailed);
1085 CommandObjectTypeFormatterDelete::CommandOptions::g_option_table[] =
1087 { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Delete from every category."},
1088 { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Delete from given category."},
1089 { LLDB_OPT_SET_3, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Delete from given language's category."},
1090 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1093 class CommandObjectTypeFormatterClear : public CommandObjectParsed
1097 class CommandOptions : public Options
1101 CommandOptions (CommandInterpreter &interpreter) :
1102 Options (interpreter)
1106 ~CommandOptions () override {}
1109 SetOptionValue (uint32_t option_idx, const char *option_arg) override
1112 const int short_option = m_getopt_table[option_idx].val;
1114 switch (short_option)
1117 m_delete_all = true;
1120 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1128 OptionParsingStarting () override
1130 m_delete_all = false;
1133 const OptionDefinition*
1134 GetDefinitions () override
1136 return g_option_table;
1139 // Options table: Required for subclasses of Options.
1141 static OptionDefinition g_option_table[];
1143 // Instance variables to hold the values for command options.
1147 CommandOptions m_options;
1148 uint32_t m_formatter_kind_mask;
1151 GetOptions () override
1157 CommandObjectTypeFormatterClear (CommandInterpreter &interpreter,
1158 uint32_t formatter_kind_mask,
1161 CommandObjectParsed (interpreter,
1165 m_options(interpreter),
1166 m_formatter_kind_mask(formatter_kind_mask)
1170 ~CommandObjectTypeFormatterClear () override
1176 FormatterSpecificDeletion ()
1181 DoExecute (Args& command, CommandReturnObject &result) override
1183 if (m_options.m_delete_all)
1185 DataVisualization::Categories::ForEach( [this] (const TypeCategoryImplSP& category_sp) -> bool {
1186 category_sp->Clear(m_formatter_kind_mask);
1192 lldb::TypeCategoryImplSP category;
1193 if (command.GetArgumentCount() > 0)
1195 const char* cat_name = command.GetArgumentAtIndex(0);
1196 ConstString cat_nameCS(cat_name);
1197 DataVisualization::Categories::GetCategory(cat_nameCS, category);
1201 DataVisualization::Categories::GetCategory(ConstString(NULL), category);
1203 category->Clear(m_formatter_kind_mask);
1206 FormatterSpecificDeletion();
1208 result.SetStatus(eReturnStatusSuccessFinishResult);
1209 return result.Succeeded();
1215 CommandObjectTypeFormatterClear::CommandOptions::g_option_table[] =
1217 { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Clear every category."},
1218 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1221 //-------------------------------------------------------------------------
1222 // CommandObjectTypeFormatDelete
1223 //-------------------------------------------------------------------------
1225 class CommandObjectTypeFormatDelete : public CommandObjectTypeFormatterDelete
1228 CommandObjectTypeFormatDelete (CommandInterpreter &interpreter) :
1229 CommandObjectTypeFormatterDelete (interpreter,
1230 eFormatCategoryItemValue | eFormatCategoryItemRegexValue,
1231 "type format delete",
1232 "Delete an existing formatting style for a type.")
1236 ~CommandObjectTypeFormatDelete () override
1241 //-------------------------------------------------------------------------
1242 // CommandObjectTypeFormatClear
1243 //-------------------------------------------------------------------------
1245 class CommandObjectTypeFormatClear : public CommandObjectTypeFormatterClear
1248 CommandObjectTypeFormatClear (CommandInterpreter &interpreter) :
1249 CommandObjectTypeFormatterClear (interpreter,
1250 eFormatCategoryItemValue | eFormatCategoryItemRegexValue,
1251 "type format clear",
1252 "Delete all existing format styles.")
1257 template <typename FormatterType>
1258 class CommandObjectTypeFormatterList : public CommandObjectParsed
1260 typedef typename FormatterType::SharedPointer FormatterSharedPointer;
1262 class CommandOptions : public Options
1266 CommandOptions (CommandInterpreter &interpreter) :
1267 Options (interpreter),
1268 m_category_regex("",""),
1269 m_category_language(lldb::eLanguageTypeUnknown, lldb::eLanguageTypeUnknown)
1273 ~CommandOptions () override {}
1276 SetOptionValue (uint32_t option_idx, const char *option_arg) override
1279 const int short_option = m_getopt_table[option_idx].val;
1281 switch (short_option)
1284 m_category_regex.SetCurrentValue(option_arg);
1287 error = m_category_language.SetValueFromString(option_arg);
1290 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1298 OptionParsingStarting () override
1300 m_category_regex.Clear();
1301 m_category_language.Clear();
1304 const OptionDefinition*
1305 GetDefinitions () override
1307 static OptionDefinition g_option_table[] =
1309 { LLDB_OPT_SET_1, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Only show categories matching this filter."},
1310 { LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Only show the category for a specific language."},
1311 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1314 return g_option_table;
1317 // Options table: Required for subclasses of Options.
1319 static OptionDefinition g_option_table[];
1321 // Instance variables to hold the values for command options.
1323 OptionValueString m_category_regex;
1324 OptionValueLanguage m_category_language;
1327 CommandOptions m_options;
1330 GetOptions () override
1336 CommandObjectTypeFormatterList (CommandInterpreter &interpreter,
1339 CommandObjectParsed (interpreter,
1343 m_options(interpreter)
1345 CommandArgumentEntry type_arg;
1346 CommandArgumentData type_style_arg;
1348 type_style_arg.arg_type = eArgTypeName;
1349 type_style_arg.arg_repetition = eArgRepeatOptional;
1351 type_arg.push_back (type_style_arg);
1353 m_arguments.push_back (type_arg);
1356 ~CommandObjectTypeFormatterList () override
1362 FormatterSpecificList (CommandReturnObject &result)
1367 DoExecute (Args& command, CommandReturnObject &result) override
1369 const size_t argc = command.GetArgumentCount();
1371 std::unique_ptr<RegularExpression> category_regex;
1372 std::unique_ptr<RegularExpression> formatter_regex;
1374 if (m_options.m_category_regex.OptionWasSet())
1376 category_regex.reset(new RegularExpression());
1377 if (!category_regex->Compile(m_options.m_category_regex.GetCurrentValue()))
1379 result.AppendErrorWithFormat("syntax error in category regular expression '%s'", m_options.m_category_regex.GetCurrentValue());
1380 result.SetStatus(eReturnStatusFailed);
1387 const char* arg = command.GetArgumentAtIndex(1);
1388 formatter_regex.reset(new RegularExpression());
1389 if (!formatter_regex->Compile(arg))
1391 result.AppendErrorWithFormat("syntax error in regular expression '%s'", arg);
1392 result.SetStatus(eReturnStatusFailed);
1397 auto category_closure = [&result, &formatter_regex] (const lldb::TypeCategoryImplSP& category) -> void {
1398 result.GetOutputStream().Printf("-----------------------\nCategory: %s\n-----------------------\n", category->GetName());
1399 TypeCategoryImpl::ForEachCallbacks<FormatterType> foreach;
1400 foreach.SetExact([&result, &formatter_regex] (ConstString name, const FormatterSharedPointer& format_sp) -> bool {
1401 if (formatter_regex)
1404 if (0 == strcmp(name.AsCString(), formatter_regex->GetText()))
1408 else if (formatter_regex->Execute(name.AsCString()))
1417 result.GetOutputStream().Printf ("%s: %s\n", name.AsCString(), format_sp->GetDescription().c_str());
1422 foreach.SetWithRegex( [&result, &formatter_regex] (RegularExpressionSP regex_sp, const FormatterSharedPointer& format_sp) -> bool {
1423 if (formatter_regex)
1426 if (0 == strcmp(regex_sp->GetText(), formatter_regex->GetText()))
1430 else if (formatter_regex->Execute(regex_sp->GetText()))
1439 result.GetOutputStream().Printf ("%s: %s\n", regex_sp->GetText(), format_sp->GetDescription().c_str());
1444 category->ForEach(foreach);
1447 if (m_options.m_category_language.OptionWasSet())
1449 lldb::TypeCategoryImplSP category_sp;
1450 DataVisualization::Categories::GetCategory(m_options.m_category_language.GetCurrentValue(), category_sp);
1452 category_closure(category_sp);
1456 DataVisualization::Categories::ForEach( [this, &command, &result, &category_regex, &formatter_regex, &category_closure] (const lldb::TypeCategoryImplSP& category) -> bool {
1460 if (0 == strcmp(category->GetName(), category_regex->GetText()))
1464 else if (category_regex->Execute(category->GetName()))
1473 category_closure(category);
1478 FormatterSpecificList(result);
1481 result.SetStatus(eReturnStatusSuccessFinishResult);
1482 return result.Succeeded();
1486 //-------------------------------------------------------------------------
1487 // CommandObjectTypeFormatList
1488 //-------------------------------------------------------------------------
1490 class CommandObjectTypeFormatList : public CommandObjectTypeFormatterList<TypeFormatImpl>
1494 CommandObjectTypeFormatList (CommandInterpreter &interpreter) :
1495 CommandObjectTypeFormatterList(interpreter,
1497 "Show a list of current formats.")
1502 #ifndef LLDB_DISABLE_PYTHON
1504 //-------------------------------------------------------------------------
1505 // CommandObjectTypeSummaryAdd
1506 //-------------------------------------------------------------------------
1508 #endif // #ifndef LLDB_DISABLE_PYTHON
1511 CommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
1514 const int short_option = m_getopt_table[option_idx].val;
1517 switch (short_option)
1520 m_flags.SetCascades(Args::StringToBoolean(option_arg, true, &success));
1522 error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
1525 m_flags.SetDontShowChildren(false);
1528 m_flags.SetHideEmptyAggregates(true);
1531 m_flags.SetDontShowValue(true);
1534 m_flags.SetShowMembersOneLiner(true);
1537 m_format_string = std::string(option_arg);
1540 m_flags.SetSkipPointers(true);
1543 m_flags.SetSkipReferences(true);
1549 m_name.SetCString(option_arg);
1552 m_python_script = std::string(option_arg);
1553 m_is_add_script = true;
1556 m_python_function = std::string(option_arg);
1557 m_is_add_script = true;
1560 m_is_add_script = true;
1563 m_category = std::string(option_arg);
1566 m_flags.SetHideItemNames(true);
1569 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1577 CommandObjectTypeSummaryAdd::CommandOptions::OptionParsingStarting ()
1579 m_flags.Clear().SetCascades().SetDontShowChildren().SetDontShowValue(false);
1580 m_flags.SetShowMembersOneLiner(false).SetSkipPointers(false).SetSkipReferences(false).SetHideItemNames(false);
1584 m_python_script = "";
1585 m_python_function = "";
1586 m_format_string = "";
1587 m_is_add_script = false;
1588 m_category = "default";
1593 #ifndef LLDB_DISABLE_PYTHON
1596 CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturnObject &result)
1598 const size_t argc = command.GetArgumentCount();
1600 if (argc < 1 && !m_options.m_name)
1602 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
1603 result.SetStatus(eReturnStatusFailed);
1607 TypeSummaryImplSP script_format;
1609 if (!m_options.m_python_function.empty()) // we have a Python function ready to use
1611 const char *funct_name = m_options.m_python_function.c_str();
1612 if (!funct_name || !funct_name[0])
1614 result.AppendError ("function name empty.\n");
1615 result.SetStatus (eReturnStatusFailed);
1619 std::string code = (" " + m_options.m_python_function + "(valobj,internal_dict)");
1621 script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
1625 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1627 if (interpreter && interpreter->CheckObjectExists(funct_name) == false)
1628 result.AppendWarningWithFormat("The provided function \"%s\" does not exist - "
1629 "please define it before attempting to use this summary.\n",
1632 else if (!m_options.m_python_script.empty()) // we have a quick 1-line script, just use it
1634 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1637 result.AppendError ("script interpreter missing - unable to generate function wrapper.\n");
1638 result.SetStatus (eReturnStatusFailed);
1641 StringList funct_sl;
1642 funct_sl << m_options.m_python_script.c_str();
1643 std::string funct_name_str;
1644 if (!interpreter->GenerateTypeScriptFunction (funct_sl,
1647 result.AppendError ("unable to generate function wrapper.\n");
1648 result.SetStatus (eReturnStatusFailed);
1651 if (funct_name_str.empty())
1653 result.AppendError ("script interpreter failed to generate a valid function name.\n");
1654 result.SetStatus (eReturnStatusFailed);
1658 std::string code = " " + m_options.m_python_script;
1660 script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
1661 funct_name_str.c_str(),
1666 // Use an IOHandler to grab Python code from the user
1667 ScriptAddOptions *options = new ScriptAddOptions(m_options.m_flags,
1670 m_options.m_category);
1672 for (size_t i = 0; i < argc; i++)
1674 const char* typeA = command.GetArgumentAtIndex(i);
1675 if (typeA && *typeA)
1676 options->m_target_types << typeA;
1679 result.AppendError("empty typenames not allowed");
1680 result.SetStatus(eReturnStatusFailed);
1685 m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
1686 *this, // IOHandlerDelegate
1687 true, // Run IOHandler in async mode
1688 options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
1689 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1691 return result.Succeeded();
1694 // if I am here, script_format must point to something good, so I can add that
1695 // as a script summary to all interested parties
1699 for (size_t i = 0; i < command.GetArgumentCount(); i++)
1701 const char *type_name = command.GetArgumentAtIndex(i);
1702 CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
1704 (m_options.m_regex ? eRegexSummary : eRegularSummary),
1705 m_options.m_category,
1709 result.AppendError(error.AsCString());
1710 result.SetStatus(eReturnStatusFailed);
1715 if (m_options.m_name)
1717 AddSummary(m_options.m_name, script_format, eNamedSummary, m_options.m_category, &error);
1720 result.AppendError(error.AsCString());
1721 result.AppendError("added to types, but not given a name");
1722 result.SetStatus(eReturnStatusFailed);
1727 return result.Succeeded();
1734 CommandObjectTypeSummaryAdd::Execute_StringSummary (Args& command, CommandReturnObject &result)
1736 const size_t argc = command.GetArgumentCount();
1738 if (argc < 1 && !m_options.m_name)
1740 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
1741 result.SetStatus(eReturnStatusFailed);
1745 if (!m_options.m_flags.GetShowMembersOneLiner() && m_options.m_format_string.empty())
1747 result.AppendError("empty summary strings not allowed");
1748 result.SetStatus(eReturnStatusFailed);
1752 const char* format_cstr = (m_options.m_flags.GetShowMembersOneLiner() ? "" : m_options.m_format_string.c_str());
1754 // ${var%S} is an endless recursion, prevent it
1755 if (strcmp(format_cstr, "${var%S}") == 0)
1757 result.AppendError("recursive summary not allowed");
1758 result.SetStatus(eReturnStatusFailed);
1764 lldb::TypeSummaryImplSP entry(new StringSummaryFormat(m_options.m_flags,
1769 result.AppendError(error.AsCString());
1770 result.SetStatus(eReturnStatusFailed);
1774 // now I have a valid format, let's add it to every type
1776 for (size_t i = 0; i < argc; i++)
1778 const char* typeA = command.GetArgumentAtIndex(i);
1779 if (!typeA || typeA[0] == '\0')
1781 result.AppendError("empty typenames not allowed");
1782 result.SetStatus(eReturnStatusFailed);
1785 ConstString typeCS(typeA);
1789 (m_options.m_regex ? eRegexSummary : eRegularSummary),
1790 m_options.m_category,
1795 result.AppendError(error.AsCString());
1796 result.SetStatus(eReturnStatusFailed);
1801 if (m_options.m_name)
1803 AddSummary(m_options.m_name, entry, eNamedSummary, m_options.m_category, &error);
1806 result.AppendError(error.AsCString());
1807 result.AppendError("added to types, but not given a name");
1808 result.SetStatus(eReturnStatusFailed);
1813 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1814 return result.Succeeded();
1817 CommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter) :
1818 CommandObjectParsed (interpreter,
1820 "Add a new summary style for a type.",
1822 IOHandlerDelegateMultiline ("DONE"),
1823 m_options (interpreter)
1825 CommandArgumentEntry type_arg;
1826 CommandArgumentData type_style_arg;
1828 type_style_arg.arg_type = eArgTypeName;
1829 type_style_arg.arg_repetition = eArgRepeatPlus;
1831 type_arg.push_back (type_style_arg);
1833 m_arguments.push_back (type_arg);
1837 The following examples of 'type summary add' refer to this code snippet for context:
1843 JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}
1845 JustADemo demo_instance(42, 3.14);
1847 typedef JustADemo NewDemo;
1848 NewDemo new_demo_instance(42, 3.14);
1850 (lldb) type summary add --summary-string "the answer is ${*var.ptr}" JustADemo
1852 Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42"
1854 (lldb) type summary add --summary-string "the answer is ${*var.ptr}, and the question is ${var.value}" JustADemo
1856 Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42 and the question is 3.14"
1858 )" "Alternatively, you could define formatting for all pointers to integers and \
1859 rely on that when formatting JustADemo to obtain the same result:" R"(
1861 (lldb) type summary add --summary-string "${var%V} -> ${*var}" "int *"
1862 (lldb) type summary add --summary-string "the answer is ${var.ptr}, and the question is ${var.value}" JustADemo
1864 )" "Type summaries are automatically applied to derived typedefs, so the examples \
1865 above apply to both JustADemo and NewDemo. The cascade option can be used to \
1866 suppress this behavior:" R"(
1868 (lldb) type summary add --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo -C no
1870 The summary will now be used for values of JustADemo but not NewDemo.
1872 )" "By default summaries are shown for pointers and references to values of the \
1873 specified type. To suppress formatting for pointers use the -p option, or apply \
1874 the corresponding -r option to suppress formatting for references:" R"(
1876 (lldb) type summary add -p -r --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo
1878 )" "One-line summaries including all fields in a type can be inferred without supplying an \
1879 explicit summary string by passing the -c option:" R"(
1881 (lldb) type summary add -c JustADemo
1882 (lldb) frame variable demo_instance
1883 (ptr=<address>, value=3.14)
1885 )" "Type summaries normally suppress the nested display of individual fields. To \
1886 supply a summary to supplement the default structure add the -e option:" R"(
1888 (lldb) type summary add -e --summary-string "*ptr = ${*var.ptr}" JustADemo
1890 )" "Now when displaying JustADemo values the int* is displayed, followed by the \
1891 standard LLDB sequence of children, one per line:" R"(
1898 )" "You can also add summaries written in Python. These scripts use lldb public API to \
1899 gather information from your variables and produce a meaningful summary. To start a \
1900 multi-line script use the -P option. The function declaration will be displayed along with \
1901 a comment describing the two arguments. End your script with the word 'DONE' on a line by \
1904 (lldb) type summary add JustADemo -P
1905 def function (valobj,internal_dict):
1906 """valobj: an SBValue which you want to provide a summary for
1907 internal_dict: an LLDB support object not to be used"""
1908 value = valobj.GetChildMemberWithName('value');
1909 return 'My value is ' + value.GetValue();
1912 Alternatively, the -o option can be used when providing a simple one-line Python script:
1914 (lldb) type summary add JustADemo -o "value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();")"
1919 CommandObjectTypeSummaryAdd::DoExecute (Args& command, CommandReturnObject &result)
1921 WarnOnPotentialUnquotedUnsignedType(command, result);
1923 if (m_options.m_is_add_script)
1925 #ifndef LLDB_DISABLE_PYTHON
1926 return Execute_ScriptSummary(command, result);
1928 result.AppendError ("python is disabled");
1929 result.SetStatus(eReturnStatusFailed);
1934 return Execute_StringSummary(command, result);
1938 FixArrayTypeNameWithRegex (ConstString &type_name)
1940 llvm::StringRef type_name_ref(type_name.GetStringRef());
1942 if (type_name_ref.endswith("[]"))
1944 std::string type_name_str(type_name.GetCString());
1945 type_name_str.resize(type_name_str.length()-2);
1946 if (type_name_str.back() != ' ')
1947 type_name_str.append(" \\[[0-9]+\\]");
1949 type_name_str.append("\\[[0-9]+\\]");
1950 type_name.SetCString(type_name_str.c_str());
1957 CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name,
1958 TypeSummaryImplSP entry,
1959 SummaryFormatType type,
1960 std::string category_name,
1963 lldb::TypeCategoryImplSP category;
1964 DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
1966 if (type == eRegularSummary)
1968 if (FixArrayTypeNameWithRegex (type_name))
1969 type = eRegexSummary;
1972 if (type == eRegexSummary)
1974 RegularExpressionSP typeRX(new RegularExpression());
1975 if (!typeRX->Compile(type_name.GetCString()))
1978 error->SetErrorString("regex format error (maybe this is not really a regex?)");
1982 category->GetRegexTypeSummariesContainer()->Delete(type_name);
1983 category->GetRegexTypeSummariesContainer()->Add(typeRX, entry);
1987 else if (type == eNamedSummary)
1989 // system named summaries do not exist (yet?)
1990 DataVisualization::NamedSummaryFormats::Add(type_name,entry);
1995 category->GetTypeSummariesContainer()->Add(type_name, entry);
2001 CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] =
2003 { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
2004 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
2005 { LLDB_OPT_SET_ALL, false, "no-value", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't show the value, just show the summary, for this type."},
2006 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
2007 { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
2008 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."},
2009 { LLDB_OPT_SET_1 , true, "inline-children", 'c', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "If true, inline all child values into summary string."},
2010 { LLDB_OPT_SET_1 , false, "omit-names", 'O', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "If true, omit value names in the summary display."},
2011 { LLDB_OPT_SET_2 , true, "summary-string", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSummaryString, "Summary string used to display text and object contents."},
2012 { LLDB_OPT_SET_3, false, "python-script", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonScript, "Give a one-liner Python script as part of the command."},
2013 { LLDB_OPT_SET_3, false, "python-function", 'F', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, "Give the name of a Python function to use for this type."},
2014 { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Input Python code to use for this type manually."},
2015 { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Expand aggregate data types to show children on separate lines."},
2016 { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "hide-empty", 'h', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Do not expand aggregate data types with no children."},
2017 { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "A name for this summary string."},
2018 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2022 //-------------------------------------------------------------------------
2023 // CommandObjectTypeSummaryDelete
2024 //-------------------------------------------------------------------------
2026 class CommandObjectTypeSummaryDelete : public CommandObjectTypeFormatterDelete
2029 CommandObjectTypeSummaryDelete (CommandInterpreter &interpreter) :
2030 CommandObjectTypeFormatterDelete (interpreter,
2031 eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary,
2032 "type summary delete",
2033 "Delete an existing summary for a type.")
2037 ~CommandObjectTypeSummaryDelete () override
2043 FormatterSpecificDeletion (ConstString typeCS) override
2045 if (m_options.m_language != lldb::eLanguageTypeUnknown)
2047 return DataVisualization::NamedSummaryFormats::Delete(typeCS);
2051 class CommandObjectTypeSummaryClear : public CommandObjectTypeFormatterClear
2054 CommandObjectTypeSummaryClear (CommandInterpreter &interpreter) :
2055 CommandObjectTypeFormatterClear (interpreter,
2056 eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary,
2057 "type summary clear",
2058 "Delete all existing summaries.")
2064 FormatterSpecificDeletion () override
2066 DataVisualization::NamedSummaryFormats::Clear();
2070 //-------------------------------------------------------------------------
2071 // CommandObjectTypeSummaryList
2072 //-------------------------------------------------------------------------
2074 class CommandObjectTypeSummaryList : public CommandObjectTypeFormatterList<TypeSummaryImpl>
2078 CommandObjectTypeSummaryList (CommandInterpreter &interpreter) :
2079 CommandObjectTypeFormatterList(interpreter,
2080 "type summary list",
2081 "Show a list of current summaries.")
2087 FormatterSpecificList (CommandReturnObject &result) override
2089 if (DataVisualization::NamedSummaryFormats::GetCount() > 0)
2091 result.GetOutputStream().Printf("Named summaries:\n");
2092 DataVisualization::NamedSummaryFormats::ForEach( [&result] (ConstString name, const TypeSummaryImplSP& summary_sp) -> bool {
2093 result.GetOutputStream().Printf ("%s: %s\n", name.AsCString(), summary_sp->GetDescription().c_str());
2100 //-------------------------------------------------------------------------
2101 // CommandObjectTypeCategoryDefine
2102 //-------------------------------------------------------------------------
2104 class CommandObjectTypeCategoryDefine : public CommandObjectParsed
2107 class CommandOptions : public Options
2111 CommandOptions (CommandInterpreter &interpreter) :
2112 Options (interpreter),
2113 m_define_enabled(false,false),
2114 m_cate_language(eLanguageTypeUnknown,eLanguageTypeUnknown)
2118 ~CommandOptions () override {}
2121 SetOptionValue (uint32_t option_idx, const char *option_arg) override
2124 const int short_option = m_getopt_table[option_idx].val;
2126 switch (short_option)
2129 m_define_enabled.SetValueFromString("true");
2132 error = m_cate_language.SetValueFromString(option_arg);
2135 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
2143 OptionParsingStarting () override
2145 m_define_enabled.Clear();
2146 m_cate_language.Clear();
2149 const OptionDefinition*
2150 GetDefinitions () override
2152 return g_option_table;
2155 // Options table: Required for subclasses of Options.
2157 static OptionDefinition g_option_table[];
2159 // Instance variables to hold the values for command options.
2161 OptionValueBoolean m_define_enabled;
2162 OptionValueLanguage m_cate_language;
2167 CommandOptions m_options;
2170 GetOptions () override
2176 CommandObjectTypeCategoryDefine (CommandInterpreter &interpreter) :
2177 CommandObjectParsed (interpreter,
2178 "type category define",
2179 "Define a new category as a source of formatters.",
2181 m_options(interpreter)
2183 CommandArgumentEntry type_arg;
2184 CommandArgumentData type_style_arg;
2186 type_style_arg.arg_type = eArgTypeName;
2187 type_style_arg.arg_repetition = eArgRepeatPlus;
2189 type_arg.push_back (type_style_arg);
2191 m_arguments.push_back (type_arg);
2195 ~CommandObjectTypeCategoryDefine () override
2201 DoExecute (Args& command, CommandReturnObject &result) override
2203 const size_t argc = command.GetArgumentCount();
2207 result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str());
2208 result.SetStatus(eReturnStatusFailed);
2212 for (size_t i = 0; i < argc; i++)
2214 const char* cateName = command.GetArgumentAtIndex(i);
2215 TypeCategoryImplSP category_sp;
2216 if (DataVisualization::Categories::GetCategory(ConstString(cateName), category_sp) && category_sp)
2218 category_sp->AddLanguage(m_options.m_cate_language.GetCurrentValue());
2219 if (m_options.m_define_enabled.GetCurrentValue())
2220 DataVisualization::Categories::Enable(category_sp, TypeCategoryMap::Default);
2224 result.SetStatus(eReturnStatusSuccessFinishResult);
2225 return result.Succeeded();
2231 CommandObjectTypeCategoryDefine::CommandOptions::g_option_table[] =
2233 { LLDB_OPT_SET_ALL, false, "enabled", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "If specified, this category will be created enabled."},
2234 { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Specify the language that this category is supported for."},
2235 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2238 //-------------------------------------------------------------------------
2239 // CommandObjectTypeCategoryEnable
2240 //-------------------------------------------------------------------------
2242 class CommandObjectTypeCategoryEnable : public CommandObjectParsed
2244 class CommandOptions : public Options
2248 CommandOptions (CommandInterpreter &interpreter) :
2249 Options (interpreter)
2253 ~CommandOptions () override {}
2256 SetOptionValue (uint32_t option_idx, const char *option_arg) override
2259 const int short_option = m_getopt_table[option_idx].val;
2261 switch (short_option)
2266 m_language = Language::GetLanguageTypeFromString(option_arg);
2267 if (m_language == lldb::eLanguageTypeUnknown)
2268 error.SetErrorStringWithFormat ("unrecognized language '%s'", option_arg);
2272 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
2280 OptionParsingStarting () override
2282 m_language = lldb::eLanguageTypeUnknown;
2285 const OptionDefinition*
2286 GetDefinitions () override
2288 return g_option_table;
2291 // Options table: Required for subclasses of Options.
2293 static OptionDefinition g_option_table[];
2295 // Instance variables to hold the values for command options.
2297 lldb::LanguageType m_language;
2301 CommandOptions m_options;
2304 GetOptions () override
2310 CommandObjectTypeCategoryEnable (CommandInterpreter &interpreter) :
2311 CommandObjectParsed (interpreter,
2312 "type category enable",
2313 "Enable a category as a source of formatters.",
2315 m_options(interpreter)
2317 CommandArgumentEntry type_arg;
2318 CommandArgumentData type_style_arg;
2320 type_style_arg.arg_type = eArgTypeName;
2321 type_style_arg.arg_repetition = eArgRepeatPlus;
2323 type_arg.push_back (type_style_arg);
2325 m_arguments.push_back (type_arg);
2329 ~CommandObjectTypeCategoryEnable () override
2335 DoExecute (Args& command, CommandReturnObject &result) override
2337 const size_t argc = command.GetArgumentCount();
2340 m_options.m_language == lldb::eLanguageTypeUnknown)
2342 result.AppendErrorWithFormat ("%s takes arguments and/or a language", m_cmd_name.c_str());
2343 result.SetStatus(eReturnStatusFailed);
2347 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
2349 DataVisualization::Categories::EnableStar();
2353 for (int i = argc - 1; i >= 0; i--)
2355 const char* typeA = command.GetArgumentAtIndex(i);
2356 ConstString typeCS(typeA);
2360 result.AppendError("empty category name not allowed");
2361 result.SetStatus(eReturnStatusFailed);
2364 DataVisualization::Categories::Enable(typeCS);
2365 lldb::TypeCategoryImplSP cate;
2366 if (DataVisualization::Categories::GetCategory(typeCS, cate) && cate.get())
2368 if (cate->GetCount() == 0)
2370 result.AppendWarning("empty category enabled (typo?)");
2376 if (m_options.m_language != lldb::eLanguageTypeUnknown)
2377 DataVisualization::Categories::Enable(m_options.m_language);
2379 result.SetStatus(eReturnStatusSuccessFinishResult);
2380 return result.Succeeded();
2386 CommandObjectTypeCategoryEnable::CommandOptions::g_option_table[] =
2388 { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Enable the category for this language."},
2389 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2392 //-------------------------------------------------------------------------
2393 // CommandObjectTypeCategoryDelete
2394 //-------------------------------------------------------------------------
2396 class CommandObjectTypeCategoryDelete : public CommandObjectParsed
2399 CommandObjectTypeCategoryDelete (CommandInterpreter &interpreter) :
2400 CommandObjectParsed (interpreter,
2401 "type category delete",
2402 "Delete a category and all associated formatters.",
2405 CommandArgumentEntry type_arg;
2406 CommandArgumentData type_style_arg;
2408 type_style_arg.arg_type = eArgTypeName;
2409 type_style_arg.arg_repetition = eArgRepeatPlus;
2411 type_arg.push_back (type_style_arg);
2413 m_arguments.push_back (type_arg);
2417 ~CommandObjectTypeCategoryDelete () override
2423 DoExecute (Args& command, CommandReturnObject &result) override
2425 const size_t argc = command.GetArgumentCount();
2429 result.AppendErrorWithFormat ("%s takes 1 or more arg.\n", m_cmd_name.c_str());
2430 result.SetStatus(eReturnStatusFailed);
2434 bool success = true;
2436 // the order is not relevant here
2437 for (int i = argc - 1; i >= 0; i--)
2439 const char* typeA = command.GetArgumentAtIndex(i);
2440 ConstString typeCS(typeA);
2444 result.AppendError("empty category name not allowed");
2445 result.SetStatus(eReturnStatusFailed);
2448 if (!DataVisualization::Categories::Delete(typeCS))
2449 success = false; // keep deleting even if we hit an error
2453 result.SetStatus(eReturnStatusSuccessFinishResult);
2454 return result.Succeeded();
2458 result.AppendError("cannot delete one or more categories\n");
2459 result.SetStatus(eReturnStatusFailed);
2465 //-------------------------------------------------------------------------
2466 // CommandObjectTypeCategoryDisable
2467 //-------------------------------------------------------------------------
2469 class CommandObjectTypeCategoryDisable : public CommandObjectParsed
2471 class CommandOptions : public Options
2475 CommandOptions (CommandInterpreter &interpreter) :
2476 Options (interpreter)
2480 ~CommandOptions () override {}
2483 SetOptionValue (uint32_t option_idx, const char *option_arg) override
2486 const int short_option = m_getopt_table[option_idx].val;
2488 switch (short_option)
2493 m_language = Language::GetLanguageTypeFromString(option_arg);
2494 if (m_language == lldb::eLanguageTypeUnknown)
2495 error.SetErrorStringWithFormat ("unrecognized language '%s'", option_arg);
2499 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
2507 OptionParsingStarting () override
2509 m_language = lldb::eLanguageTypeUnknown;
2512 const OptionDefinition*
2513 GetDefinitions () override
2515 return g_option_table;
2518 // Options table: Required for subclasses of Options.
2520 static OptionDefinition g_option_table[];
2522 // Instance variables to hold the values for command options.
2524 lldb::LanguageType m_language;
2528 CommandOptions m_options;
2531 GetOptions () override
2537 CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) :
2538 CommandObjectParsed (interpreter,
2539 "type category disable",
2540 "Disable a category as a source of formatters.",
2542 m_options(interpreter)
2544 CommandArgumentEntry type_arg;
2545 CommandArgumentData type_style_arg;
2547 type_style_arg.arg_type = eArgTypeName;
2548 type_style_arg.arg_repetition = eArgRepeatPlus;
2550 type_arg.push_back (type_style_arg);
2552 m_arguments.push_back (type_arg);
2556 ~CommandObjectTypeCategoryDisable () override
2562 DoExecute (Args& command, CommandReturnObject &result) override
2564 const size_t argc = command.GetArgumentCount();
2567 m_options.m_language == lldb::eLanguageTypeUnknown)
2569 result.AppendErrorWithFormat ("%s takes arguments and/or a language", m_cmd_name.c_str());
2570 result.SetStatus(eReturnStatusFailed);
2574 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
2576 DataVisualization::Categories::DisableStar();
2580 // the order is not relevant here
2581 for (int i = argc - 1; i >= 0; i--)
2583 const char* typeA = command.GetArgumentAtIndex(i);
2584 ConstString typeCS(typeA);
2588 result.AppendError("empty category name not allowed");
2589 result.SetStatus(eReturnStatusFailed);
2592 DataVisualization::Categories::Disable(typeCS);
2596 if (m_options.m_language != lldb::eLanguageTypeUnknown)
2597 DataVisualization::Categories::Disable(m_options.m_language);
2599 result.SetStatus(eReturnStatusSuccessFinishResult);
2600 return result.Succeeded();
2606 CommandObjectTypeCategoryDisable::CommandOptions::g_option_table[] =
2608 { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Enable the category for this language."},
2609 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2612 //-------------------------------------------------------------------------
2613 // CommandObjectTypeCategoryList
2614 //-------------------------------------------------------------------------
2616 class CommandObjectTypeCategoryList : public CommandObjectParsed
2619 CommandObjectTypeCategoryList (CommandInterpreter &interpreter) :
2620 CommandObjectParsed (interpreter,
2621 "type category list",
2622 "Provide a list of all existing categories.",
2625 CommandArgumentEntry type_arg;
2626 CommandArgumentData type_style_arg;
2628 type_style_arg.arg_type = eArgTypeName;
2629 type_style_arg.arg_repetition = eArgRepeatOptional;
2631 type_arg.push_back (type_style_arg);
2633 m_arguments.push_back (type_arg);
2636 ~CommandObjectTypeCategoryList () override
2642 DoExecute (Args& command, CommandReturnObject &result) override
2644 const size_t argc = command.GetArgumentCount();
2646 std::unique_ptr<RegularExpression> regex;
2650 regex.reset(new RegularExpression());
2651 const char* arg = command.GetArgumentAtIndex(0);
2652 if (!regex->Compile(arg))
2654 result.AppendErrorWithFormat("syntax error in category regular expression '%s'", arg);
2655 result.SetStatus(eReturnStatusFailed);
2661 result.AppendErrorWithFormat ("%s takes 0 or one arg.\n", m_cmd_name.c_str());
2662 result.SetStatus(eReturnStatusFailed);
2666 DataVisualization::Categories::ForEach( [®ex, &result] (const lldb::TypeCategoryImplSP& category_sp) -> bool {
2670 if (0 == strcmp(category_sp->GetName(), regex->GetText()))
2674 else if (regex->Execute(category_sp->GetName()))
2683 result.GetOutputStream().Printf("Category: %s\n", category_sp->GetDescription().c_str());
2688 result.SetStatus(eReturnStatusSuccessFinishResult);
2689 return result.Succeeded();
2694 //-------------------------------------------------------------------------
2695 // CommandObjectTypeFilterList
2696 //-------------------------------------------------------------------------
2698 class CommandObjectTypeFilterList : public CommandObjectTypeFormatterList<TypeFilterImpl>
2702 CommandObjectTypeFilterList (CommandInterpreter &interpreter) :
2703 CommandObjectTypeFormatterList(interpreter,
2705 "Show a list of current filters.")
2710 #ifndef LLDB_DISABLE_PYTHON
2712 //-------------------------------------------------------------------------
2713 // CommandObjectTypeSynthList
2714 //-------------------------------------------------------------------------
2716 class CommandObjectTypeSynthList : public CommandObjectTypeFormatterList<SyntheticChildren>
2720 CommandObjectTypeSynthList (CommandInterpreter &interpreter) :
2721 CommandObjectTypeFormatterList(interpreter,
2722 "type synthetic list",
2723 "Show a list of current synthetic providers.")
2728 #endif // #ifndef LLDB_DISABLE_PYTHON
2729 //-------------------------------------------------------------------------
2730 // CommandObjectTypeFilterDelete
2731 //-------------------------------------------------------------------------
2733 class CommandObjectTypeFilterDelete : public CommandObjectTypeFormatterDelete
2736 CommandObjectTypeFilterDelete (CommandInterpreter &interpreter) :
2737 CommandObjectTypeFormatterDelete (interpreter,
2738 eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter,
2739 "type filter delete",
2740 "Delete an existing filter for a type.")
2744 ~CommandObjectTypeFilterDelete () override
2749 #ifndef LLDB_DISABLE_PYTHON
2751 //-------------------------------------------------------------------------
2752 // CommandObjectTypeSynthDelete
2753 //-------------------------------------------------------------------------
2755 class CommandObjectTypeSynthDelete : public CommandObjectTypeFormatterDelete
2758 CommandObjectTypeSynthDelete (CommandInterpreter &interpreter) :
2759 CommandObjectTypeFormatterDelete (interpreter,
2760 eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth,
2761 "type synthetic delete",
2762 "Delete an existing synthetic provider for a type.")
2766 ~CommandObjectTypeSynthDelete () override
2771 #endif // #ifndef LLDB_DISABLE_PYTHON
2773 //-------------------------------------------------------------------------
2774 // CommandObjectTypeFilterClear
2775 //-------------------------------------------------------------------------
2777 class CommandObjectTypeFilterClear : public CommandObjectTypeFormatterClear
2780 CommandObjectTypeFilterClear (CommandInterpreter &interpreter) :
2781 CommandObjectTypeFormatterClear (interpreter,
2782 eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter,
2783 "type filter clear",
2784 "Delete all existing filter.")
2789 #ifndef LLDB_DISABLE_PYTHON
2790 //-------------------------------------------------------------------------
2791 // CommandObjectTypeSynthClear
2792 //-------------------------------------------------------------------------
2794 class CommandObjectTypeSynthClear : public CommandObjectTypeFormatterClear
2797 CommandObjectTypeSynthClear (CommandInterpreter &interpreter) :
2798 CommandObjectTypeFormatterClear (interpreter,
2799 eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth,
2800 "type synthetic clear",
2801 "Delete all existing synthetic providers.")
2807 CommandObjectTypeSynthAdd::Execute_HandwritePython (Args& command, CommandReturnObject &result)
2809 SynthAddOptions *options = new SynthAddOptions ( m_options.m_skip_pointers,
2810 m_options.m_skip_references,
2811 m_options.m_cascade,
2813 m_options.m_category);
2815 const size_t argc = command.GetArgumentCount();
2817 for (size_t i = 0; i < argc; i++)
2819 const char* typeA = command.GetArgumentAtIndex(i);
2820 if (typeA && *typeA)
2821 options->m_target_types << typeA;
2824 result.AppendError("empty typenames not allowed");
2825 result.SetStatus(eReturnStatusFailed);
2830 m_interpreter.GetPythonCommandsFromIOHandler (" ", // Prompt
2831 *this, // IOHandlerDelegate
2832 true, // Run IOHandler in async mode
2833 options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
2834 result.SetStatus(eReturnStatusSuccessFinishNoResult);
2835 return result.Succeeded();
2839 CommandObjectTypeSynthAdd::Execute_PythonClass (Args& command, CommandReturnObject &result)
2841 const size_t argc = command.GetArgumentCount();
2845 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
2846 result.SetStatus(eReturnStatusFailed);
2850 if (m_options.m_class_name.empty() && !m_options.m_input_python)
2852 result.AppendErrorWithFormat ("%s needs either a Python class name or -P to directly input Python code.\n", m_cmd_name.c_str());
2853 result.SetStatus(eReturnStatusFailed);
2857 SyntheticChildrenSP entry;
2859 ScriptedSyntheticChildren* impl = new ScriptedSyntheticChildren(SyntheticChildren::Flags().
2860 SetCascades(m_options.m_cascade).
2861 SetSkipPointers(m_options.m_skip_pointers).
2862 SetSkipReferences(m_options.m_skip_references),
2863 m_options.m_class_name.c_str());
2867 ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
2869 if (interpreter && interpreter->CheckObjectExists(impl->GetPythonClassName()) == false)
2870 result.AppendWarning("The provided class does not exist - please define it before attempting to use this synthetic provider");
2872 // now I have a valid provider, let's add it to every type
2874 lldb::TypeCategoryImplSP category;
2875 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
2879 for (size_t i = 0; i < argc; i++)
2881 const char* typeA = command.GetArgumentAtIndex(i);
2882 ConstString typeCS(typeA);
2885 if (!AddSynth(typeCS,
2887 m_options.m_regex ? eRegexSynth : eRegularSynth,
2888 m_options.m_category,
2891 result.AppendError(error.AsCString());
2892 result.SetStatus(eReturnStatusFailed);
2898 result.AppendError("empty typenames not allowed");
2899 result.SetStatus(eReturnStatusFailed);
2904 result.SetStatus(eReturnStatusSuccessFinishNoResult);
2905 return result.Succeeded();
2908 CommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) :
2909 CommandObjectParsed (interpreter,
2910 "type synthetic add",
2911 "Add a new synthetic provider for a type.",
2913 IOHandlerDelegateMultiline ("DONE"),
2914 m_options (interpreter)
2916 CommandArgumentEntry type_arg;
2917 CommandArgumentData type_style_arg;
2919 type_style_arg.arg_type = eArgTypeName;
2920 type_style_arg.arg_repetition = eArgRepeatPlus;
2922 type_arg.push_back (type_style_arg);
2924 m_arguments.push_back (type_arg);
2929 CommandObjectTypeSynthAdd::AddSynth(ConstString type_name,
2930 SyntheticChildrenSP entry,
2931 SynthFormatType type,
2932 std::string category_name,
2935 lldb::TypeCategoryImplSP category;
2936 DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
2938 if (type == eRegularSynth)
2940 if (FixArrayTypeNameWithRegex (type_name))
2944 if (category->AnyMatches(type_name,
2945 eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter,
2949 error->SetErrorStringWithFormat("cannot add synthetic for type %s when filter is defined in same category!", type_name.AsCString());
2953 if (type == eRegexSynth)
2955 RegularExpressionSP typeRX(new RegularExpression());
2956 if (!typeRX->Compile(type_name.GetCString()))
2959 error->SetErrorString("regex format error (maybe this is not really a regex?)");
2963 category->GetRegexTypeSyntheticsContainer()->Delete(type_name);
2964 category->GetRegexTypeSyntheticsContainer()->Add(typeRX, entry);
2970 category->GetTypeSyntheticsContainer()->Add(type_name, entry);
2976 CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] =
2978 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
2979 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
2980 { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
2981 { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
2982 { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass, "Use this Python class to produce synthetic children."},
2983 { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type Python code to generate a class that provides synthetic children."},
2984 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."},
2985 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2988 #endif // #ifndef LLDB_DISABLE_PYTHON
2990 class CommandObjectTypeFilterAdd : public CommandObjectParsed
2995 class CommandOptions : public Options
2997 typedef std::vector<std::string> option_vector;
3000 CommandOptions (CommandInterpreter &interpreter) :
3001 Options (interpreter)
3005 ~CommandOptions () override {}
3008 SetOptionValue (uint32_t option_idx, const char *option_arg) override
3011 const int short_option = m_getopt_table[option_idx].val;
3014 switch (short_option)
3017 m_cascade = Args::StringToBoolean(option_arg, true, &success);
3019 error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
3022 m_expr_paths.push_back(option_arg);
3023 has_child_list = true;
3026 m_skip_pointers = true;
3029 m_skip_references = true;
3032 m_category = std::string(option_arg);
3038 error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
3046 OptionParsingStarting () override
3049 m_skip_pointers = false;
3050 m_skip_references = false;
3051 m_category = "default";
3052 m_expr_paths.clear();
3053 has_child_list = false;
3057 const OptionDefinition*
3058 GetDefinitions () override
3060 return g_option_table;
3063 // Options table: Required for subclasses of Options.
3065 static OptionDefinition g_option_table[];
3067 // Instance variables to hold the values for command options.
3070 bool m_skip_references;
3071 bool m_skip_pointers;
3072 bool m_input_python;
3073 option_vector m_expr_paths;
3074 std::string m_category;
3076 bool has_child_list;
3080 typedef option_vector::iterator ExpressionPathsIterator;
3083 CommandOptions m_options;
3086 GetOptions () override
3091 enum FilterFormatType
3098 AddFilter(ConstString type_name,
3099 TypeFilterImplSP entry,
3100 FilterFormatType type,
3101 std::string category_name,
3104 lldb::TypeCategoryImplSP category;
3105 DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
3107 if (type == eRegularFilter)
3109 if (FixArrayTypeNameWithRegex (type_name))
3110 type = eRegexFilter;
3113 if (category->AnyMatches(type_name,
3114 eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth,
3118 error->SetErrorStringWithFormat("cannot add filter for type %s when synthetic is defined in same category!", type_name.AsCString());
3122 if (type == eRegexFilter)
3124 RegularExpressionSP typeRX(new RegularExpression());
3125 if (!typeRX->Compile(type_name.GetCString()))
3128 error->SetErrorString("regex format error (maybe this is not really a regex?)");
3132 category->GetRegexTypeFiltersContainer()->Delete(type_name);
3133 category->GetRegexTypeFiltersContainer()->Add(typeRX, entry);
3139 category->GetTypeFiltersContainer()->Add(type_name, entry);
3147 CommandObjectTypeFilterAdd (CommandInterpreter &interpreter) :
3148 CommandObjectParsed (interpreter,
3150 "Add a new filter for a type.",
3152 m_options (interpreter)
3154 CommandArgumentEntry type_arg;
3155 CommandArgumentData type_style_arg;
3157 type_style_arg.arg_type = eArgTypeName;
3158 type_style_arg.arg_repetition = eArgRepeatPlus;
3160 type_arg.push_back (type_style_arg);
3162 m_arguments.push_back (type_arg);
3166 The following examples of 'type filter add' refer to this code snippet for context:
3181 Adding a simple filter:
3183 (lldb) type filter add --child a --child g Foo
3184 (lldb) frame variable my_foo
3186 )" "Produces output where only a and g are displayed. Other children of my_foo \
3187 (b, c, d, e, f, h and i) are available by asking for them explicitly:" R"(
3189 (lldb) frame variable my_foo.b my_foo.c my_foo.i
3191 )" "The formatting option --raw on frame variable bypasses the filter, showing \
3192 all children of my_foo as if no filter was defined:" R"(
3194 (lldb) frame variable my_foo --raw)"
3198 ~CommandObjectTypeFilterAdd () override
3204 DoExecute (Args& command, CommandReturnObject &result) override
3206 const size_t argc = command.GetArgumentCount();
3210 result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
3211 result.SetStatus(eReturnStatusFailed);
3215 if (m_options.m_expr_paths.size() == 0)
3217 result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str());
3218 result.SetStatus(eReturnStatusFailed);
3222 TypeFilterImplSP entry(new TypeFilterImpl(SyntheticChildren::Flags().SetCascades(m_options.m_cascade).
3223 SetSkipPointers(m_options.m_skip_pointers).
3224 SetSkipReferences(m_options.m_skip_references)));
3226 // go through the expression paths
3227 CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end();
3229 for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
3230 entry->AddExpressionPath(*begin);
3233 // now I have a valid provider, let's add it to every type
3235 lldb::TypeCategoryImplSP category;
3236 DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
3240 WarnOnPotentialUnquotedUnsignedType(command, result);
3242 for (size_t i = 0; i < argc; i++)
3244 const char* typeA = command.GetArgumentAtIndex(i);
3245 ConstString typeCS(typeA);
3248 if (!AddFilter(typeCS,
3250 m_options.m_regex ? eRegexFilter : eRegularFilter,
3251 m_options.m_category,
3254 result.AppendError(error.AsCString());
3255 result.SetStatus(eReturnStatusFailed);
3261 result.AppendError("empty typenames not allowed");
3262 result.SetStatus(eReturnStatusFailed);
3267 result.SetStatus(eReturnStatusSuccessFinishNoResult);
3268 return result.Succeeded();
3274 CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] =
3276 { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
3277 { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
3278 { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
3279 { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
3280 { LLDB_OPT_SET_ALL, false, "child", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpressionPath, "Include this expression path in the synthetic view."},
3281 { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."},
3282 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
3285 //----------------------------------------------------------------------
3287 //----------------------------------------------------------------------
3288 class CommandObjectTypeLookup : public CommandObjectRaw
3292 class CommandOptions : public OptionGroup
3299 m_language(eLanguageTypeUnknown)
3302 ~CommandOptions () override {}
3305 GetNumDefinitions () override
3310 const OptionDefinition*
3311 GetDefinitions () override
3313 return g_option_table;
3317 SetOptionValue (CommandInterpreter &interpreter,
3318 uint32_t option_idx,
3319 const char *option_value) override
3323 const int short_option = g_option_table[option_idx].short_option;
3325 switch (short_option)
3332 m_language = Language::GetLanguageTypeFromString(option_value);
3336 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
3344 OptionParsingStarting (CommandInterpreter &interpreter) override
3346 m_show_help = false;
3347 m_language = eLanguageTypeUnknown;
3350 // Options table: Required for subclasses of Options.
3352 static OptionDefinition g_option_table[];
3354 lldb::LanguageType m_language;
3357 OptionGroupOptions m_option_group;
3358 CommandOptions m_command_options;
3362 CommandObjectTypeLookup (CommandInterpreter &interpreter) :
3363 CommandObjectRaw (interpreter,
3365 "Lookup a type by name in the select target.",
3366 "type lookup <typename>",
3367 eCommandRequiresTarget),
3368 m_option_group(interpreter),
3371 m_option_group.Append(&m_command_options);
3372 m_option_group.Finalize();
3375 ~CommandObjectTypeLookup () override
3380 GetOptions () override
3382 return &m_option_group;
3386 DoExecute (const char *raw_command_line, CommandReturnObject &result) override
3388 if (!raw_command_line || !raw_command_line[0])
3390 result.SetError("type lookup cannot be invoked without a type name as argument");
3394 m_option_group.NotifyOptionParsingStarting();
3396 const char * name_of_type = NULL;
3398 if (raw_command_line[0] == '-')
3400 // We have some options and these options MUST end with --.
3401 const char *end_options = NULL;
3402 const char *s = raw_command_line;
3405 end_options = ::strstr (s, "--");
3408 end_options += 2; // Get past the "--"
3409 if (::isspace (end_options[0]))
3411 name_of_type = end_options;
3412 while (::isspace (*name_of_type))
3422 Args args (llvm::StringRef(raw_command_line, end_options - raw_command_line));
3423 if (!ParseOptions (args, result))
3426 Error error (m_option_group.NotifyOptionParsingFinished());
3429 result.AppendError (error.AsCString());
3430 result.SetStatus (eReturnStatusFailed);
3435 if (nullptr == name_of_type)
3436 name_of_type = raw_command_line;
3438 TargetSP target_sp(GetCommandInterpreter().GetDebugger().GetSelectedTarget());
3439 const bool fill_all_in = true;
3440 ExecutionContext exe_ctx(target_sp.get(), fill_all_in);
3441 ExecutionContextScope *best_scope = exe_ctx.GetBestExecutionContextScope();
3443 bool any_found = false;
3445 std::vector<Language*> languages;
3447 if (m_command_options.m_language == eLanguageTypeUnknown)
3449 // FIXME: hardcoding languages is not good
3450 languages.push_back(Language::FindPlugin(eLanguageTypeObjC));
3451 languages.push_back(Language::FindPlugin(eLanguageTypeC_plus_plus));
3455 languages.push_back(Language::FindPlugin(m_command_options.m_language));
3458 for (Language* language : languages)
3463 if (auto scavenger = language->GetTypeScavenger())
3465 Language::TypeScavenger::ResultSet search_results;
3466 if (scavenger->Find(best_scope, name_of_type, search_results) > 0)
3468 for (const auto& search_result : search_results)
3470 if (search_result && search_result->IsValid())
3473 search_result->DumpToStream(result.GetOutputStream(), this->m_command_options.m_show_help);
3480 result.SetStatus (any_found ? lldb::eReturnStatusSuccessFinishResult : lldb::eReturnStatusSuccessFinishNoResult);
3487 CommandObjectTypeLookup::CommandOptions::g_option_table[] =
3489 { LLDB_OPT_SET_ALL, false, "show-help", 'h', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display available help for types"},
3490 { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Which language's types should the search scope be"},
3491 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
3494 template <typename FormatterType>
3495 class CommandObjectFormatterInfo : public CommandObjectRaw
3498 typedef std::function<typename FormatterType::SharedPointer(ValueObject&)> DiscoveryFunction;
3499 CommandObjectFormatterInfo (CommandInterpreter &interpreter,
3500 const char* formatter_name,
3501 DiscoveryFunction discovery_func) :
3502 CommandObjectRaw(interpreter,
3506 eCommandRequiresFrame),
3507 m_formatter_name(formatter_name ? formatter_name : ""),
3508 m_discovery_function(discovery_func)
3511 name.Printf("type %s info", formatter_name);
3512 SetCommandName(name.GetData());
3514 help.Printf("This command evaluates the provided expression and shows which %s is applied to the resulting value (if any).", formatter_name);
3515 SetHelp(help.GetData());
3516 StreamString syntax;
3517 syntax.Printf("type %s info <expr>", formatter_name);
3518 SetSyntax(syntax.GetData());
3521 ~CommandObjectFormatterInfo () override
3527 DoExecute (const char *command, CommandReturnObject &result) override
3529 auto target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
3530 auto frame_sp = target_sp->GetProcessSP()->GetThreadList().GetSelectedThread()->GetSelectedFrame();
3531 ValueObjectSP result_valobj_sp;
3532 EvaluateExpressionOptions options;
3533 lldb::ExpressionResults expr_result = target_sp->EvaluateExpression(command, frame_sp.get(), result_valobj_sp, options);
3534 if (expr_result == eExpressionCompleted && result_valobj_sp)
3536 result_valobj_sp = result_valobj_sp->GetQualifiedRepresentationIfAvailable(target_sp->GetPreferDynamicValue(), target_sp->GetEnableSyntheticValue());
3537 typename FormatterType::SharedPointer formatter_sp = m_discovery_function(*result_valobj_sp);
3540 std::string description(formatter_sp->GetDescription());
3541 result.AppendMessageWithFormat("%s applied to (%s) %s is: %s\n",
3542 m_formatter_name.c_str(),
3543 result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"),
3545 description.c_str());
3546 result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
3550 result.AppendMessageWithFormat("no %s applies to (%s) %s\n",
3551 m_formatter_name.c_str(),
3552 result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"),
3554 result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
3560 result.AppendError("failed to evaluate expression");
3561 result.SetStatus(lldb::eReturnStatusFailed);
3567 std::string m_formatter_name;
3568 DiscoveryFunction m_discovery_function;
3571 class CommandObjectTypeFormat : public CommandObjectMultiword
3574 CommandObjectTypeFormat (CommandInterpreter &interpreter) :
3575 CommandObjectMultiword (interpreter,
3577 "A set of commands for editing variable value display options",
3578 "type format [<sub-command-options>] ")
3580 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFormatAdd (interpreter)));
3581 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFormatClear (interpreter)));
3582 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFormatDelete (interpreter)));
3583 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFormatList (interpreter)));
3584 LoadSubCommand ("info", CommandObjectSP (new CommandObjectFormatterInfo<TypeFormatImpl>(interpreter,
3586 [](ValueObject& valobj) -> TypeFormatImpl::SharedPointer {
3587 return valobj.GetValueFormat();
3592 ~CommandObjectTypeFormat () override
3597 #ifndef LLDB_DISABLE_PYTHON
3599 class CommandObjectTypeSynth : public CommandObjectMultiword
3602 CommandObjectTypeSynth (CommandInterpreter &interpreter) :
3603 CommandObjectMultiword (interpreter,
3605 "A set of commands for operating on synthetic type representations",
3606 "type synthetic [<sub-command-options>] ")
3608 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSynthAdd (interpreter)));
3609 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSynthClear (interpreter)));
3610 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSynthDelete (interpreter)));
3611 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSynthList (interpreter)));
3612 LoadSubCommand ("info", CommandObjectSP (new CommandObjectFormatterInfo<SyntheticChildren>(interpreter,
3614 [](ValueObject& valobj) -> SyntheticChildren::SharedPointer {
3615 return valobj.GetSyntheticChildren();
3620 ~CommandObjectTypeSynth () override
3625 #endif // #ifndef LLDB_DISABLE_PYTHON
3627 class CommandObjectTypeFilter : public CommandObjectMultiword
3630 CommandObjectTypeFilter (CommandInterpreter &interpreter) :
3631 CommandObjectMultiword (interpreter,
3633 "A set of commands for operating on type filters",
3634 "type synthetic [<sub-command-options>] ")
3636 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeFilterAdd (interpreter)));
3637 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeFilterClear (interpreter)));
3638 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFilterDelete (interpreter)));
3639 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeFilterList (interpreter)));
3643 ~CommandObjectTypeFilter () override
3648 class CommandObjectTypeCategory : public CommandObjectMultiword
3651 CommandObjectTypeCategory (CommandInterpreter &interpreter) :
3652 CommandObjectMultiword (interpreter,
3654 "A set of commands for operating on categories",
3655 "type category [<sub-command-options>] ")
3657 LoadSubCommand ("define", CommandObjectSP (new CommandObjectTypeCategoryDefine (interpreter)));
3658 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTypeCategoryEnable (interpreter)));
3659 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTypeCategoryDisable (interpreter)));
3660 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeCategoryDelete (interpreter)));
3661 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeCategoryList (interpreter)));
3665 ~CommandObjectTypeCategory () override
3670 class CommandObjectTypeSummary : public CommandObjectMultiword
3673 CommandObjectTypeSummary (CommandInterpreter &interpreter) :
3674 CommandObjectMultiword (interpreter,
3676 "A set of commands for editing variable summary display options",
3677 "type summary [<sub-command-options>] ")
3679 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTypeSummaryAdd (interpreter)));
3680 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter)));
3681 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeSummaryDelete (interpreter)));
3682 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTypeSummaryList (interpreter)));
3683 LoadSubCommand ("info", CommandObjectSP (new CommandObjectFormatterInfo<TypeSummaryImpl>(interpreter,
3685 [](ValueObject& valobj) -> TypeSummaryImpl::SharedPointer {
3686 return valobj.GetSummaryFormat();
3691 ~CommandObjectTypeSummary () override
3696 //-------------------------------------------------------------------------
3697 // CommandObjectType
3698 //-------------------------------------------------------------------------
3700 CommandObjectType::CommandObjectType (CommandInterpreter &interpreter) :
3701 CommandObjectMultiword (interpreter,
3703 "A set of commands for operating on the type system",
3704 "type [<sub-command-options>]")
3706 LoadSubCommand ("category", CommandObjectSP (new CommandObjectTypeCategory (interpreter)));
3707 LoadSubCommand ("filter", CommandObjectSP (new CommandObjectTypeFilter (interpreter)));
3708 LoadSubCommand ("format", CommandObjectSP (new CommandObjectTypeFormat (interpreter)));
3709 LoadSubCommand ("summary", CommandObjectSP (new CommandObjectTypeSummary (interpreter)));
3710 #ifndef LLDB_DISABLE_PYTHON
3711 LoadSubCommand ("synthetic", CommandObjectSP (new CommandObjectTypeSynth (interpreter)));
3713 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTypeLookup (interpreter)));
3717 CommandObjectType::~CommandObjectType ()