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