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