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