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