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