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