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