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