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