]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - source/Commands/CommandObjectType.cpp
Vendor import of lldb trunk r256945:
[FreeBSD/FreeBSD.git] / source / Commands / CommandObjectType.cpp
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/Interpreter/OptionValueString.h"
36 #include "lldb/Target/Language.h"
37 #include "lldb/Target/Process.h"
38 #include "lldb/Target/StackFrame.h"
39 #include "lldb/Target/Target.h"
40 #include "lldb/Target/Thread.h"
41 #include "lldb/Target/ThreadList.h"
42
43 using namespace lldb;
44 using namespace lldb_private;
45
46
47 class ScriptAddOptions
48 {
49     
50 public:
51     
52     TypeSummaryImpl::Flags m_flags;
53     
54     StringList m_target_types;
55     
56     bool m_regex;
57         
58     ConstString m_name;
59     
60     std::string m_category;
61     
62     ScriptAddOptions(const TypeSummaryImpl::Flags& flags,
63                      bool regx,
64                      const ConstString& name,
65                      std::string catg) :
66         m_flags(flags),
67         m_regex(regx),
68         m_name(name),
69         m_category(catg)
70     {
71     }
72     
73     typedef std::shared_ptr<ScriptAddOptions> SharedPointer;
74     
75 };
76
77 class SynthAddOptions
78 {
79     
80 public:
81     
82     bool m_skip_pointers;
83     bool m_skip_references;
84     bool m_cascade;
85     bool m_regex;
86     StringList m_target_types;
87     
88     std::string m_category;
89     
90     SynthAddOptions(bool sptr,
91                     bool sref,
92                     bool casc,
93                     bool regx,
94                     std::string catg) :
95     m_skip_pointers(sptr),
96     m_skip_references(sref),
97     m_cascade(casc),
98     m_regex(regx),
99     m_target_types(),
100     m_category(catg)
101     {
102     }
103     
104     typedef std::shared_ptr<SynthAddOptions> SharedPointer;
105     
106 };
107
108 static bool
109 WarnOnPotentialUnquotedUnsignedType (Args& command, CommandReturnObject &result)
110 {
111     for (unsigned idx = 0; idx < command.GetArgumentCount(); idx++)
112     {
113         const char* arg = command.GetArgumentAtIndex(idx);
114         if (idx+1 < command.GetArgumentCount())
115         {
116             if (arg && 0 == strcmp(arg,"unsigned"))
117             {
118                 const char* next = command.GetArgumentAtIndex(idx+1);
119                 if (next &&
120                     (0 == strcmp(next, "int") ||
121                      0 == strcmp(next, "short") ||
122                      0 == strcmp(next, "char") ||
123                      0 == strcmp(next, "long")))
124                 {
125                     result.AppendWarningWithFormat("%s %s being treated as two types. if you meant the combined type name use quotes, as in \"%s %s\"\n",
126                                                    arg,next,arg,next);
127                     return true;
128                 }
129             }
130         }
131     }
132     return false;
133 }
134
135 class CommandObjectTypeSummaryAdd :
136     public CommandObjectParsed,
137     public IOHandlerDelegateMultiline
138 {
139     
140 private:
141     
142     class CommandOptions : public Options
143     {
144     public:
145         
146         CommandOptions (CommandInterpreter &interpreter) :
147         Options (interpreter)
148         {
149         }
150         
151         ~CommandOptions () override {}
152         
153         Error
154         SetOptionValue (uint32_t option_idx, const char *option_arg) override;
155         
156         void
157         OptionParsingStarting () override;
158         
159         const OptionDefinition*
160         GetDefinitions () override
161         {
162             return g_option_table;
163         }
164         
165         // Options table: Required for subclasses of Options.
166         
167         static OptionDefinition g_option_table[];
168         
169         // Instance variables to hold the values for command options.
170         
171         TypeSummaryImpl::Flags m_flags;
172         bool m_regex;
173         std::string m_format_string;
174         ConstString m_name;
175         std::string m_python_script;
176         std::string m_python_function;
177         bool m_is_add_script;
178         std::string m_category;
179     };
180     
181     CommandOptions m_options;
182     
183     Options *
184     GetOptions () override
185     {
186         return &m_options;
187     }
188     
189     bool
190     Execute_ScriptSummary (Args& command, CommandReturnObject &result);
191     
192     bool
193     Execute_StringSummary (Args& command, CommandReturnObject &result);
194     
195 public:
196     
197     enum SummaryFormatType
198     {
199         eRegularSummary,
200         eRegexSummary,
201         eNamedSummary
202     };
203     
204     CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter);
205     
206     ~CommandObjectTypeSummaryAdd () override
207     {
208     }
209     
210     void
211     IOHandlerActivated (IOHandler &io_handler) override
212     {
213         static const char *g_summary_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
214         "def function (valobj,internal_dict):\n"
215         "     \"\"\"valobj: an SBValue which you want to provide a summary for\n"
216         "        internal_dict: an LLDB support object not to be used\"\"\"\n";
217
218         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
219         if (output_sp)
220         {
221             output_sp->PutCString(g_summary_addreader_instructions);
222             output_sp->Flush();
223         }
224     }
225     
226     
227     void
228     IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
229     {
230         StreamFileSP error_sp = io_handler.GetErrorStreamFile();
231         
232 #ifndef LLDB_DISABLE_PYTHON
233         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
234         if (interpreter)
235         {
236             StringList lines;
237             lines.SplitIntoLines(data);
238             if (lines.GetSize() > 0)
239             {
240                 ScriptAddOptions *options_ptr = ((ScriptAddOptions*)io_handler.GetUserData());
241                 if (options_ptr)
242                 {
243                     ScriptAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
244                     
245                     ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
246                     if (interpreter)
247                     {
248                         std::string funct_name_str;
249                         if (interpreter->GenerateTypeScriptFunction (lines, funct_name_str))
250                         {
251                             if (funct_name_str.empty())
252                             {
253                                 error_sp->Printf ("unable to obtain a valid function name from the script interpreter.\n");
254                                 error_sp->Flush();
255                             }
256                             else
257                             {
258                                 // now I have a valid function name, let's add this as script for every type in the list
259                                 
260                                 TypeSummaryImplSP script_format;
261                                 script_format.reset(new ScriptSummaryFormat(options->m_flags,
262                                                                             funct_name_str.c_str(),
263                                                                             lines.CopyList("    ").c_str()));
264                                 
265                                 Error error;
266                                 
267                                 for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
268                                 {
269                                     const char *type_name = options->m_target_types.GetStringAtIndex(i);
270                                     CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
271                                                                             script_format,
272                                                                             (options->m_regex ? CommandObjectTypeSummaryAdd::eRegexSummary : CommandObjectTypeSummaryAdd::eRegularSummary),
273                                                                             options->m_category,
274                                                                             &error);
275                                     if (error.Fail())
276                                     {
277                                         error_sp->Printf ("error: %s", error.AsCString());
278                                         error_sp->Flush();
279                                     }
280                                 }
281                                 
282                                 if (options->m_name)
283                                 {
284                                     CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
285                                                                              script_format,
286                                                                              CommandObjectTypeSummaryAdd::eNamedSummary,
287                                                                              options->m_category,
288                                                                              &error);
289                                     if (error.Fail())
290                                     {
291                                         CommandObjectTypeSummaryAdd::AddSummary (options->m_name,
292                                                                                  script_format,
293                                                                                  CommandObjectTypeSummaryAdd::eNamedSummary,
294                                                                                  options->m_category,
295                                                                                  &error);
296                                         if (error.Fail())
297                                         {
298                                             error_sp->Printf ("error: %s", error.AsCString());
299                                             error_sp->Flush();
300                                         }
301                                     }
302                                     else
303                                     {
304                                         error_sp->Printf ("error: %s", error.AsCString());
305                                         error_sp->Flush();
306                                     }
307                                 }
308                                 else
309                                 {
310                                     if (error.AsCString())
311                                     {
312                                         error_sp->Printf ("error: %s", error.AsCString());
313                                         error_sp->Flush();
314                                     }
315                                 }
316                             }
317                         }
318                         else
319                         {
320                             error_sp->Printf ("error: unable to generate a function.\n");
321                             error_sp->Flush();
322                         }
323                     }
324                     else
325                     {
326                         error_sp->Printf ("error: no script interpreter.\n");
327                         error_sp->Flush();
328                     }
329                 }
330                 else
331                 {
332                     error_sp->Printf ("error: internal synchronization information missing or invalid.\n");
333                     error_sp->Flush();
334                 }
335             }
336             else
337             {
338                 error_sp->Printf ("error: empty function, didn't add python command.\n");
339                 error_sp->Flush();
340             }
341         }
342         else
343         {
344             error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
345             error_sp->Flush();
346         }
347 #endif // #ifndef LLDB_DISABLE_PYTHON
348         io_handler.SetIsDone(true);
349     }
350     
351     static bool
352     AddSummary(ConstString type_name,
353                lldb::TypeSummaryImplSP entry,
354                SummaryFormatType type,
355                std::string category,
356                Error* error = NULL);
357 protected:
358     bool
359     DoExecute (Args& command, CommandReturnObject &result) override;
360     
361 };
362
363 static const char *g_synth_addreader_instructions =   "Enter your Python command(s). Type 'DONE' to end.\n"
364 "You must define a Python class with these methods:\n"
365 "    def __init__(self, valobj, dict):\n"
366 "    def num_children(self):\n"
367 "    def get_child_at_index(self, index):\n"
368 "    def get_child_index(self, name):\n"
369 "    def update(self):\n"
370 "        '''Optional'''\n"
371 "class synthProvider:\n";
372
373 class CommandObjectTypeSynthAdd :
374     public CommandObjectParsed,
375     public IOHandlerDelegateMultiline
376 {
377     
378 private:
379     
380     class CommandOptions : public Options
381     {
382     public:
383         
384         CommandOptions (CommandInterpreter &interpreter) :
385             Options (interpreter)
386         {
387         }
388         
389         ~CommandOptions () override {}
390         
391         Error
392         SetOptionValue (uint32_t option_idx, const char *option_arg) override
393         {
394             Error error;
395             const int short_option = m_getopt_table[option_idx].val;
396             bool success;
397             
398             switch (short_option)
399             {
400                 case 'C':
401                     m_cascade = Args::StringToBoolean(option_arg, true, &success);
402                     if (!success)
403                         error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
404                     break;
405                 case 'P':
406                     handwrite_python = true;
407                     break;
408                 case 'l':
409                     m_class_name = std::string(option_arg);
410                     is_class_based = true;
411                     break;
412                 case 'p':
413                     m_skip_pointers = true;
414                     break;
415                 case 'r':
416                     m_skip_references = true;
417                     break;
418                 case 'w':
419                     m_category = std::string(option_arg);
420                     break;
421                 case 'x':
422                     m_regex = true;
423                     break;
424                 default:
425                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
426                     break;
427             }
428             
429             return error;
430         }
431         
432         void
433         OptionParsingStarting () override
434         {
435             m_cascade = true;
436             m_class_name = "";
437             m_skip_pointers = false;
438             m_skip_references = false;
439             m_category = "default";
440             is_class_based = false;
441             handwrite_python = false;
442             m_regex = false;
443         }
444         
445         const OptionDefinition*
446         GetDefinitions () override
447         {
448             return g_option_table;
449         }
450         
451         // Options table: Required for subclasses of Options.
452         
453         static OptionDefinition g_option_table[];
454         
455         // Instance variables to hold the values for command options.
456         
457         bool m_cascade;
458         bool m_skip_references;
459         bool m_skip_pointers;
460         std::string m_class_name;
461         bool m_input_python;
462         std::string m_category;
463         
464         bool is_class_based;
465         
466         bool handwrite_python;
467         
468         bool m_regex;
469         
470     };
471     
472     CommandOptions m_options;
473     
474     Options *
475     GetOptions () override
476     {
477         return &m_options;
478     }
479     
480     bool
481     Execute_HandwritePython (Args& command, CommandReturnObject &result);
482     
483     bool
484     Execute_PythonClass (Args& command, CommandReturnObject &result);
485     
486 protected:
487     bool
488     DoExecute (Args& command, CommandReturnObject &result) override
489     {
490         WarnOnPotentialUnquotedUnsignedType(command, result);
491         
492         if (m_options.handwrite_python)
493             return Execute_HandwritePython(command, result);
494         else if (m_options.is_class_based)
495             return Execute_PythonClass(command, result);
496         else
497         {
498             result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line");
499             result.SetStatus(eReturnStatusFailed);
500             return false;
501         }
502     }
503     
504     void
505     IOHandlerActivated (IOHandler &io_handler) override
506     {
507         StreamFileSP output_sp(io_handler.GetOutputStreamFile());
508         if (output_sp)
509         {
510             output_sp->PutCString(g_synth_addreader_instructions);
511             output_sp->Flush();
512         }
513     }
514     
515     
516     void
517     IOHandlerInputComplete (IOHandler &io_handler, std::string &data) override
518     {
519         StreamFileSP error_sp = io_handler.GetErrorStreamFile();
520         
521 #ifndef LLDB_DISABLE_PYTHON
522         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
523         if (interpreter)
524         {
525             StringList lines;
526             lines.SplitIntoLines(data);
527             if (lines.GetSize() > 0)
528             {
529                 SynthAddOptions *options_ptr = ((SynthAddOptions*)io_handler.GetUserData());
530                 if (options_ptr)
531                 {
532                     SynthAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
533                     
534                     ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
535                     if (interpreter)
536                     {
537                         std::string class_name_str;
538                         if (interpreter->GenerateTypeSynthClass (lines, class_name_str))
539                         {
540                             if (class_name_str.empty())
541                             {
542                                 error_sp->Printf ("error: unable to obtain a proper name for the class.\n");
543                                 error_sp->Flush();
544                             }
545                             else
546                             {
547                                 // everything should be fine now, let's add the synth provider class
548                                 
549                                 SyntheticChildrenSP synth_provider;
550                                 synth_provider.reset(new ScriptedSyntheticChildren(SyntheticChildren::Flags().SetCascades(options->m_cascade).
551                                                                                    SetSkipPointers(options->m_skip_pointers).
552                                                                                    SetSkipReferences(options->m_skip_references),
553                                                                                    class_name_str.c_str()));
554                                 
555                                 
556                                 lldb::TypeCategoryImplSP category;
557                                 DataVisualization::Categories::GetCategory(ConstString(options->m_category.c_str()), category);
558                                 
559                                 Error error;
560                                 
561                                 for (size_t i = 0; i < options->m_target_types.GetSize(); i++)
562                                 {
563                                     const char *type_name = options->m_target_types.GetStringAtIndex(i);
564                                     ConstString const_type_name(type_name);
565                                     if (const_type_name)
566                                     {
567                                         if (!CommandObjectTypeSynthAdd::AddSynth(const_type_name,
568                                                                                  synth_provider,
569                                                                                  options->m_regex ? CommandObjectTypeSynthAdd::eRegexSynth : CommandObjectTypeSynthAdd::eRegularSynth,
570                                                                                  options->m_category,
571                                                                                  &error))
572                                         {
573                                             error_sp->Printf("error: %s\n", error.AsCString());
574                                             error_sp->Flush();
575                                             break;
576                                         }
577                                     }
578                                     else
579                                     {
580                                         error_sp->Printf ("error: invalid type name.\n");
581                                         error_sp->Flush();
582                                         break;
583                                     }
584                                 }
585                             }
586                         }
587                         else
588                         {
589                             error_sp->Printf ("error: unable to generate a class.\n");
590                             error_sp->Flush();
591                         }
592                     }
593                     else
594                     {
595                         error_sp->Printf ("error: no script interpreter.\n");
596                         error_sp->Flush();
597                     }
598                 }
599                 else
600                 {
601                     error_sp->Printf ("error: internal synchronization data missing.\n");
602                     error_sp->Flush();
603                 }
604             }
605             else
606             {
607                 error_sp->Printf ("error: empty function, didn't add python command.\n");
608                 error_sp->Flush();
609             }
610         }
611         else
612         {
613             error_sp->Printf ("error: script interpreter missing, didn't add python command.\n");
614             error_sp->Flush();
615         }
616         
617 #endif // #ifndef LLDB_DISABLE_PYTHON
618         io_handler.SetIsDone(true);
619     }
620
621 public:
622     
623     enum SynthFormatType
624     {
625         eRegularSynth,
626         eRegexSynth
627     };
628     
629     CommandObjectTypeSynthAdd (CommandInterpreter &interpreter);
630     
631     ~CommandObjectTypeSynthAdd () override
632     {
633     }
634     
635     static bool
636     AddSynth(ConstString type_name,
637              lldb::SyntheticChildrenSP entry,
638              SynthFormatType type,
639              std::string category_name,
640              Error* error);
641 };
642
643 //-------------------------------------------------------------------------
644 // CommandObjectTypeFormatAdd
645 //-------------------------------------------------------------------------
646
647 class CommandObjectTypeFormatAdd : public CommandObjectParsed
648 {
649     
650 private:
651     
652     class CommandOptions : public OptionGroup
653     {
654     public:
655         
656         CommandOptions () :
657             OptionGroup()
658         {
659         }
660         
661         ~CommandOptions () override
662         {
663         }
664         
665         uint32_t
666         GetNumDefinitions () override;
667         
668         const OptionDefinition*
669         GetDefinitions () override
670         {
671             return g_option_table;
672         }
673         
674         void
675         OptionParsingStarting (CommandInterpreter &interpreter) override
676         {
677             m_cascade = true;
678             m_skip_pointers = false;
679             m_skip_references = false;
680             m_regex = false;
681             m_category.assign("default");
682             m_custom_type_name.clear();
683         }
684         Error
685         SetOptionValue (CommandInterpreter &interpreter,
686                         uint32_t option_idx,
687                         const char *option_value) override
688         {
689             Error error;
690             const int short_option = g_option_table[option_idx].short_option;
691             bool success;
692             
693             switch (short_option)
694             {
695                 case 'C':
696                     m_cascade = Args::StringToBoolean(option_value, true, &success);
697                     if (!success)
698                         error.SetErrorStringWithFormat("invalid value for cascade: %s", option_value);
699                     break;
700                 case 'p':
701                     m_skip_pointers = true;
702                     break;
703                 case 'w':
704                     m_category.assign(option_value);
705                     break;
706                 case 'r':
707                     m_skip_references = true;
708                     break;
709                 case 'x':
710                     m_regex = true;
711                     break;
712                 case 't':
713                     m_custom_type_name.assign(option_value);
714                     break;
715                 default:
716                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
717                     break;
718             }
719             
720             return error;
721         }
722         
723         // Options table: Required for subclasses of Options.
724         
725         static OptionDefinition g_option_table[];
726         
727         // Instance variables to hold the values for command options.
728         
729         bool m_cascade;
730         bool m_skip_references;
731         bool m_skip_pointers;
732         bool m_regex;
733         std::string m_category;
734         std::string m_custom_type_name;
735     };
736     
737     OptionGroupOptions m_option_group;
738     OptionGroupFormat m_format_options;
739     CommandOptions m_command_options;
740     
741     Options *
742     GetOptions () override
743     {
744         return &m_option_group;
745     }
746     
747 public:
748     CommandObjectTypeFormatAdd (CommandInterpreter &interpreter) :
749         CommandObjectParsed (interpreter,
750                              "type format add",
751                              "Add a new formatting style for a type.",
752                              NULL), 
753         m_option_group (interpreter),
754         m_format_options (eFormatInvalid),
755         m_command_options ()
756     {
757         CommandArgumentEntry type_arg;
758         CommandArgumentData type_style_arg;
759         
760         type_style_arg.arg_type = eArgTypeName;
761         type_style_arg.arg_repetition = eArgRepeatPlus;
762         
763         type_arg.push_back (type_style_arg);
764
765         m_arguments.push_back (type_arg);
766         
767         SetHelpLong(
768 R"(
769 The following examples of 'type format add' refer to this code snippet for context:
770
771     typedef int Aint;
772     typedef float Afloat;
773     typedef Aint Bint;
774     typedef Afloat Bfloat;
775
776     Aint ix = 5;
777     Bint iy = 5;
778
779     Afloat fx = 3.14;
780     BFloat fy = 3.14;
781
782 Adding default formatting:
783
784 (lldb) type format add -f hex AInt
785 (lldb) frame variable iy
786
787 )" "    Produces hexidecimal display of iy, because no formatter is available for Bint and \
788 the one for Aint is used instead." R"(
789
790 To prevent this use the cascade option '-C no' to prevent evaluation of typedef chains:
791
792
793 (lldb) type format add -f hex -C no AInt
794
795 Similar reasoning applies to this:
796
797 (lldb) type format add -f hex -C no float -p
798
799 )" "    All float values and float references are now formatted as hexadecimal, but not \
800 pointers to floats.  Nor will it change the default display for Afloat and Bfloat objects."
801                     );
802     
803         // Add the "--format" to all options groups
804         m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1);
805         m_option_group.Append (&m_command_options);
806         m_option_group.Finalize();
807
808     }
809     
810     ~CommandObjectTypeFormatAdd () override
811     {
812     }
813     
814 protected:
815     bool
816     DoExecute (Args& command, CommandReturnObject &result) override
817     {
818         const size_t argc = command.GetArgumentCount();
819         
820         if (argc < 1)
821         {
822             result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
823             result.SetStatus(eReturnStatusFailed);
824             return false;
825         }
826         
827         const Format format = m_format_options.GetFormat();
828         if (format == eFormatInvalid && m_command_options.m_custom_type_name.empty())
829         {
830             result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str());
831             result.SetStatus(eReturnStatusFailed);
832             return false;
833         }
834         
835         TypeFormatImplSP entry;
836         
837         if (m_command_options.m_custom_type_name.empty())
838             entry.reset(new TypeFormatImpl_Format(format,
839                                                   TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
840                                                   SetSkipPointers(m_command_options.m_skip_pointers).
841                                                   SetSkipReferences(m_command_options.m_skip_references)));
842         else
843             entry.reset(new TypeFormatImpl_EnumType(ConstString(m_command_options.m_custom_type_name.c_str()),
844                                                     TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
845                                                     SetSkipPointers(m_command_options.m_skip_pointers).
846                                                     SetSkipReferences(m_command_options.m_skip_references)));
847
848         // now I have a valid format, let's add it to every type
849         
850         TypeCategoryImplSP category_sp;
851         DataVisualization::Categories::GetCategory(ConstString(m_command_options.m_category), category_sp);
852         if (!category_sp)
853             return false;
854         
855         WarnOnPotentialUnquotedUnsignedType(command, result);
856         
857         for (size_t i = 0; i < argc; i++)
858         {
859             const char* typeA = command.GetArgumentAtIndex(i);
860             ConstString typeCS(typeA);
861             if (typeCS)
862             {
863                 if (m_command_options.m_regex)
864                 {
865                     RegularExpressionSP typeRX(new RegularExpression());
866                     if (!typeRX->Compile(typeCS.GetCString()))
867                     {
868                         result.AppendError("regex format error (maybe this is not really a regex?)");
869                         result.SetStatus(eReturnStatusFailed);
870                         return false;
871                     }
872                     category_sp->GetRegexTypeSummariesContainer()->Delete(typeCS);
873                     category_sp->GetRegexTypeFormatsContainer()->Add(typeRX, entry);
874                 }
875                 else
876                     category_sp->GetTypeFormatsContainer()->Add(typeCS, entry);
877             }
878             else
879             {
880                 result.AppendError("empty typenames not allowed");
881                 result.SetStatus(eReturnStatusFailed);
882                 return false;
883             }
884         }
885         
886         result.SetStatus(eReturnStatusSuccessFinishNoResult);
887         return result.Succeeded();
888     }
889 };
890
891 OptionDefinition
892 CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] =
893 {
894     { LLDB_OPT_SET_ALL, false,  "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,    "Add this to the given category instead of the default one."},
895     { LLDB_OPT_SET_ALL, false,  "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
896     { LLDB_OPT_SET_ALL, false,  "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
897     { LLDB_OPT_SET_ALL, false,  "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
898     { LLDB_OPT_SET_ALL, false,  "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
899     { LLDB_OPT_SET_2,   false,  "type", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,    "Format variables as if they were of this type."},
900     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
901 };
902
903
904 uint32_t
905 CommandObjectTypeFormatAdd::CommandOptions::GetNumDefinitions ()
906 {
907     return sizeof(g_option_table) / sizeof (OptionDefinition);
908 }
909
910 class CommandObjectTypeFormatterDelete : public CommandObjectParsed
911 {
912 protected:
913     class CommandOptions : public Options
914     {
915     public:
916         
917         CommandOptions (CommandInterpreter &interpreter) :
918         Options (interpreter)
919         {
920         }
921         
922         ~CommandOptions () override {}
923         
924         Error
925         SetOptionValue (uint32_t option_idx, const char *option_arg) override
926         {
927             Error error;
928             const int short_option = m_getopt_table[option_idx].val;
929             
930             switch (short_option)
931             {
932                 case 'a':
933                     m_delete_all = true;
934                     break;
935                 case 'w':
936                     m_category = std::string(option_arg);
937                     break;
938                 case 'l':
939                     m_language = Language::GetLanguageTypeFromString(option_arg);
940                     break;
941                 default:
942                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
943                     break;
944             }
945             
946             return error;
947         }
948         
949         void
950         OptionParsingStarting () override
951         {
952             m_delete_all = false;
953             m_category = "default";
954             m_language = lldb::eLanguageTypeUnknown;
955         }
956         
957         const OptionDefinition*
958         GetDefinitions () override
959         {
960             return g_option_table;
961         }
962         
963         // Options table: Required for subclasses of Options.
964         
965         static OptionDefinition g_option_table[];
966         
967         // Instance variables to hold the values for command options.
968         
969         bool m_delete_all;
970         std::string m_category;
971         lldb::LanguageType m_language;
972     };
973     
974     CommandOptions m_options;
975     uint32_t m_formatter_kind_mask;
976     
977     Options *
978     GetOptions () override
979     {
980         return &m_options;
981     }
982     
983 public:
984     CommandObjectTypeFormatterDelete (CommandInterpreter &interpreter,
985                                       uint32_t formatter_kind_mask,
986                                       const char* name,
987                                       const char* help) :
988     CommandObjectParsed (interpreter,
989                          name,
990                          help,
991                          NULL),
992     m_options(interpreter),
993     m_formatter_kind_mask(formatter_kind_mask)
994     {
995         CommandArgumentEntry type_arg;
996         CommandArgumentData type_style_arg;
997         
998         type_style_arg.arg_type = eArgTypeName;
999         type_style_arg.arg_repetition = eArgRepeatPlain;
1000         
1001         type_arg.push_back (type_style_arg);
1002         
1003         m_arguments.push_back (type_arg);
1004         
1005     }
1006     
1007     ~CommandObjectTypeFormatterDelete () override = default;
1008     
1009 protected:
1010     virtual bool
1011     FormatterSpecificDeletion (ConstString typeCS)
1012     {
1013         return false;
1014     }
1015     
1016     bool
1017     DoExecute (Args& command, CommandReturnObject &result) override
1018     {
1019         const size_t argc = command.GetArgumentCount();
1020         
1021         if (argc != 1)
1022         {
1023             result.AppendErrorWithFormat ("%s takes 1 arg.\n", m_cmd_name.c_str());
1024             result.SetStatus(eReturnStatusFailed);
1025             return false;
1026         }
1027         
1028         const char* typeA = command.GetArgumentAtIndex(0);
1029         ConstString typeCS(typeA);
1030         
1031         if (!typeCS)
1032         {
1033             result.AppendError("empty typenames not allowed");
1034             result.SetStatus(eReturnStatusFailed);
1035             return false;
1036         }
1037         
1038         if (m_options.m_delete_all)
1039         {
1040             DataVisualization::Categories::ForEach( [this, typeCS] (const lldb::TypeCategoryImplSP& category_sp) -> bool {
1041                 category_sp->Delete(typeCS, m_formatter_kind_mask);
1042                 return true;
1043             });
1044             result.SetStatus(eReturnStatusSuccessFinishNoResult);
1045             return result.Succeeded();
1046         }
1047         
1048         bool delete_category = false;
1049         bool extra_deletion = 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, m_formatter_kind_mask);
1057             extra_deletion = FormatterSpecificDeletion(typeCS);
1058         }
1059         else
1060         {
1061             lldb::TypeCategoryImplSP category;
1062             DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
1063             if (category)
1064                 delete_category = category->Delete(typeCS, m_formatter_kind_mask);
1065             extra_deletion = FormatterSpecificDeletion(typeCS);
1066         }
1067         
1068         if (delete_category || extra_deletion)
1069         {
1070             result.SetStatus(eReturnStatusSuccessFinishNoResult);
1071             return result.Succeeded();
1072         }
1073         else
1074         {
1075             result.AppendErrorWithFormat ("no custom formatter for %s.\n", typeA);
1076             result.SetStatus(eReturnStatusFailed);
1077             return false;
1078         }
1079         
1080     }
1081     
1082 };
1083
1084 OptionDefinition
1085 CommandObjectTypeFormatterDelete::CommandOptions::g_option_table[] =
1086 {
1087     { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,  "Delete from every category."},
1088     { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Delete from given category."},
1089     { LLDB_OPT_SET_3, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,  "Delete from given language's category."},
1090     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1091 };
1092
1093 class CommandObjectTypeFormatterClear : public CommandObjectParsed
1094 {
1095 private:
1096     
1097     class CommandOptions : public Options
1098     {
1099     public:
1100         
1101         CommandOptions (CommandInterpreter &interpreter) :
1102         Options (interpreter)
1103         {
1104         }
1105         
1106         ~CommandOptions () override {}
1107         
1108         Error
1109         SetOptionValue (uint32_t option_idx, const char *option_arg) override
1110         {
1111             Error error;
1112             const int short_option = m_getopt_table[option_idx].val;
1113             
1114             switch (short_option)
1115             {
1116                 case 'a':
1117                     m_delete_all = true;
1118                     break;
1119                 default:
1120                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1121                     break;
1122             }
1123             
1124             return error;
1125         }
1126         
1127         void
1128         OptionParsingStarting () override
1129         {
1130             m_delete_all = false;
1131         }
1132         
1133         const OptionDefinition*
1134         GetDefinitions () override
1135         {
1136             return g_option_table;
1137         }
1138         
1139         // Options table: Required for subclasses of Options.
1140         
1141         static OptionDefinition g_option_table[];
1142         
1143         // Instance variables to hold the values for command options.
1144         bool m_delete_all;
1145     };
1146     
1147     CommandOptions m_options;
1148     uint32_t m_formatter_kind_mask;
1149
1150     Options *
1151     GetOptions () override
1152     {
1153         return &m_options;
1154     }
1155     
1156 public:
1157     CommandObjectTypeFormatterClear (CommandInterpreter &interpreter,
1158                                      uint32_t formatter_kind_mask,
1159                                      const char* name,
1160                                      const char* help) :
1161     CommandObjectParsed (interpreter,
1162                          name,
1163                          help,
1164                          NULL),
1165     m_options(interpreter),
1166     m_formatter_kind_mask(formatter_kind_mask)
1167     {
1168     }
1169     
1170     ~CommandObjectTypeFormatterClear () override
1171     {
1172     }
1173     
1174 protected:
1175     virtual void
1176     FormatterSpecificDeletion ()
1177     {
1178     }
1179     
1180     bool
1181     DoExecute (Args& command, CommandReturnObject &result) override
1182     {
1183         if (m_options.m_delete_all)
1184         {
1185             DataVisualization::Categories::ForEach( [this] (const TypeCategoryImplSP& category_sp) -> bool {
1186                 category_sp->Clear(m_formatter_kind_mask);
1187                 return true;
1188             });
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             {
1201                 DataVisualization::Categories::GetCategory(ConstString(NULL), category);
1202             }
1203             category->Clear(m_formatter_kind_mask);
1204         }
1205         
1206         FormatterSpecificDeletion();
1207         
1208         result.SetStatus(eReturnStatusSuccessFinishResult);
1209         return result.Succeeded();
1210     }
1211     
1212 };
1213
1214 OptionDefinition
1215 CommandObjectTypeFormatterClear::CommandOptions::g_option_table[] =
1216 {
1217     { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,  "Clear every category."},
1218     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1219 };
1220
1221 //-------------------------------------------------------------------------
1222 // CommandObjectTypeFormatDelete
1223 //-------------------------------------------------------------------------
1224
1225 class CommandObjectTypeFormatDelete : public CommandObjectTypeFormatterDelete
1226 {
1227 public:
1228     CommandObjectTypeFormatDelete (CommandInterpreter &interpreter) :
1229         CommandObjectTypeFormatterDelete (interpreter,
1230                                           eFormatCategoryItemValue | eFormatCategoryItemRegexValue,
1231                                           "type format delete",
1232                                           "Delete an existing formatting style for a type.")
1233     {
1234     }
1235     
1236     ~CommandObjectTypeFormatDelete () override
1237     {
1238     }
1239 };
1240
1241 //-------------------------------------------------------------------------
1242 // CommandObjectTypeFormatClear
1243 //-------------------------------------------------------------------------
1244
1245 class CommandObjectTypeFormatClear : public CommandObjectTypeFormatterClear
1246 {
1247 public:
1248     CommandObjectTypeFormatClear (CommandInterpreter &interpreter) :
1249         CommandObjectTypeFormatterClear (interpreter,
1250                                          eFormatCategoryItemValue | eFormatCategoryItemRegexValue,
1251                                          "type format clear",
1252                                          "Delete all existing format styles.")
1253     {
1254     }
1255 };
1256
1257 template <typename FormatterType>
1258 class CommandObjectTypeFormatterList : public CommandObjectParsed
1259 {
1260     typedef typename FormatterType::SharedPointer FormatterSharedPointer;
1261
1262     class CommandOptions : public Options
1263     {
1264     public:
1265         
1266         CommandOptions (CommandInterpreter &interpreter) :
1267         Options (interpreter),
1268         m_category_regex("",""),
1269         m_category_language(lldb::eLanguageTypeUnknown, lldb::eLanguageTypeUnknown)
1270         {
1271         }
1272         
1273         ~CommandOptions () override {}
1274         
1275         Error
1276         SetOptionValue (uint32_t option_idx, const char *option_arg) override
1277         {
1278             Error error;
1279             const int short_option = m_getopt_table[option_idx].val;
1280             
1281             switch (short_option)
1282             {
1283                 case 'w':
1284                     m_category_regex.SetCurrentValue(option_arg);
1285                     break;
1286                 case 'l':
1287                     error = m_category_language.SetValueFromString(option_arg);
1288                     break;
1289                 default:
1290                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1291                     break;
1292             }
1293             
1294             return error;
1295         }
1296         
1297         void
1298         OptionParsingStarting () override
1299         {
1300             m_category_regex.Clear();
1301             m_category_language.Clear();
1302         }
1303         
1304         const OptionDefinition*
1305         GetDefinitions () override
1306         {
1307             static OptionDefinition g_option_table[] =
1308             {
1309                 { LLDB_OPT_SET_1, false, "category-regex", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,  "Only show categories matching this filter."},
1310                 { LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,  "Only show the category for a specific language."},
1311                 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
1312             };
1313
1314             return g_option_table;
1315         }
1316         
1317         // Options table: Required for subclasses of Options.
1318         
1319         static OptionDefinition g_option_table[];
1320         
1321         // Instance variables to hold the values for command options.
1322         
1323         OptionValueString m_category_regex;
1324         OptionValueLanguage m_category_language;
1325     };
1326     
1327     CommandOptions m_options;
1328     
1329     Options *
1330     GetOptions () override
1331     {
1332         return &m_options;
1333     }
1334
1335 public:
1336     CommandObjectTypeFormatterList (CommandInterpreter &interpreter,
1337                                     const char* name,
1338                                     const char* help) :
1339         CommandObjectParsed (interpreter,
1340                              name,
1341                              help,
1342                              NULL),
1343     m_options(interpreter)
1344     {
1345         CommandArgumentEntry type_arg;
1346         CommandArgumentData type_style_arg;
1347         
1348         type_style_arg.arg_type = eArgTypeName;
1349         type_style_arg.arg_repetition = eArgRepeatOptional;
1350         
1351         type_arg.push_back (type_style_arg);
1352         
1353         m_arguments.push_back (type_arg);
1354     }
1355     
1356     ~CommandObjectTypeFormatterList () override
1357     {
1358     }
1359     
1360 protected:
1361     virtual void
1362     FormatterSpecificList (CommandReturnObject &result)
1363     {
1364     }
1365     
1366     bool
1367     DoExecute (Args& command, CommandReturnObject &result) override
1368     {
1369         const size_t argc = command.GetArgumentCount();
1370         
1371         std::unique_ptr<RegularExpression> category_regex;
1372         std::unique_ptr<RegularExpression> formatter_regex;
1373         
1374         if (m_options.m_category_regex.OptionWasSet())
1375         {
1376             category_regex.reset(new RegularExpression());
1377             if (!category_regex->Compile(m_options.m_category_regex.GetCurrentValue()))
1378             {
1379                 result.AppendErrorWithFormat("syntax error in category regular expression '%s'", m_options.m_category_regex.GetCurrentValue());
1380                 result.SetStatus(eReturnStatusFailed);
1381                 return false;
1382             }
1383         }
1384         
1385         if (argc == 1)
1386         {
1387             const char* arg = command.GetArgumentAtIndex(1);
1388             formatter_regex.reset(new RegularExpression());
1389             if (!formatter_regex->Compile(arg))
1390             {
1391                 result.AppendErrorWithFormat("syntax error in regular expression '%s'", arg);
1392                 result.SetStatus(eReturnStatusFailed);
1393                 return false;
1394             }
1395         }
1396         
1397         auto category_closure = [&result, &formatter_regex] (const lldb::TypeCategoryImplSP& category) -> void {
1398             result.GetOutputStream().Printf("-----------------------\nCategory: %s\n-----------------------\n", category->GetName());
1399             TypeCategoryImpl::ForEachCallbacks<FormatterType> foreach;
1400             foreach.SetExact([&result, &formatter_regex] (ConstString name, const FormatterSharedPointer& format_sp) -> bool {
1401                 if (formatter_regex)
1402                 {
1403                     bool escape = true;
1404                     if (0 == strcmp(name.AsCString(), formatter_regex->GetText()))
1405                     {
1406                         escape = false;
1407                     }
1408                     else if (formatter_regex->Execute(name.AsCString()))
1409                     {
1410                         escape = false;
1411                     }
1412                     
1413                     if (escape)
1414                         return true;
1415                 }
1416                 
1417                 result.GetOutputStream().Printf ("%s: %s\n", name.AsCString(), format_sp->GetDescription().c_str());
1418                 
1419                 return true;
1420             });
1421             
1422             foreach.SetWithRegex( [&result, &formatter_regex] (RegularExpressionSP regex_sp, const FormatterSharedPointer& format_sp) -> bool {
1423                 if (formatter_regex)
1424                 {
1425                     bool escape = true;
1426                     if (0 == strcmp(regex_sp->GetText(), formatter_regex->GetText()))
1427                     {
1428                         escape = false;
1429                     }
1430                     else if (formatter_regex->Execute(regex_sp->GetText()))
1431                     {
1432                         escape = false;
1433                     }
1434                     
1435                     if (escape)
1436                         return true;
1437                 }
1438                 
1439                 result.GetOutputStream().Printf ("%s: %s\n", regex_sp->GetText(), format_sp->GetDescription().c_str());
1440                 
1441                 return true;
1442             });
1443             
1444             category->ForEach(foreach);
1445         };
1446         
1447         if (m_options.m_category_language.OptionWasSet())
1448         {
1449             lldb::TypeCategoryImplSP category_sp;
1450             DataVisualization::Categories::GetCategory(m_options.m_category_language.GetCurrentValue(), category_sp);
1451             if (category_sp)
1452                 category_closure(category_sp);
1453         }
1454         else
1455         {
1456             DataVisualization::Categories::ForEach( [this, &command, &result, &category_regex, &formatter_regex, &category_closure] (const lldb::TypeCategoryImplSP& category) -> bool {
1457                 if (category_regex)
1458                 {
1459                     bool escape = true;
1460                     if (0 == strcmp(category->GetName(), category_regex->GetText()))
1461                     {
1462                         escape = false;
1463                     }
1464                     else if (category_regex->Execute(category->GetName()))
1465                     {
1466                         escape = false;
1467                     }
1468                     
1469                     if (escape)
1470                         return true;
1471                 }
1472                 
1473                 category_closure(category);
1474                 
1475                 return true;
1476             });
1477             
1478             FormatterSpecificList(result);
1479         }
1480         
1481         result.SetStatus(eReturnStatusSuccessFinishResult);
1482         return result.Succeeded();
1483     }
1484 };
1485
1486 //-------------------------------------------------------------------------
1487 // CommandObjectTypeFormatList
1488 //-------------------------------------------------------------------------
1489
1490 class CommandObjectTypeFormatList : public CommandObjectTypeFormatterList<TypeFormatImpl>
1491 {
1492 public:
1493     
1494     CommandObjectTypeFormatList (CommandInterpreter &interpreter) :
1495         CommandObjectTypeFormatterList(interpreter,
1496                                        "type format list",
1497                                        "Show a list of current formats.")
1498     {
1499     }
1500 };
1501
1502 #ifndef LLDB_DISABLE_PYTHON
1503
1504 //-------------------------------------------------------------------------
1505 // CommandObjectTypeSummaryAdd
1506 //-------------------------------------------------------------------------
1507
1508 #endif // #ifndef LLDB_DISABLE_PYTHON
1509
1510 Error
1511 CommandObjectTypeSummaryAdd::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
1512 {
1513     Error error;
1514     const int short_option = m_getopt_table[option_idx].val;
1515     bool success;
1516     
1517     switch (short_option)
1518     {
1519         case 'C':
1520             m_flags.SetCascades(Args::StringToBoolean(option_arg, true, &success));
1521             if (!success)
1522                 error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
1523             break;
1524         case 'e':
1525             m_flags.SetDontShowChildren(false);
1526             break;
1527         case 'h':
1528             m_flags.SetHideEmptyAggregates(true);
1529             break;
1530         case 'v':
1531             m_flags.SetDontShowValue(true);
1532             break;
1533         case 'c':
1534             m_flags.SetShowMembersOneLiner(true);
1535             break;
1536         case 's':
1537             m_format_string = std::string(option_arg);
1538             break;
1539         case 'p':
1540             m_flags.SetSkipPointers(true);
1541             break;
1542         case 'r':
1543             m_flags.SetSkipReferences(true);
1544             break;
1545         case 'x':
1546             m_regex = true;
1547             break;
1548         case 'n':
1549             m_name.SetCString(option_arg);
1550             break;
1551         case 'o':
1552             m_python_script = std::string(option_arg);
1553             m_is_add_script = true;
1554             break;
1555         case 'F':
1556             m_python_function = std::string(option_arg);
1557             m_is_add_script = true;
1558             break;
1559         case 'P':
1560             m_is_add_script = true;
1561             break;
1562         case 'w':
1563             m_category = std::string(option_arg);
1564             break;
1565         case 'O':
1566             m_flags.SetHideItemNames(true);
1567             break;
1568         default:
1569             error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
1570             break;
1571     }
1572     
1573     return error;
1574 }
1575
1576 void
1577 CommandObjectTypeSummaryAdd::CommandOptions::OptionParsingStarting ()
1578 {
1579     m_flags.Clear().SetCascades().SetDontShowChildren().SetDontShowValue(false);
1580     m_flags.SetShowMembersOneLiner(false).SetSkipPointers(false).SetSkipReferences(false).SetHideItemNames(false);
1581
1582     m_regex = false;
1583     m_name.Clear();
1584     m_python_script = "";
1585     m_python_function = "";
1586     m_format_string = "";
1587     m_is_add_script = false;
1588     m_category = "default";
1589 }
1590
1591
1592
1593 #ifndef LLDB_DISABLE_PYTHON
1594
1595 bool
1596 CommandObjectTypeSummaryAdd::Execute_ScriptSummary (Args& command, CommandReturnObject &result)
1597 {
1598     const size_t argc = command.GetArgumentCount();
1599     
1600     if (argc < 1 && !m_options.m_name)
1601     {
1602         result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
1603         result.SetStatus(eReturnStatusFailed);
1604         return false;
1605     }
1606     
1607     TypeSummaryImplSP script_format;
1608     
1609     if (!m_options.m_python_function.empty()) // we have a Python function ready to use
1610     {
1611         const char *funct_name = m_options.m_python_function.c_str();
1612         if (!funct_name || !funct_name[0])
1613         {
1614             result.AppendError ("function name empty.\n");
1615             result.SetStatus (eReturnStatusFailed);
1616             return false;
1617         }
1618         
1619         std::string code = ("    " + m_options.m_python_function + "(valobj,internal_dict)");
1620         
1621         script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
1622                                                     funct_name,
1623                                                     code.c_str()));
1624         
1625         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1626         
1627         if (interpreter && interpreter->CheckObjectExists(funct_name) == false)
1628             result.AppendWarningWithFormat("The provided function \"%s\" does not exist - "
1629                                            "please define it before attempting to use this summary.\n",
1630                                            funct_name);
1631     }
1632     else if (!m_options.m_python_script.empty()) // we have a quick 1-line script, just use it
1633     {
1634         ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
1635         if (!interpreter)
1636         {
1637             result.AppendError ("script interpreter missing - unable to generate function wrapper.\n");
1638             result.SetStatus (eReturnStatusFailed);
1639             return false;
1640         }
1641         StringList funct_sl;
1642         funct_sl << m_options.m_python_script.c_str();
1643         std::string funct_name_str;
1644         if (!interpreter->GenerateTypeScriptFunction (funct_sl, 
1645                                                       funct_name_str))
1646         {
1647             result.AppendError ("unable to generate function wrapper.\n");
1648             result.SetStatus (eReturnStatusFailed);
1649             return false;
1650         }
1651         if (funct_name_str.empty())
1652         {
1653             result.AppendError ("script interpreter failed to generate a valid function name.\n");
1654             result.SetStatus (eReturnStatusFailed);
1655             return false;
1656         }
1657         
1658         std::string code = "    " + m_options.m_python_script;
1659         
1660         script_format.reset(new ScriptSummaryFormat(m_options.m_flags,
1661                                                     funct_name_str.c_str(),
1662                                                     code.c_str()));
1663     }
1664     else
1665     {
1666         // Use an IOHandler to grab Python code from the user
1667         ScriptAddOptions *options = new ScriptAddOptions(m_options.m_flags,
1668                                                          m_options.m_regex,
1669                                                          m_options.m_name,
1670                                                          m_options.m_category);
1671         
1672         for (size_t i = 0; i < argc; i++)
1673         {
1674             const char* typeA = command.GetArgumentAtIndex(i);
1675             if (typeA && *typeA)
1676                 options->m_target_types << typeA;
1677             else
1678             {
1679                 result.AppendError("empty typenames not allowed");
1680                 result.SetStatus(eReturnStatusFailed);
1681                 return false;
1682             }
1683         }
1684         
1685         m_interpreter.GetPythonCommandsFromIOHandler ("    ",   // Prompt
1686                                                       *this,    // IOHandlerDelegate
1687                                                       true,     // Run IOHandler in async mode
1688                                                       options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
1689         result.SetStatus(eReturnStatusSuccessFinishNoResult);
1690
1691         return result.Succeeded();
1692     }
1693     
1694     // if I am here, script_format must point to something good, so I can add that
1695     // as a script summary to all interested parties
1696     
1697     Error error;
1698     
1699     for (size_t i = 0; i < command.GetArgumentCount(); i++)
1700     {
1701         const char *type_name = command.GetArgumentAtIndex(i);
1702         CommandObjectTypeSummaryAdd::AddSummary(ConstString(type_name),
1703                                                 script_format,
1704                                                 (m_options.m_regex ? eRegexSummary : eRegularSummary),
1705                                                 m_options.m_category,
1706                                                 &error);
1707         if (error.Fail())
1708         {
1709             result.AppendError(error.AsCString());
1710             result.SetStatus(eReturnStatusFailed);
1711             return false;
1712         }
1713     }
1714     
1715     if (m_options.m_name)
1716     {
1717         AddSummary(m_options.m_name, script_format, eNamedSummary, m_options.m_category, &error);
1718         if (error.Fail())
1719         {
1720             result.AppendError(error.AsCString());
1721             result.AppendError("added to types, but not given a name");
1722             result.SetStatus(eReturnStatusFailed);
1723             return false;
1724         }
1725     }
1726     
1727     return result.Succeeded();
1728 }
1729
1730 #endif
1731
1732
1733 bool
1734 CommandObjectTypeSummaryAdd::Execute_StringSummary (Args& command, CommandReturnObject &result)
1735 {
1736     const size_t argc = command.GetArgumentCount();
1737     
1738     if (argc < 1 && !m_options.m_name)
1739     {
1740         result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
1741         result.SetStatus(eReturnStatusFailed);
1742         return false;
1743     }
1744     
1745     if (!m_options.m_flags.GetShowMembersOneLiner() && m_options.m_format_string.empty())
1746     {
1747         result.AppendError("empty summary strings not allowed");
1748         result.SetStatus(eReturnStatusFailed);
1749         return false;
1750     }
1751     
1752     const char* format_cstr = (m_options.m_flags.GetShowMembersOneLiner() ? "" : m_options.m_format_string.c_str());
1753     
1754     // ${var%S} is an endless recursion, prevent it
1755     if (strcmp(format_cstr, "${var%S}") == 0)
1756     {
1757         result.AppendError("recursive summary not allowed");
1758         result.SetStatus(eReturnStatusFailed);
1759         return false;
1760     }
1761     
1762     Error error;
1763     
1764     lldb::TypeSummaryImplSP entry(new StringSummaryFormat(m_options.m_flags,
1765                                                         format_cstr));
1766     
1767     if (error.Fail())
1768     {
1769         result.AppendError(error.AsCString());
1770         result.SetStatus(eReturnStatusFailed);
1771         return false;
1772     }
1773     
1774     // now I have a valid format, let's add it to every type
1775     
1776     for (size_t i = 0; i < argc; i++)
1777     {
1778         const char* typeA = command.GetArgumentAtIndex(i);
1779         if (!typeA || typeA[0] == '\0')
1780         {
1781             result.AppendError("empty typenames not allowed");
1782             result.SetStatus(eReturnStatusFailed);
1783             return false;
1784         }
1785         ConstString typeCS(typeA);
1786         
1787         AddSummary(typeCS,
1788                    entry,
1789                    (m_options.m_regex ? eRegexSummary : eRegularSummary),
1790                    m_options.m_category,
1791                    &error);
1792         
1793         if (error.Fail())
1794         {
1795             result.AppendError(error.AsCString());
1796             result.SetStatus(eReturnStatusFailed);
1797             return false;
1798         }
1799     }
1800     
1801     if (m_options.m_name)
1802     {
1803         AddSummary(m_options.m_name, entry, eNamedSummary, m_options.m_category, &error);
1804         if (error.Fail())
1805         {
1806             result.AppendError(error.AsCString());
1807             result.AppendError("added to types, but not given a name");
1808             result.SetStatus(eReturnStatusFailed);
1809             return false;
1810         }
1811     }
1812     
1813     result.SetStatus(eReturnStatusSuccessFinishNoResult);
1814     return result.Succeeded();
1815 }
1816
1817 CommandObjectTypeSummaryAdd::CommandObjectTypeSummaryAdd (CommandInterpreter &interpreter) :
1818     CommandObjectParsed (interpreter,
1819                          "type summary add",
1820                          "Add a new summary style for a type.",
1821                          NULL),
1822     IOHandlerDelegateMultiline ("DONE"),
1823     m_options (interpreter)
1824 {
1825     CommandArgumentEntry type_arg;
1826     CommandArgumentData type_style_arg;
1827     
1828     type_style_arg.arg_type = eArgTypeName;
1829     type_style_arg.arg_repetition = eArgRepeatPlus;
1830     
1831     type_arg.push_back (type_style_arg);
1832     
1833     m_arguments.push_back (type_arg);
1834     
1835     SetHelpLong(
1836 R"(
1837 The following examples of 'type summary add' refer to this code snippet for context:
1838
1839     struct JustADemo
1840     {
1841         int* ptr;
1842         float value;
1843         JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}
1844     };
1845     JustADemo demo_instance(42, 3.14);
1846
1847     typedef JustADemo NewDemo;
1848     NewDemo new_demo_instance(42, 3.14);
1849
1850 (lldb) type summary add --summary-string "the answer is ${*var.ptr}" JustADemo
1851
1852     Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42"
1853
1854 (lldb) type summary add --summary-string "the answer is ${*var.ptr}, and the question is ${var.value}" JustADemo
1855
1856     Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42 and the question is 3.14"
1857
1858 )" "Alternatively, you could define formatting for all pointers to integers and \
1859 rely on that when formatting JustADemo to obtain the same result:" R"(
1860
1861 (lldb) type summary add --summary-string "${var%V} -> ${*var}" "int *"
1862 (lldb) type summary add --summary-string "the answer is ${var.ptr}, and the question is ${var.value}" JustADemo
1863
1864 )" "Type summaries are automatically applied to derived typedefs, so the examples \
1865 above apply to both JustADemo and NewDemo.  The cascade option can be used to \
1866 suppress this behavior:" R"(
1867
1868 (lldb) type summary add --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo -C no
1869
1870     The summary will now be used for values of JustADemo but not NewDemo.
1871
1872 )" "By default summaries are shown for pointers and references to values of the \
1873 specified type.  To suppress formatting for pointers use the -p option, or apply \
1874 the corresponding -r option to suppress formatting for references:" R"(
1875
1876 (lldb) type summary add -p -r --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo
1877
1878 )" "One-line summaries including all fields in a type can be inferred without supplying an \
1879 explicit summary string by passing the -c option:" R"(
1880
1881 (lldb) type summary add -c JustADemo
1882 (lldb) frame variable demo_instance
1883 (ptr=<address>, value=3.14)
1884
1885 )" "Type summaries normally suppress the nested display of individual fields.  To \
1886 supply a summary to supplement the default structure add the -e option:" R"(
1887
1888 (lldb) type summary add -e --summary-string "*ptr = ${*var.ptr}" JustADemo
1889
1890 )" "Now when displaying JustADemo values the int* is displayed, followed by the \
1891 standard LLDB sequence of children, one per line:" R"(
1892
1893 *ptr = 42 {
1894   ptr = <address>
1895   value = 3.14
1896 }
1897
1898 )" "You can also add summaries written in Python.  These scripts use lldb public API to \
1899 gather information from your variables and produce a meaningful summary.  To start a \
1900 multi-line script use the -P option.  The function declaration will be displayed along with \
1901 a comment describing the two arguments.  End your script with the  word 'DONE' on a line by \
1902 itself:" R"(
1903
1904 (lldb) type summary add JustADemo -P
1905 def function (valobj,internal_dict):
1906 """valobj: an SBValue which you want to provide a summary for
1907 internal_dict: an LLDB support object not to be used"""
1908     value = valobj.GetChildMemberWithName('value');
1909     return 'My value is ' + value.GetValue();
1910     DONE
1911
1912 Alternatively, the -o option can be used when providing a simple one-line Python script:
1913
1914 (lldb) type summary add JustADemo -o "value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();")"
1915     );
1916 }
1917
1918 bool
1919 CommandObjectTypeSummaryAdd::DoExecute (Args& command, CommandReturnObject &result)
1920 {
1921     WarnOnPotentialUnquotedUnsignedType(command, result);
1922
1923     if (m_options.m_is_add_script)
1924     {
1925 #ifndef LLDB_DISABLE_PYTHON
1926         return Execute_ScriptSummary(command, result);
1927 #else
1928         result.AppendError ("python is disabled");
1929         result.SetStatus(eReturnStatusFailed);
1930         return false;
1931 #endif
1932     }
1933     
1934     return Execute_StringSummary(command, result);
1935 }
1936
1937 static bool
1938 FixArrayTypeNameWithRegex (ConstString &type_name)
1939 {
1940     llvm::StringRef type_name_ref(type_name.GetStringRef());
1941     
1942     if (type_name_ref.endswith("[]"))
1943     {
1944         std::string type_name_str(type_name.GetCString());
1945         type_name_str.resize(type_name_str.length()-2);
1946         if (type_name_str.back() != ' ')
1947             type_name_str.append(" \\[[0-9]+\\]");
1948         else
1949             type_name_str.append("\\[[0-9]+\\]");
1950         type_name.SetCString(type_name_str.c_str());
1951         return true;
1952     }
1953     return false;
1954 }
1955
1956 bool
1957 CommandObjectTypeSummaryAdd::AddSummary(ConstString type_name,
1958                                         TypeSummaryImplSP entry,
1959                                         SummaryFormatType type,
1960                                         std::string category_name,
1961                                         Error* error)
1962 {
1963     lldb::TypeCategoryImplSP category;
1964     DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
1965     
1966     if (type == eRegularSummary)
1967     {
1968         if (FixArrayTypeNameWithRegex (type_name))
1969             type = eRegexSummary;
1970     }
1971     
1972     if (type == eRegexSummary)
1973     {
1974         RegularExpressionSP typeRX(new RegularExpression());
1975         if (!typeRX->Compile(type_name.GetCString()))
1976         {
1977             if (error)
1978                 error->SetErrorString("regex format error (maybe this is not really a regex?)");
1979             return false;
1980         }
1981         
1982         category->GetRegexTypeSummariesContainer()->Delete(type_name);
1983         category->GetRegexTypeSummariesContainer()->Add(typeRX, entry);
1984         
1985         return true;
1986     }
1987     else if (type == eNamedSummary)
1988     {
1989         // system named summaries do not exist (yet?)
1990         DataVisualization::NamedSummaryFormats::Add(type_name,entry);
1991         return true;
1992     }
1993     else
1994     {
1995         category->GetTypeSummariesContainer()->Add(type_name, entry);
1996         return true;
1997     }
1998 }    
1999
2000 OptionDefinition
2001 CommandObjectTypeSummaryAdd::CommandOptions::g_option_table[] =
2002 {
2003     { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,    "Add this to the given category instead of the default one."},
2004     { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
2005     { LLDB_OPT_SET_ALL, false, "no-value", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Don't show the value, just show the summary, for this type."},
2006     { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
2007     { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
2008     { LLDB_OPT_SET_ALL, false,  "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
2009     { LLDB_OPT_SET_1  , true, "inline-children", 'c', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,    "If true, inline all child values into summary string."},
2010     { LLDB_OPT_SET_1  , false, "omit-names", 'O', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,    "If true, omit value names in the summary display."},
2011     { LLDB_OPT_SET_2  , true, "summary-string", 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeSummaryString,    "Summary string used to display text and object contents."},
2012     { LLDB_OPT_SET_3, false, "python-script", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonScript, "Give a one-liner Python script as part of the command."},
2013     { LLDB_OPT_SET_3, false, "python-function", 'F', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonFunction, "Give the name of a Python function to use for this type."},
2014     { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Input Python code to use for this type manually."},
2015     { LLDB_OPT_SET_2 | LLDB_OPT_SET_3,   false, "expand", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,    "Expand aggregate data types to show children on separate lines."},
2016     { LLDB_OPT_SET_2 | LLDB_OPT_SET_3,   false, "hide-empty", 'h', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,    "Do not expand aggregate data types with no children."},
2017     { LLDB_OPT_SET_2 | LLDB_OPT_SET_3,   false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,    "A name for this summary string."},
2018     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2019 };
2020
2021
2022 //-------------------------------------------------------------------------
2023 // CommandObjectTypeSummaryDelete
2024 //-------------------------------------------------------------------------
2025
2026 class CommandObjectTypeSummaryDelete : public CommandObjectTypeFormatterDelete
2027 {
2028 public:
2029     CommandObjectTypeSummaryDelete (CommandInterpreter &interpreter) :
2030     CommandObjectTypeFormatterDelete (interpreter,
2031                                       eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary,
2032                                       "type summary delete",
2033                                       "Delete an existing summary for a type.")
2034     {
2035     }
2036     
2037     ~CommandObjectTypeSummaryDelete () override
2038     {
2039     }
2040     
2041 protected:
2042     bool
2043     FormatterSpecificDeletion (ConstString typeCS) override
2044     {
2045         if (m_options.m_language != lldb::eLanguageTypeUnknown)
2046             return false;
2047         return DataVisualization::NamedSummaryFormats::Delete(typeCS);
2048     }
2049 };
2050
2051 class CommandObjectTypeSummaryClear : public CommandObjectTypeFormatterClear
2052 {
2053 public:
2054     CommandObjectTypeSummaryClear (CommandInterpreter &interpreter) :
2055     CommandObjectTypeFormatterClear (interpreter,
2056                                      eFormatCategoryItemSummary | eFormatCategoryItemRegexSummary,
2057                                      "type summary clear",
2058                                      "Delete all existing summaries.")
2059     {
2060     }
2061     
2062 protected:
2063     void
2064     FormatterSpecificDeletion () override
2065     {
2066         DataVisualization::NamedSummaryFormats::Clear();
2067     }
2068 };
2069
2070 //-------------------------------------------------------------------------
2071 // CommandObjectTypeSummaryList
2072 //-------------------------------------------------------------------------
2073
2074 class CommandObjectTypeSummaryList : public CommandObjectTypeFormatterList<TypeSummaryImpl>
2075 {
2076 public:
2077     
2078     CommandObjectTypeSummaryList (CommandInterpreter &interpreter) :
2079     CommandObjectTypeFormatterList(interpreter,
2080                                    "type summary list",
2081                                    "Show a list of current summaries.")
2082     {
2083     }
2084     
2085 protected:
2086     void
2087     FormatterSpecificList (CommandReturnObject &result) override
2088     {
2089         if (DataVisualization::NamedSummaryFormats::GetCount() > 0)
2090         {
2091             result.GetOutputStream().Printf("Named summaries:\n");
2092             DataVisualization::NamedSummaryFormats::ForEach( [&result] (ConstString name, const TypeSummaryImplSP& summary_sp) -> bool {
2093                 result.GetOutputStream().Printf ("%s: %s\n", name.AsCString(), summary_sp->GetDescription().c_str());
2094                 return true;
2095             });
2096         }
2097     }
2098 };
2099
2100 //-------------------------------------------------------------------------
2101 // CommandObjectTypeCategoryDefine
2102 //-------------------------------------------------------------------------
2103
2104 class CommandObjectTypeCategoryDefine : public CommandObjectParsed
2105 {
2106     
2107     class CommandOptions : public Options
2108     {
2109     public:
2110         
2111         CommandOptions (CommandInterpreter &interpreter) :
2112         Options (interpreter),
2113         m_define_enabled(false,false),
2114         m_cate_language(eLanguageTypeUnknown,eLanguageTypeUnknown)
2115         {
2116         }
2117         
2118         ~CommandOptions () override {}
2119         
2120         Error
2121         SetOptionValue (uint32_t option_idx, const char *option_arg) override
2122         {
2123             Error error;
2124             const int short_option = m_getopt_table[option_idx].val;
2125             
2126             switch (short_option)
2127             {
2128                 case 'e':
2129                     m_define_enabled.SetValueFromString("true");
2130                     break;
2131                 case 'l':
2132                     error = m_cate_language.SetValueFromString(option_arg);
2133                     break;
2134                 default:
2135                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
2136                     break;
2137             }
2138             
2139             return error;
2140         }
2141         
2142         void
2143         OptionParsingStarting () override
2144         {
2145             m_define_enabled.Clear();
2146             m_cate_language.Clear();
2147         }
2148         
2149         const OptionDefinition*
2150         GetDefinitions () override
2151         {
2152             return g_option_table;
2153         }
2154         
2155         // Options table: Required for subclasses of Options.
2156         
2157         static OptionDefinition g_option_table[];
2158         
2159         // Instance variables to hold the values for command options.
2160         
2161         OptionValueBoolean m_define_enabled;
2162         OptionValueLanguage m_cate_language;
2163         
2164         
2165     };
2166     
2167     CommandOptions m_options;
2168     
2169     Options *
2170     GetOptions () override
2171     {
2172         return &m_options;
2173     }
2174
2175 public:
2176     CommandObjectTypeCategoryDefine (CommandInterpreter &interpreter) :
2177     CommandObjectParsed (interpreter,
2178                          "type category define",
2179                          "Define a new category as a source of formatters.",
2180                          NULL),
2181     m_options(interpreter)
2182     {
2183         CommandArgumentEntry type_arg;
2184         CommandArgumentData type_style_arg;
2185         
2186         type_style_arg.arg_type = eArgTypeName;
2187         type_style_arg.arg_repetition = eArgRepeatPlus;
2188         
2189         type_arg.push_back (type_style_arg);
2190         
2191         m_arguments.push_back (type_arg);
2192         
2193     }
2194     
2195     ~CommandObjectTypeCategoryDefine () override
2196     {
2197     }
2198     
2199 protected:
2200     bool
2201     DoExecute (Args& command, CommandReturnObject &result) override
2202     {
2203         const size_t argc = command.GetArgumentCount();
2204         
2205         if (argc < 1)
2206         {
2207             result.AppendErrorWithFormat ("%s takes 1 or more args.\n", m_cmd_name.c_str());
2208             result.SetStatus(eReturnStatusFailed);
2209             return false;
2210         }
2211         
2212         for (size_t i = 0; i < argc; i++)
2213         {
2214             const char* cateName = command.GetArgumentAtIndex(i);
2215             TypeCategoryImplSP category_sp;
2216             if (DataVisualization::Categories::GetCategory(ConstString(cateName), category_sp) && category_sp)
2217             {
2218                 category_sp->AddLanguage(m_options.m_cate_language.GetCurrentValue());
2219                 if (m_options.m_define_enabled.GetCurrentValue())
2220                     DataVisualization::Categories::Enable(category_sp, TypeCategoryMap::Default);
2221             }
2222         }
2223         
2224         result.SetStatus(eReturnStatusSuccessFinishResult);
2225         return result.Succeeded();
2226     }
2227     
2228 };
2229
2230 OptionDefinition
2231 CommandObjectTypeCategoryDefine::CommandOptions::g_option_table[] =
2232 {
2233     { LLDB_OPT_SET_ALL, false, "enabled", 'e', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,  "If specified, this category will be created enabled."},
2234     { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,  "Specify the language that this category is supported for."},
2235     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2236 };
2237
2238 //-------------------------------------------------------------------------
2239 // CommandObjectTypeCategoryEnable
2240 //-------------------------------------------------------------------------
2241
2242 class CommandObjectTypeCategoryEnable : public CommandObjectParsed
2243 {
2244     class CommandOptions : public Options
2245     {
2246     public:
2247         
2248         CommandOptions (CommandInterpreter &interpreter) :
2249         Options (interpreter)
2250         {
2251         }
2252         
2253         ~CommandOptions () override {}
2254         
2255         Error
2256         SetOptionValue (uint32_t option_idx, const char *option_arg) override
2257         {
2258             Error error;
2259             const int short_option = m_getopt_table[option_idx].val;
2260             
2261             switch (short_option)
2262             {
2263                 case 'l':
2264                     if (option_arg)
2265                     {
2266                         m_language = Language::GetLanguageTypeFromString(option_arg);
2267                         if (m_language == lldb::eLanguageTypeUnknown)
2268                             error.SetErrorStringWithFormat ("unrecognized language '%s'", option_arg);
2269                     }
2270                     break;
2271                 default:
2272                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
2273                     break;
2274             }
2275             
2276             return error;
2277         }
2278         
2279         void
2280         OptionParsingStarting () override
2281         {
2282             m_language = lldb::eLanguageTypeUnknown;
2283         }
2284         
2285         const OptionDefinition*
2286         GetDefinitions () override
2287         {
2288             return g_option_table;
2289         }
2290         
2291         // Options table: Required for subclasses of Options.
2292         
2293         static OptionDefinition g_option_table[];
2294         
2295         // Instance variables to hold the values for command options.
2296         
2297         lldb::LanguageType m_language;
2298         
2299     };
2300     
2301     CommandOptions m_options;
2302     
2303     Options *
2304     GetOptions () override
2305     {
2306         return &m_options;
2307     }
2308     
2309 public:
2310     CommandObjectTypeCategoryEnable (CommandInterpreter &interpreter) :
2311         CommandObjectParsed (interpreter,
2312                              "type category enable",
2313                              "Enable a category as a source of formatters.",
2314                              NULL),
2315         m_options(interpreter)
2316     {
2317         CommandArgumentEntry type_arg;
2318         CommandArgumentData type_style_arg;
2319         
2320         type_style_arg.arg_type = eArgTypeName;
2321         type_style_arg.arg_repetition = eArgRepeatPlus;
2322         
2323         type_arg.push_back (type_style_arg);
2324         
2325         m_arguments.push_back (type_arg);
2326         
2327     }
2328     
2329     ~CommandObjectTypeCategoryEnable () override
2330     {
2331     }
2332     
2333 protected:
2334     bool
2335     DoExecute (Args& command, CommandReturnObject &result) override
2336     {
2337         const size_t argc = command.GetArgumentCount();
2338         
2339         if (argc < 1 &&
2340             m_options.m_language == lldb::eLanguageTypeUnknown)
2341         {
2342             result.AppendErrorWithFormat ("%s takes arguments and/or a language", m_cmd_name.c_str());
2343             result.SetStatus(eReturnStatusFailed);
2344             return false;
2345         }
2346         
2347         if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
2348         {
2349             DataVisualization::Categories::EnableStar();
2350         }
2351         else if (argc > 0)
2352         {
2353             for (int i = argc - 1; i >= 0; i--)
2354             {
2355                 const char* typeA = command.GetArgumentAtIndex(i);
2356                 ConstString typeCS(typeA);
2357                 
2358                 if (!typeCS)
2359                 {
2360                     result.AppendError("empty category name not allowed");
2361                     result.SetStatus(eReturnStatusFailed);
2362                     return false;
2363                 }
2364                 DataVisualization::Categories::Enable(typeCS);
2365                 lldb::TypeCategoryImplSP cate;
2366                 if (DataVisualization::Categories::GetCategory(typeCS, cate) && cate.get())
2367                 {
2368                     if (cate->GetCount() == 0)
2369                     {
2370                         result.AppendWarning("empty category enabled (typo?)");
2371                     }
2372                 }
2373             }
2374         }
2375         
2376         if (m_options.m_language != lldb::eLanguageTypeUnknown)
2377             DataVisualization::Categories::Enable(m_options.m_language);
2378         
2379         result.SetStatus(eReturnStatusSuccessFinishResult);
2380         return result.Succeeded();
2381     }
2382     
2383 };
2384
2385 OptionDefinition
2386 CommandObjectTypeCategoryEnable::CommandOptions::g_option_table[] =
2387 {
2388     { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,  "Enable the category for this language."},
2389     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2390 };
2391
2392 //-------------------------------------------------------------------------
2393 // CommandObjectTypeCategoryDelete
2394 //-------------------------------------------------------------------------
2395
2396 class CommandObjectTypeCategoryDelete : public CommandObjectParsed
2397 {
2398 public:
2399     CommandObjectTypeCategoryDelete (CommandInterpreter &interpreter) :
2400         CommandObjectParsed (interpreter,
2401                              "type category delete",
2402                              "Delete a category and all associated formatters.",
2403                              NULL)
2404     {
2405         CommandArgumentEntry type_arg;
2406         CommandArgumentData type_style_arg;
2407           
2408         type_style_arg.arg_type = eArgTypeName;
2409         type_style_arg.arg_repetition = eArgRepeatPlus;
2410                 
2411         type_arg.push_back (type_style_arg);
2412         
2413         m_arguments.push_back (type_arg);
2414         
2415     }
2416     
2417     ~CommandObjectTypeCategoryDelete () override
2418     {
2419     }
2420     
2421 protected:
2422     bool
2423     DoExecute (Args& command, CommandReturnObject &result) override
2424     {
2425         const size_t argc = command.GetArgumentCount();
2426         
2427         if (argc < 1)
2428         {
2429             result.AppendErrorWithFormat ("%s takes 1 or more arg.\n", m_cmd_name.c_str());
2430             result.SetStatus(eReturnStatusFailed);
2431             return false;
2432         }
2433         
2434         bool success = true;
2435         
2436         // the order is not relevant here
2437         for (int i = argc - 1; i >= 0; i--)
2438         {
2439             const char* typeA = command.GetArgumentAtIndex(i);
2440             ConstString typeCS(typeA);
2441             
2442             if (!typeCS)
2443             {
2444                 result.AppendError("empty category name not allowed");
2445                 result.SetStatus(eReturnStatusFailed);
2446                 return false;
2447             }
2448             if (!DataVisualization::Categories::Delete(typeCS))
2449                 success = false; // keep deleting even if we hit an error
2450         }
2451         if (success)
2452         {
2453             result.SetStatus(eReturnStatusSuccessFinishResult);
2454             return result.Succeeded();
2455         }
2456         else
2457         {
2458             result.AppendError("cannot delete one or more categories\n");
2459             result.SetStatus(eReturnStatusFailed);
2460             return false;
2461         }
2462     }
2463 };
2464
2465 //-------------------------------------------------------------------------
2466 // CommandObjectTypeCategoryDisable
2467 //-------------------------------------------------------------------------
2468
2469 class CommandObjectTypeCategoryDisable : public CommandObjectParsed
2470 {
2471     class CommandOptions : public Options
2472     {
2473     public:
2474         
2475         CommandOptions (CommandInterpreter &interpreter) :
2476         Options (interpreter)
2477         {
2478         }
2479         
2480         ~CommandOptions () override {}
2481         
2482         Error
2483         SetOptionValue (uint32_t option_idx, const char *option_arg) override
2484         {
2485             Error error;
2486             const int short_option = m_getopt_table[option_idx].val;
2487             
2488             switch (short_option)
2489             {
2490                 case 'l':
2491                     if (option_arg)
2492                     {
2493                         m_language = Language::GetLanguageTypeFromString(option_arg);
2494                         if (m_language == lldb::eLanguageTypeUnknown)
2495                             error.SetErrorStringWithFormat ("unrecognized language '%s'", option_arg);
2496                     }
2497                     break;
2498                 default:
2499                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
2500                     break;
2501             }
2502             
2503             return error;
2504         }
2505         
2506         void
2507         OptionParsingStarting () override
2508         {
2509             m_language = lldb::eLanguageTypeUnknown;
2510         }
2511         
2512         const OptionDefinition*
2513         GetDefinitions () override
2514         {
2515             return g_option_table;
2516         }
2517         
2518         // Options table: Required for subclasses of Options.
2519         
2520         static OptionDefinition g_option_table[];
2521         
2522         // Instance variables to hold the values for command options.
2523         
2524         lldb::LanguageType m_language;
2525         
2526     };
2527     
2528     CommandOptions m_options;
2529     
2530     Options *
2531     GetOptions () override
2532     {
2533         return &m_options;
2534     }
2535
2536 public:
2537     CommandObjectTypeCategoryDisable (CommandInterpreter &interpreter) :
2538         CommandObjectParsed (interpreter,
2539                              "type category disable",
2540                              "Disable a category as a source of formatters.",
2541                              NULL),
2542         m_options(interpreter)
2543     {
2544         CommandArgumentEntry type_arg;
2545         CommandArgumentData type_style_arg;
2546         
2547         type_style_arg.arg_type = eArgTypeName;
2548         type_style_arg.arg_repetition = eArgRepeatPlus;
2549         
2550         type_arg.push_back (type_style_arg);
2551         
2552         m_arguments.push_back (type_arg);
2553         
2554     }
2555     
2556     ~CommandObjectTypeCategoryDisable () override
2557     {
2558     }
2559     
2560 protected:
2561     bool
2562     DoExecute (Args& command, CommandReturnObject &result) override
2563     {
2564         const size_t argc = command.GetArgumentCount();
2565         
2566         if (argc < 1 &&
2567             m_options.m_language == lldb::eLanguageTypeUnknown)
2568         {
2569             result.AppendErrorWithFormat ("%s takes arguments and/or a language", m_cmd_name.c_str());
2570             result.SetStatus(eReturnStatusFailed);
2571             return false;
2572         }
2573         
2574         if (argc == 1 && strcmp(command.GetArgumentAtIndex(0),"*") == 0)
2575         {
2576             DataVisualization::Categories::DisableStar();
2577         }
2578         else if (argc > 0)
2579         {
2580             // the order is not relevant here
2581             for (int i = argc - 1; i >= 0; i--)
2582             {
2583                 const char* typeA = command.GetArgumentAtIndex(i);
2584                 ConstString typeCS(typeA);
2585                 
2586                 if (!typeCS)
2587                 {
2588                     result.AppendError("empty category name not allowed");
2589                     result.SetStatus(eReturnStatusFailed);
2590                     return false;
2591                 }
2592                 DataVisualization::Categories::Disable(typeCS);
2593             }
2594         }
2595         
2596         if (m_options.m_language != lldb::eLanguageTypeUnknown)
2597             DataVisualization::Categories::Disable(m_options.m_language);
2598
2599         result.SetStatus(eReturnStatusSuccessFinishResult);
2600         return result.Succeeded();
2601     }
2602     
2603 };
2604
2605 OptionDefinition
2606 CommandObjectTypeCategoryDisable::CommandOptions::g_option_table[] =
2607 {
2608     { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,  "Enable the category for this language."},
2609     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2610 };
2611
2612 //-------------------------------------------------------------------------
2613 // CommandObjectTypeCategoryList
2614 //-------------------------------------------------------------------------
2615
2616 class CommandObjectTypeCategoryList : public CommandObjectParsed
2617 {
2618 public:
2619     CommandObjectTypeCategoryList (CommandInterpreter &interpreter) :
2620         CommandObjectParsed (interpreter,
2621                              "type category list",
2622                              "Provide a list of all existing categories.",
2623                              NULL)
2624     {
2625         CommandArgumentEntry type_arg;
2626         CommandArgumentData type_style_arg;
2627         
2628         type_style_arg.arg_type = eArgTypeName;
2629         type_style_arg.arg_repetition = eArgRepeatOptional;
2630         
2631         type_arg.push_back (type_style_arg);
2632         
2633         m_arguments.push_back (type_arg);
2634     }
2635     
2636     ~CommandObjectTypeCategoryList () override
2637     {
2638     }
2639     
2640 protected:
2641     bool
2642     DoExecute (Args& command, CommandReturnObject &result) override
2643     {
2644         const size_t argc = command.GetArgumentCount();
2645
2646         std::unique_ptr<RegularExpression> regex;
2647         
2648         if (argc == 1)
2649         {
2650             regex.reset(new RegularExpression());
2651             const char* arg = command.GetArgumentAtIndex(0);
2652             if (!regex->Compile(arg))
2653             {
2654                 result.AppendErrorWithFormat("syntax error in category regular expression '%s'", arg);
2655                 result.SetStatus(eReturnStatusFailed);
2656                 return false;
2657             }
2658         }
2659         else if (argc != 0)
2660         {
2661             result.AppendErrorWithFormat ("%s takes 0 or one arg.\n", m_cmd_name.c_str());
2662             result.SetStatus(eReturnStatusFailed);
2663             return false;
2664         }
2665         
2666         DataVisualization::Categories::ForEach( [&regex, &result] (const lldb::TypeCategoryImplSP& category_sp) -> bool {
2667             if (regex)
2668             {
2669                 bool escape = true;
2670                 if (0 == strcmp(category_sp->GetName(), regex->GetText()))
2671                 {
2672                     escape = false;
2673                 }
2674                 else if (regex->Execute(category_sp->GetName()))
2675                 {
2676                     escape = false;
2677                 }
2678                 
2679                 if (escape)
2680                     return true;
2681             }
2682             
2683             result.GetOutputStream().Printf("Category: %s\n", category_sp->GetDescription().c_str());
2684             
2685             return true;
2686         });
2687         
2688         result.SetStatus(eReturnStatusSuccessFinishResult);
2689         return result.Succeeded();
2690     }
2691     
2692 };
2693
2694 //-------------------------------------------------------------------------
2695 // CommandObjectTypeFilterList
2696 //-------------------------------------------------------------------------
2697
2698 class CommandObjectTypeFilterList : public CommandObjectTypeFormatterList<TypeFilterImpl>
2699 {
2700 public:
2701     
2702     CommandObjectTypeFilterList (CommandInterpreter &interpreter) :
2703     CommandObjectTypeFormatterList(interpreter,
2704                                    "type filter list",
2705                                    "Show a list of current filters.")
2706     {
2707     }
2708 };
2709
2710 #ifndef LLDB_DISABLE_PYTHON
2711
2712 //-------------------------------------------------------------------------
2713 // CommandObjectTypeSynthList
2714 //-------------------------------------------------------------------------
2715
2716 class CommandObjectTypeSynthList : public CommandObjectTypeFormatterList<SyntheticChildren>
2717 {
2718 public:
2719     
2720     CommandObjectTypeSynthList (CommandInterpreter &interpreter) :
2721     CommandObjectTypeFormatterList(interpreter,
2722                                    "type synthetic list",
2723                                    "Show a list of current synthetic providers.")
2724     {
2725     }
2726 };
2727
2728 #endif // #ifndef LLDB_DISABLE_PYTHON
2729 //-------------------------------------------------------------------------
2730 // CommandObjectTypeFilterDelete
2731 //-------------------------------------------------------------------------
2732
2733 class CommandObjectTypeFilterDelete : public CommandObjectTypeFormatterDelete
2734 {
2735 public:
2736     CommandObjectTypeFilterDelete (CommandInterpreter &interpreter) :
2737     CommandObjectTypeFormatterDelete (interpreter,
2738                                       eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter,
2739                                       "type filter delete",
2740                                       "Delete an existing filter for a type.")
2741     {
2742     }
2743     
2744     ~CommandObjectTypeFilterDelete () override
2745     {
2746     }
2747 };
2748
2749 #ifndef LLDB_DISABLE_PYTHON
2750
2751 //-------------------------------------------------------------------------
2752 // CommandObjectTypeSynthDelete
2753 //-------------------------------------------------------------------------
2754
2755 class CommandObjectTypeSynthDelete : public CommandObjectTypeFormatterDelete
2756 {
2757 public:
2758     CommandObjectTypeSynthDelete (CommandInterpreter &interpreter) :
2759     CommandObjectTypeFormatterDelete (interpreter,
2760                                       eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth,
2761                                       "type synthetic delete",
2762                                       "Delete an existing synthetic provider for a type.")
2763     {
2764     }
2765     
2766     ~CommandObjectTypeSynthDelete () override
2767     {
2768     }
2769 };
2770
2771 #endif // #ifndef LLDB_DISABLE_PYTHON
2772
2773 //-------------------------------------------------------------------------
2774 // CommandObjectTypeFilterClear
2775 //-------------------------------------------------------------------------
2776
2777 class CommandObjectTypeFilterClear : public CommandObjectTypeFormatterClear
2778 {
2779 public:
2780     CommandObjectTypeFilterClear (CommandInterpreter &interpreter) :
2781     CommandObjectTypeFormatterClear (interpreter,
2782                                      eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter,
2783                                      "type filter clear",
2784                                      "Delete all existing filter.")
2785     {
2786     }
2787 };
2788
2789 #ifndef LLDB_DISABLE_PYTHON
2790 //-------------------------------------------------------------------------
2791 // CommandObjectTypeSynthClear
2792 //-------------------------------------------------------------------------
2793
2794 class CommandObjectTypeSynthClear : public CommandObjectTypeFormatterClear
2795 {
2796 public:
2797     CommandObjectTypeSynthClear (CommandInterpreter &interpreter) :
2798     CommandObjectTypeFormatterClear (interpreter,
2799                                      eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth,
2800                                      "type synthetic clear",
2801                                      "Delete all existing synthetic providers.")
2802     {
2803     }
2804 };
2805
2806 bool
2807 CommandObjectTypeSynthAdd::Execute_HandwritePython (Args& command, CommandReturnObject &result)
2808 {
2809     SynthAddOptions *options = new SynthAddOptions ( m_options.m_skip_pointers,
2810                                                      m_options.m_skip_references,
2811                                                      m_options.m_cascade,
2812                                                      m_options.m_regex,
2813                                                      m_options.m_category);
2814     
2815     const size_t argc = command.GetArgumentCount();
2816     
2817     for (size_t i = 0; i < argc; i++)
2818     {
2819         const char* typeA = command.GetArgumentAtIndex(i);
2820         if (typeA && *typeA)
2821             options->m_target_types << typeA;
2822         else
2823         {
2824             result.AppendError("empty typenames not allowed");
2825             result.SetStatus(eReturnStatusFailed);
2826             return false;
2827         }
2828     }
2829     
2830     m_interpreter.GetPythonCommandsFromIOHandler ("    ",   // Prompt
2831                                                   *this,    // IOHandlerDelegate
2832                                                   true,     // Run IOHandler in async mode
2833                                                   options); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions
2834     result.SetStatus(eReturnStatusSuccessFinishNoResult);
2835     return result.Succeeded();
2836 }
2837
2838 bool
2839 CommandObjectTypeSynthAdd::Execute_PythonClass (Args& command, CommandReturnObject &result)
2840 {
2841     const size_t argc = command.GetArgumentCount();
2842     
2843     if (argc < 1)
2844     {
2845         result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
2846         result.SetStatus(eReturnStatusFailed);
2847         return false;
2848     }
2849     
2850     if (m_options.m_class_name.empty() && !m_options.m_input_python)
2851     {
2852         result.AppendErrorWithFormat ("%s needs either a Python class name or -P to directly input Python code.\n", m_cmd_name.c_str());
2853         result.SetStatus(eReturnStatusFailed);
2854         return false;
2855     }
2856     
2857     SyntheticChildrenSP entry;
2858     
2859     ScriptedSyntheticChildren* impl = new ScriptedSyntheticChildren(SyntheticChildren::Flags().
2860                                                                     SetCascades(m_options.m_cascade).
2861                                                                     SetSkipPointers(m_options.m_skip_pointers).
2862                                                                     SetSkipReferences(m_options.m_skip_references),
2863                                                                     m_options.m_class_name.c_str());
2864     
2865     entry.reset(impl);
2866     
2867     ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter();
2868     
2869     if (interpreter && interpreter->CheckObjectExists(impl->GetPythonClassName()) == false)
2870         result.AppendWarning("The provided class does not exist - please define it before attempting to use this synthetic provider");
2871     
2872     // now I have a valid provider, let's add it to every type
2873     
2874     lldb::TypeCategoryImplSP category;
2875     DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
2876     
2877     Error error;
2878     
2879     for (size_t i = 0; i < argc; i++)
2880     {
2881         const char* typeA = command.GetArgumentAtIndex(i);
2882         ConstString typeCS(typeA);
2883         if (typeCS)
2884         {
2885             if (!AddSynth(typeCS,
2886                           entry,
2887                           m_options.m_regex ? eRegexSynth : eRegularSynth,
2888                           m_options.m_category,
2889                           &error))
2890             {
2891                 result.AppendError(error.AsCString());
2892                 result.SetStatus(eReturnStatusFailed);
2893                 return false;
2894             }
2895         }
2896         else
2897         {
2898             result.AppendError("empty typenames not allowed");
2899             result.SetStatus(eReturnStatusFailed);
2900             return false;
2901         }
2902     }
2903     
2904     result.SetStatus(eReturnStatusSuccessFinishNoResult);
2905     return result.Succeeded();
2906 }
2907     
2908 CommandObjectTypeSynthAdd::CommandObjectTypeSynthAdd (CommandInterpreter &interpreter) :
2909     CommandObjectParsed (interpreter,
2910                          "type synthetic add",
2911                          "Add a new synthetic provider for a type.",
2912                          NULL),
2913     IOHandlerDelegateMultiline ("DONE"),
2914     m_options (interpreter)
2915 {
2916     CommandArgumentEntry type_arg;
2917     CommandArgumentData type_style_arg;
2918     
2919     type_style_arg.arg_type = eArgTypeName;
2920     type_style_arg.arg_repetition = eArgRepeatPlus;
2921     
2922     type_arg.push_back (type_style_arg);
2923     
2924     m_arguments.push_back (type_arg);
2925     
2926 }
2927
2928 bool
2929 CommandObjectTypeSynthAdd::AddSynth(ConstString type_name,
2930                                     SyntheticChildrenSP entry,
2931                                     SynthFormatType type,
2932                                     std::string category_name,
2933                                     Error* error)
2934 {
2935     lldb::TypeCategoryImplSP category;
2936     DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
2937     
2938     if (type == eRegularSynth)
2939     {
2940         if (FixArrayTypeNameWithRegex (type_name))
2941             type = eRegexSynth;
2942     }
2943     
2944     if (category->AnyMatches(type_name,
2945                              eFormatCategoryItemFilter | eFormatCategoryItemRegexFilter,
2946                              false))
2947     {
2948         if (error)
2949             error->SetErrorStringWithFormat("cannot add synthetic for type %s when filter is defined in same category!", type_name.AsCString());
2950         return false;
2951     }
2952     
2953     if (type == eRegexSynth)
2954     {
2955         RegularExpressionSP typeRX(new RegularExpression());
2956         if (!typeRX->Compile(type_name.GetCString()))
2957         {
2958             if (error)
2959                 error->SetErrorString("regex format error (maybe this is not really a regex?)");
2960             return false;
2961         }
2962         
2963         category->GetRegexTypeSyntheticsContainer()->Delete(type_name);
2964         category->GetRegexTypeSyntheticsContainer()->Add(typeRX, entry);
2965         
2966         return true;
2967     }
2968     else
2969     {
2970         category->GetTypeSyntheticsContainer()->Add(type_name, entry);
2971         return true;
2972     }
2973 }
2974
2975 OptionDefinition
2976 CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] =
2977 {
2978     { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
2979     { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
2980     { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
2981     { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,         "Add this to the given category instead of the default one."},
2982     { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypePythonClass,    "Use this Python class to produce synthetic children."},
2983     { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,    "Type Python code to generate a class that provides synthetic children."},
2984     { LLDB_OPT_SET_ALL, false,  "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
2985     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
2986 };
2987
2988 #endif // #ifndef LLDB_DISABLE_PYTHON
2989
2990 class CommandObjectTypeFilterAdd : public CommandObjectParsed
2991 {
2992     
2993 private:
2994     
2995     class CommandOptions : public Options
2996     {
2997         typedef std::vector<std::string> option_vector;
2998     public:
2999         
3000         CommandOptions (CommandInterpreter &interpreter) :
3001         Options (interpreter)
3002         {
3003         }
3004         
3005         ~CommandOptions () override {}
3006         
3007         Error
3008         SetOptionValue (uint32_t option_idx, const char *option_arg) override
3009         {
3010             Error error;
3011             const int short_option = m_getopt_table[option_idx].val;
3012             bool success;
3013             
3014             switch (short_option)
3015             {
3016                 case 'C':
3017                     m_cascade = Args::StringToBoolean(option_arg, true, &success);
3018                     if (!success)
3019                         error.SetErrorStringWithFormat("invalid value for cascade: %s", option_arg);
3020                     break;
3021                 case 'c':
3022                     m_expr_paths.push_back(option_arg);
3023                     has_child_list = true;
3024                     break;
3025                 case 'p':
3026                     m_skip_pointers = true;
3027                     break;
3028                 case 'r':
3029                     m_skip_references = true;
3030                     break;
3031                 case 'w':
3032                     m_category = std::string(option_arg);
3033                     break;
3034                 case 'x':
3035                     m_regex = true;
3036                     break;
3037                 default:
3038                     error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
3039                     break;
3040             }
3041             
3042             return error;
3043         }
3044         
3045         void
3046         OptionParsingStarting () override
3047         {
3048             m_cascade = true;
3049             m_skip_pointers = false;
3050             m_skip_references = false;
3051             m_category = "default";
3052             m_expr_paths.clear();
3053             has_child_list = false;
3054             m_regex = false;
3055         }
3056         
3057         const OptionDefinition*
3058         GetDefinitions () override
3059         {
3060             return g_option_table;
3061         }
3062         
3063         // Options table: Required for subclasses of Options.
3064         
3065         static OptionDefinition g_option_table[];
3066         
3067         // Instance variables to hold the values for command options.
3068         
3069         bool m_cascade;
3070         bool m_skip_references;
3071         bool m_skip_pointers;
3072         bool m_input_python;
3073         option_vector m_expr_paths;
3074         std::string m_category;
3075                 
3076         bool has_child_list;
3077         
3078         bool m_regex;
3079         
3080         typedef option_vector::iterator ExpressionPathsIterator;
3081     };
3082     
3083     CommandOptions m_options;
3084     
3085     Options *
3086     GetOptions () override
3087     {
3088         return &m_options;
3089     }
3090     
3091     enum FilterFormatType
3092     {
3093         eRegularFilter,
3094         eRegexFilter
3095     };
3096     
3097     bool
3098     AddFilter(ConstString type_name,
3099               TypeFilterImplSP entry,
3100               FilterFormatType type,
3101               std::string category_name,
3102               Error* error)
3103     {
3104         lldb::TypeCategoryImplSP category;
3105         DataVisualization::Categories::GetCategory(ConstString(category_name.c_str()), category);
3106         
3107         if (type == eRegularFilter)
3108         {
3109             if (FixArrayTypeNameWithRegex (type_name))
3110                 type = eRegexFilter;
3111         }
3112         
3113         if (category->AnyMatches(type_name,
3114                                  eFormatCategoryItemSynth | eFormatCategoryItemRegexSynth,
3115                                  false))
3116         {
3117             if (error)
3118                 error->SetErrorStringWithFormat("cannot add filter for type %s when synthetic is defined in same category!", type_name.AsCString());
3119             return false;
3120         }
3121         
3122         if (type == eRegexFilter)
3123         {
3124             RegularExpressionSP typeRX(new RegularExpression());
3125             if (!typeRX->Compile(type_name.GetCString()))
3126             {
3127                 if (error)
3128                     error->SetErrorString("regex format error (maybe this is not really a regex?)");
3129                 return false;
3130             }
3131             
3132             category->GetRegexTypeFiltersContainer()->Delete(type_name);
3133             category->GetRegexTypeFiltersContainer()->Add(typeRX, entry);
3134             
3135             return true;
3136         }
3137         else
3138         {
3139             category->GetTypeFiltersContainer()->Add(type_name, entry);
3140             return true;
3141         }
3142     }
3143
3144         
3145 public:
3146     
3147     CommandObjectTypeFilterAdd (CommandInterpreter &interpreter) :
3148         CommandObjectParsed (interpreter,
3149                              "type filter add",
3150                              "Add a new filter for a type.",
3151                              NULL),
3152         m_options (interpreter)
3153     {
3154         CommandArgumentEntry type_arg;
3155         CommandArgumentData type_style_arg;
3156         
3157         type_style_arg.arg_type = eArgTypeName;
3158         type_style_arg.arg_repetition = eArgRepeatPlus;
3159         
3160         type_arg.push_back (type_style_arg);
3161         
3162         m_arguments.push_back (type_arg);
3163         
3164         SetHelpLong(
3165 R"(
3166 The following examples of 'type filter add' refer to this code snippet for context:
3167
3168     class Foo {
3169         int a;
3170         int b;
3171         int c;
3172         int d;
3173         int e;
3174         int f;
3175         int g;
3176         int h;
3177         int i;
3178     }
3179     Foo my_foo;
3180
3181 Adding a simple filter:
3182
3183 (lldb) type filter add --child a --child g Foo
3184 (lldb) frame variable my_foo
3185
3186 )" "Produces output where only a and g are displayed.  Other children of my_foo \
3187 (b, c, d, e, f, h and i) are available by asking for them explicitly:" R"(
3188
3189 (lldb) frame variable my_foo.b my_foo.c my_foo.i
3190
3191 )" "The formatting option --raw on frame variable bypasses the filter, showing \
3192 all children of my_foo as if no filter was defined:" R"(
3193
3194 (lldb) frame variable my_foo --raw)"
3195         );
3196     }
3197     
3198     ~CommandObjectTypeFilterAdd () override
3199     {
3200     }
3201     
3202 protected:
3203     bool
3204     DoExecute (Args& command, CommandReturnObject &result) override
3205     {
3206         const size_t argc = command.GetArgumentCount();
3207         
3208         if (argc < 1)
3209         {
3210             result.AppendErrorWithFormat ("%s takes one or more args.\n", m_cmd_name.c_str());
3211             result.SetStatus(eReturnStatusFailed);
3212             return false;
3213         }
3214         
3215         if (m_options.m_expr_paths.size() == 0)
3216         {
3217             result.AppendErrorWithFormat ("%s needs one or more children.\n", m_cmd_name.c_str());
3218             result.SetStatus(eReturnStatusFailed);
3219             return false;
3220         }
3221         
3222         TypeFilterImplSP entry(new TypeFilterImpl(SyntheticChildren::Flags().SetCascades(m_options.m_cascade).
3223                                        SetSkipPointers(m_options.m_skip_pointers).
3224                                                   SetSkipReferences(m_options.m_skip_references)));
3225         
3226         // go through the expression paths
3227         CommandOptions::ExpressionPathsIterator begin, end = m_options.m_expr_paths.end();
3228         
3229         for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
3230             entry->AddExpressionPath(*begin);
3231         
3232         
3233         // now I have a valid provider, let's add it to every type
3234         
3235         lldb::TypeCategoryImplSP category;
3236         DataVisualization::Categories::GetCategory(ConstString(m_options.m_category.c_str()), category);
3237         
3238         Error error;
3239         
3240         WarnOnPotentialUnquotedUnsignedType(command, result);
3241         
3242         for (size_t i = 0; i < argc; i++)
3243         {
3244             const char* typeA = command.GetArgumentAtIndex(i);
3245             ConstString typeCS(typeA);
3246             if (typeCS)
3247             {
3248                 if (!AddFilter(typeCS,
3249                           entry,
3250                           m_options.m_regex ? eRegexFilter : eRegularFilter,
3251                           m_options.m_category,
3252                           &error))
3253                 {
3254                     result.AppendError(error.AsCString());
3255                     result.SetStatus(eReturnStatusFailed);
3256                     return false;
3257                 }
3258             }
3259             else
3260             {
3261                 result.AppendError("empty typenames not allowed");
3262                 result.SetStatus(eReturnStatusFailed);
3263                 return false;
3264             }
3265         }
3266         
3267         result.SetStatus(eReturnStatusSuccessFinishNoResult);
3268         return result.Succeeded();
3269     }
3270
3271 };
3272
3273 OptionDefinition
3274 CommandObjectTypeFilterAdd::CommandOptions::g_option_table[] =
3275 {
3276     { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeBoolean,    "If true, cascade through typedef chains."},
3277     { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Don't use this format for pointers-to-type objects."},
3278     { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,         "Don't use this format for references-to-type objects."},
3279     { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeName,         "Add this to the given category instead of the default one."},
3280     { LLDB_OPT_SET_ALL, false, "child", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeExpressionPath,    "Include this expression path in the synthetic view."},
3281     { LLDB_OPT_SET_ALL, false,  "regex", 'x', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,    "Type names are actually regular expressions."},
3282     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
3283 };
3284
3285 //----------------------------------------------------------------------
3286 // "type lookup"
3287 //----------------------------------------------------------------------
3288 class CommandObjectTypeLookup : public CommandObjectRaw
3289 {
3290 protected:
3291     
3292     class CommandOptions : public OptionGroup
3293     {
3294     public:
3295         
3296         CommandOptions () :
3297         OptionGroup(),
3298         m_show_help(false),
3299         m_language(eLanguageTypeUnknown)
3300         {}
3301         
3302         ~CommandOptions () override {}
3303         
3304         uint32_t
3305         GetNumDefinitions () override
3306         {
3307             return 3;
3308         }
3309         
3310         const OptionDefinition*
3311         GetDefinitions () override
3312         {
3313             return g_option_table;
3314         }
3315         
3316         Error
3317         SetOptionValue (CommandInterpreter &interpreter,
3318                         uint32_t option_idx,
3319                         const char *option_value) override
3320         {
3321             Error error;
3322             
3323             const int short_option = g_option_table[option_idx].short_option;
3324             
3325             switch (short_option)
3326             {
3327                 case 'h':
3328                     m_show_help = true;
3329                     break;
3330                     
3331                 case 'l':
3332                     m_language = Language::GetLanguageTypeFromString(option_value);
3333                     break;
3334                     
3335                 default:
3336                     error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
3337                     break;
3338             }
3339             
3340             return error;
3341         }
3342         
3343         void
3344         OptionParsingStarting (CommandInterpreter &interpreter) override
3345         {
3346             m_show_help = false;
3347             m_language = eLanguageTypeUnknown;
3348         }
3349         
3350         // Options table: Required for subclasses of Options.
3351         
3352         static OptionDefinition g_option_table[];
3353         bool m_show_help;
3354         lldb::LanguageType m_language;
3355     };
3356     
3357     OptionGroupOptions m_option_group;
3358     CommandOptions m_command_options;
3359     
3360 public:
3361     
3362     CommandObjectTypeLookup (CommandInterpreter &interpreter) :
3363     CommandObjectRaw (interpreter,
3364                       "type lookup",
3365                       "Lookup a type by name in the select target.",
3366                       "type lookup <typename>",
3367                       eCommandRequiresTarget),
3368     m_option_group(interpreter),
3369     m_command_options()
3370     {
3371         m_option_group.Append(&m_command_options);
3372         m_option_group.Finalize();
3373     }
3374     
3375     ~CommandObjectTypeLookup () override
3376     {
3377     }
3378     
3379     Options *
3380     GetOptions () override
3381     {
3382         return &m_option_group;
3383     }
3384     
3385     bool
3386     DoExecute (const char *raw_command_line, CommandReturnObject &result) override
3387     {
3388         if (!raw_command_line || !raw_command_line[0])
3389         {
3390             result.SetError("type lookup cannot be invoked without a type name as argument");
3391             return false;
3392         }
3393         
3394         m_option_group.NotifyOptionParsingStarting();
3395         
3396         const char * name_of_type = NULL;
3397         
3398         if (raw_command_line[0] == '-')
3399         {
3400             // We have some options and these options MUST end with --.
3401             const char *end_options = NULL;
3402             const char *s = raw_command_line;
3403             while (s && s[0])
3404             {
3405                 end_options = ::strstr (s, "--");
3406                 if (end_options)
3407                 {
3408                     end_options += 2; // Get past the "--"
3409                     if (::isspace (end_options[0]))
3410                     {
3411                         name_of_type = end_options;
3412                         while (::isspace (*name_of_type))
3413                             ++name_of_type;
3414                         break;
3415                     }
3416                 }
3417                 s = end_options;
3418             }
3419             
3420             if (end_options)
3421             {
3422                 Args args (llvm::StringRef(raw_command_line, end_options - raw_command_line));
3423                 if (!ParseOptions (args, result))
3424                     return false;
3425                 
3426                 Error error (m_option_group.NotifyOptionParsingFinished());
3427                 if (error.Fail())
3428                 {
3429                     result.AppendError (error.AsCString());
3430                     result.SetStatus (eReturnStatusFailed);
3431                     return false;
3432                 }
3433             }
3434         }
3435         if (nullptr == name_of_type)
3436             name_of_type = raw_command_line;
3437         
3438         TargetSP target_sp(GetCommandInterpreter().GetDebugger().GetSelectedTarget());
3439         const bool fill_all_in = true;
3440         ExecutionContext exe_ctx(target_sp.get(), fill_all_in);
3441         ExecutionContextScope *best_scope = exe_ctx.GetBestExecutionContextScope();
3442         
3443         bool any_found = false;
3444         
3445         std::vector<Language*> languages;
3446         
3447         if (m_command_options.m_language == eLanguageTypeUnknown)
3448         {
3449             // FIXME: hardcoding languages is not good
3450             languages.push_back(Language::FindPlugin(eLanguageTypeObjC));
3451             languages.push_back(Language::FindPlugin(eLanguageTypeC_plus_plus));
3452         }
3453         else
3454         {
3455             languages.push_back(Language::FindPlugin(m_command_options.m_language));
3456         }
3457         
3458         for (Language* language : languages)
3459         {
3460             if (!language)
3461                 continue;
3462
3463             if (auto scavenger = language->GetTypeScavenger())
3464             {
3465                 Language::TypeScavenger::ResultSet search_results;
3466                 if (scavenger->Find(best_scope, name_of_type, search_results) > 0)
3467                 {
3468                     for (const auto& search_result : search_results)
3469                     {
3470                         if (search_result && search_result->IsValid())
3471                         {
3472                             any_found = true;
3473                             search_result->DumpToStream(result.GetOutputStream(), this->m_command_options.m_show_help);
3474                         }
3475                     }
3476                 }
3477             }
3478         }
3479         
3480         result.SetStatus (any_found ? lldb::eReturnStatusSuccessFinishResult : lldb::eReturnStatusSuccessFinishNoResult);
3481         return true;
3482     }
3483     
3484 };
3485
3486 OptionDefinition
3487 CommandObjectTypeLookup::CommandOptions::g_option_table[] =
3488 {
3489     { LLDB_OPT_SET_ALL, false, "show-help",        'h', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone,    "Display available help for types"},
3490     { LLDB_OPT_SET_ALL, false, "language",         'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage,    "Which language's types should the search scope be"},
3491     { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
3492 };
3493
3494 template <typename FormatterType>
3495 class CommandObjectFormatterInfo : public CommandObjectRaw
3496 {
3497 public:
3498     typedef std::function<typename FormatterType::SharedPointer(ValueObject&)> DiscoveryFunction;
3499     CommandObjectFormatterInfo (CommandInterpreter &interpreter,
3500                                 const char* formatter_name,
3501                                 DiscoveryFunction discovery_func) :
3502     CommandObjectRaw(interpreter,
3503                      nullptr,
3504                      nullptr,
3505                      nullptr,
3506                      eCommandRequiresFrame),
3507     m_formatter_name(formatter_name ? formatter_name : ""),
3508     m_discovery_function(discovery_func)
3509     {
3510         StreamString name;
3511         name.Printf("type %s info", formatter_name);
3512         SetCommandName(name.GetData());
3513         StreamString help;
3514         help.Printf("This command evaluates the provided expression and shows which %s is applied to the resulting value (if any).", formatter_name);
3515         SetHelp(help.GetData());
3516         StreamString syntax;
3517         syntax.Printf("type %s info <expr>", formatter_name);
3518         SetSyntax(syntax.GetData());
3519     }
3520     
3521     ~CommandObjectFormatterInfo () override
3522     {
3523     }
3524     
3525 protected:
3526     bool
3527     DoExecute (const char *command, CommandReturnObject &result) override
3528     {
3529         auto target_sp = m_interpreter.GetDebugger().GetSelectedTarget();
3530         auto frame_sp = target_sp->GetProcessSP()->GetThreadList().GetSelectedThread()->GetSelectedFrame();
3531         ValueObjectSP result_valobj_sp;
3532         EvaluateExpressionOptions options;
3533         lldb::ExpressionResults expr_result = target_sp->EvaluateExpression(command, frame_sp.get(), result_valobj_sp, options);
3534         if (expr_result == eExpressionCompleted && result_valobj_sp)
3535         {
3536             result_valobj_sp = result_valobj_sp->GetQualifiedRepresentationIfAvailable(target_sp->GetPreferDynamicValue(), target_sp->GetEnableSyntheticValue());
3537             typename FormatterType::SharedPointer formatter_sp = m_discovery_function(*result_valobj_sp);
3538             if (formatter_sp)
3539             {
3540                 std::string description(formatter_sp->GetDescription());
3541                 result.AppendMessageWithFormat("%s applied to (%s) %s is: %s\n",
3542                                                m_formatter_name.c_str(),
3543                                                result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"),
3544                                                command,
3545                                                description.c_str());
3546                 result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
3547             }
3548             else
3549             {
3550                 result.AppendMessageWithFormat("no %s applies to (%s) %s\n",
3551                                                m_formatter_name.c_str(),
3552                                                result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>"),
3553                                                command);
3554                 result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
3555             }
3556             return true;
3557         }
3558         else
3559         {
3560             result.AppendError("failed to evaluate expression");
3561             result.SetStatus(lldb::eReturnStatusFailed);
3562             return false;
3563         }
3564     }
3565
3566 private:
3567     std::string m_formatter_name;
3568     DiscoveryFunction m_discovery_function;
3569 };
3570
3571 class CommandObjectTypeFormat : public CommandObjectMultiword
3572 {
3573 public:
3574     CommandObjectTypeFormat (CommandInterpreter &interpreter) :
3575         CommandObjectMultiword (interpreter,
3576                                 "type format",
3577                                 "A set of commands for editing variable value display options",
3578                                 "type format [<sub-command-options>] ")
3579     {
3580         LoadSubCommand ("add",    CommandObjectSP (new CommandObjectTypeFormatAdd (interpreter)));
3581         LoadSubCommand ("clear",  CommandObjectSP (new CommandObjectTypeFormatClear (interpreter)));
3582         LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTypeFormatDelete (interpreter)));
3583         LoadSubCommand ("list",   CommandObjectSP (new CommandObjectTypeFormatList (interpreter)));
3584         LoadSubCommand ("info",   CommandObjectSP (new CommandObjectFormatterInfo<TypeFormatImpl>(interpreter,
3585                                                                                                   "format",
3586                                                                                                   [](ValueObject& valobj) -> TypeFormatImpl::SharedPointer {
3587                                                                                                       return valobj.GetValueFormat();
3588                                                                                                   })));
3589     }
3590
3591
3592     ~CommandObjectTypeFormat () override
3593     {
3594     }
3595 };
3596
3597 #ifndef LLDB_DISABLE_PYTHON
3598
3599 class CommandObjectTypeSynth : public CommandObjectMultiword
3600 {
3601 public:
3602     CommandObjectTypeSynth (CommandInterpreter &interpreter) :
3603     CommandObjectMultiword (interpreter,
3604                             "type synthetic",
3605                             "A set of commands for operating on synthetic type representations",
3606                             "type synthetic [<sub-command-options>] ")
3607     {
3608         LoadSubCommand ("add",           CommandObjectSP (new CommandObjectTypeSynthAdd (interpreter)));
3609         LoadSubCommand ("clear",         CommandObjectSP (new CommandObjectTypeSynthClear (interpreter)));
3610         LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeSynthDelete (interpreter)));
3611         LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeSynthList (interpreter)));
3612         LoadSubCommand ("info",          CommandObjectSP (new CommandObjectFormatterInfo<SyntheticChildren>(interpreter,
3613                                                                                                             "synthetic",
3614                                                                                                             [](ValueObject& valobj) -> SyntheticChildren::SharedPointer {
3615                                                                                                                 return valobj.GetSyntheticChildren();
3616                                                                                                             })));
3617     }
3618     
3619     
3620     ~CommandObjectTypeSynth () override
3621     {
3622     }
3623 };
3624
3625 #endif // #ifndef LLDB_DISABLE_PYTHON
3626
3627 class CommandObjectTypeFilter : public CommandObjectMultiword
3628 {
3629 public:
3630     CommandObjectTypeFilter (CommandInterpreter &interpreter) :
3631     CommandObjectMultiword (interpreter,
3632                             "type filter",
3633                             "A set of commands for operating on type filters",
3634                             "type synthetic [<sub-command-options>] ")
3635     {
3636         LoadSubCommand ("add",           CommandObjectSP (new CommandObjectTypeFilterAdd (interpreter)));
3637         LoadSubCommand ("clear",         CommandObjectSP (new CommandObjectTypeFilterClear (interpreter)));
3638         LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeFilterDelete (interpreter)));
3639         LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeFilterList (interpreter)));
3640     }
3641     
3642     
3643     ~CommandObjectTypeFilter () override
3644     {
3645     }
3646 };
3647
3648 class CommandObjectTypeCategory : public CommandObjectMultiword
3649 {
3650 public:
3651     CommandObjectTypeCategory (CommandInterpreter &interpreter) :
3652     CommandObjectMultiword (interpreter,
3653                             "type category",
3654                             "A set of commands for operating on categories",
3655                             "type category [<sub-command-options>] ")
3656     {
3657         LoadSubCommand ("define",        CommandObjectSP (new CommandObjectTypeCategoryDefine (interpreter)));
3658         LoadSubCommand ("enable",        CommandObjectSP (new CommandObjectTypeCategoryEnable (interpreter)));
3659         LoadSubCommand ("disable",       CommandObjectSP (new CommandObjectTypeCategoryDisable (interpreter)));
3660         LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeCategoryDelete (interpreter)));
3661         LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeCategoryList (interpreter)));
3662     }
3663     
3664     
3665     ~CommandObjectTypeCategory () override
3666     {
3667     }
3668 };
3669
3670 class CommandObjectTypeSummary : public CommandObjectMultiword
3671 {
3672 public:
3673     CommandObjectTypeSummary (CommandInterpreter &interpreter) :
3674     CommandObjectMultiword (interpreter,
3675                             "type summary",
3676                             "A set of commands for editing variable summary display options",
3677                             "type summary [<sub-command-options>] ")
3678     {
3679         LoadSubCommand ("add",           CommandObjectSP (new CommandObjectTypeSummaryAdd (interpreter)));
3680         LoadSubCommand ("clear",         CommandObjectSP (new CommandObjectTypeSummaryClear (interpreter)));
3681         LoadSubCommand ("delete",        CommandObjectSP (new CommandObjectTypeSummaryDelete (interpreter)));
3682         LoadSubCommand ("list",          CommandObjectSP (new CommandObjectTypeSummaryList (interpreter)));
3683         LoadSubCommand ("info",          CommandObjectSP (new CommandObjectFormatterInfo<TypeSummaryImpl>(interpreter,
3684                                                                                                           "summary",
3685                                                                                                             [](ValueObject& valobj) -> TypeSummaryImpl::SharedPointer {
3686                                                                                                                 return valobj.GetSummaryFormat();
3687                                                                                                             })));
3688     }
3689     
3690     
3691     ~CommandObjectTypeSummary () override
3692     {
3693     }
3694 };
3695
3696 //-------------------------------------------------------------------------
3697 // CommandObjectType
3698 //-------------------------------------------------------------------------
3699
3700 CommandObjectType::CommandObjectType (CommandInterpreter &interpreter) :
3701     CommandObjectMultiword (interpreter,
3702                             "type",
3703                             "A set of commands for operating on the type system",
3704                             "type [<sub-command-options>]")
3705 {
3706     LoadSubCommand ("category",  CommandObjectSP (new CommandObjectTypeCategory (interpreter)));
3707     LoadSubCommand ("filter",    CommandObjectSP (new CommandObjectTypeFilter (interpreter)));
3708     LoadSubCommand ("format",    CommandObjectSP (new CommandObjectTypeFormat (interpreter)));
3709     LoadSubCommand ("summary",   CommandObjectSP (new CommandObjectTypeSummary (interpreter)));
3710 #ifndef LLDB_DISABLE_PYTHON
3711     LoadSubCommand ("synthetic", CommandObjectSP (new CommandObjectTypeSynth (interpreter)));
3712 #endif
3713     LoadSubCommand ("lookup",   CommandObjectSP (new CommandObjectTypeLookup (interpreter)));
3714 }
3715
3716
3717 CommandObjectType::~CommandObjectType ()
3718 {
3719 }