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