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