1 //===-- CommandObjectType.cpp ----------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "CommandObjectType.h"
11 
12 // C Includes
13 
14 #include <ctype.h>
15 
16 // C++ Includes
17 #include <functional>
18 
19 #include "llvm/ADT/StringRef.h"
20 
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/Target/Language.h"
36 #include "lldb/Target/Process.h"
37 #include "lldb/Target/StackFrame.h"
38 #include "lldb/Target/Target.h"
39 #include "lldb/Target/Thread.h"
40 #include "lldb/Target/ThreadList.h"
41 
42 using namespace lldb;
43 using namespace lldb_private;
44 
45 
46 class ScriptAddOptions
47 {
48 
49 public:
50 
51     TypeSummaryImpl::Flags m_flags;
52 
53     StringList m_target_types;
54 
55     bool m_regex;
56 
57     ConstString m_name;
58 
59     std::string m_category;
60 
61     ScriptAddOptions(const TypeSummaryImpl::Flags& flags,
62                      bool regx,
63                      const ConstString& name,
64                      std::string catg) :
65         m_flags(flags),
66         m_regex(regx),
67         m_name(name),
68         m_category(catg)
69     {
70     }
71 
72     typedef std::shared_ptr<ScriptAddOptions> SharedPointer;
73 
74 };
75 
76 class SynthAddOptions
77 {
78 
79 public:
80 
81     bool m_skip_pointers;
82     bool m_skip_references;
83     bool m_cascade;
84     bool m_regex;
85     StringList m_target_types;
86 
87     std::string m_category;
88 
89     SynthAddOptions(bool sptr,
90                     bool sref,
91                     bool casc,
92                     bool regx,
93                     std::string catg) :
94     m_skip_pointers(sptr),
95     m_skip_references(sref),
96     m_cascade(casc),
97     m_regex(regx),
98     m_target_types(),
99     m_category(catg)
100     {
101     }
102 
103     typedef std::shared_ptr<SynthAddOptions> SharedPointer;
104 
105 };
106 
107 static bool
108 WarnOnPotentialUnquotedUnsignedType (Args& command, CommandReturnObject &result)
109 {
110     for (unsigned idx = 0; idx < command.GetArgumentCount(); idx++)
111     {
112         const char* arg = command.GetArgumentAtIndex(idx);
113         if (idx+1 < command.GetArgumentCount())
114         {
115             if (arg && 0 == strcmp(arg,"unsigned"))
116             {
117                 const char* next = command.GetArgumentAtIndex(idx+1);
118                 if (next &&
119                     (0 == strcmp(next, "int") ||
120                      0 == strcmp(next, "short") ||
121                      0 == strcmp(next, "char") ||
122                      0 == strcmp(next, "long")))
123                 {
124                     result.AppendWarningWithFormat("%s %s being treated as two types. if you meant the combined type name use quotes, as in \"%s %s\"\n",
125                                                    arg,next,arg,next);
126                     return true;
127                 }
128             }
129         }
130     }
131     return false;
132 }
133 
134 class CommandObjectTypeSummaryAdd :
135     public CommandObjectParsed,
136     public IOHandlerDelegateMultiline
137 {
138 
139 private:
140 
141     class CommandOptions : public Options
142     {
143     public:
144 
145         CommandOptions (CommandInterpreter &interpreter) :
146         Options (interpreter)
147         {
148         }
149 
150         ~CommandOptions () override {}
151 
152         Error
153         SetOptionValue (uint32_t option_idx, const char *option_arg) override;
154 
155         void
156         OptionParsingStarting () override;
157 
158         const OptionDefinition*
159         GetDefinitions () override
160         {
161             return g_option_table;
162         }
163 
164         // Options table: Required for subclasses of Options.
165 
166         static OptionDefinition g_option_table[];
167 
168         // Instance variables to hold the values for command options.
169 
170         TypeSummaryImpl::Flags m_flags;
171         bool m_regex;
172         std::string m_format_string;
173         ConstString m_name;
174         std::string m_python_script;
175         std::string m_python_function;
176         bool m_is_add_script;
177         std::string m_category;
178     };
179 
180     CommandOptions m_options;
181 
182     Options *
183     GetOptions () override
184     {
185         return &m_options;
186     }
187 
188     bool
189     Execute_ScriptSummary (Args& command, CommandReturnObject &result);
190 
191     bool
192     Execute_StringSummary (Args& command, CommandReturnObject &result);
193 
194 public:
195 
196     enum SummaryFormatType
197     {
198         eRegularSummary,
199         eRegexSummary,
200         eNamedSummary
201     };
202 
203     CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter);
204 
205     ~CommandObjectTypeSummaryAdd () override
206     {
207     }
208 
209     void
210     IOHandlerActivated (IOHandler &io_handler) override
211     {
212         static const char *g_summary_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
213         "def function (valobj,internal_dict):\n"
214         "     \"\"\"valobj: an SBValue which you want to provide a summary for\n"
215         "        internal_dict: an LLDB support object not to be used\"\"\"\n";
216 
217         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
218         if (output_sp)
219         {
220             output_sp->PutCString(g_summary_addreader_instructions);
221             output_sp->Flush();
222         }
223     }
224 
225 
226     void
227     IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
228     {
229         StreamFileSP error_sp = io_handler.GetErrorStreamFile();
230 
231 #ifndef LLDB_DISABLE_PYTHON
232         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
233         if (interpreter)
234         {
235             StringList lines;
236             lines.SplitIntoLines(data);
237             if (lines.GetSize() > 0)
238             {
239                 ScriptAddOptions *options_ptr = ((ScriptAddOptions*)io_handler.GetUserData());
240                 if (options_ptr)
241                 {
242                     ScriptAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
243 
244                     ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
245                     if (interpreter)
246                     {
247                         std::string funct_name_str;
248                         if (interpreter->GenerateTypeScriptFunction (lines, funct_name_str))
249                         {
250                             if (funct_name_str.empty())
251                             {
252                                 error_sp->Printf ("unable to obtain a valid function name from the script interpreter.\n");
253                                 error_sp->Flush();
254                             }
255                             else
256                             {
257                                 // now I have a valid function name, let's add this as script for every type in the list
258 
259                                 TypeSummaryImplSP script_format;
260                                 script_format.reset(new ScriptSummaryFormat(options->m_flags,
261                                                                             funct_name_str.c_str(),
262                                                                             lines.CopyList("    ").c_str()));
263 
264                                 Error error;
265 
266                                 for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
267                                 {
268                                     const char *type_name = options->m_target_types.GetStringAtIndex(i);
269                                     CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
270                                                                             script_format,
271                                                                             (options->m_regex ? CommandObjectTypeSummaryAdd::eRegexSummary : CommandObjectTypeSummaryAdd::eRegularSummary),
272                                                                             options->m_category,
273                                                                             &error);
274                                     if (error.Fail())
275                                     {
276                                         error_sp->Printf ("error: %s", error.AsCString());
277                                         error_sp->Flush();
278                                     }
279                                 }
280 
281                                 if (options->m_name)
282                                 {
283                                     CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
284                                                                              script_format,
285                                                                              CommandObjectTypeSummaryAdd::eNamedSummary,
286                                                                              options->m_category,
287                                                                              &error);
288                                     if (error.Fail())
289                                     {
290                                         CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
291                                                                                  script_format,
292                                                                                  CommandObjectTypeSummaryAdd::eNamedSummary,
293                                                                                  options->m_category,
294                                                                                  &error);
295                                         if (error.Fail())
296                                         {
297                                             error_sp->Printf ("error: %s", error.AsCString());
298                                             error_sp->Flush();
299                                         }
300                                     }
301                                     else
302                                     {
303                                         error_sp->Printf ("error: %s", error.AsCString());
304                                         error_sp->Flush();
305                                     }
306                                 }
307                                 else
308                                 {
309                                     if (error.AsCString())
310                                     {
311                                         error_sp->Printf ("error: %s", error.AsCString());
312                                         error_sp->Flush();
313                                     }
314                                 }
315                             }
316                         }
317                         else
318                         {
319                             error_sp->Printf ("error: unable to generate a function.\n");
320                             error_sp->Flush();
321                         }
322                     }
323                     else
324                     {
325                         error_sp->Printf ("error: no script interpreter.\n");
326                         error_sp->Flush();
327                     }
328                 }
329                 else
330                 {
331                     error_sp->Printf ("error: internal synchronization information missing or invalid.\n");
332                     error_sp->Flush();
333                 }
334             }
335             else
336             {
337                 error_sp->Printf ("error: empty function, didn't add python command.\n");
338                 error_sp->Flush();
339             }
340         }
341         else
342         {
343             error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
344             error_sp->Flush();
345         }
346 #endif // #ifndef LLDB_DISABLE_PYTHON
347         io_handler.SetIsDone(true);
348     }
349 
350     static bool
351     AddSummary(ConstString type_name,
352                lldb::TypeSummaryImplSP entry,
353                SummaryFormatType type,
354                std::string category,
355                Error* error = NULL);
356 protected:
357     bool
358     DoExecute (Args& command, CommandReturnObject &result) override;
359 
360 };
361 
362 static const char *g_synth_addreader_instructions =   "Enter your Python command(s). Type 'DONE' to end.\n"
363 "You must define a Python class with these methods:\n"
364 "    def __init__(self, valobj, dict):\n"
365 "    def num_children(self):\n"
366 "    def get_child_at_index(self, index):\n"
367 "    def get_child_index(self, name):\n"
368 "    def update(self):\n"
369 "        '''Optional'''\n"
370 "class synthProvider:\n";
371 
372 class CommandObjectTypeSynthAdd :
373     public CommandObjectParsed,
374     public IOHandlerDelegateMultiline
375 {
376 
377 private:
378 
379     class CommandOptions : public Options
380     {
381     public:
382 
383         CommandOptions (CommandInterpreter &interpreter) :
384             Options (interpreter)
385         {
386         }
387 
388         ~CommandOptions () override {}
389 
390         Error
391         SetOptionValue (uint32_t option_idx, const char *option_arg) override
392         {
393             Error error;
394             const int short_option = m_getopt_table[option_idx].val;
395             bool success;
396 
397             switch (short_option)
398             {
399                 case 'C':
400                     m_cascade = Args::StringToBoolean(option_arg, true, &success);
401                     if (!success)
402                         error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
403                     break;
404                 case 'P':
405                     handwrite_python = true;
406                     break;
407                 case 'l':
408                     m_class_name = std::string(option_arg);
409                     is_class_based = true;
410                     break;
411                 case 'p':
412                     m_skip_pointers = true;
413                     break;
414                 case 'r':
415                     m_skip_references = true;
416                     break;
417                 case 'w':
418                     m_category = std::string(option_arg);
419                     break;
420                 case 'x':
421                     m_regex = true;
422                     break;
423                 default:
424                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
425                     break;
426             }
427 
428             return error;
429         }
430 
431         void
432         OptionParsingStarting () override
433         {
434             m_cascade = true;
435             m_class_name = "";
436             m_skip_pointers = false;
437             m_skip_references = false;
438             m_category = "default";
439             is_class_based = false;
440             handwrite_python = false;
441             m_regex = false;
442         }
443 
444         const OptionDefinition*
445         GetDefinitions () override
446         {
447             return g_option_table;
448         }
449 
450         // Options table: Required for subclasses of Options.
451 
452         static OptionDefinition g_option_table[];
453 
454         // Instance variables to hold the values for command options.
455 
456         bool m_cascade;
457         bool m_skip_references;
458         bool m_skip_pointers;
459         std::string m_class_name;
460         bool m_input_python;
461         std::string m_category;
462 
463         bool is_class_based;
464 
465         bool handwrite_python;
466 
467         bool m_regex;
468 
469     };
470 
471     CommandOptions m_options;
472 
473     Options *
474     GetOptions () override
475     {
476         return &m_options;
477     }
478 
479     bool
480     Execute_HandwritePython (Args& command, CommandReturnObject &result);
481 
482     bool
483     Execute_PythonClass (Args& command, CommandReturnObject &result);
484 
485 protected:
486     bool
487     DoExecute (Args& command, CommandReturnObject &result) override
488     {
489         WarnOnPotentialUnquotedUnsignedType(command, result);
490 
491         if (m_options.handwrite_python)
492             return Execute_HandwritePython(command, result);
493         else if (m_options.is_class_based)
494             return Execute_PythonClass(command, result);
495         else
496         {
497             result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line");
498             result.SetStatus(eReturnStatusFailed);
499             return false;
500         }
501     }
502 
503     void
504     IOHandlerActivated (IOHandler &io_handler) override
505     {
506         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
507         if (output_sp)
508         {
509             output_sp->PutCString(g_synth_addreader_instructions);
510             output_sp->Flush();
511         }
512     }
513 
514 
515     void
516     IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
517     {
518         StreamFileSP error_sp = io_handler.GetErrorStreamFile();
519 
520 #ifndef LLDB_DISABLE_PYTHON
521         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
522         if (interpreter)
523         {
524             StringList lines;
525             lines.SplitIntoLines(data);
526             if (lines.GetSize() > 0)
527             {
528                 SynthAddOptions *options_ptr = ((SynthAddOptions*)io_handler.GetUserData());
529                 if (options_ptr)
530                 {
531                     SynthAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
532 
533                     ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
534                     if (interpreter)
535                     {
536                         std::string class_name_str;
537                         if (interpreter->GenerateTypeSynthClass (lines, class_name_str))
538                         {
539                             if (class_name_str.empty())
540                             {
541                                 error_sp->Printf ("error: unable to obtain a proper name for the class.\n");
542                                 error_sp->Flush();
543                             }
544                             else
545                             {
546                                 // everything should be fine now, let's add the synth provider class
547 
548                                 SyntheticChildrenSP synth_provider;
549                                 synth_provider.reset(new ScriptedSyntheticChildren(SyntheticChildren::Flags().SetCascades(options->m_cascade).
550                                                                                    SetSkipPointers(options->m_skip_pointers).
551                                                                                    SetSkipReferences(options->m_skip_references),
552                                                                                    class_name_str.c_str()));
553 
554 
555                                 lldb::TypeCategoryImplSP category;
556                                 DataVisualization::Categories::GetCategory(ConstString(options->m_category.c_str()), category);
557 
558                                 Error error;
559 
560                                 for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
561                                 {
562                                     const char *type_name = options->m_target_types.GetStringAtIndex(i);
563                                     ConstString const_type_name(type_name);
564                                     if (const_type_name)
565                                     {
566                                         if (!CommandObjectTypeSynthAdd::AddSynth(const_type_name,
567                                                                                  synth_provider,
568                                                                                  options->m_regex ? CommandObjectTypeSynthAdd::eRegexSynth : CommandObjectTypeSynthAdd::eRegularSynth,
569                                                                                  options->m_category,
570                                                                                  &error))
571                                         {
572                                             error_sp->Printf("error: %s\n", error.AsCString());
573                                             error_sp->Flush();
574                                             break;
575                                         }
576                                     }
577                                     else
578                                     {
579                                         error_sp->Printf ("error: invalid type name.\n");
580                                         error_sp->Flush();
581                                         break;
582                                     }
583                                 }
584                             }
585                         }
586                         else
587                         {
588                             error_sp->Printf ("error: unable to generate a class.\n");
589                             error_sp->Flush();
590                         }
591                     }
592                     else
593                     {
594                         error_sp->Printf ("error: no script interpreter.\n");
595                         error_sp->Flush();
596                     }
597                 }
598                 else
599                 {
600                     error_sp->Printf ("error: internal synchronization data missing.\n");
601                     error_sp->Flush();
602                 }
603             }
604             else
605             {
606                 error_sp->Printf ("error: empty function, didn't add python command.\n");
607                 error_sp->Flush();
608             }
609         }
610         else
611         {
612             error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
613             error_sp->Flush();
614         }
615 
616 #endif // #ifndef LLDB_DISABLE_PYTHON
617         io_handler.SetIsDone(true);
618     }
619 
620 public:
621 
622     enum SynthFormatType
623     {
624         eRegularSynth,
625         eRegexSynth
626     };
627 
628     CommandObjectTypeSynthAdd (CommandInterpreter &interpreter);
629 
630     ~CommandObjectTypeSynthAdd () override
631     {
632     }
633 
634     static bool
635     AddSynth(ConstString type_name,
636              lldb::SyntheticChildrenSP entry,
637              SynthFormatType type,
638              std::string category_name,
639              Error* error);
640 };
641 
642 //-------------------------------------------------------------------------
643 // CommandObjectTypeFormatAdd
644 //-------------------------------------------------------------------------
645 
646 class CommandObjectTypeFormatAdd : public CommandObjectParsed
647 {
648 
649 private:
650 
651     class CommandOptions : public OptionGroup
652     {
653     public:
654 
655         CommandOptions () :
656             OptionGroup()
657         {
658         }
659 
660         ~CommandOptions () override
661         {
662         }
663 
664         uint32_t
665         GetNumDefinitions () override;
666 
667         const OptionDefinition*
668         GetDefinitions () override
669         {
670             return g_option_table;
671         }
672 
673         void
674         OptionParsingStarting (CommandInterpreter &interpreter) override
675         {
676             m_cascade = true;
677             m_skip_pointers = false;
678             m_skip_references = false;
679             m_regex = false;
680             m_category.assign("default");
681             m_custom_type_name.clear();
682         }
683         Error
684         SetOptionValue (CommandInterpreter &interpreter,
685                         uint32_t option_idx,
686                         const char *option_value) override
687         {
688             Error error;
689             const int short_option = g_option_table[option_idx].short_option;
690             bool success;
691 
692             switch (short_option)
693             {
694                 case 'C':
695                     m_cascade = Args::StringToBoolean(option_value, true, &success);
696                     if (!success)
697                         error.SetErrorStringWithFormat("invalid value for cascade: %s", option_value);
698                     break;
699                 case 'p':
700                     m_skip_pointers = true;
701                     break;
702                 case 'w':
703                     m_category.assign(option_value);
704                     break;
705                 case 'r':
706                     m_skip_references = true;
707                     break;
708                 case 'x':
709                     m_regex = true;
710                     break;
711                 case 't':
712                     m_custom_type_name.assign(option_value);
713                     break;
714                 default:
715                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
716                     break;
717             }
718 
719             return error;
720         }
721 
722         // Options table: Required for subclasses of Options.
723 
724         static OptionDefinition g_option_table[];
725 
726         // Instance variables to hold the values for command options.
727 
728         bool m_cascade;
729         bool m_skip_references;
730         bool m_skip_pointers;
731         bool m_regex;
732         std::string m_category;
733         std::string m_custom_type_name;
734     };
735 
736     OptionGroupOptions m_option_group;
737     OptionGroupFormat m_format_options;
738     CommandOptions m_command_options;
739 
740     Options *
741     GetOptions () override
742     {
743         return &m_option_group;
744     }
745 
746 public:
747     CommandObjectTypeFormatAdd (CommandInterpreter &interpreter) :
748         CommandObjectParsed (interpreter,
749                              "type format add",
750                              "Add a new formatting style for a type.",
751                              NULL),
752         m_option_group (interpreter),
753         m_format_options (eFormatInvalid),
754         m_command_options ()
755     {
756         CommandArgumentEntry type_arg;
757         CommandArgumentData type_style_arg;
758 
759         type_style_arg.arg_type = eArgTypeName;
760         type_style_arg.arg_repetition = eArgRepeatPlus;
761 
762         type_arg.push_back (type_style_arg);
763 
764         m_arguments.push_back (type_arg);
765 
766         SetHelpLong(
767 R"(
768 The following examples of 'type format add' refer to this code snippet for context:
769 
770     typedef int Aint;
771     typedef float Afloat;
772     typedef Aint Bint;
773     typedef Afloat Bfloat;
774 
775     Aint ix = 5;
776     Bint iy = 5;
777 
778     Afloat fx = 3.14;
779     BFloat fy = 3.14;
780 
781 Adding default formatting:
782 
783 (lldb) type format add -f hex AInt
784 (lldb) frame variable iy
785 
786 )" "    Produces hexidecimal display of iy, because no formatter is available for Bint and \
787 the one for Aint is used instead." R"(
788 
789 To prevent this use the cascade option '-C no' to prevent evaluation of typedef chains:
790 
791 
792 (lldb) type format add -f hex -C no AInt
793 
794 Similar reasoning applies to this:
795 
796 (lldb) type format add -f hex -C no float -p
797 
798 )" "    All float values and float references are now formatted as hexadecimal, but not \
799 pointers to floats.  Nor will it change the default display for Afloat and Bfloat objects."
800                     );
801 
802         // Add the "--format" to all options groups
803         m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1);
804         m_option_group.Append (&m_command_options);
805         m_option_group.Finalize();
806 
807     }
808 
809     ~CommandObjectTypeFormatAdd () override
810     {
811     }
812 
813 protected:
814     bool
815     DoExecute (Args& command, CommandReturnObject &result) override
816     {
817         const size_t argc = command.GetArgumentCount();
818 
819         if (argc < 1)
820         {
821             result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
822             result.SetStatus(eReturnStatusFailed);
823             return false;
824         }
825 
826         const Format format = m_format_options.GetFormat();
827         if (format == eFormatInvalid && m_command_options.m_custom_type_name.empty())
828         {
829             result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str());
830             result.SetStatus(eReturnStatusFailed);
831             return false;
832         }
833 
834         TypeFormatImplSP entry;
835 
836         if (m_command_options.m_custom_type_name.empty())
837             entry.reset(new TypeFormatImpl_Format(format,
838                                                   TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
839                                                   SetSkipPointers(m_command_options.m_skip_pointers).
840                                                   SetSkipReferences(m_command_options.m_skip_references)));
841         else
842             entry.reset(new TypeFormatImpl_EnumType(ConstString(m_command_options.m_custom_type_name.c_str()),
843                                                     TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
844                                                     SetSkipPointers(m_command_options.m_skip_pointers).
845                                                     SetSkipReferences(m_command_options.m_skip_references)));
846 
847         // now I have a valid format, let's add it to every type
848 
849         TypeCategoryImplSP category_sp;
850         DataVisualization::Categories::GetCategory(ConstString(m_command_options.m_category), category_sp);
851         if (!category_sp)
852             return false;
853 
854         WarnOnPotentialUnquotedUnsignedType(command, result);
855 
856         for (size_t i = 0; i < argc; i++)
857         {
858             const char* typeA = command.GetArgumentAtIndex(i);
859             ConstString typeCS(typeA);
860             if (typeCS)
861             {
862                 if (m_command_options.m_regex)
863                 {
864                     RegularExpressionSP typeRX(new RegularExpression());
865                     if (!typeRX->Compile(typeCS.GetCString()))
866                     {
867                         result.AppendError("regex format error (maybe this is not really a regex?)");
868                         result.SetStatus(eReturnStatusFailed);
869                         return false;
870                     }
871                     category_sp->GetRegexTypeSummariesContainer()->Delete(typeCS);
872                     category_sp->GetRegexTypeFormatsContainer()->Add(typeRX, entry);
873                 }
874                 else
875                     category_sp->GetTypeFormatsContainer()->Add(typeCS, entry);
876             }
877             else
878             {
879                 result.AppendError("empty typenames not allowed");
880                 result.SetStatus(eReturnStatusFailed);
881                 return false;
882             }
883         }
884 
885         result.SetStatus(eReturnStatusSuccessFinishNoResult);
886         return result.Succeeded();
887     }
888 };
889 
890 OptionDefinition
891 CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] =
892 {
893     { LLDB_OPT_SET_ALL, false,  "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,    "Add this to the given category instead of the default one."},
894     { LLDB_OPT_SET_ALL, false,  "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
895     { LLDB_OPT_SET_ALL, false,  "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
896     { LLDB_OPT_SET_ALL, false,  "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
897     { LLDB_OPT_SET_ALL, false,  "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
898     { LLDB_OPT_SET_2,   false,  "type", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,    "Format variables as if they were of this type."},
899     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
900 };
901 
902 
903 uint32_t
904 CommandObjectTypeFormatAdd::CommandOptions::GetNumDefinitions ()
905 {
906     return sizeof(g_option_table) / sizeof (OptionDefinition);
907 }
908 
909 
910 //-------------------------------------------------------------------------
911 // CommandObjectTypeFormatDelete
912 //-------------------------------------------------------------------------
913 
914 class CommandObjectTypeFormatDelete : public CommandObjectParsed
915 {
916 private:
917     class CommandOptions : public Options
918     {
919     public:
920 
921         CommandOptions (CommandInterpreter &interpreter) :
922         Options (interpreter)
923         {
924         }
925 
926         ~CommandOptions () override {}
927 
928         Error
929         SetOptionValue (uint32_t option_idx, const char *option_arg) override
930         {
931             Error error;
932             const int short_option = m_getopt_table[option_idx].val;
933 
934             switch (short_option)
935             {
936                 case 'a':
937                     m_delete_all = true;
938                     break;
939                 case 'w':
940                     m_category = std::string(option_arg);
941                     break;
942                 case 'l':
943                     m_language = Language::GetLanguageTypeFromString(option_arg);
944                     break;
945                 default:
946                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
947                     break;
948             }
949 
950             return error;
951         }
952 
953         void
954         OptionParsingStarting () override
955         {
956             m_delete_all = false;
957             m_category = "default";
958             m_language = lldb::eLanguageTypeUnknown;
959         }
960 
961         const OptionDefinition*
962         GetDefinitions () override
963         {
964             return g_option_table;
965         }
966 
967         // Options table: Required for subclasses of Options.
968 
969         static OptionDefinition g_option_table[];
970 
971         // Instance variables to hold the values for command options.
972 
973         bool m_delete_all;
974         std::string m_category;
975         lldb::LanguageType m_language;
976     };
977 
978     CommandOptions m_options;
979 
980     Options *
981     GetOptions () override
982     {
983         return &m_options;
984     }
985 
986     static bool
987     PerCategoryCallback(void* param,
988                         const lldb::TypeCategoryImplSP& category_sp)
989     {
990 		ConstString *name = (ConstString*)param;
991 		category_sp->Delete(*name, eFormatCategoryItemValue | eFormatCategoryItemRegexValue);
992 		return true;
993     }
994 
995 public:
996     CommandObjectTypeFormatDelete (CommandInterpreter &interpreter) :
997         CommandObjectParsed (interpreter,
998                              "type format delete",
999                              "Delete an existing formatting style for a type.",
1000                              NULL),
1001     m_options(interpreter)
1002     {
1003         CommandArgumentEntry type_arg;
1004         CommandArgumentData type_style_arg;
1005 
1006         type_style_arg.arg_type = eArgTypeName;
1007         type_style_arg.arg_repetition = eArgRepeatPlain;
1008 
1009         type_arg.push_back (type_style_arg);
1010 
1011         m_arguments.push_back (type_arg);
1012 
1013     }
1014 
1015     ~CommandObjectTypeFormatDelete () override
1016     {
1017     }
1018 
1019 protected:
1020     bool
1021     DoExecute (Args& command, CommandReturnObject &result) override
1022     {
1023         const size_t argc = command.GetArgumentCount();
1024 
1025         if (argc != 1)
1026         {
1027             result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
1028             result.SetStatus(eReturnStatusFailed);
1029             return false;
1030         }
1031 
1032         const char* typeA = command.GetArgumentAtIndex(0);
1033         ConstString typeCS(typeA);
1034 
1035         if (!typeCS)
1036         {
1037             result.AppendError("empty typenames not allowed");
1038             result.SetStatus(eReturnStatusFailed);
1039             return false;
1040         }
1041 
1042         if (m_options.m_delete_all)
1043         {
1044             DataVisualization::Categories::LoopThrough(PerCategoryCallback, &typeCS);
1045             result.SetStatus(eReturnStatusSuccessFinishNoResult);
1046             return result.Succeeded();
1047         }
1048 
1049         bool delete_category = false;
1050 
1051         if (m_options.m_language != lldb::eLanguageTypeUnknown)
1052         {
1053             lldb::TypeCategoryImplSP category;
1054             DataVisualization::Categories::GetCategory(m_options.m_language, category);
1055             if (category)
1056                 delete_category = category->Delete(typeCS, eFormatCategoryItemValue | eFormatCategoryItemRegexValue);
1057         }
1058         else
1059         {
1060             lldb::TypeCategoryImplSP category;
1061             DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
1062             if (category)
1063                 delete_category = category->Delete(typeCS, eFormatCategoryItemValue | eFormatCategoryItemRegexValue);
1064         }
1065 
1066         if (delete_category)
1067         {
1068             result.SetStatus(eReturnStatusSuccessFinishNoResult);
1069             return result.Succeeded();
1070         }
1071         else
1072         {
1073             result.AppendErrorWithFormat ("no custom format for %s.\n", typeA);
1074             result.SetStatus(eReturnStatusFailed);
1075             return false;
1076         }
1077 
1078     }
1079 
1080 };
1081 
1082 OptionDefinition
1083 CommandObjectTypeFormatDelete::CommandOptions::g_option_table[] =
1084 {
1085     { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,  "Delete from every category."},
1086     { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Delete from given category."},
1087     { LLDB_OPT_SET_3, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,  "Delete from given language's category."},
1088     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1089 };
1090 
1091 //-------------------------------------------------------------------------
1092 // CommandObjectTypeFormatClear
1093 //-------------------------------------------------------------------------
1094 
1095 class CommandObjectTypeFormatClear : public CommandObjectParsed
1096 {
1097 private:
1098 
1099     class CommandOptions : public Options
1100     {
1101     public:
1102 
1103         CommandOptions (CommandInterpreter &interpreter) :
1104         Options (interpreter)
1105         {
1106         }
1107 
1108         ~CommandOptions () override {}
1109 
1110         Error
1111         SetOptionValue (uint32_t option_idx, const char *option_arg) override
1112         {
1113             Error error;
1114             const int short_option = m_getopt_table[option_idx].val;
1115 
1116             switch (short_option)
1117             {
1118                 case 'a':
1119                     m_delete_all = true;
1120                     break;
1121                 default:
1122                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1123                     break;
1124             }
1125 
1126             return error;
1127         }
1128 
1129         void
1130         OptionParsingStarting () override
1131         {
1132             m_delete_all = false;
1133         }
1134 
1135         const OptionDefinition*
1136         GetDefinitions () override
1137         {
1138             return g_option_table;
1139         }
1140 
1141         // Options table: Required for subclasses of Options.
1142 
1143         static OptionDefinition g_option_table[];
1144 
1145         // Instance variables to hold the values for command options.
1146 
1147         bool m_delete_all;
1148         bool m_delete_named;
1149     };
1150 
1151     CommandOptions m_options;
1152 
1153     Options *
1154     GetOptions () override
1155     {
1156         return &m_options;
1157     }
1158 
1159     static bool
1160     PerCategoryCallback(void* param,
1161                         const lldb::TypeCategoryImplSP& cate)
1162     {
1163         cate->GetTypeFormatsContainer()->Clear();
1164         cate->GetRegexTypeFormatsContainer()->Clear();
1165         return true;
1166 
1167     }
1168 
1169 public:
1170     CommandObjectTypeFormatClear (CommandInterpreter &interpreter) :
1171         CommandObjectParsed (interpreter,
1172                              "type format clear",
1173                              "Delete all existing format styles.",
1174                              NULL),
1175     m_options(interpreter)
1176     {
1177     }
1178 
1179     ~CommandObjectTypeFormatClear () override
1180     {
1181     }
1182 
1183 protected:
1184     bool
1185     DoExecute (Args& command, CommandReturnObject &result) override
1186     {
1187         if (m_options.m_delete_all)
1188             DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL);
1189 
1190         else
1191         {
1192             lldb::TypeCategoryImplSP category;
1193             if (command.GetArgumentCount() > 0)
1194             {
1195                 const char* cat_name = command.GetArgumentAtIndex(0);
1196                 ConstString cat_nameCS(cat_name);
1197                 DataVisualization::Categories::GetCategory(cat_nameCS, category);
1198             }
1199             else
1200                 DataVisualization::Categories::GetCategory(ConstString(NULL), category);
1201             category->Clear(eFormatCategoryItemValue | eFormatCategoryItemRegexValue);
1202         }
1203 
1204         result.SetStatus(eReturnStatusSuccessFinishResult);
1205         return result.Succeeded();
1206     }
1207 
1208 };
1209 
1210 OptionDefinition
1211 CommandObjectTypeFormatClear::CommandOptions::g_option_table[] =
1212 {
1213     { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,  "Clear every category."},
1214     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1215 };
1216 
1217 //-------------------------------------------------------------------------
1218 // CommandObjectTypeFormatList
1219 //-------------------------------------------------------------------------
1220 
1221 bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeFormatImplSP& entry);
1222 bool CommandObjectTypeRXFormatList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeFormatImplSP& entry);
1223 
1224 class CommandObjectTypeFormatList;
1225 
1226 struct CommandObjectTypeFormatList_LoopCallbackParam {
1227     CommandObjectTypeFormatList* self;
1228     CommandReturnObject* result;
1229     RegularExpression* regex;
1230     RegularExpression* cate_regex;
1231     CommandObjectTypeFormatList_LoopCallbackParam(CommandObjectTypeFormatList* S, CommandReturnObject* R,
1232                                             RegularExpression* X = NULL, RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}
1233 };
1234 
1235 class CommandObjectTypeFormatList : public CommandObjectParsed
1236 {
1237     class CommandOptions : public Options
1238     {
1239     public:
1240 
1241         CommandOptions (CommandInterpreter &interpreter) :
1242         Options (interpreter)
1243         {
1244         }
1245 
1246         ~CommandOptions () override {}
1247 
1248         Error
1249         SetOptionValue (uint32_t option_idx, const char *option_arg) override
1250         {
1251             Error error;
1252             const int short_option = m_getopt_table[option_idx].val;
1253 
1254             switch (short_option)
1255             {
1256                 case 'w':
1257                     m_category_regex = std::string(option_arg);
1258                     break;
1259                 default:
1260                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1261                     break;
1262             }
1263 
1264             return error;
1265         }
1266 
1267         void
1268         OptionParsingStarting () override
1269         {
1270             m_category_regex = "";
1271         }
1272 
1273         const OptionDefinition*
1274         GetDefinitions () override
1275         {
1276             return g_option_table;
1277         }
1278 
1279         // Options table: Required for subclasses of Options.
1280 
1281         static OptionDefinition g_option_table[];
1282 
1283         // Instance variables to hold the values for command options.
1284 
1285         std::string m_category_regex;
1286 
1287     };
1288 
1289     CommandOptions m_options;
1290 
1291     Options *
1292     GetOptions () override
1293     {
1294         return &m_options;
1295     }
1296 
1297 public:
1298     CommandObjectTypeFormatList (CommandInterpreter &interpreter) :
1299         CommandObjectParsed (interpreter,
1300                              "type format list",
1301                              "Show a list of current formatting styles.",
1302                              NULL),
1303     m_options(interpreter)
1304     {
1305         CommandArgumentEntry type_arg;
1306         CommandArgumentData type_style_arg;
1307 
1308         type_style_arg.arg_type = eArgTypeName;
1309         type_style_arg.arg_repetition = eArgRepeatOptional;
1310 
1311         type_arg.push_back (type_style_arg);
1312 
1313         m_arguments.push_back (type_arg);
1314     }
1315 
1316     ~CommandObjectTypeFormatList () override
1317     {
1318     }
1319 
1320 protected:
1321     bool
1322     DoExecute (Args& command, CommandReturnObject &result) override
1323     {
1324         const size_t argc = command.GetArgumentCount();
1325 
1326         CommandObjectTypeFormatList_LoopCallbackParam *param;
1327         RegularExpression* cate_regex =
1328         m_options.m_category_regex.empty() ? NULL :
1329         new RegularExpression(m_options.m_category_regex.c_str());
1330 
1331         if (argc == 1)
1332         {
1333             RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
1334             regex->Compile(command.GetArgumentAtIndex(0));
1335             param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,regex,cate_regex);
1336         }
1337         else
1338             param = new CommandObjectTypeFormatList_LoopCallbackParam(this,&result,NULL,cate_regex);
1339 
1340         DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
1341         delete param;
1342 
1343         if (cate_regex)
1344             delete cate_regex;
1345 
1346         result.SetStatus(eReturnStatusSuccessFinishResult);
1347         return result.Succeeded();
1348     }
1349 
1350 private:
1351 
1352     static bool
1353     PerCategoryCallback(void* param_vp,
1354                         const lldb::TypeCategoryImplSP& cate)
1355     {
1356 
1357         CommandObjectTypeFormatList_LoopCallbackParam* param =
1358         (CommandObjectTypeFormatList_LoopCallbackParam*)param_vp;
1359         CommandReturnObject* result = param->result;
1360 
1361         const char* cate_name = cate->GetName();
1362 
1363         // if the category is disabled or empty and there is no regex, just skip it
1364         if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemValue | eFormatCategoryItemRegexValue) == 0) && param->cate_regex == NULL)
1365             return true;
1366 
1367         // if we have a regex and this category does not match it, just skip it
1368         if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)
1369             return true;
1370 
1371         result->GetOutputStream().Printf("-----------------------\nCategory: %s\n-----------------------\n", cate->GetDescription().c_str());
1372 
1373         cate->GetTypeFormatsContainer()->LoopThrough(CommandObjectTypeFormatList_LoopCallback, param_vp);
1374 
1375         if (cate->GetRegexTypeSummariesContainer()->GetCount() > 0)
1376         {
1377             result->GetOutputStream().Printf("Regex-based summaries (slower):\n");
1378             cate->GetRegexTypeFormatsContainer()->LoopThrough(CommandObjectTypeRXFormatList_LoopCallback, param_vp);
1379         }
1380         return true;
1381     }
1382 
1383 
1384     bool
1385     LoopCallback (const char* type,
1386                   const lldb::TypeFormatImplSP& entry,
1387                   RegularExpression* regex,
1388                   CommandReturnObject *result)
1389     {
1390         if (regex == NULL || strcmp(type,regex->GetText()) == 0 || regex->Execute(type))
1391             result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());
1392         return true;
1393     }
1394 
1395     friend bool CommandObjectTypeFormatList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeFormatImplSP& entry);
1396     friend bool CommandObjectTypeRXFormatList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeFormatImplSP& entry);
1397 
1398 };
1399 
1400 bool
1401 CommandObjectTypeFormatList_LoopCallback (
1402                                     void* pt2self,
1403                                     ConstString type,
1404                                     const lldb::TypeFormatImplSP& entry)
1405 {
1406     CommandObjectTypeFormatList_LoopCallbackParam* param = (CommandObjectTypeFormatList_LoopCallbackParam*)pt2self;
1407     return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);
1408 }
1409 
1410 bool
1411 CommandObjectTypeRXFormatList_LoopCallback (
1412                                              void* pt2self,
1413                                              lldb::RegularExpressionSP regex,
1414                                              const lldb::TypeFormatImplSP& entry)
1415 {
1416     CommandObjectTypeFormatList_LoopCallbackParam* param = (CommandObjectTypeFormatList_LoopCallbackParam*)pt2self;
1417     return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
1418 }
1419 
1420 OptionDefinition
1421 CommandObjectTypeFormatList::CommandOptions::g_option_table[] =
1422 {
1423     { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
1424     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1425 };
1426 
1427 #ifndef LLDB_DISABLE_PYTHON
1428 
1429 //-------------------------------------------------------------------------
1430 // CommandObjectTypeSummaryAdd
1431 //-------------------------------------------------------------------------
1432 
1433 #endif // #ifndef LLDB_DISABLE_PYTHON
1434 
1435 Error
1436 CommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
1437 {
1438     Error error;
1439     const int short_option = m_getopt_table[option_idx].val;
1440     bool success;
1441 
1442     switch (short_option)
1443     {
1444         case 'C':
1445             m_flags.SetCascades(Args::StringToBoolean(option_arg, true, &success));
1446             if (!success)
1447                 error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
1448             break;
1449         case 'e':
1450             m_flags.SetDontShowChildren(false);
1451             break;
1452         case 'h':
1453             m_flags.SetHideEmptyAggregates(true);
1454             break;
1455         case 'v':
1456             m_flags.SetDontShowValue(true);
1457             break;
1458         case 'c':
1459             m_flags.SetShowMembersOneLiner(true);
1460             break;
1461         case 's':
1462             m_format_string = std::string(option_arg);
1463             break;
1464         case 'p':
1465             m_flags.SetSkipPointers(true);
1466             break;
1467         case 'r':
1468             m_flags.SetSkipReferences(true);
1469             break;
1470         case 'x':
1471             m_regex = true;
1472             break;
1473         case 'n':
1474             m_name.SetCString(option_arg);
1475             break;
1476         case 'o':
1477             m_python_script = std::string(option_arg);
1478             m_is_add_script = true;
1479             break;
1480         case 'F':
1481             m_python_function = std::string(option_arg);
1482             m_is_add_script = true;
1483             break;
1484         case 'P':
1485             m_is_add_script = true;
1486             break;
1487         case 'w':
1488             m_category = std::string(option_arg);
1489             break;
1490         case 'O':
1491             m_flags.SetHideItemNames(true);
1492             break;
1493         default:
1494             error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1495             break;
1496     }
1497 
1498     return error;
1499 }
1500 
1501 void
1502 CommandObjectTypeSummaryAdd::CommandOptions::OptionParsingStarting ()
1503 {
1504     m_flags.Clear().SetCascades().SetDontShowChildren().SetDontShowValue(false);
1505     m_flags.SetShowMembersOneLiner(false).SetSkipPointers(false).SetSkipReferences(false).SetHideItemNames(false);
1506 
1507     m_regex = false;
1508     m_name.Clear();
1509     m_python_script = "";
1510     m_python_function = "";
1511     m_format_string = "";
1512     m_is_add_script = false;
1513     m_category = "default";
1514 }
1515 
1516 
1517 
1518 #ifndef LLDB_DISABLE_PYTHON
1519 
1520 bool
1521 CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturnObject &result)
1522 {
1523     const size_t argc = command.GetArgumentCount();
1524 
1525     if (argc < 1 && !m_options.m_name)
1526     {
1527         result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
1528         result.SetStatus(eReturnStatusFailed);
1529         return false;
1530     }
1531 
1532     TypeSummaryImplSP script_format;
1533 
1534     if (!m_options.m_python_function.empty()) // we have a Python function ready to use
1535     {
1536         const char *funct_name = m_options.m_python_function.c_str();
1537         if (!funct_name || !funct_name[0])
1538         {
1539             result.AppendError ("function name empty.\n");
1540             result.SetStatus (eReturnStatusFailed);
1541             return false;
1542         }
1543 
1544         std::string code = ("    " + m_options.m_python_function + "(valobj,internal_dict)");
1545 
1546         script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
1547                                                     funct_name,
1548                                                     code.c_str()));
1549 
1550         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1551 
1552         if (interpreter && interpreter->CheckObjectExists(funct_name) == false)
1553             result.AppendWarningWithFormat("The provided function \"%s\" does not exist - "
1554                                            "please define it before attempting to use this summary.\n",
1555                                            funct_name);
1556     }
1557     else if (!m_options.m_python_script.empty()) // we have a quick 1-line script, just use it
1558     {
1559         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1560         if (!interpreter)
1561         {
1562             result.AppendError ("script interpreter missing - unable to generate function wrapper.\n");
1563             result.SetStatus (eReturnStatusFailed);
1564             return false;
1565         }
1566         StringList funct_sl;
1567         funct_sl << m_options.m_python_script.c_str();
1568         std::string funct_name_str;
1569         if (!interpreter->GenerateTypeScriptFunction (funct_sl,
1570                                                       funct_name_str))
1571         {
1572             result.AppendError ("unable to generate function wrapper.\n");
1573             result.SetStatus (eReturnStatusFailed);
1574             return false;
1575         }
1576         if (funct_name_str.empty())
1577         {
1578             result.AppendError ("script interpreter failed to generate a valid function name.\n");
1579             result.SetStatus (eReturnStatusFailed);
1580             return false;
1581         }
1582 
1583         std::string code = "    " + m_options.m_python_script;
1584 
1585         script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
1586                                                     funct_name_str.c_str(),
1587                                                     code.c_str()));
1588     }
1589     else
1590     {
1591         // Use an IOHandler to grab Python code from the user
1592         ScriptAddOptions *options = new ScriptAddOptions(m_options.m_flags,
1593                                                          m_options.m_regex,
1594                                                          m_options.m_name,
1595                                                          m_options.m_category);
1596 
1597         for (size_t i = 0; i < argc; i++)
1598         {
1599             const char* typeA = command.GetArgumentAtIndex(i);
1600             if (typeA && *typeA)
1601                 options->m_target_types << typeA;
1602             else
1603             {
1604                 result.AppendError("empty typenames not allowed");
1605                 result.SetStatus(eReturnStatusFailed);
1606                 return false;
1607             }
1608         }
1609 
1610         m_interpreter.GetPythonCommandsFromIOHandler ("    ",   // Prompt
1611                                                       *this,    // IOHandlerDelegate
1612                                                       true,     // Run IOHandler in async mode
1613                                                       options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
1614         result.SetStatus(eReturnStatusSuccessFinishNoResult);
1615 
1616         return result.Succeeded();
1617     }
1618 
1619     // if I am here, script_format must point to something good, so I can add that
1620     // as a script summary to all interested parties
1621 
1622     Error error;
1623 
1624     for (size_t i = 0; i < command.GetArgumentCount(); i++)
1625     {
1626         const char *type_name = command.GetArgumentAtIndex(i);
1627         CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
1628                                                 script_format,
1629                                                 (m_options.m_regex ? eRegexSummary : eRegularSummary),
1630                                                 m_options.m_category,
1631                                                 &error);
1632         if (error.Fail())
1633         {
1634             result.AppendError(error.AsCString());
1635             result.SetStatus(eReturnStatusFailed);
1636             return false;
1637         }
1638     }
1639 
1640     if (m_options.m_name)
1641     {
1642         AddSummary(m_options.m_name, script_format, eNamedSummary, m_options.m_category, &error);
1643         if (error.Fail())
1644         {
1645             result.AppendError(error.AsCString());
1646             result.AppendError("added to types, but not given a name");
1647             result.SetStatus(eReturnStatusFailed);
1648             return false;
1649         }
1650     }
1651 
1652     return result.Succeeded();
1653 }
1654 
1655 #endif
1656 
1657 
1658 bool
1659 CommandObjectTypeSummaryAdd::Execute_StringSummary (Args& command, CommandReturnObject &result)
1660 {
1661     const size_t argc = command.GetArgumentCount();
1662 
1663     if (argc < 1 && !m_options.m_name)
1664     {
1665         result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
1666         result.SetStatus(eReturnStatusFailed);
1667         return false;
1668     }
1669 
1670     if (!m_options.m_flags.GetShowMembersOneLiner() && m_options.m_format_string.empty())
1671     {
1672         result.AppendError("empty summary strings not allowed");
1673         result.SetStatus(eReturnStatusFailed);
1674         return false;
1675     }
1676 
1677     const char* format_cstr = (m_options.m_flags.GetShowMembersOneLiner() ? "" : m_options.m_format_string.c_str());
1678 
1679     // ${var%S} is an endless recursion, prevent it
1680     if (strcmp(format_cstr, "${var%S}") == 0)
1681     {
1682         result.AppendError("recursive summary not allowed");
1683         result.SetStatus(eReturnStatusFailed);
1684         return false;
1685     }
1686 
1687     Error error;
1688 
1689     lldb::TypeSummaryImplSP entry(new StringSummaryFormat(m_options.m_flags,
1690                                                         format_cstr));
1691 
1692     if (error.Fail())
1693     {
1694         result.AppendError(error.AsCString());
1695         result.SetStatus(eReturnStatusFailed);
1696         return false;
1697     }
1698 
1699     // now I have a valid format, let's add it to every type
1700 
1701     for (size_t i = 0; i < argc; i++)
1702     {
1703         const char* typeA = command.GetArgumentAtIndex(i);
1704         if (!typeA || typeA[0] == '\0')
1705         {
1706             result.AppendError("empty typenames not allowed");
1707             result.SetStatus(eReturnStatusFailed);
1708             return false;
1709         }
1710         ConstString typeCS(typeA);
1711 
1712         AddSummary(typeCS,
1713                    entry,
1714                    (m_options.m_regex ? eRegexSummary : eRegularSummary),
1715                    m_options.m_category,
1716                    &error);
1717 
1718         if (error.Fail())
1719         {
1720             result.AppendError(error.AsCString());
1721             result.SetStatus(eReturnStatusFailed);
1722             return false;
1723         }
1724     }
1725 
1726     if (m_options.m_name)
1727     {
1728         AddSummary(m_options.m_name, entry, eNamedSummary, m_options.m_category, &error);
1729         if (error.Fail())
1730         {
1731             result.AppendError(error.AsCString());
1732             result.AppendError("added to types, but not given a name");
1733             result.SetStatus(eReturnStatusFailed);
1734             return false;
1735         }
1736     }
1737 
1738     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1739     return result.Succeeded();
1740 }
1741 
1742 CommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter) :
1743     CommandObjectParsed (interpreter,
1744                          "type summary add",
1745                          "Add a new summary style for a type.",
1746                          NULL),
1747     IOHandlerDelegateMultiline ("DONE"),
1748     m_options (interpreter)
1749 {
1750     CommandArgumentEntry type_arg;
1751     CommandArgumentData type_style_arg;
1752 
1753     type_style_arg.arg_type = eArgTypeName;
1754     type_style_arg.arg_repetition = eArgRepeatPlus;
1755 
1756     type_arg.push_back (type_style_arg);
1757 
1758     m_arguments.push_back (type_arg);
1759 
1760     SetHelpLong(
1761 R"(
1762 The following examples of 'type summary add' refer to this code snippet for context:
1763 
1764     struct JustADemo
1765     {
1766         int* ptr;
1767         float value;
1768         JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}
1769     };
1770     JustADemo demo_instance(42, 3.14);
1771 
1772     typedef JustADemo NewDemo;
1773     NewDemo new_demo_instance(42, 3.14);
1774 
1775 (lldb) type summary add --summary-string "the answer is ${*var.ptr}" JustADemo
1776 
1777     Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42"
1778 
1779 (lldb) type summary add --summary-string "the answer is ${*var.ptr}, and the question is ${var.value}" JustADemo
1780 
1781     Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42 and the question is 3.14"
1782 
1783 )" "Alternatively, you could define formatting for all pointers to integers and \
1784 rely on that when formatting JustADemo to obtain the same result:" R"(
1785 
1786 (lldb) type summary add --summary-string "${var%V} -> ${*var}" "int *"
1787 (lldb) type summary add --summary-string "the answer is ${var.ptr}, and the question is ${var.value}" JustADemo
1788 
1789 )" "Type summaries are automatically applied to derived typedefs, so the examples \
1790 above apply to both JustADemo and NewDemo.  The cascade option can be used to \
1791 suppress this behavior:" R"(
1792 
1793 (lldb) type summary add --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo -C no
1794 
1795     The summary will now be used for values of JustADemo but not NewDemo.
1796 
1797 )" "By default summaries are shown for pointers and references to values of the \
1798 specified type.  To suppress formatting for pointers use the -p option, or apply \
1799 the corresponding -r option to suppress formatting for references:" R"(
1800 
1801 (lldb) type summary add -p -r --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo
1802 
1803 )" "One-line summaries including all fields in a type can be inferred without supplying an \
1804 explicit summary string by passing the -c option:" R"(
1805 
1806 (lldb) type summary add -c JustADemo
1807 (lldb) frame variable demo_instance
1808 (ptr=<address>, value=3.14)
1809 
1810 )" "Type summaries normally suppress the nested display of individual fields.  To \
1811 supply a summary to supplement the default structure add the -e option:" R"(
1812 
1813 (lldb) type summary add -e --summary-string "*ptr = ${*var.ptr}" JustADemo
1814 
1815 )" "Now when displaying JustADemo values the int* is displayed, followed by the \
1816 standard LLDB sequence of children, one per line:" R"(
1817 
1818 *ptr = 42 {
1819   ptr = <address>
1820   value = 3.14
1821 }
1822 
1823 )" "You can also add summaries written in Python.  These scripts use lldb public API to \
1824 gather information from your variables and produce a meaningful summary.  To start a \
1825 multi-line script use the -P option.  The function declaration will be displayed along with \
1826 a comment describing the two arguments.  End your script with the  word 'DONE' on a line by \
1827 itself:" R"(
1828 
1829 (lldb) type summary add JustADemo -P
1830 def function (valobj,internal_dict):
1831 """valobj: an SBValue which you want to provide a summary for
1832 internal_dict: an LLDB support object not to be used"""
1833     value = valobj.GetChildMemberWithName('value');
1834     return 'My value is ' + value.GetValue();
1835     DONE
1836 
1837 Alternatively, the -o option can be used when providing a simple one-line Python script:
1838 
1839 (lldb) type summary add JustADemo -o "value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();")"
1840     );
1841 }
1842 
1843 bool
1844 CommandObjectTypeSummaryAdd::DoExecute (Args& command, CommandReturnObject &result)
1845 {
1846     WarnOnPotentialUnquotedUnsignedType(command, result);
1847 
1848     if (m_options.m_is_add_script)
1849     {
1850 #ifndef LLDB_DISABLE_PYTHON
1851         return Execute_ScriptSummary(command, result);
1852 #else
1853         result.AppendError ("python is disabled");
1854         result.SetStatus(eReturnStatusFailed);
1855         return false;
1856 #endif
1857     }
1858 
1859     return Execute_StringSummary(command, result);
1860 }
1861 
1862 static bool
1863 FixArrayTypeNameWithRegex (ConstString &type_name)
1864 {
1865     llvm::StringRef type_name_ref(type_name.GetStringRef());
1866 
1867     if (type_name_ref.endswith("[]"))
1868     {
1869         std::string type_name_str(type_name.GetCString());
1870         type_name_str.resize(type_name_str.length()-2);
1871         if (type_name_str.back() != ' ')
1872             type_name_str.append(" \\[[0-9]+\\]");
1873         else
1874             type_name_str.append("\\[[0-9]+\\]");
1875         type_name.SetCString(type_name_str.c_str());
1876         return true;
1877     }
1878     return false;
1879 }
1880 
1881 bool
1882 CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name,
1883                                         TypeSummaryImplSP entry,
1884                                         SummaryFormatType type,
1885                                         std::string category_name,
1886                                         Error* error)
1887 {
1888     lldb::TypeCategoryImplSP category;
1889     DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
1890 
1891     if (type == eRegularSummary)
1892     {
1893         if (FixArrayTypeNameWithRegex (type_name))
1894             type = eRegexSummary;
1895     }
1896 
1897     if (type == eRegexSummary)
1898     {
1899         RegularExpressionSP typeRX(new RegularExpression());
1900         if (!typeRX->Compile(type_name.GetCString()))
1901         {
1902             if (error)
1903                 error->SetErrorString("regex format error (maybe this is not really a regex?)");
1904             return false;
1905         }
1906 
1907         category->GetRegexTypeSummariesContainer()->Delete(type_name);
1908         category->GetRegexTypeSummariesContainer()->Add(typeRX, entry);
1909 
1910         return true;
1911     }
1912     else if (type == eNamedSummary)
1913     {
1914         // system named summaries do not exist (yet?)
1915         DataVisualization::NamedSummaryFormats::Add(type_name,entry);
1916         return true;
1917     }
1918     else
1919     {
1920         category->GetTypeSummariesContainer()->Add(type_name, entry);
1921         return true;
1922     }
1923 }
1924 
1925 OptionDefinition
1926 CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] =
1927 {
1928     { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,    "Add this to the given category instead of the default one."},
1929     { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
1930     { 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."},
1931     { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
1932     { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
1933     { LLDB_OPT_SET_ALL, false,  "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
1934     { LLDB_OPT_SET_1  , true, "inline-children", 'c', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,    "If true, inline all child values into summary string."},
1935     { LLDB_OPT_SET_1  , false, "omit-names", 'O', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,    "If true, omit value names in the summary display."},
1936     { LLDB_OPT_SET_2  , true, "summary-string", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSummaryString,    "Summary string used to display text and object contents."},
1937     { 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."},
1938     { 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."},
1939     { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Input Python code to use for this type manually."},
1940     { 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."},
1941     { 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."},
1942     { LLDB_OPT_SET_2 | LLDB_OPT_SET_3,   false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,    "A name for this summary string."},
1943     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1944 };
1945 
1946 
1947 //-------------------------------------------------------------------------
1948 // CommandObjectTypeSummaryDelete
1949 //-------------------------------------------------------------------------
1950 
1951 class CommandObjectTypeSummaryDelete : public CommandObjectParsed
1952 {
1953 private:
1954     class CommandOptions : public Options
1955     {
1956     public:
1957 
1958         CommandOptions (CommandInterpreter &interpreter) :
1959         Options (interpreter)
1960         {
1961         }
1962 
1963         ~CommandOptions () override {}
1964 
1965         Error
1966         SetOptionValue (uint32_t option_idx, const char *option_arg) override
1967         {
1968             Error error;
1969             const int short_option = m_getopt_table[option_idx].val;
1970 
1971             switch (short_option)
1972             {
1973                 case 'a':
1974                     m_delete_all = true;
1975                     break;
1976                 case 'w':
1977                     m_category = std::string(option_arg);
1978                     break;
1979                 case 'l':
1980                     m_language = Language::GetLanguageTypeFromString(option_arg);
1981                     break;
1982                 default:
1983                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1984                     break;
1985             }
1986 
1987             return error;
1988         }
1989 
1990         void
1991         OptionParsingStarting () override
1992         {
1993             m_delete_all = false;
1994             m_category = "default";
1995             m_language = lldb::eLanguageTypeUnknown;
1996         }
1997 
1998         const OptionDefinition*
1999         GetDefinitions () override
2000         {
2001             return g_option_table;
2002         }
2003 
2004         // Options table: Required for subclasses of Options.
2005 
2006         static OptionDefinition g_option_table[];
2007 
2008         // Instance variables to hold the values for command options.
2009 
2010         bool m_delete_all;
2011         std::string m_category;
2012         lldb::LanguageType m_language;
2013     };
2014 
2015     CommandOptions m_options;
2016 
2017     Options *
2018     GetOptions () override
2019     {
2020         return &m_options;
2021     }
2022 
2023     static bool
2024     PerCategoryCallback(void* param,
2025                         const lldb::TypeCategoryImplSP& category_sp)
2026     {
2027 		ConstString *name = (ConstString*)param;
2028 		category_sp->Delete(*name, eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary);
2029 		return true;
2030     }
2031 
2032 public:
2033     CommandObjectTypeSummaryDelete (CommandInterpreter &interpreter) :
2034         CommandObjectParsed (interpreter,
2035                              "type summary delete",
2036                              "Delete an existing summary style for a type.",
2037                              NULL),
2038         m_options(interpreter)
2039     {
2040         CommandArgumentEntry type_arg;
2041         CommandArgumentData type_style_arg;
2042 
2043         type_style_arg.arg_type = eArgTypeName;
2044         type_style_arg.arg_repetition = eArgRepeatPlain;
2045 
2046         type_arg.push_back (type_style_arg);
2047 
2048         m_arguments.push_back (type_arg);
2049 
2050     }
2051 
2052     ~CommandObjectTypeSummaryDelete () override
2053     {
2054     }
2055 
2056 protected:
2057     bool
2058     DoExecute (Args& command, CommandReturnObject &result) override
2059     {
2060         const size_t argc = command.GetArgumentCount();
2061 
2062         if (argc != 1)
2063         {
2064             result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
2065             result.SetStatus(eReturnStatusFailed);
2066             return false;
2067         }
2068 
2069         const char* typeA = command.GetArgumentAtIndex(0);
2070         ConstString typeCS(typeA);
2071 
2072         if (!typeCS)
2073         {
2074             result.AppendError("empty typenames not allowed");
2075             result.SetStatus(eReturnStatusFailed);
2076             return false;
2077         }
2078 
2079         if (m_options.m_delete_all)
2080         {
2081             DataVisualization::Categories::LoopThrough(PerCategoryCallback, &typeCS);
2082             result.SetStatus(eReturnStatusSuccessFinishNoResult);
2083             return result.Succeeded();
2084         }
2085 
2086         bool delete_category = false;
2087         bool delete_named = false;
2088 
2089         if (m_options.m_language != lldb::eLanguageTypeUnknown)
2090         {
2091             lldb::TypeCategoryImplSP category;
2092             DataVisualization::Categories::GetCategory(m_options.m_language, category);
2093             if (category)
2094                 delete_category = category->Delete(typeCS, eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary);
2095         }
2096         else
2097         {
2098             lldb::TypeCategoryImplSP category;
2099             DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
2100             if (category)
2101                 delete_category = category->Delete(typeCS, eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary);
2102             delete_named = DataVisualization::NamedSummaryFormats::Delete(typeCS);
2103         }
2104 
2105         if (delete_category || delete_named)
2106         {
2107             result.SetStatus(eReturnStatusSuccessFinishNoResult);
2108             return result.Succeeded();
2109         }
2110         else
2111         {
2112             result.AppendErrorWithFormat ("no custom summary for %s.\n", typeA);
2113             result.SetStatus(eReturnStatusFailed);
2114             return false;
2115         }
2116 
2117     }
2118 };
2119 
2120 OptionDefinition
2121 CommandObjectTypeSummaryDelete::CommandOptions::g_option_table[] =
2122 {
2123     { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,  "Delete from every category."},
2124     { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Delete from given category."},
2125     { LLDB_OPT_SET_3, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,  "Delete from given language's category."},
2126     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2127 };
2128 
2129 class CommandObjectTypeSummaryClear : public CommandObjectParsed
2130 {
2131 private:
2132 
2133     class CommandOptions : public Options
2134     {
2135     public:
2136 
2137         CommandOptions (CommandInterpreter &interpreter) :
2138         Options (interpreter)
2139         {
2140         }
2141 
2142         ~CommandOptions () override {}
2143 
2144         Error
2145         SetOptionValue (uint32_t option_idx, const char *option_arg) override
2146         {
2147             Error error;
2148             const int short_option = m_getopt_table[option_idx].val;
2149 
2150             switch (short_option)
2151             {
2152                 case 'a':
2153                     m_delete_all = true;
2154                     break;
2155                 default:
2156                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
2157                     break;
2158             }
2159 
2160             return error;
2161         }
2162 
2163         void
2164         OptionParsingStarting () override
2165         {
2166             m_delete_all = false;
2167         }
2168 
2169         const OptionDefinition*
2170         GetDefinitions () override
2171         {
2172             return g_option_table;
2173         }
2174 
2175         // Options table: Required for subclasses of Options.
2176 
2177         static OptionDefinition g_option_table[];
2178 
2179         // Instance variables to hold the values for command options.
2180 
2181         bool m_delete_all;
2182         bool m_delete_named;
2183     };
2184 
2185     CommandOptions m_options;
2186 
2187     Options *
2188     GetOptions () override
2189     {
2190         return &m_options;
2191     }
2192 
2193     static bool
2194     PerCategoryCallback(void* param,
2195                         const lldb::TypeCategoryImplSP& cate)
2196     {
2197         cate->GetTypeSummariesContainer()->Clear();
2198         cate->GetRegexTypeSummariesContainer()->Clear();
2199         return true;
2200 
2201     }
2202 
2203 public:
2204     CommandObjectTypeSummaryClear (CommandInterpreter &interpreter) :
2205         CommandObjectParsed (interpreter,
2206                              "type summary clear",
2207                              "Delete all existing summary styles.",
2208                              NULL),
2209         m_options(interpreter)
2210     {
2211     }
2212 
2213     ~CommandObjectTypeSummaryClear () override
2214     {
2215     }
2216 
2217 protected:
2218     bool
2219     DoExecute (Args& command, CommandReturnObject &result) override
2220     {
2221 
2222         if (m_options.m_delete_all)
2223             DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL);
2224 
2225         else
2226         {
2227             lldb::TypeCategoryImplSP category;
2228             if (command.GetArgumentCount() > 0)
2229             {
2230                 const char* cat_name = command.GetArgumentAtIndex(0);
2231                 ConstString cat_nameCS(cat_name);
2232                 DataVisualization::Categories::GetCategory(cat_nameCS, category);
2233             }
2234             else
2235                 DataVisualization::Categories::GetCategory(ConstString(NULL), category);
2236             category->Clear(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary);
2237         }
2238 
2239         DataVisualization::NamedSummaryFormats::Clear();
2240 
2241         result.SetStatus(eReturnStatusSuccessFinishResult);
2242         return result.Succeeded();
2243     }
2244 
2245 };
2246 
2247 OptionDefinition
2248 CommandObjectTypeSummaryClear::CommandOptions::g_option_table[] =
2249 {
2250     { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,  "Clear every category."},
2251     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2252 };
2253 
2254 //-------------------------------------------------------------------------
2255 // CommandObjectTypeSummaryList
2256 //-------------------------------------------------------------------------
2257 
2258 bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, ConstString type, const StringSummaryFormat::SharedPointer& entry);
2259 bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const StringSummaryFormat::SharedPointer& entry);
2260 
2261 class CommandObjectTypeSummaryList;
2262 
2263 struct CommandObjectTypeSummaryList_LoopCallbackParam {
2264     CommandObjectTypeSummaryList* self;
2265     CommandReturnObject* result;
2266     RegularExpression* regex;
2267     RegularExpression* cate_regex;
2268     CommandObjectTypeSummaryList_LoopCallbackParam(CommandObjectTypeSummaryList* S, CommandReturnObject* R,
2269                                                   RegularExpression* X = NULL,
2270                                                   RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}
2271 };
2272 
2273 class CommandObjectTypeSummaryList : public CommandObjectParsed
2274 {
2275 
2276     class CommandOptions : public Options
2277     {
2278     public:
2279 
2280         CommandOptions (CommandInterpreter &interpreter) :
2281         Options (interpreter)
2282         {
2283         }
2284 
2285         ~CommandOptions () override {}
2286 
2287         Error
2288         SetOptionValue (uint32_t option_idx, const char *option_arg) override
2289         {
2290             Error error;
2291             const int short_option = m_getopt_table[option_idx].val;
2292 
2293             switch (short_option)
2294             {
2295                 case 'w':
2296                     m_category_regex = std::string(option_arg);
2297                     break;
2298                 default:
2299                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
2300                     break;
2301             }
2302 
2303             return error;
2304         }
2305 
2306         void
2307         OptionParsingStarting () override
2308         {
2309             m_category_regex = "";
2310         }
2311 
2312         const OptionDefinition*
2313         GetDefinitions () override
2314         {
2315             return g_option_table;
2316         }
2317 
2318         // Options table: Required for subclasses of Options.
2319 
2320         static OptionDefinition g_option_table[];
2321 
2322         // Instance variables to hold the values for command options.
2323 
2324         std::string m_category_regex;
2325 
2326     };
2327 
2328     CommandOptions m_options;
2329 
2330     Options *
2331     GetOptions () override
2332     {
2333         return &m_options;
2334     }
2335 
2336 public:
2337     CommandObjectTypeSummaryList (CommandInterpreter &interpreter) :
2338         CommandObjectParsed (interpreter,
2339                              "type summary list",
2340                              "Show a list of current summary styles.",
2341                              NULL),
2342         m_options(interpreter)
2343     {
2344         CommandArgumentEntry type_arg;
2345         CommandArgumentData type_style_arg;
2346 
2347         type_style_arg.arg_type = eArgTypeName;
2348         type_style_arg.arg_repetition = eArgRepeatOptional;
2349 
2350         type_arg.push_back (type_style_arg);
2351 
2352         m_arguments.push_back (type_arg);
2353     }
2354 
2355     ~CommandObjectTypeSummaryList () override
2356     {
2357     }
2358 
2359 protected:
2360     bool
2361     DoExecute (Args& command, CommandReturnObject &result) override
2362     {
2363         const size_t argc = command.GetArgumentCount();
2364 
2365         CommandObjectTypeSummaryList_LoopCallbackParam *param;
2366         RegularExpression* cate_regex =
2367         m_options.m_category_regex.empty() ? NULL :
2368         new RegularExpression(m_options.m_category_regex.c_str());
2369 
2370         if (argc == 1)
2371         {
2372             RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
2373             regex->Compile(command.GetArgumentAtIndex(0));
2374             param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex,cate_regex);
2375         }
2376         else
2377             param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,NULL,cate_regex);
2378 
2379         DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
2380         delete param;
2381 
2382         if (DataVisualization::NamedSummaryFormats::GetCount() > 0)
2383         {
2384             result.GetOutputStream().Printf("Named summaries:\n");
2385             if (argc == 1)
2386             {
2387                 RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
2388                 regex->Compile(command.GetArgumentAtIndex(0));
2389                 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result,regex);
2390             }
2391             else
2392                 param = new CommandObjectTypeSummaryList_LoopCallbackParam(this,&result);
2393             DataVisualization::NamedSummaryFormats::LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param);
2394             delete param;
2395         }
2396 
2397         if (cate_regex)
2398             delete cate_regex;
2399 
2400         result.SetStatus(eReturnStatusSuccessFinishResult);
2401         return result.Succeeded();
2402     }
2403 
2404 private:
2405 
2406     static bool
2407     PerCategoryCallback(void* param_vp,
2408                         const lldb::TypeCategoryImplSP& cate)
2409     {
2410 
2411         CommandObjectTypeSummaryList_LoopCallbackParam* param =
2412             (CommandObjectTypeSummaryList_LoopCallbackParam*)param_vp;
2413         CommandReturnObject* result = param->result;
2414 
2415         const char* cate_name = cate->GetName();
2416 
2417         // if the category is disabled or empty and there is no regex, just skip it
2418         if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary) == 0) && param->cate_regex == NULL)
2419             return true;
2420 
2421         // if we have a regex and this category does not match it, just skip it
2422         if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)
2423             return true;
2424 
2425         result->GetOutputStream().Printf("-----------------------\nCategory: %s\n-----------------------\n", cate->GetDescription().c_str());
2426 
2427         cate->GetTypeSummariesContainer()->LoopThrough(CommandObjectTypeSummaryList_LoopCallback, param_vp);
2428 
2429         if (cate->GetRegexTypeSummariesContainer()->GetCount() > 0)
2430         {
2431             result->GetOutputStream().Printf("Regex-based summaries (slower):\n");
2432             cate->GetRegexTypeSummariesContainer()->LoopThrough(CommandObjectTypeRXSummaryList_LoopCallback, param_vp);
2433         }
2434         return true;
2435     }
2436 
2437 
2438     bool
2439     LoopCallback (const char* type,
2440                   const lldb::TypeSummaryImplSP& entry,
2441                   RegularExpression* regex,
2442                   CommandReturnObject *result)
2443     {
2444         if (regex == NULL || strcmp(type,regex->GetText()) == 0 || regex->Execute(type))
2445                 result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());
2446         return true;
2447     }
2448 
2449     friend bool CommandObjectTypeSummaryList_LoopCallback(void* pt2self, ConstString type, const lldb::TypeSummaryImplSP& entry);
2450     friend bool CommandObjectTypeRXSummaryList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const lldb::TypeSummaryImplSP& entry);
2451 };
2452 
2453 bool
2454 CommandObjectTypeSummaryList_LoopCallback (
2455                                           void* pt2self,
2456                                           ConstString type,
2457                                           const lldb::TypeSummaryImplSP& entry)
2458 {
2459     CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self;
2460     return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);
2461 }
2462 
2463 bool
2464 CommandObjectTypeRXSummaryList_LoopCallback (
2465                                            void* pt2self,
2466                                            lldb::RegularExpressionSP regex,
2467                                            const lldb::TypeSummaryImplSP& entry)
2468 {
2469     CommandObjectTypeSummaryList_LoopCallbackParam* param = (CommandObjectTypeSummaryList_LoopCallbackParam*)pt2self;
2470     return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
2471 }
2472 
2473 OptionDefinition
2474 CommandObjectTypeSummaryList::CommandOptions::g_option_table[] =
2475 {
2476     { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
2477     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2478 };
2479 
2480 //-------------------------------------------------------------------------
2481 // CommandObjectTypeCategoryDefine
2482 //-------------------------------------------------------------------------
2483 
2484 class CommandObjectTypeCategoryDefine : public CommandObjectParsed
2485 {
2486 
2487     class CommandOptions : public Options
2488     {
2489     public:
2490 
2491         CommandOptions (CommandInterpreter &interpreter) :
2492         Options (interpreter),
2493         m_define_enabled(false,false),
2494         m_cate_language(eLanguageTypeUnknown,eLanguageTypeUnknown)
2495         {
2496         }
2497 
2498         ~CommandOptions () override {}
2499 
2500         Error
2501         SetOptionValue (uint32_t option_idx, const char *option_arg) override
2502         {
2503             Error error;
2504             const int short_option = m_getopt_table[option_idx].val;
2505 
2506             switch (short_option)
2507             {
2508                 case 'e':
2509                     m_define_enabled.SetValueFromString("true");
2510                     break;
2511                 case 'l':
2512                     error = m_cate_language.SetValueFromString(option_arg);
2513                     break;
2514                 default:
2515                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
2516                     break;
2517             }
2518 
2519             return error;
2520         }
2521 
2522         void
2523         OptionParsingStarting () override
2524         {
2525             m_define_enabled.Clear();
2526             m_cate_language.Clear();
2527         }
2528 
2529         const OptionDefinition*
2530         GetDefinitions () override
2531         {
2532             return g_option_table;
2533         }
2534 
2535         // Options table: Required for subclasses of Options.
2536 
2537         static OptionDefinition g_option_table[];
2538 
2539         // Instance variables to hold the values for command options.
2540 
2541         OptionValueBoolean m_define_enabled;
2542         OptionValueLanguage m_cate_language;
2543 
2544 
2545     };
2546 
2547     CommandOptions m_options;
2548 
2549     Options *
2550     GetOptions () override
2551     {
2552         return &m_options;
2553     }
2554 
2555 public:
2556     CommandObjectTypeCategoryDefine (CommandInterpreter &interpreter) :
2557     CommandObjectParsed (interpreter,
2558                          "type category define",
2559                          "Define a new category as a source of formatters.",
2560                          NULL),
2561     m_options(interpreter)
2562     {
2563         CommandArgumentEntry type_arg;
2564         CommandArgumentData type_style_arg;
2565 
2566         type_style_arg.arg_type = eArgTypeName;
2567         type_style_arg.arg_repetition = eArgRepeatPlus;
2568 
2569         type_arg.push_back (type_style_arg);
2570 
2571         m_arguments.push_back (type_arg);
2572 
2573     }
2574 
2575     ~CommandObjectTypeCategoryDefine () override
2576     {
2577     }
2578 
2579 protected:
2580     bool
2581     DoExecute (Args& command, CommandReturnObject &result) override
2582     {
2583         const size_t argc = command.GetArgumentCount();
2584 
2585         if (argc < 1)
2586         {
2587             result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str());
2588             result.SetStatus(eReturnStatusFailed);
2589             return false;
2590         }
2591 
2592         for (size_t i = 0; i < argc; i++)
2593         {
2594             const char* cateName = command.GetArgumentAtIndex(i);
2595             TypeCategoryImplSP category_sp;
2596             if (DataVisualization::Categories::GetCategory(ConstString(cateName), category_sp) && category_sp)
2597             {
2598                 category_sp->AddLanguage(m_options.m_cate_language.GetCurrentValue());
2599                 if (m_options.m_define_enabled.GetCurrentValue())
2600                     DataVisualization::Categories::Enable(category_sp, TypeCategoryMap::Default);
2601             }
2602         }
2603 
2604         result.SetStatus(eReturnStatusSuccessFinishResult);
2605         return result.Succeeded();
2606     }
2607 
2608 };
2609 
2610 OptionDefinition
2611 CommandObjectTypeCategoryDefine::CommandOptions::g_option_table[] =
2612 {
2613     { LLDB_OPT_SET_ALL, false, "enabled", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,  "If specified, this category will be created enabled."},
2614     { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,  "Specify the language that this category is supported for."},
2615     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2616 };
2617 
2618 //-------------------------------------------------------------------------
2619 // CommandObjectTypeCategoryEnable
2620 //-------------------------------------------------------------------------
2621 
2622 class CommandObjectTypeCategoryEnable : public CommandObjectParsed
2623 {
2624     class CommandOptions : public Options
2625     {
2626     public:
2627 
2628         CommandOptions (CommandInterpreter &interpreter) :
2629         Options (interpreter)
2630         {
2631         }
2632 
2633         ~CommandOptions () override {}
2634 
2635         Error
2636         SetOptionValue (uint32_t option_idx, const char *option_arg) override
2637         {
2638             Error error;
2639             const int short_option = m_getopt_table[option_idx].val;
2640 
2641             switch (short_option)
2642             {
2643                 case 'l':
2644                     if (option_arg)
2645                     {
2646                         m_language = Language::GetLanguageTypeFromString(option_arg);
2647                         if (m_language == lldb::eLanguageTypeUnknown)
2648                             error.SetErrorStringWithFormat ("unrecognized language '%s'", option_arg);
2649                     }
2650                     break;
2651                 default:
2652                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
2653                     break;
2654             }
2655 
2656             return error;
2657         }
2658 
2659         void
2660         OptionParsingStarting () override
2661         {
2662             m_language = lldb::eLanguageTypeUnknown;
2663         }
2664 
2665         const OptionDefinition*
2666         GetDefinitions () override
2667         {
2668             return g_option_table;
2669         }
2670 
2671         // Options table: Required for subclasses of Options.
2672 
2673         static OptionDefinition g_option_table[];
2674 
2675         // Instance variables to hold the values for command options.
2676 
2677         lldb::LanguageType m_language;
2678 
2679     };
2680 
2681     CommandOptions m_options;
2682 
2683     Options *
2684     GetOptions () override
2685     {
2686         return &m_options;
2687     }
2688 
2689 public:
2690     CommandObjectTypeCategoryEnable (CommandInterpreter &interpreter) :
2691         CommandObjectParsed (interpreter,
2692                              "type category enable",
2693                              "Enable a category as a source of formatters.",
2694                              NULL),
2695         m_options(interpreter)
2696     {
2697         CommandArgumentEntry type_arg;
2698         CommandArgumentData type_style_arg;
2699 
2700         type_style_arg.arg_type = eArgTypeName;
2701         type_style_arg.arg_repetition = eArgRepeatPlus;
2702 
2703         type_arg.push_back (type_style_arg);
2704 
2705         m_arguments.push_back (type_arg);
2706 
2707     }
2708 
2709     ~CommandObjectTypeCategoryEnable () override
2710     {
2711     }
2712 
2713 protected:
2714     bool
2715     DoExecute (Args& command, CommandReturnObject &result) override
2716     {
2717         const size_t argc = command.GetArgumentCount();
2718 
2719         if (argc < 1 &&
2720             m_options.m_language == lldb::eLanguageTypeUnknown)
2721         {
2722             result.AppendErrorWithFormat ("%s takes arguments and/or a language", m_cmd_name.c_str());
2723             result.SetStatus(eReturnStatusFailed);
2724             return false;
2725         }
2726 
2727         if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
2728         {
2729             DataVisualization::Categories::EnableStar();
2730         }
2731         else if (argc > 0)
2732         {
2733             for (int i = argc - 1; i >= 0; i--)
2734             {
2735                 const char* typeA = command.GetArgumentAtIndex(i);
2736                 ConstString typeCS(typeA);
2737 
2738                 if (!typeCS)
2739                 {
2740                     result.AppendError("empty category name not allowed");
2741                     result.SetStatus(eReturnStatusFailed);
2742                     return false;
2743                 }
2744                 DataVisualization::Categories::Enable(typeCS);
2745                 lldb::TypeCategoryImplSP cate;
2746                 if (DataVisualization::Categories::GetCategory(typeCS, cate) && cate.get())
2747                 {
2748                     if (cate->GetCount() == 0)
2749                     {
2750                         result.AppendWarning("empty category enabled (typo?)");
2751                     }
2752                 }
2753             }
2754         }
2755 
2756         if (m_options.m_language != lldb::eLanguageTypeUnknown)
2757             DataVisualization::Categories::Enable(m_options.m_language);
2758 
2759         result.SetStatus(eReturnStatusSuccessFinishResult);
2760         return result.Succeeded();
2761     }
2762 
2763 };
2764 
2765 OptionDefinition
2766 CommandObjectTypeCategoryEnable::CommandOptions::g_option_table[] =
2767 {
2768     { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,  "Enable the category for this language."},
2769     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2770 };
2771 
2772 //-------------------------------------------------------------------------
2773 // CommandObjectTypeCategoryDelete
2774 //-------------------------------------------------------------------------
2775 
2776 class CommandObjectTypeCategoryDelete : public CommandObjectParsed
2777 {
2778 public:
2779     CommandObjectTypeCategoryDelete (CommandInterpreter &interpreter) :
2780         CommandObjectParsed (interpreter,
2781                              "type category delete",
2782                              "Delete a category and all associated formatters.",
2783                              NULL)
2784     {
2785         CommandArgumentEntry type_arg;
2786         CommandArgumentData type_style_arg;
2787 
2788         type_style_arg.arg_type = eArgTypeName;
2789         type_style_arg.arg_repetition = eArgRepeatPlus;
2790 
2791         type_arg.push_back (type_style_arg);
2792 
2793         m_arguments.push_back (type_arg);
2794 
2795     }
2796 
2797     ~CommandObjectTypeCategoryDelete () override
2798     {
2799     }
2800 
2801 protected:
2802     bool
2803     DoExecute (Args& command, CommandReturnObject &result) override
2804     {
2805         const size_t argc = command.GetArgumentCount();
2806 
2807         if (argc < 1)
2808         {
2809             result.AppendErrorWithFormat ("%s takes 1 or more arg.\n", m_cmd_name.c_str());
2810             result.SetStatus(eReturnStatusFailed);
2811             return false;
2812         }
2813 
2814         bool success = true;
2815 
2816         // the order is not relevant here
2817         for (int i = argc - 1; i >= 0; i--)
2818         {
2819             const char* typeA = command.GetArgumentAtIndex(i);
2820             ConstString typeCS(typeA);
2821 
2822             if (!typeCS)
2823             {
2824                 result.AppendError("empty category name not allowed");
2825                 result.SetStatus(eReturnStatusFailed);
2826                 return false;
2827             }
2828             if (!DataVisualization::Categories::Delete(typeCS))
2829                 success = false; // keep deleting even if we hit an error
2830         }
2831         if (success)
2832         {
2833             result.SetStatus(eReturnStatusSuccessFinishResult);
2834             return result.Succeeded();
2835         }
2836         else
2837         {
2838             result.AppendError("cannot delete one or more categories\n");
2839             result.SetStatus(eReturnStatusFailed);
2840             return false;
2841         }
2842     }
2843 };
2844 
2845 //-------------------------------------------------------------------------
2846 // CommandObjectTypeCategoryDisable
2847 //-------------------------------------------------------------------------
2848 
2849 class CommandObjectTypeCategoryDisable : public CommandObjectParsed
2850 {
2851     class CommandOptions : public Options
2852     {
2853     public:
2854 
2855         CommandOptions (CommandInterpreter &interpreter) :
2856         Options (interpreter)
2857         {
2858         }
2859 
2860         ~CommandOptions () override {}
2861 
2862         Error
2863         SetOptionValue (uint32_t option_idx, const char *option_arg) override
2864         {
2865             Error error;
2866             const int short_option = m_getopt_table[option_idx].val;
2867 
2868             switch (short_option)
2869             {
2870                 case 'l':
2871                     if (option_arg)
2872                     {
2873                         m_language = Language::GetLanguageTypeFromString(option_arg);
2874                         if (m_language == lldb::eLanguageTypeUnknown)
2875                             error.SetErrorStringWithFormat ("unrecognized language '%s'", option_arg);
2876                     }
2877                     break;
2878                 default:
2879                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
2880                     break;
2881             }
2882 
2883             return error;
2884         }
2885 
2886         void
2887         OptionParsingStarting () override
2888         {
2889             m_language = lldb::eLanguageTypeUnknown;
2890         }
2891 
2892         const OptionDefinition*
2893         GetDefinitions () override
2894         {
2895             return g_option_table;
2896         }
2897 
2898         // Options table: Required for subclasses of Options.
2899 
2900         static OptionDefinition g_option_table[];
2901 
2902         // Instance variables to hold the values for command options.
2903 
2904         lldb::LanguageType m_language;
2905 
2906     };
2907 
2908     CommandOptions m_options;
2909 
2910     Options *
2911     GetOptions () override
2912     {
2913         return &m_options;
2914     }
2915 
2916 public:
2917     CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) :
2918         CommandObjectParsed (interpreter,
2919                              "type category disable",
2920                              "Disable a category as a source of formatters.",
2921                              NULL),
2922         m_options(interpreter)
2923     {
2924         CommandArgumentEntry type_arg;
2925         CommandArgumentData type_style_arg;
2926 
2927         type_style_arg.arg_type = eArgTypeName;
2928         type_style_arg.arg_repetition = eArgRepeatPlus;
2929 
2930         type_arg.push_back (type_style_arg);
2931 
2932         m_arguments.push_back (type_arg);
2933 
2934     }
2935 
2936     ~CommandObjectTypeCategoryDisable () override
2937     {
2938     }
2939 
2940 protected:
2941     bool
2942     DoExecute (Args& command, CommandReturnObject &result) override
2943     {
2944         const size_t argc = command.GetArgumentCount();
2945 
2946         if (argc < 1 &&
2947             m_options.m_language == lldb::eLanguageTypeUnknown)
2948         {
2949             result.AppendErrorWithFormat ("%s takes arguments and/or a language", m_cmd_name.c_str());
2950             result.SetStatus(eReturnStatusFailed);
2951             return false;
2952         }
2953 
2954         if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
2955         {
2956             DataVisualization::Categories::DisableStar();
2957         }
2958         else if (argc > 0)
2959         {
2960             // the order is not relevant here
2961             for (int i = argc - 1; i >= 0; i--)
2962             {
2963                 const char* typeA = command.GetArgumentAtIndex(i);
2964                 ConstString typeCS(typeA);
2965 
2966                 if (!typeCS)
2967                 {
2968                     result.AppendError("empty category name not allowed");
2969                     result.SetStatus(eReturnStatusFailed);
2970                     return false;
2971                 }
2972                 DataVisualization::Categories::Disable(typeCS);
2973             }
2974         }
2975 
2976         if (m_options.m_language != lldb::eLanguageTypeUnknown)
2977             DataVisualization::Categories::Disable(m_options.m_language);
2978 
2979         result.SetStatus(eReturnStatusSuccessFinishResult);
2980         return result.Succeeded();
2981     }
2982 
2983 };
2984 
2985 OptionDefinition
2986 CommandObjectTypeCategoryDisable::CommandOptions::g_option_table[] =
2987 {
2988     { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,  "Enable the category for this language."},
2989     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2990 };
2991 
2992 //-------------------------------------------------------------------------
2993 // CommandObjectTypeCategoryList
2994 //-------------------------------------------------------------------------
2995 
2996 class CommandObjectTypeCategoryList : public CommandObjectParsed
2997 {
2998 private:
2999 
3000     struct CommandObjectTypeCategoryList_CallbackParam
3001     {
3002         CommandReturnObject* result;
3003         RegularExpression* regex;
3004 
3005         CommandObjectTypeCategoryList_CallbackParam(CommandReturnObject* res,
3006                                                     RegularExpression* rex = NULL) :
3007         result(res),
3008         regex(rex)
3009         {
3010         }
3011 
3012     };
3013 
3014     static bool
3015     PerCategoryCallback(void* param_vp,
3016                         const lldb::TypeCategoryImplSP& cate)
3017     {
3018         CommandObjectTypeCategoryList_CallbackParam* param =
3019             (CommandObjectTypeCategoryList_CallbackParam*)param_vp;
3020         CommandReturnObject* result = param->result;
3021         RegularExpression* regex = param->regex;
3022 
3023         const char* cate_name = cate->GetName();
3024 
3025         if (regex == NULL || strcmp(cate_name, regex->GetText()) == 0 || regex->Execute(cate_name))
3026             result->GetOutputStream().Printf("Category: %s\n", cate->GetDescription().c_str());
3027         return true;
3028     }
3029 public:
3030     CommandObjectTypeCategoryList (CommandInterpreter &interpreter) :
3031         CommandObjectParsed (interpreter,
3032                              "type category list",
3033                              "Provide a list of all existing categories.",
3034                              NULL)
3035     {
3036         CommandArgumentEntry type_arg;
3037         CommandArgumentData type_style_arg;
3038 
3039         type_style_arg.arg_type = eArgTypeName;
3040         type_style_arg.arg_repetition = eArgRepeatOptional;
3041 
3042         type_arg.push_back (type_style_arg);
3043 
3044         m_arguments.push_back (type_arg);
3045     }
3046 
3047     ~CommandObjectTypeCategoryList () override
3048     {
3049     }
3050 
3051 protected:
3052     bool
3053     DoExecute (Args& command, CommandReturnObject &result) override
3054     {
3055         const size_t argc = command.GetArgumentCount();
3056         RegularExpression* regex = NULL;
3057 
3058         if (argc == 0)
3059             ;
3060         else if (argc == 1)
3061             regex = new RegularExpression(command.GetArgumentAtIndex(0));
3062         else
3063         {
3064             result.AppendErrorWithFormat ("%s takes 0 or one arg.\n", m_cmd_name.c_str());
3065             result.SetStatus(eReturnStatusFailed);
3066             return false;
3067         }
3068 
3069         CommandObjectTypeCategoryList_CallbackParam param(&result,
3070                                                           regex);
3071 
3072         DataVisualization::Categories::LoopThrough(PerCategoryCallback, &param);
3073 
3074         if (regex)
3075             delete regex;
3076 
3077         result.SetStatus(eReturnStatusSuccessFinishResult);
3078         return result.Succeeded();
3079     }
3080 
3081 };
3082 
3083 //-------------------------------------------------------------------------
3084 // CommandObjectTypeFilterList
3085 //-------------------------------------------------------------------------
3086 
3087 bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);
3088 bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
3089 
3090 class CommandObjectTypeFilterList;
3091 
3092 struct CommandObjectTypeFilterList_LoopCallbackParam {
3093     CommandObjectTypeFilterList* self;
3094     CommandReturnObject* result;
3095     RegularExpression* regex;
3096     RegularExpression* cate_regex;
3097     CommandObjectTypeFilterList_LoopCallbackParam(CommandObjectTypeFilterList* S, CommandReturnObject* R,
3098                                                   RegularExpression* X = NULL,
3099                                                   RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}
3100 };
3101 
3102 class CommandObjectTypeFilterList : public CommandObjectParsed
3103 {
3104 
3105     class CommandOptions : public Options
3106     {
3107     public:
3108 
3109         CommandOptions (CommandInterpreter &interpreter) :
3110         Options (interpreter)
3111         {
3112         }
3113 
3114         ~CommandOptions () override {}
3115 
3116         Error
3117         SetOptionValue (uint32_t option_idx, const char *option_arg) override
3118         {
3119             Error error;
3120             const int short_option = m_getopt_table[option_idx].val;
3121 
3122             switch (short_option)
3123             {
3124                 case 'w':
3125                     m_category_regex = std::string(option_arg);
3126                     break;
3127                 default:
3128                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
3129                     break;
3130             }
3131 
3132             return error;
3133         }
3134 
3135         void
3136         OptionParsingStarting () override
3137         {
3138             m_category_regex = "";
3139         }
3140 
3141         const OptionDefinition*
3142         GetDefinitions () override
3143         {
3144             return g_option_table;
3145         }
3146 
3147         // Options table: Required for subclasses of Options.
3148 
3149         static OptionDefinition g_option_table[];
3150 
3151         // Instance variables to hold the values for command options.
3152 
3153         std::string m_category_regex;
3154 
3155     };
3156 
3157     CommandOptions m_options;
3158 
3159     Options *
3160     GetOptions () override
3161     {
3162         return &m_options;
3163     }
3164 
3165 public:
3166     CommandObjectTypeFilterList (CommandInterpreter &interpreter) :
3167         CommandObjectParsed (interpreter,
3168                              "type filter list",
3169                              "Show a list of current filters.",
3170                              NULL),
3171         m_options(interpreter)
3172     {
3173         CommandArgumentEntry type_arg;
3174         CommandArgumentData type_style_arg;
3175 
3176         type_style_arg.arg_type = eArgTypeName;
3177         type_style_arg.arg_repetition = eArgRepeatOptional;
3178 
3179         type_arg.push_back (type_style_arg);
3180 
3181         m_arguments.push_back (type_arg);
3182     }
3183 
3184     ~CommandObjectTypeFilterList () override
3185     {
3186     }
3187 
3188 protected:
3189     bool
3190     DoExecute (Args& command, CommandReturnObject &result) override
3191     {
3192         const size_t argc = command.GetArgumentCount();
3193 
3194         CommandObjectTypeFilterList_LoopCallbackParam *param;
3195         RegularExpression* cate_regex =
3196         m_options.m_category_regex.empty() ? NULL :
3197         new RegularExpression(m_options.m_category_regex.c_str());
3198 
3199         if (argc == 1)
3200         {
3201             RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
3202             regex->Compile(command.GetArgumentAtIndex(0));
3203             param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,regex,cate_regex);
3204         }
3205         else
3206             param = new CommandObjectTypeFilterList_LoopCallbackParam(this,&result,NULL,cate_regex);
3207 
3208         DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
3209         delete param;
3210 
3211         if (cate_regex)
3212             delete cate_regex;
3213 
3214         result.SetStatus(eReturnStatusSuccessFinishResult);
3215         return result.Succeeded();
3216     }
3217 
3218 private:
3219 
3220     static bool
3221     PerCategoryCallback(void* param_vp,
3222                         const lldb::TypeCategoryImplSP& cate)
3223     {
3224 
3225         const char* cate_name = cate->GetName();
3226 
3227         CommandObjectTypeFilterList_LoopCallbackParam* param =
3228         (CommandObjectTypeFilterList_LoopCallbackParam*)param_vp;
3229         CommandReturnObject* result = param->result;
3230 
3231         // if the category is disabled or empty and there is no regex, just skip it
3232         if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter) == 0) && param->cate_regex == NULL)
3233             return true;
3234 
3235         // if we have a regex and this category does not match it, just skip it
3236         if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)
3237             return true;
3238 
3239         result->GetOutputStream().Printf("-----------------------\nCategory: %s\n-----------------------\n", cate->GetDescription().c_str());
3240 
3241         cate->GetTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterList_LoopCallback, param_vp);
3242 
3243         if (cate->GetRegexTypeFiltersContainer()->GetCount() > 0)
3244         {
3245             result->GetOutputStream().Printf("Regex-based filters (slower):\n");
3246             cate->GetRegexTypeFiltersContainer()->LoopThrough(CommandObjectTypeFilterRXList_LoopCallback, param_vp);
3247         }
3248 
3249         return true;
3250     }
3251 
3252     bool
3253     LoopCallback (const char* type,
3254                   const SyntheticChildren::SharedPointer& entry,
3255                   RegularExpression* regex,
3256                   CommandReturnObject *result)
3257     {
3258         if (regex == NULL || regex->Execute(type))
3259             result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());
3260         return true;
3261     }
3262 
3263     friend bool CommandObjectTypeFilterList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);
3264     friend bool CommandObjectTypeFilterRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
3265 };
3266 
3267 bool
3268 CommandObjectTypeFilterList_LoopCallback (void* pt2self,
3269                                          ConstString type,
3270                                          const SyntheticChildren::SharedPointer& entry)
3271 {
3272     CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self;
3273     return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);
3274 }
3275 
3276 bool
3277 CommandObjectTypeFilterRXList_LoopCallback (void* pt2self,
3278                                            lldb::RegularExpressionSP regex,
3279                                            const SyntheticChildren::SharedPointer& entry)
3280 {
3281     CommandObjectTypeFilterList_LoopCallbackParam* param = (CommandObjectTypeFilterList_LoopCallbackParam*)pt2self;
3282     return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
3283 }
3284 
3285 
3286 OptionDefinition
3287 CommandObjectTypeFilterList::CommandOptions::g_option_table[] =
3288 {
3289     { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
3290     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
3291 };
3292 
3293 #ifndef LLDB_DISABLE_PYTHON
3294 
3295 //-------------------------------------------------------------------------
3296 // CommandObjectTypeSynthList
3297 //-------------------------------------------------------------------------
3298 
3299 bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);
3300 bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
3301 
3302 class CommandObjectTypeSynthList;
3303 
3304 struct CommandObjectTypeSynthList_LoopCallbackParam {
3305     CommandObjectTypeSynthList* self;
3306     CommandReturnObject* result;
3307     RegularExpression* regex;
3308     RegularExpression* cate_regex;
3309     CommandObjectTypeSynthList_LoopCallbackParam(CommandObjectTypeSynthList* S, CommandReturnObject* R,
3310                                                  RegularExpression* X = NULL,
3311                                                  RegularExpression* CX = NULL) : self(S), result(R), regex(X), cate_regex(CX) {}
3312 };
3313 
3314 class CommandObjectTypeSynthList : public CommandObjectParsed
3315 {
3316 
3317     class CommandOptions : public Options
3318     {
3319     public:
3320 
3321         CommandOptions (CommandInterpreter &interpreter) :
3322         Options (interpreter)
3323         {
3324         }
3325 
3326         ~CommandOptions () override {}
3327 
3328         Error
3329         SetOptionValue (uint32_t option_idx, const char *option_arg) override
3330         {
3331             Error error;
3332             const int short_option = m_getopt_table[option_idx].val;
3333 
3334             switch (short_option)
3335             {
3336                 case 'w':
3337                     m_category_regex = std::string(option_arg);
3338                     break;
3339                 default:
3340                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
3341                     break;
3342             }
3343 
3344             return error;
3345         }
3346 
3347         void
3348         OptionParsingStarting () override
3349         {
3350             m_category_regex = "";
3351         }
3352 
3353         const OptionDefinition*
3354         GetDefinitions () override
3355         {
3356             return g_option_table;
3357         }
3358 
3359         // Options table: Required for subclasses of Options.
3360 
3361         static OptionDefinition g_option_table[];
3362 
3363         // Instance variables to hold the values for command options.
3364 
3365         std::string m_category_regex;
3366 
3367     };
3368 
3369     CommandOptions m_options;
3370 
3371     Options *
3372     GetOptions () override
3373     {
3374         return &m_options;
3375     }
3376 
3377 public:
3378     CommandObjectTypeSynthList (CommandInterpreter &interpreter) :
3379         CommandObjectParsed (interpreter,
3380                              "type synthetic list",
3381                              "Show a list of current synthetic providers.",
3382                              NULL),
3383         m_options(interpreter)
3384     {
3385         CommandArgumentEntry type_arg;
3386         CommandArgumentData type_style_arg;
3387 
3388         type_style_arg.arg_type = eArgTypeName;
3389         type_style_arg.arg_repetition = eArgRepeatOptional;
3390 
3391         type_arg.push_back (type_style_arg);
3392 
3393         m_arguments.push_back (type_arg);
3394     }
3395 
3396     ~CommandObjectTypeSynthList () override
3397     {
3398     }
3399 
3400 protected:
3401     bool
3402     DoExecute (Args& command, CommandReturnObject &result) override
3403     {
3404         const size_t argc = command.GetArgumentCount();
3405 
3406         CommandObjectTypeSynthList_LoopCallbackParam *param;
3407         RegularExpression* cate_regex =
3408         m_options.m_category_regex.empty() ? NULL :
3409         new RegularExpression(m_options.m_category_regex.c_str());
3410 
3411         if (argc == 1)
3412         {
3413             RegularExpression* regex = new RegularExpression(command.GetArgumentAtIndex(0));
3414             regex->Compile(command.GetArgumentAtIndex(0));
3415             param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,regex,cate_regex);
3416         }
3417         else
3418             param = new CommandObjectTypeSynthList_LoopCallbackParam(this,&result,NULL,cate_regex);
3419 
3420         DataVisualization::Categories::LoopThrough(PerCategoryCallback,param);
3421         delete param;
3422 
3423         if (cate_regex)
3424             delete cate_regex;
3425 
3426         result.SetStatus(eReturnStatusSuccessFinishResult);
3427         return result.Succeeded();
3428     }
3429 
3430 private:
3431 
3432     static bool
3433     PerCategoryCallback(void* param_vp,
3434                         const lldb::TypeCategoryImplSP& cate)
3435     {
3436 
3437         CommandObjectTypeSynthList_LoopCallbackParam* param =
3438         (CommandObjectTypeSynthList_LoopCallbackParam*)param_vp;
3439         CommandReturnObject* result = param->result;
3440 
3441         const char* cate_name = cate->GetName();
3442 
3443         // if the category is disabled or empty and there is no regex, just skip it
3444         if ((cate->IsEnabled() == false || cate->GetCount(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth) == 0) && param->cate_regex == NULL)
3445             return true;
3446 
3447         // if we have a regex and this category does not match it, just skip it
3448         if(param->cate_regex != NULL && strcmp(cate_name,param->cate_regex->GetText()) != 0 && param->cate_regex->Execute(cate_name) == false)
3449             return true;
3450 
3451         result->GetOutputStream().Printf("-----------------------\nCategory: %s\n-----------------------\n", cate->GetDescription().c_str());
3452 
3453         cate->GetTypeSyntheticsContainer()->LoopThrough(CommandObjectTypeSynthList_LoopCallback, param_vp);
3454 
3455         if (cate->GetRegexTypeSyntheticsContainer()->GetCount() > 0)
3456         {
3457             result->GetOutputStream().Printf("Regex-based synthetic providers (slower):\n");
3458             cate->GetRegexTypeSyntheticsContainer()->LoopThrough(CommandObjectTypeSynthRXList_LoopCallback, param_vp);
3459         }
3460 
3461         return true;
3462     }
3463 
3464     bool
3465     LoopCallback (const char* type,
3466                   const SyntheticChildren::SharedPointer& entry,
3467                   RegularExpression* regex,
3468                   CommandReturnObject *result)
3469     {
3470         if (regex == NULL || regex->Execute(type))
3471             result->GetOutputStream().Printf ("%s: %s\n", type, entry->GetDescription().c_str());
3472         return true;
3473     }
3474 
3475     friend bool CommandObjectTypeSynthList_LoopCallback(void* pt2self, ConstString type, const SyntheticChildren::SharedPointer& entry);
3476     friend bool CommandObjectTypeSynthRXList_LoopCallback(void* pt2self, lldb::RegularExpressionSP regex, const SyntheticChildren::SharedPointer& entry);
3477 };
3478 
3479 bool
3480 CommandObjectTypeSynthList_LoopCallback (void* pt2self,
3481                                          ConstString type,
3482                                          const SyntheticChildren::SharedPointer& entry)
3483 {
3484     CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self;
3485     return param->self->LoopCallback(type.AsCString(), entry, param->regex, param->result);
3486 }
3487 
3488 bool
3489 CommandObjectTypeSynthRXList_LoopCallback (void* pt2self,
3490                                          lldb::RegularExpressionSP regex,
3491                                          const SyntheticChildren::SharedPointer& entry)
3492 {
3493     CommandObjectTypeSynthList_LoopCallbackParam* param = (CommandObjectTypeSynthList_LoopCallbackParam*)pt2self;
3494     return param->self->LoopCallback(regex->GetText(), entry, param->regex, param->result);
3495 }
3496 
3497 
3498 OptionDefinition
3499 CommandObjectTypeSynthList::CommandOptions::g_option_table[] =
3500 {
3501     { LLDB_OPT_SET_ALL, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
3502     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
3503 };
3504 
3505 #endif // #ifndef LLDB_DISABLE_PYTHON
3506 //-------------------------------------------------------------------------
3507 // CommandObjectTypeFilterDelete
3508 //-------------------------------------------------------------------------
3509 
3510 class CommandObjectTypeFilterDelete : public CommandObjectParsed
3511 {
3512 private:
3513     class CommandOptions : public Options
3514     {
3515     public:
3516 
3517         CommandOptions (CommandInterpreter &interpreter) :
3518         Options (interpreter)
3519         {
3520         }
3521 
3522         ~CommandOptions () override {}
3523 
3524         Error
3525         SetOptionValue (uint32_t option_idx, const char *option_arg) override
3526         {
3527             Error error;
3528             const int short_option = m_getopt_table[option_idx].val;
3529 
3530             switch (short_option)
3531             {
3532                 case 'a':
3533                     m_delete_all = true;
3534                     break;
3535                 case 'w':
3536                     m_category = std::string(option_arg);
3537                     break;
3538                 case 'l':
3539                     m_language = Language::GetLanguageTypeFromString(option_arg);
3540                     break;
3541                 default:
3542                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
3543                     break;
3544             }
3545 
3546             return error;
3547         }
3548 
3549         void
3550         OptionParsingStarting () override
3551         {
3552             m_delete_all = false;
3553             m_category = "default";
3554             m_language = lldb::eLanguageTypeUnknown;
3555         }
3556 
3557         const OptionDefinition*
3558         GetDefinitions () override
3559         {
3560             return g_option_table;
3561         }
3562 
3563         // Options table: Required for subclasses of Options.
3564 
3565         static OptionDefinition g_option_table[];
3566 
3567         // Instance variables to hold the values for command options.
3568 
3569         bool m_delete_all;
3570         std::string m_category;
3571         lldb::LanguageType m_language;
3572     };
3573 
3574     CommandOptions m_options;
3575 
3576     Options *
3577     GetOptions () override
3578     {
3579         return &m_options;
3580     }
3581 
3582     static bool
3583     PerCategoryCallback(void* param,
3584                         const lldb::TypeCategoryImplSP& cate)
3585     {
3586         ConstString *name = (ConstString*)param;
3587         return cate->Delete(*name, eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter);
3588     }
3589 
3590 public:
3591     CommandObjectTypeFilterDelete (CommandInterpreter &interpreter) :
3592         CommandObjectParsed (interpreter,
3593                              "type filter delete",
3594                              "Delete an existing filter for a type.",
3595                              NULL),
3596         m_options(interpreter)
3597     {
3598         CommandArgumentEntry type_arg;
3599         CommandArgumentData type_style_arg;
3600 
3601         type_style_arg.arg_type = eArgTypeName;
3602         type_style_arg.arg_repetition = eArgRepeatPlain;
3603 
3604         type_arg.push_back (type_style_arg);
3605 
3606         m_arguments.push_back (type_arg);
3607 
3608     }
3609 
3610     ~CommandObjectTypeFilterDelete () override
3611     {
3612     }
3613 
3614 protected:
3615     bool
3616     DoExecute (Args& command, CommandReturnObject &result) override
3617     {
3618         const size_t argc = command.GetArgumentCount();
3619 
3620         if (argc != 1)
3621         {
3622             result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
3623             result.SetStatus(eReturnStatusFailed);
3624             return false;
3625         }
3626 
3627         const char* typeA = command.GetArgumentAtIndex(0);
3628         ConstString typeCS(typeA);
3629 
3630         if (!typeCS)
3631         {
3632             result.AppendError("empty typenames not allowed");
3633             result.SetStatus(eReturnStatusFailed);
3634             return false;
3635         }
3636 
3637         if (m_options.m_delete_all)
3638         {
3639             DataVisualization::Categories::LoopThrough(PerCategoryCallback, (void*)&typeCS);
3640             result.SetStatus(eReturnStatusSuccessFinishNoResult);
3641             return result.Succeeded();
3642         }
3643 
3644         bool delete_category = false;
3645 
3646         if (m_options.m_language != lldb::eLanguageTypeUnknown)
3647         {
3648             lldb::TypeCategoryImplSP category;
3649             DataVisualization::Categories::GetCategory(m_options.m_language, category);
3650             if (category)
3651                 delete_category = category->Delete(typeCS, eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter);
3652         }
3653         else
3654         {
3655             lldb::TypeCategoryImplSP category;
3656             DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
3657             if (category)
3658                 delete_category = category->Delete(typeCS, eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter);
3659         }
3660 
3661         if (delete_category)
3662         {
3663             result.SetStatus(eReturnStatusSuccessFinishNoResult);
3664             return result.Succeeded();
3665         }
3666         else
3667         {
3668             result.AppendErrorWithFormat ("no custom filter for %s.\n", typeA);
3669             result.SetStatus(eReturnStatusFailed);
3670             return false;
3671         }
3672     }
3673 };
3674 
3675 OptionDefinition
3676 CommandObjectTypeFilterDelete::CommandOptions::g_option_table[] =
3677 {
3678     { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,  "Delete from every category."},
3679     { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Delete from given category."},
3680     { LLDB_OPT_SET_3, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,  "Delete from given language's category."},
3681     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
3682 };
3683 
3684 #ifndef LLDB_DISABLE_PYTHON
3685 
3686 //-------------------------------------------------------------------------
3687 // CommandObjectTypeSynthDelete
3688 //-------------------------------------------------------------------------
3689 
3690 class CommandObjectTypeSynthDelete : public CommandObjectParsed
3691 {
3692 private:
3693     class CommandOptions : public Options
3694     {
3695     public:
3696 
3697         CommandOptions (CommandInterpreter &interpreter) :
3698         Options (interpreter)
3699         {
3700         }
3701 
3702         ~CommandOptions () override {}
3703 
3704         Error
3705         SetOptionValue (uint32_t option_idx, const char *option_arg) override
3706         {
3707             Error error;
3708             const int short_option = m_getopt_table[option_idx].val;
3709 
3710             switch (short_option)
3711             {
3712                 case 'a':
3713                     m_delete_all = true;
3714                     break;
3715                 case 'w':
3716                     m_category = std::string(option_arg);
3717                     break;
3718                 case 'l':
3719                     m_language = Language::GetLanguageTypeFromString(option_arg);
3720                     break;
3721                 default:
3722                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
3723                     break;
3724             }
3725 
3726             return error;
3727         }
3728 
3729         void
3730         OptionParsingStarting () override
3731         {
3732             m_delete_all = false;
3733             m_category = "default";
3734             m_language = lldb::eLanguageTypeUnknown;
3735         }
3736 
3737         const OptionDefinition*
3738         GetDefinitions () override
3739         {
3740             return g_option_table;
3741         }
3742 
3743         // Options table: Required for subclasses of Options.
3744 
3745         static OptionDefinition g_option_table[];
3746 
3747         // Instance variables to hold the values for command options.
3748 
3749         bool m_delete_all;
3750         std::string m_category;
3751         lldb::LanguageType m_language;
3752     };
3753 
3754     CommandOptions m_options;
3755 
3756     Options *
3757     GetOptions () override
3758     {
3759         return &m_options;
3760     }
3761 
3762     static bool
3763     PerCategoryCallback(void* param,
3764                         const lldb::TypeCategoryImplSP& cate)
3765     {
3766         ConstString* name = (ConstString*)param;
3767         return cate->Delete(*name, eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth);
3768     }
3769 
3770 public:
3771     CommandObjectTypeSynthDelete (CommandInterpreter &interpreter) :
3772         CommandObjectParsed (interpreter,
3773                              "type synthetic delete",
3774                              "Delete an existing synthetic provider for a type.",
3775                              NULL),
3776         m_options(interpreter)
3777     {
3778         CommandArgumentEntry type_arg;
3779         CommandArgumentData type_style_arg;
3780 
3781         type_style_arg.arg_type = eArgTypeName;
3782         type_style_arg.arg_repetition = eArgRepeatPlain;
3783 
3784         type_arg.push_back (type_style_arg);
3785 
3786         m_arguments.push_back (type_arg);
3787 
3788     }
3789 
3790     ~CommandObjectTypeSynthDelete () override
3791     {
3792     }
3793 
3794 protected:
3795     bool
3796     DoExecute (Args& command, CommandReturnObject &result) override
3797     {
3798         const size_t argc = command.GetArgumentCount();
3799 
3800         if (argc != 1)
3801         {
3802             result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
3803             result.SetStatus(eReturnStatusFailed);
3804             return false;
3805         }
3806 
3807         const char* typeA = command.GetArgumentAtIndex(0);
3808         ConstString typeCS(typeA);
3809 
3810         if (!typeCS)
3811         {
3812             result.AppendError("empty typenames not allowed");
3813             result.SetStatus(eReturnStatusFailed);
3814             return false;
3815         }
3816 
3817         if (m_options.m_delete_all)
3818         {
3819             DataVisualization::Categories::LoopThrough(PerCategoryCallback, (void*)&typeCS);
3820             result.SetStatus(eReturnStatusSuccessFinishNoResult);
3821             return result.Succeeded();
3822         }
3823 
3824         bool delete_category = false;
3825 
3826         if (m_options.m_language != lldb::eLanguageTypeUnknown)
3827         {
3828             lldb::TypeCategoryImplSP category;
3829             DataVisualization::Categories::GetCategory(m_options.m_language, category);
3830             if (category)
3831                 delete_category = category->Delete(typeCS, eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth);
3832         }
3833         else
3834         {
3835             lldb::TypeCategoryImplSP category;
3836             DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
3837             if (category)
3838                 delete_category = category->Delete(typeCS, eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth);
3839         }
3840 
3841         if (delete_category)
3842         {
3843             result.SetStatus(eReturnStatusSuccessFinishNoResult);
3844             return result.Succeeded();
3845         }
3846         else
3847         {
3848             result.AppendErrorWithFormat ("no custom synthetic provider for %s.\n", typeA);
3849             result.SetStatus(eReturnStatusFailed);
3850             return false;
3851         }
3852     }
3853 };
3854 
3855 OptionDefinition
3856 CommandObjectTypeSynthDelete::CommandOptions::g_option_table[] =
3857 {
3858     { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,  "Delete from every category."},
3859     { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Delete from given category."},
3860     { LLDB_OPT_SET_3, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,  "Delete from given language's category."},
3861     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
3862 };
3863 
3864 #endif // #ifndef LLDB_DISABLE_PYTHON
3865 
3866 //-------------------------------------------------------------------------
3867 // CommandObjectTypeFilterClear
3868 //-------------------------------------------------------------------------
3869 
3870 class CommandObjectTypeFilterClear : public CommandObjectParsed
3871 {
3872 private:
3873 
3874     class CommandOptions : public Options
3875     {
3876     public:
3877 
3878         CommandOptions (CommandInterpreter &interpreter) :
3879         Options (interpreter)
3880         {
3881         }
3882 
3883         ~CommandOptions () override {}
3884 
3885         Error
3886         SetOptionValue (uint32_t option_idx, const char *option_arg) override
3887         {
3888             Error error;
3889             const int short_option = m_getopt_table[option_idx].val;
3890 
3891             switch (short_option)
3892             {
3893                 case 'a':
3894                     m_delete_all = true;
3895                     break;
3896                 default:
3897                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
3898                     break;
3899             }
3900 
3901             return error;
3902         }
3903 
3904         void
3905         OptionParsingStarting () override
3906         {
3907             m_delete_all = false;
3908         }
3909 
3910         const OptionDefinition*
3911         GetDefinitions () override
3912         {
3913             return g_option_table;
3914         }
3915 
3916         // Options table: Required for subclasses of Options.
3917 
3918         static OptionDefinition g_option_table[];
3919 
3920         // Instance variables to hold the values for command options.
3921 
3922         bool m_delete_all;
3923         bool m_delete_named;
3924     };
3925 
3926     CommandOptions m_options;
3927 
3928     Options *
3929     GetOptions () override
3930     {
3931         return &m_options;
3932     }
3933 
3934     static bool
3935     PerCategoryCallback(void* param,
3936                         const lldb::TypeCategoryImplSP& cate)
3937     {
3938         cate->Clear(eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter);
3939         return true;
3940 
3941     }
3942 
3943 public:
3944     CommandObjectTypeFilterClear (CommandInterpreter &interpreter) :
3945         CommandObjectParsed (interpreter,
3946                              "type filter clear",
3947                              "Delete all existing filters.",
3948                              NULL),
3949         m_options(interpreter)
3950     {
3951     }
3952 
3953     ~CommandObjectTypeFilterClear () override
3954     {
3955     }
3956 
3957 protected:
3958     bool
3959     DoExecute (Args& command, CommandReturnObject &result) override
3960     {
3961 
3962         if (m_options.m_delete_all)
3963             DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL);
3964 
3965         else
3966         {
3967             lldb::TypeCategoryImplSP category;
3968             if (command.GetArgumentCount() > 0)
3969             {
3970                 const char* cat_name = command.GetArgumentAtIndex(0);
3971                 ConstString cat_nameCS(cat_name);
3972                 DataVisualization::Categories::GetCategory(cat_nameCS, category);
3973             }
3974             else
3975                 DataVisualization::Categories::GetCategory(ConstString(NULL), category);
3976             category->GetTypeFiltersContainer()->Clear();
3977             category->GetRegexTypeFiltersContainer()->Clear();
3978         }
3979 
3980         result.SetStatus(eReturnStatusSuccessFinishResult);
3981         return result.Succeeded();
3982     }
3983 
3984 };
3985 
3986 OptionDefinition
3987 CommandObjectTypeFilterClear::CommandOptions::g_option_table[] =
3988 {
3989     { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,  "Clear every category."},
3990     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
3991 };
3992 
3993 #ifndef LLDB_DISABLE_PYTHON
3994 //-------------------------------------------------------------------------
3995 // CommandObjectTypeSynthClear
3996 //-------------------------------------------------------------------------
3997 
3998 class CommandObjectTypeSynthClear : public CommandObjectParsed
3999 {
4000 private:
4001 
4002     class CommandOptions : public Options
4003     {
4004     public:
4005 
4006         CommandOptions (CommandInterpreter &interpreter) :
4007         Options (interpreter)
4008         {
4009         }
4010 
4011         ~CommandOptions () override {}
4012 
4013         Error
4014         SetOptionValue (uint32_t option_idx, const char *option_arg) override
4015         {
4016             Error error;
4017             const int short_option = m_getopt_table[option_idx].val;
4018 
4019             switch (short_option)
4020             {
4021                 case 'a':
4022                     m_delete_all = true;
4023                     break;
4024                 default:
4025                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
4026                     break;
4027             }
4028 
4029             return error;
4030         }
4031 
4032         void
4033         OptionParsingStarting () override
4034         {
4035             m_delete_all = false;
4036         }
4037 
4038         const OptionDefinition*
4039         GetDefinitions () override
4040         {
4041             return g_option_table;
4042         }
4043 
4044         // Options table: Required for subclasses of Options.
4045 
4046         static OptionDefinition g_option_table[];
4047 
4048         // Instance variables to hold the values for command options.
4049 
4050         bool m_delete_all;
4051         bool m_delete_named;
4052     };
4053 
4054     CommandOptions m_options;
4055 
4056     Options *
4057     GetOptions () override
4058     {
4059         return &m_options;
4060     }
4061 
4062     static bool
4063     PerCategoryCallback(void* param,
4064                         const lldb::TypeCategoryImplSP& cate)
4065     {
4066         cate->Clear(eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth);
4067         return true;
4068 
4069     }
4070 
4071 public:
4072     CommandObjectTypeSynthClear (CommandInterpreter &interpreter) :
4073         CommandObjectParsed (interpreter,
4074                              "type synthetic clear",
4075                              "Delete all existing synthetic providers.",
4076                              NULL),
4077         m_options(interpreter)
4078     {
4079     }
4080 
4081     ~CommandObjectTypeSynthClear () override
4082     {
4083     }
4084 
4085 protected:
4086     bool
4087     DoExecute (Args& command, CommandReturnObject &result) override
4088     {
4089 
4090         if (m_options.m_delete_all)
4091             DataVisualization::Categories::LoopThrough(PerCategoryCallback, NULL);
4092 
4093         else
4094         {
4095             lldb::TypeCategoryImplSP category;
4096             if (command.GetArgumentCount() > 0)
4097             {
4098                 const char* cat_name = command.GetArgumentAtIndex(0);
4099                 ConstString cat_nameCS(cat_name);
4100                 DataVisualization::Categories::GetCategory(cat_nameCS, category);
4101             }
4102             else
4103                 DataVisualization::Categories::GetCategory(ConstString(NULL), category);
4104             category->GetTypeSyntheticsContainer()->Clear();
4105             category->GetRegexTypeSyntheticsContainer()->Clear();
4106         }
4107 
4108         result.SetStatus(eReturnStatusSuccessFinishResult);
4109         return result.Succeeded();
4110     }
4111 
4112 };
4113 
4114 OptionDefinition
4115 CommandObjectTypeSynthClear::CommandOptions::g_option_table[] =
4116 {
4117     { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,  "Clear every category."},
4118     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
4119 };
4120 
4121 
4122 bool
4123 CommandObjectTypeSynthAdd::Execute_HandwritePython (Args& command, CommandReturnObject &result)
4124 {
4125     SynthAddOptions *options = new SynthAddOptions ( m_options.m_skip_pointers,
4126                                                      m_options.m_skip_references,
4127                                                      m_options.m_cascade,
4128                                                      m_options.m_regex,
4129                                                      m_options.m_category);
4130 
4131     const size_t argc = command.GetArgumentCount();
4132 
4133     for (size_t i = 0; i < argc; i++)
4134     {
4135         const char* typeA = command.GetArgumentAtIndex(i);
4136         if (typeA && *typeA)
4137             options->m_target_types << typeA;
4138         else
4139         {
4140             result.AppendError("empty typenames not allowed");
4141             result.SetStatus(eReturnStatusFailed);
4142             return false;
4143         }
4144     }
4145 
4146     m_interpreter.GetPythonCommandsFromIOHandler ("    ",   // Prompt
4147                                                   *this,    // IOHandlerDelegate
4148                                                   true,     // Run IOHandler in async mode
4149                                                   options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
4150     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4151     return result.Succeeded();
4152 }
4153 
4154 bool
4155 CommandObjectTypeSynthAdd::Execute_PythonClass (Args& command, CommandReturnObject &result)
4156 {
4157     const size_t argc = command.GetArgumentCount();
4158 
4159     if (argc < 1)
4160     {
4161         result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
4162         result.SetStatus(eReturnStatusFailed);
4163         return false;
4164     }
4165 
4166     if (m_options.m_class_name.empty() && !m_options.m_input_python)
4167     {
4168         result.AppendErrorWithFormat ("%s needs either a Python class name or -P to directly input Python code.\n", m_cmd_name.c_str());
4169         result.SetStatus(eReturnStatusFailed);
4170         return false;
4171     }
4172 
4173     SyntheticChildrenSP entry;
4174 
4175     ScriptedSyntheticChildren* impl = new ScriptedSyntheticChildren(SyntheticChildren::Flags().
4176                                                                     SetCascades(m_options.m_cascade).
4177                                                                     SetSkipPointers(m_options.m_skip_pointers).
4178                                                                     SetSkipReferences(m_options.m_skip_references),
4179                                                                     m_options.m_class_name.c_str());
4180 
4181     entry.reset(impl);
4182 
4183     ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
4184 
4185     if (interpreter && interpreter->CheckObjectExists(impl->GetPythonClassName()) == false)
4186         result.AppendWarning("The provided class does not exist - please define it before attempting to use this synthetic provider");
4187 
4188     // now I have a valid provider, let's add it to every type
4189 
4190     lldb::TypeCategoryImplSP category;
4191     DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
4192 
4193     Error error;
4194 
4195     for (size_t i = 0; i < argc; i++)
4196     {
4197         const char* typeA = command.GetArgumentAtIndex(i);
4198         ConstString typeCS(typeA);
4199         if (typeCS)
4200         {
4201             if (!AddSynth(typeCS,
4202                           entry,
4203                           m_options.m_regex ? eRegexSynth : eRegularSynth,
4204                           m_options.m_category,
4205                           &error))
4206             {
4207                 result.AppendError(error.AsCString());
4208                 result.SetStatus(eReturnStatusFailed);
4209                 return false;
4210             }
4211         }
4212         else
4213         {
4214             result.AppendError("empty typenames not allowed");
4215             result.SetStatus(eReturnStatusFailed);
4216             return false;
4217         }
4218     }
4219 
4220     result.SetStatus(eReturnStatusSuccessFinishNoResult);
4221     return result.Succeeded();
4222 }
4223 
4224 CommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) :
4225     CommandObjectParsed (interpreter,
4226                          "type synthetic add",
4227                          "Add a new synthetic provider for a type.",
4228                          NULL),
4229     IOHandlerDelegateMultiline ("DONE"),
4230     m_options (interpreter)
4231 {
4232     CommandArgumentEntry type_arg;
4233     CommandArgumentData type_style_arg;
4234 
4235     type_style_arg.arg_type = eArgTypeName;
4236     type_style_arg.arg_repetition = eArgRepeatPlus;
4237 
4238     type_arg.push_back (type_style_arg);
4239 
4240     m_arguments.push_back (type_arg);
4241 
4242 }
4243 
4244 bool
4245 CommandObjectTypeSynthAdd::AddSynth(ConstString type_name,
4246                                     SyntheticChildrenSP entry,
4247                                     SynthFormatType type,
4248                                     std::string category_name,
4249                                     Error* error)
4250 {
4251     lldb::TypeCategoryImplSP category;
4252     DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
4253 
4254     if (type == eRegularSynth)
4255     {
4256         if (FixArrayTypeNameWithRegex (type_name))
4257             type = eRegexSynth;
4258     }
4259 
4260     if (category->AnyMatches(type_name,
4261                              eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter,
4262                              false))
4263     {
4264         if (error)
4265             error->SetErrorStringWithFormat("cannot add synthetic for type %s when filter is defined in same category!", type_name.AsCString());
4266         return false;
4267     }
4268 
4269     if (type == eRegexSynth)
4270     {
4271         RegularExpressionSP typeRX(new RegularExpression());
4272         if (!typeRX->Compile(type_name.GetCString()))
4273         {
4274             if (error)
4275                 error->SetErrorString("regex format error (maybe this is not really a regex?)");
4276             return false;
4277         }
4278 
4279         category->GetRegexTypeSyntheticsContainer()->Delete(type_name);
4280         category->GetRegexTypeSyntheticsContainer()->Add(typeRX, entry);
4281 
4282         return true;
4283     }
4284     else
4285     {
4286         category->GetTypeSyntheticsContainer()->Add(type_name, entry);
4287         return true;
4288     }
4289 }
4290 
4291 OptionDefinition
4292 CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] =
4293 {
4294     { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
4295     { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
4296     { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
4297     { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,         "Add this to the given category instead of the default one."},
4298     { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass,    "Use this Python class to produce synthetic children."},
4299     { 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."},
4300     { LLDB_OPT_SET_ALL, false,  "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
4301     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
4302 };
4303 
4304 #endif // #ifndef LLDB_DISABLE_PYTHON
4305 
4306 class CommandObjectTypeFilterAdd : public CommandObjectParsed
4307 {
4308 
4309 private:
4310 
4311     class CommandOptions : public Options
4312     {
4313         typedef std::vector<std::string> option_vector;
4314     public:
4315 
4316         CommandOptions (CommandInterpreter &interpreter) :
4317         Options (interpreter)
4318         {
4319         }
4320 
4321         ~CommandOptions () override {}
4322 
4323         Error
4324         SetOptionValue (uint32_t option_idx, const char *option_arg) override
4325         {
4326             Error error;
4327             const int short_option = m_getopt_table[option_idx].val;
4328             bool success;
4329 
4330             switch (short_option)
4331             {
4332                 case 'C':
4333                     m_cascade = Args::StringToBoolean(option_arg, true, &success);
4334                     if (!success)
4335                         error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
4336                     break;
4337                 case 'c':
4338                     m_expr_paths.push_back(option_arg);
4339                     has_child_list = true;
4340                     break;
4341                 case 'p':
4342                     m_skip_pointers = true;
4343                     break;
4344                 case 'r':
4345                     m_skip_references = true;
4346                     break;
4347                 case 'w':
4348                     m_category = std::string(option_arg);
4349                     break;
4350                 case 'x':
4351                     m_regex = true;
4352                     break;
4353                 default:
4354                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
4355                     break;
4356             }
4357 
4358             return error;
4359         }
4360 
4361         void
4362         OptionParsingStarting () override
4363         {
4364             m_cascade = true;
4365             m_skip_pointers = false;
4366             m_skip_references = false;
4367             m_category = "default";
4368             m_expr_paths.clear();
4369             has_child_list = false;
4370             m_regex = false;
4371         }
4372 
4373         const OptionDefinition*
4374         GetDefinitions () override
4375         {
4376             return g_option_table;
4377         }
4378 
4379         // Options table: Required for subclasses of Options.
4380 
4381         static OptionDefinition g_option_table[];
4382 
4383         // Instance variables to hold the values for command options.
4384 
4385         bool m_cascade;
4386         bool m_skip_references;
4387         bool m_skip_pointers;
4388         bool m_input_python;
4389         option_vector m_expr_paths;
4390         std::string m_category;
4391 
4392         bool has_child_list;
4393 
4394         bool m_regex;
4395 
4396         typedef option_vector::iterator ExpressionPathsIterator;
4397     };
4398 
4399     CommandOptions m_options;
4400 
4401     Options *
4402     GetOptions () override
4403     {
4404         return &m_options;
4405     }
4406 
4407     enum FilterFormatType
4408     {
4409         eRegularFilter,
4410         eRegexFilter
4411     };
4412 
4413     bool
4414     AddFilter(ConstString type_name,
4415               SyntheticChildrenSP entry,
4416               FilterFormatType type,
4417               std::string category_name,
4418               Error* error)
4419     {
4420         lldb::TypeCategoryImplSP category;
4421         DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
4422 
4423         if (type == eRegularFilter)
4424         {
4425             if (FixArrayTypeNameWithRegex (type_name))
4426                 type = eRegexFilter;
4427         }
4428 
4429         if (category->AnyMatches(type_name,
4430                                  eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth,
4431                                  false))
4432         {
4433             if (error)
4434                 error->SetErrorStringWithFormat("cannot add filter for type %s when synthetic is defined in same category!", type_name.AsCString());
4435             return false;
4436         }
4437 
4438         if (type == eRegexFilter)
4439         {
4440             RegularExpressionSP typeRX(new RegularExpression());
4441             if (!typeRX->Compile(type_name.GetCString()))
4442             {
4443                 if (error)
4444                     error->SetErrorString("regex format error (maybe this is not really a regex?)");
4445                 return false;
4446             }
4447 
4448             category->GetRegexTypeFiltersContainer()->Delete(type_name);
4449             category->GetRegexTypeFiltersContainer()->Add(typeRX, entry);
4450 
4451             return true;
4452         }
4453         else
4454         {
4455             category->GetTypeFiltersContainer()->Add(type_name, entry);
4456             return true;
4457         }
4458     }
4459 
4460 
4461 public:
4462 
4463     CommandObjectTypeFilterAdd (CommandInterpreter &interpreter) :
4464         CommandObjectParsed (interpreter,
4465                              "type filter add",
4466                              "Add a new filter for a type.",
4467                              NULL),
4468         m_options (interpreter)
4469     {
4470         CommandArgumentEntry type_arg;
4471         CommandArgumentData type_style_arg;
4472 
4473         type_style_arg.arg_type = eArgTypeName;
4474         type_style_arg.arg_repetition = eArgRepeatPlus;
4475 
4476         type_arg.push_back (type_style_arg);
4477 
4478         m_arguments.push_back (type_arg);
4479 
4480         SetHelpLong(
4481 R"(
4482 The following examples of 'type filter add' refer to this code snippet for context:
4483 
4484     class Foo {
4485         int a;
4486         int b;
4487         int c;
4488         int d;
4489         int e;
4490         int f;
4491         int g;
4492         int h;
4493         int i;
4494     }
4495     Foo my_foo;
4496 
4497 Adding a simple filter:
4498 
4499 (lldb) type filter add --child a --child g Foo
4500 (lldb) frame variable my_foo
4501 
4502 )" "Produces output where only a and g are displayed.  Other children of my_foo \
4503 (b, c, d, e, f, h and i) are available by asking for them explicitly:" R"(
4504 
4505 (lldb) frame variable my_foo.b my_foo.c my_foo.i
4506 
4507 )" "The formatting option --raw on frame variable bypasses the filter, showing \
4508 all children of my_foo as if no filter was defined:" R"(
4509 
4510 (lldb) frame variable my_foo --raw)"
4511         );
4512     }
4513 
4514     ~CommandObjectTypeFilterAdd () override
4515     {
4516     }
4517 
4518 protected:
4519     bool
4520     DoExecute (Args& command, CommandReturnObject &result) override
4521     {
4522         const size_t argc = command.GetArgumentCount();
4523 
4524         if (argc < 1)
4525         {
4526             result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
4527             result.SetStatus(eReturnStatusFailed);
4528             return false;
4529         }
4530 
4531         if (m_options.m_expr_paths.size() == 0)
4532         {
4533             result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str());
4534             result.SetStatus(eReturnStatusFailed);
4535             return false;
4536         }
4537 
4538         SyntheticChildrenSP entry;
4539 
4540         TypeFilterImpl* impl = new TypeFilterImpl(SyntheticChildren::Flags().SetCascades(m_options.m_cascade).
4541                                                     SetSkipPointers(m_options.m_skip_pointers).
4542                                                     SetSkipReferences(m_options.m_skip_references));
4543 
4544         entry.reset(impl);
4545 
4546         // go through the expression paths
4547         CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end();
4548 
4549         for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
4550             impl->AddExpressionPath(*begin);
4551 
4552 
4553         // now I have a valid provider, let's add it to every type
4554 
4555         lldb::TypeCategoryImplSP category;
4556         DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
4557 
4558         Error error;
4559 
4560         WarnOnPotentialUnquotedUnsignedType(command, result);
4561 
4562         for (size_t i = 0; i < argc; i++)
4563         {
4564             const char* typeA = command.GetArgumentAtIndex(i);
4565             ConstString typeCS(typeA);
4566             if (typeCS)
4567             {
4568                 if (!AddFilter(typeCS,
4569                           entry,
4570                           m_options.m_regex ? eRegexFilter : eRegularFilter,
4571                           m_options.m_category,
4572                           &error))
4573                 {
4574                     result.AppendError(error.AsCString());
4575                     result.SetStatus(eReturnStatusFailed);
4576                     return false;
4577                 }
4578             }
4579             else
4580             {
4581                 result.AppendError("empty typenames not allowed");
4582                 result.SetStatus(eReturnStatusFailed);
4583                 return false;
4584             }
4585         }
4586 
4587         result.SetStatus(eReturnStatusSuccessFinishNoResult);
4588         return result.Succeeded();
4589     }
4590 
4591 };
4592 
4593 OptionDefinition
4594 CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] =
4595 {
4596     { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
4597     { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
4598     { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
4599     { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,         "Add this to the given category instead of the default one."},
4600     { LLDB_OPT_SET_ALL, false, "child", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpressionPath,    "Include this expression path in the synthetic view."},
4601     { LLDB_OPT_SET_ALL, false,  "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
4602     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
4603 };
4604 
4605 //----------------------------------------------------------------------
4606 // "type lookup"
4607 //----------------------------------------------------------------------
4608 class CommandObjectTypeLookup : public CommandObjectRaw
4609 {
4610 protected:
4611 
4612     class CommandOptions : public OptionGroup
4613     {
4614     public:
4615 
4616         CommandOptions () :
4617         OptionGroup(),
4618         m_show_help(false),
4619         m_language(eLanguageTypeUnknown)
4620         {}
4621 
4622         ~CommandOptions () override {}
4623 
4624         uint32_t
4625         GetNumDefinitions () override
4626         {
4627             return 3;
4628         }
4629 
4630         const OptionDefinition*
4631         GetDefinitions () override
4632         {
4633             return g_option_table;
4634         }
4635 
4636         Error
4637         SetOptionValue (CommandInterpreter &interpreter,
4638                         uint32_t option_idx,
4639                         const char *option_value) override
4640         {
4641             Error error;
4642 
4643             const int short_option = g_option_table[option_idx].short_option;
4644 
4645             switch (short_option)
4646             {
4647                 case 'h':
4648                     m_show_help = true;
4649                     break;
4650 
4651                 case 'l':
4652                     m_language = Language::GetLanguageTypeFromString(option_value);
4653                     break;
4654 
4655                 default:
4656                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
4657                     break;
4658             }
4659 
4660             return error;
4661         }
4662 
4663         void
4664         OptionParsingStarting (CommandInterpreter &interpreter) override
4665         {
4666             m_show_help = false;
4667             m_language = eLanguageTypeUnknown;
4668         }
4669 
4670         // Options table: Required for subclasses of Options.
4671 
4672         static OptionDefinition g_option_table[];
4673         bool m_show_help;
4674         lldb::LanguageType m_language;
4675     };
4676 
4677     OptionGroupOptions m_option_group;
4678     CommandOptions m_command_options;
4679 
4680 public:
4681 
4682     CommandObjectTypeLookup (CommandInterpreter &interpreter) :
4683     CommandObjectRaw (interpreter,
4684                       "type lookup",
4685                       "Lookup a type by name in the select target.",
4686                       "type lookup <typename>",
4687                       eCommandRequiresTarget),
4688     m_option_group(interpreter),
4689     m_command_options()
4690     {
4691         m_option_group.Append(&m_command_options);
4692         m_option_group.Finalize();
4693     }
4694 
4695     ~CommandObjectTypeLookup () override
4696     {
4697     }
4698 
4699     Options *
4700     GetOptions () override
4701     {
4702         return &m_option_group;
4703     }
4704 
4705     bool
4706     DoExecute (const char *raw_command_line, CommandReturnObject &result) override
4707     {
4708         if (!raw_command_line || !raw_command_line[0])
4709         {
4710             result.SetError("type lookup cannot be invoked without a type name as argument");
4711             return false;
4712         }
4713 
4714         m_option_group.NotifyOptionParsingStarting();
4715 
4716         const char * name_of_type = NULL;
4717 
4718         if (raw_command_line[0] == '-')
4719         {
4720             // We have some options and these options MUST end with --.
4721             const char *end_options = NULL;
4722             const char *s = raw_command_line;
4723             while (s && s[0])
4724             {
4725                 end_options = ::strstr (s, "--");
4726                 if (end_options)
4727                 {
4728                     end_options += 2; // Get past the "--"
4729                     if (::isspace (end_options[0]))
4730                     {
4731                         name_of_type = end_options;
4732                         while (::isspace (*name_of_type))
4733                             ++name_of_type;
4734                         break;
4735                     }
4736                 }
4737                 s = end_options;
4738             }
4739 
4740             if (end_options)
4741             {
4742                 Args args (llvm::StringRef(raw_command_line, end_options - raw_command_line));
4743                 if (!ParseOptions (args, result))
4744                     return false;
4745 
4746                 Error error (m_option_group.NotifyOptionParsingFinished());
4747                 if (error.Fail())
4748                 {
4749                     result.AppendError (error.AsCString());
4750                     result.SetStatus (eReturnStatusFailed);
4751                     return false;
4752                 }
4753             }
4754         }
4755         if (nullptr == name_of_type)
4756             name_of_type = raw_command_line;
4757 
4758         TargetSP target_sp(GetCommandInterpreter().GetDebugger().GetSelectedTarget());
4759         const bool fill_all_in = true;
4760         ExecutionContext exe_ctx(target_sp.get(), fill_all_in);
4761         ExecutionContextScope *best_scope = exe_ctx.GetBestExecutionContextScope();
4762 
4763         bool any_found = false;
4764 
4765         std::vector<Language*> languages;
4766 
4767         if (m_command_options.m_language == eLanguageTypeUnknown)
4768         {
4769             // FIXME: hardcoding languages is not good
4770             languages.push_back(Language::FindPlugin(eLanguageTypeObjC));
4771             languages.push_back(Language::FindPlugin(eLanguageTypeC_plus_plus));
4772         }
4773         else
4774         {
4775             languages.push_back(Language::FindPlugin(m_command_options.m_language));
4776         }
4777 
4778         for (Language* language : languages)
4779         {
4780             if (!language)
4781                 continue;
4782 
4783             if (auto scavenger = language->GetTypeScavenger())
4784             {
4785                 Language::TypeScavenger::ResultSet search_results;
4786                 if (scavenger->Find(best_scope, name_of_type, search_results) > 0)
4787                 {
4788                     for (const auto& search_result : search_results)
4789                     {
4790                         if (search_result && search_result->IsValid())
4791                         {
4792                             any_found = true;
4793                             search_result->DumpToStream(result.GetOutputStream(), this->m_command_options.m_show_help);
4794                         }
4795                     }
4796                 }
4797             }
4798         }
4799 
4800         result.SetStatus (any_found ? lldb::eReturnStatusSuccessFinishResult : lldb::eReturnStatusSuccessFinishNoResult);
4801         return true;
4802     }
4803 
4804 };
4805 
4806 OptionDefinition
4807 CommandObjectTypeLookup::CommandOptions::g_option_table[] =
4808 {
4809     { LLDB_OPT_SET_ALL, false, "show-help",        'h', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,    "Display available help for types"},
4810     { LLDB_OPT_SET_ALL, false, "language",         'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,    "Which language's types should the search scope be"},
4811     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
4812 };
4813 
4814 template <typename FormatterType>
4815 class CommandObjectFormatterInfo : public CommandObjectRaw
4816 {
4817 public:
4818     typedef std::function<typename FormatterType::SharedPointer(ValueObject&)> DiscoveryFunction;
4819     CommandObjectFormatterInfo (CommandInterpreter &interpreter,
4820                                 const char* formatter_name,
4821                                 DiscoveryFunction discovery_func) :
4822     CommandObjectRaw(interpreter,
4823                      nullptr,
4824                      nullptr,
4825                      nullptr,
4826                      eCommandRequiresFrame),
4827     m_formatter_name(formatter_name ? formatter_name : ""),
4828     m_discovery_function(discovery_func)
4829     {
4830         StreamString name;
4831         name.Printf("type %s info", formatter_name);
4832         SetCommandName(name.GetData());
4833         StreamString help;
4834         help.Printf("This command evaluates the provided expression and shows which %s is applied to the resulting value (if any).", formatter_name);
4835         SetHelp(help.GetData());
4836         StreamString syntax;
4837         syntax.Printf("type %s info <expr>", formatter_name);
4838         SetSyntax(syntax.GetData());
4839     }
4840 
4841     ~CommandObjectFormatterInfo () override
4842     {
4843     }
4844 
4845 protected:
4846     bool
4847     DoExecute (const char *command, CommandReturnObject &result) override
4848     {
4849         auto target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
4850         auto frame_sp = target_sp->GetProcessSP()->GetThreadList().GetSelectedThread()->GetSelectedFrame();
4851         ValueObjectSP result_valobj_sp;
4852         EvaluateExpressionOptions options;
4853         lldb::ExpressionResults expr_result = target_sp->EvaluateExpression(command, frame_sp.get(), result_valobj_sp, options);
4854         if (expr_result == eExpressionCompleted && result_valobj_sp)
4855         {
4856             result_valobj_sp = result_valobj_sp->GetQualifiedRepresentationIfAvailable(target_sp->GetPreferDynamicValue(), target_sp->GetEnableSyntheticValue());
4857             typename FormatterType::SharedPointer formatter_sp = m_discovery_function(*result_valobj_sp);
4858             if (formatter_sp)
4859             {
4860                 std::string description(formatter_sp->GetDescription());
4861                 result.AppendMessageWithFormat("%s applied to (%s) %s is: %s\n",
4862                                                m_formatter_name.c_str(),
4863                                                result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"),
4864                                                command,
4865                                                description.c_str());
4866                 result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
4867             }
4868             else
4869             {
4870                 result.AppendMessageWithFormat("no %s applies to (%s) %s\n",
4871                                                m_formatter_name.c_str(),
4872                                                result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"),
4873                                                command);
4874                 result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
4875             }
4876             return true;
4877         }
4878         else
4879         {
4880             result.AppendError("failed to evaluate expression");
4881             result.SetStatus(lldb::eReturnStatusFailed);
4882             return false;
4883         }
4884     }
4885 
4886 private:
4887     std::string m_formatter_name;
4888     DiscoveryFunction m_discovery_function;
4889 };
4890 
4891 class CommandObjectTypeFormat : public CommandObjectMultiword
4892 {
4893 public:
4894     CommandObjectTypeFormat (CommandInterpreter &interpreter) :
4895         CommandObjectMultiword (interpreter,
4896                                 "type format",
4897                                 "A set of commands for editing variable value display options",
4898                                 "type format [<sub-command-options>] ")
4899     {
4900         LoadSubCommand ("add",    CommandObjectSP (new CommandObjectTypeFormatAdd (interpreter)));
4901         LoadSubCommand ("clear",  CommandObjectSP (new CommandObjectTypeFormatClear (interpreter)));
4902         LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFormatDelete (interpreter)));
4903         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectTypeFormatList (interpreter)));
4904         LoadSubCommand ("info",   CommandObjectSP (new CommandObjectFormatterInfo<TypeFormatImpl>(interpreter,
4905                                                                                                   "format",
4906                                                                                                   [](ValueObject& valobj) -> TypeFormatImpl::SharedPointer {
4907                                                                                                       return valobj.GetValueFormat();
4908                                                                                                   })));
4909     }
4910 
4911 
4912     ~CommandObjectTypeFormat () override
4913     {
4914     }
4915 };
4916 
4917 #ifndef LLDB_DISABLE_PYTHON
4918 
4919 class CommandObjectTypeSynth : public CommandObjectMultiword
4920 {
4921 public:
4922     CommandObjectTypeSynth (CommandInterpreter &interpreter) :
4923     CommandObjectMultiword (interpreter,
4924                             "type synthetic",
4925                             "A set of commands for operating on synthetic type representations",
4926                             "type synthetic [<sub-command-options>] ")
4927     {
4928         LoadSubCommand ("add",           CommandObjectSP (new CommandObjectTypeSynthAdd (interpreter)));
4929         LoadSubCommand ("clear",         CommandObjectSP (new CommandObjectTypeSynthClear (interpreter)));
4930         LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeSynthDelete (interpreter)));
4931         LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeSynthList (interpreter)));
4932         LoadSubCommand ("info",          CommandObjectSP (new CommandObjectFormatterInfo<SyntheticChildren>(interpreter,
4933                                                                                                             "synthetic",
4934                                                                                                             [](ValueObject& valobj) -> SyntheticChildren::SharedPointer {
4935                                                                                                                 return valobj.GetSyntheticChildren();
4936                                                                                                             })));
4937     }
4938 
4939 
4940     ~CommandObjectTypeSynth () override
4941     {
4942     }
4943 };
4944 
4945 #endif // #ifndef LLDB_DISABLE_PYTHON
4946 
4947 class CommandObjectTypeFilter : public CommandObjectMultiword
4948 {
4949 public:
4950     CommandObjectTypeFilter (CommandInterpreter &interpreter) :
4951     CommandObjectMultiword (interpreter,
4952                             "type filter",
4953                             "A set of commands for operating on type filters",
4954                             "type synthetic [<sub-command-options>] ")
4955     {
4956         LoadSubCommand ("add",           CommandObjectSP (new CommandObjectTypeFilterAdd (interpreter)));
4957         LoadSubCommand ("clear",         CommandObjectSP (new CommandObjectTypeFilterClear (interpreter)));
4958         LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeFilterDelete (interpreter)));
4959         LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeFilterList (interpreter)));
4960     }
4961 
4962 
4963     ~CommandObjectTypeFilter () override
4964     {
4965     }
4966 };
4967 
4968 class CommandObjectTypeCategory : public CommandObjectMultiword
4969 {
4970 public:
4971     CommandObjectTypeCategory (CommandInterpreter &interpreter) :
4972     CommandObjectMultiword (interpreter,
4973                             "type category",
4974                             "A set of commands for operating on categories",
4975                             "type category [<sub-command-options>] ")
4976     {
4977         LoadSubCommand ("define",        CommandObjectSP (new CommandObjectTypeCategoryDefine (interpreter)));
4978         LoadSubCommand ("enable",        CommandObjectSP (new CommandObjectTypeCategoryEnable (interpreter)));
4979         LoadSubCommand ("disable",       CommandObjectSP (new CommandObjectTypeCategoryDisable (interpreter)));
4980         LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeCategoryDelete (interpreter)));
4981         LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeCategoryList (interpreter)));
4982     }
4983 
4984 
4985     ~CommandObjectTypeCategory () override
4986     {
4987     }
4988 };
4989 
4990 class CommandObjectTypeSummary : public CommandObjectMultiword
4991 {
4992 public:
4993     CommandObjectTypeSummary (CommandInterpreter &interpreter) :
4994     CommandObjectMultiword (interpreter,
4995                             "type summary",
4996                             "A set of commands for editing variable summary display options",
4997                             "type summary [<sub-command-options>] ")
4998     {
4999         LoadSubCommand ("add",           CommandObjectSP (new CommandObjectTypeSummaryAdd (interpreter)));
5000         LoadSubCommand ("clear",         CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter)));
5001         LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeSummaryDelete (interpreter)));
5002         LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeSummaryList (interpreter)));
5003         LoadSubCommand ("info",          CommandObjectSP (new CommandObjectFormatterInfo<TypeSummaryImpl>(interpreter,
5004                                                                                                           "summary",
5005                                                                                                             [](ValueObject& valobj) -> TypeSummaryImpl::SharedPointer {
5006                                                                                                                 return valobj.GetSummaryFormat();
5007                                                                                                             })));
5008     }
5009 
5010 
5011     ~CommandObjectTypeSummary () override
5012     {
5013     }
5014 };
5015 
5016 //-------------------------------------------------------------------------
5017 // CommandObjectType
5018 //-------------------------------------------------------------------------
5019 
5020 CommandObjectType::CommandObjectType (CommandInterpreter &interpreter) :
5021     CommandObjectMultiword (interpreter,
5022                             "type",
5023                             "A set of commands for operating on the type system",
5024                             "type [<sub-command-options>]")
5025 {
5026     LoadSubCommand ("category",  CommandObjectSP (new CommandObjectTypeCategory (interpreter)));
5027     LoadSubCommand ("filter",    CommandObjectSP (new CommandObjectTypeFilter (interpreter)));
5028     LoadSubCommand ("format",    CommandObjectSP (new CommandObjectTypeFormat (interpreter)));
5029     LoadSubCommand ("summary",   CommandObjectSP (new CommandObjectTypeSummary (interpreter)));
5030 #ifndef LLDB_DISABLE_PYTHON
5031     LoadSubCommand ("synthetic", CommandObjectSP (new CommandObjectTypeSynth (interpreter)));
5032 #endif
5033     LoadSubCommand ("lookup",   CommandObjectSP (new CommandObjectTypeLookup (interpreter)));
5034 }
5035 
5036 
5037 CommandObjectType::~CommandObjectType ()
5038 {
5039 }
5040 
5041 
5042