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 void 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
387 bool Execute_HandwritePython(Args &command, CommandReturnObject &result);
388
389 bool Execute_PythonClass(Args &command, CommandReturnObject &result);
390
391protected:
392 void DoExecute(Args &command, CommandReturnObject &result) override {
394
396 Execute_HandwritePython(command, result);
397 else if (m_options.is_class_based)
398 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 }
404 }
405
406 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
407 StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
408 if (output_sp && interactive) {
409 output_sp->PutCString(g_synth_addreader_instructions);
410 output_sp->Flush();
411 }
412 }
413
415 std::string &data) override {
416 StreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
417
418#if LLDB_ENABLE_PYTHON
420 if (interpreter) {
421 StringList lines;
422 lines.SplitIntoLines(data);
423 if (lines.GetSize() > 0) {
424 SynthAddOptions *options_ptr =
425 ((SynthAddOptions *)io_handler.GetUserData());
426 if (options_ptr) {
428 options_ptr); // this will ensure that we get rid of the pointer
429 // when going out of scope
430
432 if (interpreter) {
433 std::string class_name_str;
434 if (interpreter->GenerateTypeSynthClass(lines, class_name_str)) {
435 if (class_name_str.empty()) {
436 error_sp->Printf(
437 "error: unable to obtain a proper name for the class.\n");
438 error_sp->Flush();
439 } else {
440 // everything should be fine now, let's add the synth provider
441 // class
442
443 SyntheticChildrenSP synth_provider;
444 synth_provider = std::make_shared<ScriptedSyntheticChildren>(
446 .SetCascades(options->m_cascade)
447 .SetSkipPointers(options->m_skip_pointers)
448 .SetSkipReferences(options->m_skip_references),
449 class_name_str.c_str());
450
453 ConstString(options->m_category.c_str()), category);
454
456
457 for (const std::string &type_name : options->m_target_types) {
458 if (!type_name.empty()) {
459 if (AddSynth(ConstString(type_name), synth_provider,
460 options->m_match_type, options->m_category,
461 &error)) {
462 error_sp->Printf("error: %s\n", error.AsCString());
463 error_sp->Flush();
464 break;
465 }
466 } else {
467 error_sp->Printf("error: invalid type name.\n");
468 error_sp->Flush();
469 break;
470 }
471 }
472 }
473 } else {
474 error_sp->Printf("error: unable to generate a class.\n");
475 error_sp->Flush();
476 }
477 } else {
478 error_sp->Printf("error: no script interpreter.\n");
479 error_sp->Flush();
480 }
481 } else {
482 error_sp->Printf("error: internal synchronization data missing.\n");
483 error_sp->Flush();
484 }
485 } else {
486 error_sp->Printf("error: empty function, didn't add python command.\n");
487 error_sp->Flush();
488 }
489 } else {
490 error_sp->Printf(
491 "error: script interpreter missing, didn't add python command.\n");
492 error_sp->Flush();
493 }
494
495#endif
496 io_handler.SetIsDone(true);
497 }
498
499public:
501
502 ~CommandObjectTypeSynthAdd() override = default;
503
504 bool AddSynth(ConstString type_name, lldb::SyntheticChildrenSP entry,
505 FormatterMatchType match_type, std::string category_name,
506 Status *error);
507};
508
509// CommandObjectTypeFormatAdd
510
511#define LLDB_OPTIONS_type_format_add
512#include "CommandOptions.inc"
513
515private:
517 public:
518 CommandOptions() = default;
519
520 ~CommandOptions() override = default;
521
522 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
523 return llvm::ArrayRef(g_type_format_add_options);
524 }
525
526 void OptionParsingStarting(ExecutionContext *execution_context) override {
527 m_cascade = true;
528 m_skip_pointers = false;
529 m_skip_references = false;
530 m_regex = false;
531 m_category.assign("default");
532 m_custom_type_name.clear();
533 }
534
535 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
536 ExecutionContext *execution_context) override {
538 const int short_option =
539 g_type_format_add_options[option_idx].short_option;
540 bool success;
541
542 switch (short_option) {
543 case 'C':
544 m_cascade = OptionArgParser::ToBoolean(option_value, true, &success);
545 if (!success)
546 error.SetErrorStringWithFormat("invalid value for cascade: %s",
547 option_value.str().c_str());
548 break;
549 case 'p':
550 m_skip_pointers = true;
551 break;
552 case 'w':
553 m_category.assign(std::string(option_value));
554 break;
555 case 'r':
556 m_skip_references = true;
557 break;
558 case 'x':
559 m_regex = true;
560 break;
561 case 't':
562 m_custom_type_name.assign(std::string(option_value));
563 break;
564 default:
565 llvm_unreachable("Unimplemented option");
566 }
567
568 return error;
569 }
570
571 // Instance variables to hold the values for command options.
572
577 std::string m_category;
579 };
580
584
585 Options *GetOptions() override { return &m_option_group; }
586
587public:
589 : CommandObjectParsed(interpreter, "type format add",
590 "Add a new formatting style for a type.", nullptr),
592 CommandArgumentEntry type_arg;
593 CommandArgumentData type_style_arg;
594
595 type_style_arg.arg_type = eArgTypeName;
596 type_style_arg.arg_repetition = eArgRepeatPlus;
597
598 type_arg.push_back(type_style_arg);
599
600 m_arguments.push_back(type_arg);
601
603 R"(
604The following examples of 'type format add' refer to this code snippet for context:
605
606 typedef int Aint;
607 typedef float Afloat;
608 typedef Aint Bint;
609 typedef Afloat Bfloat;
610
611 Aint ix = 5;
612 Bint iy = 5;
613
614 Afloat fx = 3.14;
615 BFloat fy = 3.14;
616
617Adding default formatting:
619(lldb) type format add -f hex AInt
620(lldb) frame variable iy
622)"
623 " Produces hexadecimal display of iy, because no formatter is available for Bint and \
624the one for Aint is used instead."
625 R"(
626
627To prevent this use the cascade option '-C no' to prevent evaluation of typedef chains:
628
629
630(lldb) type format add -f hex -C no AInt
631
632Similar reasoning applies to this:
633
634(lldb) type format add -f hex -C no float -p
635
636)"
637 " All float values and float references are now formatted as hexadecimal, but not \
638pointers to floats. Nor will it change the default display for Afloat and Bfloat objects.");
639
640 // Add the "--format" to all options groups
646 }
647
648 ~CommandObjectTypeFormatAdd() override = default;
649
650protected:
651 void DoExecute(Args &command, CommandReturnObject &result) override {
652 const size_t argc = command.GetArgumentCount();
653
654 if (argc < 1) {
655 result.AppendErrorWithFormat("%s takes one or more args.\n",
656 m_cmd_name.c_str());
657 return;
658 }
659
660 const Format format = m_format_options.GetFormat();
661 if (format == eFormatInvalid &&
663 result.AppendErrorWithFormat("%s needs a valid format.\n",
664 m_cmd_name.c_str());
665 return;
666 }
667
668 TypeFormatImplSP entry;
669
671 entry = std::make_shared<TypeFormatImpl_Format>(
672 format, TypeFormatImpl::Flags()
673 .SetCascades(m_command_options.m_cascade)
676 else
677 entry = std::make_shared<TypeFormatImpl_EnumType>(
683
684 // now I have a valid format, let's add it to every type
685
686 TypeCategoryImplSP category_sp;
689 if (!category_sp)
690 return;
691
693
694 for (auto &arg_entry : command.entries()) {
695 if (arg_entry.ref().empty()) {
696 result.AppendError("empty typenames not allowed");
697 return;
698 }
699
702 match_type = eFormatterMatchRegex;
703 RegularExpression typeRX(arg_entry.ref());
704 if (!typeRX.IsValid()) {
705 result.AppendError(
706 "regex format error (maybe this is not really a regex?)");
707 return;
708 }
709 }
710 category_sp->AddTypeFormat(arg_entry.ref(), match_type, entry);
711 }
712
714 }
715};
716
717#define LLDB_OPTIONS_type_formatter_delete
718#include "CommandOptions.inc"
719
721protected:
722 class CommandOptions : public Options {
723 public:
724 CommandOptions() = default;
725
726 ~CommandOptions() override = default;
727
728 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
729 ExecutionContext *execution_context) override {
731 const int short_option = m_getopt_table[option_idx].val;
732
733 switch (short_option) {
734 case 'a':
735 m_delete_all = true;
736 break;
737 case 'w':
738 m_category = std::string(option_arg);
739 break;
740 case 'l':
742 break;
743 default:
744 llvm_unreachable("Unimplemented option");
745 }
746
747 return error;
748 }
749
750 void OptionParsingStarting(ExecutionContext *execution_context) override {
751 m_delete_all = false;
752 m_category = "default";
754 }
755
756 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
757 return llvm::ArrayRef(g_type_formatter_delete_options);
758 }
759
760 // Instance variables to hold the values for command options.
761
763 std::string m_category;
765 };
766
769
770 Options *GetOptions() override { return &m_options; }
771
772 static constexpr const char *g_short_help_template =
773 "Delete an existing %s for a type.";
774
775 static constexpr const char *g_long_help_template =
776 "Delete an existing %s for a type. Unless you specify a "
777 "specific category or all categories, only the "
778 "'default' category is searched. The names must be exactly as "
779 "shown in the 'type %s list' output";
780
781public:
783 FormatCategoryItem formatter_kind)
784 : CommandObjectParsed(interpreter,
785 FormatCategoryToString(formatter_kind, false)),
786 m_formatter_kind(formatter_kind) {
787 CommandArgumentEntry type_arg;
788 CommandArgumentData type_style_arg;
789
790 type_style_arg.arg_type = eArgTypeName;
791 type_style_arg.arg_repetition = eArgRepeatPlain;
792
793 type_arg.push_back(type_style_arg);
794
795 m_arguments.push_back(type_arg);
796
797 const char *kind = FormatCategoryToString(formatter_kind, true);
798 const char *short_kind = FormatCategoryToString(formatter_kind, false);
799
800 StreamString s;
802 SetHelp(s.GetData());
803 s.Clear();
804 s.Printf(g_long_help_template, kind, short_kind);
805 SetHelpLong(s.GetData());
806 s.Clear();
807 s.Printf("type %s delete", short_kind);
809 }
810
812
813 void
815 OptionElementVector &opt_element_vector) override {
816 if (request.GetCursorIndex())
817 return;
818
820 [this, &request](const lldb::TypeCategoryImplSP &category_sp) {
821 category_sp->AutoComplete(request, m_formatter_kind);
822 return true;
823 });
824 }
825
826protected:
827 virtual bool FormatterSpecificDeletion(ConstString typeCS) { return false; }
828
829 void DoExecute(Args &command, CommandReturnObject &result) override {
830 const size_t argc = command.GetArgumentCount();
831
832 if (argc != 1) {
833 result.AppendErrorWithFormat("%s takes 1 arg.\n", m_cmd_name.c_str());
834 return;
835 }
836
837 const char *typeA = command.GetArgumentAtIndex(0);
838 ConstString typeCS(typeA);
839
840 if (!typeCS) {
841 result.AppendError("empty typenames not allowed");
842 return;
843 }
844
847 [this, typeCS](const lldb::TypeCategoryImplSP &category_sp) -> bool {
848 category_sp->Delete(typeCS, m_formatter_kind);
849 return true;
850 });
852 return;
853 }
854
855 bool delete_category = false;
856 bool extra_deletion = false;
857
861 category);
862 if (category)
863 delete_category = category->Delete(typeCS, m_formatter_kind);
864 extra_deletion = FormatterSpecificDeletion(typeCS);
865 } else {
868 ConstString(m_options.m_category.c_str()), category);
869 if (category)
870 delete_category = category->Delete(typeCS, m_formatter_kind);
871 extra_deletion = FormatterSpecificDeletion(typeCS);
872 }
873
874 if (delete_category || extra_deletion) {
876 } else {
877 result.AppendErrorWithFormat("no custom formatter for %s.\n", typeA);
878 }
879 }
880};
881
882#define LLDB_OPTIONS_type_formatter_clear
883#include "CommandOptions.inc"
884
886private:
887 class CommandOptions : public Options {
888 public:
889 CommandOptions() = default;
890
891 ~CommandOptions() override = default;
892
893 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
894 ExecutionContext *execution_context) override {
896 const int short_option = m_getopt_table[option_idx].val;
897
898 switch (short_option) {
899 case 'a':
900 m_delete_all = true;
901 break;
902 default:
903 llvm_unreachable("Unimplemented option");
904 }
905
906 return error;
907 }
908
909 void OptionParsingStarting(ExecutionContext *execution_context) override {
910 m_delete_all = false;
911 }
912
913 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
914 return llvm::ArrayRef(g_type_formatter_clear_options);
915 }
916
917 // Instance variables to hold the values for command options.
919 };
920
923
924 Options *GetOptions() override { return &m_options; }
925
926public:
928 FormatCategoryItem formatter_kind,
929 const char *name, const char *help)
930 : CommandObjectParsed(interpreter, name, help, nullptr),
931 m_formatter_kind(formatter_kind) {
933 m_arguments.push_back({category_arg});
934 }
935
937
938protected:
940
941 void DoExecute(Args &command, CommandReturnObject &result) override {
944 [this](const TypeCategoryImplSP &category_sp) -> bool {
945 category_sp->Clear(m_formatter_kind);
946 return true;
947 });
948 } else {
950 if (command.GetArgumentCount() > 0) {
951 const char *cat_name = command.GetArgumentAtIndex(0);
952 ConstString cat_nameCS(cat_name);
953 DataVisualization::Categories::GetCategory(cat_nameCS, category);
954 } else {
956 category);
957 }
958 category->Clear(m_formatter_kind);
959 }
960
962
964 }
965};
966
967// CommandObjectTypeFormatDelete
968
970public:
973 interpreter, eFormatCategoryItemFormat) {}
974
975 ~CommandObjectTypeFormatDelete() override = default;
976};
977
978// CommandObjectTypeFormatClear
979
981public:
984 "type format clear",
985 "Delete all existing format styles.") {}
986};
987
988#define LLDB_OPTIONS_type_formatter_list
989#include "CommandOptions.inc"
990
991template <typename FormatterType>
993 typedef typename FormatterType::SharedPointer FormatterSharedPointer;
994
995 class CommandOptions : public Options {
996 public:
998 : Options(), m_category_regex("", ""),
1001
1002 ~CommandOptions() override = default;
1003
1004 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1005 ExecutionContext *execution_context) override {
1006 Status error;
1007 const int short_option = m_getopt_table[option_idx].val;
1008 switch (short_option) {
1009 case 'w':
1012 break;
1013 case 'l':
1015 if (error.Success())
1017 break;
1018 default:
1019 llvm_unreachable("Unimplemented option");
1020 }
1021
1022 return error;
1023 }
1024
1025 void OptionParsingStarting(ExecutionContext *execution_context) override {
1028 }
1029
1030 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1031 return llvm::ArrayRef(g_type_formatter_list_options);
1032 }
1033
1034 // Instance variables to hold the values for command options.
1035
1038 };
1039
1041
1042 Options *GetOptions() override { return &m_options; }
1043
1044public:
1046 const char *name, const char *help)
1047 : CommandObjectParsed(interpreter, name, help, nullptr), m_options() {
1048 CommandArgumentEntry type_arg;
1049 CommandArgumentData type_style_arg;
1050
1051 type_style_arg.arg_type = eArgTypeName;
1052 type_style_arg.arg_repetition = eArgRepeatOptional;
1053
1054 type_arg.push_back(type_style_arg);
1055
1056 m_arguments.push_back(type_arg);
1057 }
1058
1060
1061protected:
1063 return false;
1064 }
1065
1066 static bool ShouldListItem(llvm::StringRef s, RegularExpression *regex) {
1067 // If we have a regex, it can match two kinds of results:
1068 // - An item created with that same regex string (exact string match), so
1069 // the user can list it using the same string it used at creation time.
1070 // - Items that match the regex.
1071 // No regex means list everything.
1072 return regex == nullptr || s == regex->GetText() || regex->Execute(s);
1073 }
1074
1075 void DoExecute(Args &command, CommandReturnObject &result) override {
1076 const size_t argc = command.GetArgumentCount();
1077
1078 std::unique_ptr<RegularExpression> category_regex;
1079 std::unique_ptr<RegularExpression> formatter_regex;
1080
1082 category_regex = std::make_unique<RegularExpression>(
1084 if (!category_regex->IsValid()) {
1085 result.AppendErrorWithFormat(
1086 "syntax error in category regular expression '%s'",
1088 return;
1089 }
1090 }
1091
1092 if (argc == 1) {
1093 const char *arg = command.GetArgumentAtIndex(0);
1094 formatter_regex = std::make_unique<RegularExpression>(arg);
1095 if (!formatter_regex->IsValid()) {
1096 result.AppendErrorWithFormat("syntax error in regular expression '%s'",
1097 arg);
1098 return;
1099 }
1100 }
1101
1102 bool any_printed = false;
1103
1104 auto category_closure =
1105 [&result, &formatter_regex,
1106 &any_printed](const lldb::TypeCategoryImplSP &category) -> void {
1107 result.GetOutputStream().Printf(
1108 "-----------------------\nCategory: %s%s\n-----------------------\n",
1109 category->GetName(), category->IsEnabled() ? "" : " (disabled)");
1110
1112 [&result, &formatter_regex,
1113 &any_printed](const TypeMatcher &type_matcher,
1114 const FormatterSharedPointer &format_sp) -> bool {
1115 if (ShouldListItem(type_matcher.GetMatchString().GetStringRef(),
1116 formatter_regex.get())) {
1117 any_printed = true;
1118 result.GetOutputStream().Printf(
1119 "%s: %s\n", type_matcher.GetMatchString().GetCString(),
1120 format_sp->GetDescription().c_str());
1121 }
1122 return true;
1123 };
1124 category->ForEach(print_formatter);
1125 };
1126
1128 lldb::TypeCategoryImplSP category_sp;
1131 if (category_sp)
1132 category_closure(category_sp);
1133 } else {
1135 [&category_regex, &category_closure](
1136 const lldb::TypeCategoryImplSP &category) -> bool {
1137 if (ShouldListItem(category->GetName(), category_regex.get())) {
1138 category_closure(category);
1139 }
1140 return true;
1141 });
1142
1143 any_printed = FormatterSpecificList(result) | any_printed;
1144 }
1145
1146 if (any_printed)
1148 else {
1149 result.GetOutputStream().PutCString("no matching results found.\n");
1151 }
1152 }
1153};
1154
1155// CommandObjectTypeFormatList
1156
1158 : public CommandObjectTypeFormatterList<TypeFormatImpl> {
1159public:
1161 : CommandObjectTypeFormatterList(interpreter, "type format list",
1162 "Show a list of current formats.") {}
1163};
1164
1166 uint32_t option_idx, llvm::StringRef option_arg,
1167 ExecutionContext *execution_context) {
1168 Status error;
1169 const int short_option = m_getopt_table[option_idx].val;
1170 bool success;
1171
1172 switch (short_option) {
1173 case 'C':
1174 m_flags.SetCascades(OptionArgParser::ToBoolean(option_arg, true, &success));
1175 if (!success)
1176 error.SetErrorStringWithFormat("invalid value for cascade: %s",
1177 option_arg.str().c_str());
1178 break;
1179 case 'e':
1181 break;
1182 case 'h':
1184 break;
1185 case 'v':
1187 break;
1188 case 'c':
1190 break;
1191 case 's':
1192 m_format_string = std::string(option_arg);
1193 break;
1194 case 'p':
1196 break;
1197 case 'r':
1199 break;
1200 case 'x':
1202 error.SetErrorString(
1203 "can't use --regex and --recognizer-function at the same time");
1204 else
1206 break;
1207 case '\x01':
1209 error.SetErrorString(
1210 "can't use --regex and --recognizer-function at the same time");
1211 else
1213 break;
1214 case 'n':
1215 m_name.SetString(option_arg);
1216 break;
1217 case 'o':
1218 m_python_script = std::string(option_arg);
1219 m_is_add_script = true;
1220 break;
1221 case 'F':
1222 m_python_function = std::string(option_arg);
1223 m_is_add_script = true;
1224 break;
1225 case 'P':
1226 m_is_add_script = true;
1227 break;
1228 case 'w':
1229 m_category = std::string(option_arg);
1230 break;
1231 case 'O':
1233 break;
1234 default:
1235 llvm_unreachable("Unimplemented option");
1236 }
1237
1238 return error;
1239}
1240
1242 ExecutionContext *execution_context) {
1243 m_flags.Clear().SetCascades().SetDontShowChildren().SetDontShowValue(false);
1244 m_flags.SetShowMembersOneLiner(false)
1245 .SetSkipPointers(false)
1246 .SetSkipReferences(false)
1247 .SetHideItemNames(false);
1248
1249 m_match_type = eFormatterMatchExact;
1250 m_name.Clear();
1251 m_python_script = "";
1252 m_python_function = "";
1253 m_format_string = "";
1254 m_is_add_script = false;
1255 m_category = "default";
1256}
1257
1258#if LLDB_ENABLE_PYTHON
1259
1261 Args &command, CommandReturnObject &result) {
1262 const size_t argc = command.GetArgumentCount();
1263
1264 if (argc < 1 && !m_options.m_name) {
1265 result.AppendErrorWithFormat("%s takes one or more args.\n",
1266 m_cmd_name.c_str());
1267 return false;
1268 }
1269
1270 TypeSummaryImplSP script_format;
1271
1273 .empty()) // we have a Python function ready to use
1274 {
1275 const char *funct_name = m_options.m_python_function.c_str();
1276 if (!funct_name || !funct_name[0]) {
1277 result.AppendError("function name empty.\n");
1278 return false;
1279 }
1280
1281 std::string code =
1282 (" " + m_options.m_python_function + "(valobj,internal_dict)");
1283
1284 script_format = std::make_shared<ScriptSummaryFormat>(
1285 m_options.m_flags, funct_name, code.c_str());
1286
1288
1289 if (interpreter && !interpreter->CheckObjectExists(funct_name))
1291 "The provided function \"%s\" does not exist - "
1292 "please define it before attempting to use this summary.\n",
1293 funct_name);
1294 } else if (!m_options.m_python_script
1295 .empty()) // we have a quick 1-line script, just use it
1296 {
1298 if (!interpreter) {
1299 result.AppendError("script interpreter missing - unable to generate "
1300 "function wrapper.\n");
1301 return false;
1302 }
1303 StringList funct_sl;
1304 funct_sl << m_options.m_python_script.c_str();
1305 std::string funct_name_str;
1306 if (!interpreter->GenerateTypeScriptFunction(funct_sl, funct_name_str)) {
1307 result.AppendError("unable to generate function wrapper.\n");
1308 return false;
1309 }
1310 if (funct_name_str.empty()) {
1311 result.AppendError(
1312 "script interpreter failed to generate a valid function name.\n");
1313 return false;
1314 }
1315
1316 std::string code = " " + m_options.m_python_script;
1317
1318 script_format = std::make_shared<ScriptSummaryFormat>(
1319 m_options.m_flags, funct_name_str.c_str(), code.c_str());
1320 } else {
1321 // Use an IOHandler to grab Python code from the user
1322 auto options = std::make_unique<ScriptAddOptions>(
1325
1326 for (auto &entry : command.entries()) {
1327 if (entry.ref().empty()) {
1328 result.AppendError("empty typenames not allowed");
1329 return false;
1330 }
1331
1332 options->m_target_types << std::string(entry.ref());
1333 }
1334
1336 " ", // Prompt
1337 *this, // IOHandlerDelegate
1338 options.release()); // Baton for the "io_handler" that will be passed
1339 // back into our IOHandlerDelegate functions
1341
1342 return result.Succeeded();
1343 }
1344
1345 // if I am here, script_format must point to something good, so I can add
1346 // that as a script summary to all interested parties
1347
1348 Status error;
1349
1350 for (auto &entry : command.entries()) {
1351 AddSummary(ConstString(entry.ref()), script_format, m_options.m_match_type,
1353 if (error.Fail()) {
1354 result.AppendError(error.AsCString());
1355 return false;
1356 }
1357 }
1358
1359 if (m_options.m_name) {
1360 AddNamedSummary(m_options.m_name, script_format, &error);
1361 if (error.Fail()) {
1362 result.AppendError(error.AsCString());
1363 result.AppendError("added to types, but not given a name");
1364 return false;
1365 }
1366 }
1367
1368 return result.Succeeded();
1369}
1370
1371#endif
1372
1374 Args &command, CommandReturnObject &result) {
1375 const size_t argc = command.GetArgumentCount();
1376
1377 if (argc < 1 && !m_options.m_name) {
1378 result.AppendErrorWithFormat("%s takes one or more args.\n",
1379 m_cmd_name.c_str());
1380 return false;
1381 }
1382
1384 m_options.m_format_string.empty()) {
1385 result.AppendError("empty summary strings not allowed");
1386 return false;
1387 }
1388
1389 const char *format_cstr = (m_options.m_flags.GetShowMembersOneLiner()
1390 ? ""
1391 : m_options.m_format_string.c_str());
1392
1393 // ${var%S} is an endless recursion, prevent it
1394 if (strcmp(format_cstr, "${var%S}") == 0) {
1395 result.AppendError("recursive summary not allowed");
1396 return false;
1397 }
1398
1399 std::unique_ptr<StringSummaryFormat> string_format(
1400 new StringSummaryFormat(m_options.m_flags, format_cstr));
1401 if (!string_format) {
1402 result.AppendError("summary creation failed");
1403 return false;
1404 }
1405 if (string_format->m_error.Fail()) {
1406 result.AppendErrorWithFormat("syntax error: %s",
1407 string_format->m_error.AsCString("<unknown>"));
1408 return false;
1409 }
1410 lldb::TypeSummaryImplSP entry(string_format.release());
1411
1412 // now I have a valid format, let's add it to every type
1413 Status error;
1414 for (auto &arg_entry : command.entries()) {
1415 if (arg_entry.ref().empty()) {
1416 result.AppendError("empty typenames not allowed");
1417 return false;
1418 }
1419 ConstString typeCS(arg_entry.ref());
1420
1422 &error);
1423
1424 if (error.Fail()) {
1425 result.AppendError(error.AsCString());
1426 return false;
1427 }
1428 }
1429
1430 if (m_options.m_name) {
1432 if (error.Fail()) {
1433 result.AppendError(error.AsCString());
1434 result.AppendError("added to types, but not given a name");
1435 return false;
1436 }
1437 }
1438
1440 return result.Succeeded();
1441}
1442
1444 CommandInterpreter &interpreter)
1445 : CommandObjectParsed(interpreter, "type summary add",
1446 "Add a new summary style for a type.", nullptr),
1447 IOHandlerDelegateMultiline("DONE"), m_options(interpreter) {
1448 CommandArgumentEntry type_arg;
1449 CommandArgumentData type_style_arg;
1450
1451 type_style_arg.arg_type = eArgTypeName;
1452 type_style_arg.arg_repetition = eArgRepeatPlus;
1453
1454 type_arg.push_back(type_style_arg);
1455
1456 m_arguments.push_back(type_arg);
1457
1459 R"(
1460The following examples of 'type summary add' refer to this code snippet for context:
1461
1462 struct JustADemo
1463 {
1464 int* ptr;
1465 float value;
1466 JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}
1467 };
1468 JustADemo demo_instance(42, 3.14);
1469
1470 typedef JustADemo NewDemo;
1471 NewDemo new_demo_instance(42, 3.14);
1472
1473(lldb) type summary add --summary-string "the answer is ${*var.ptr}" JustADemo
1474
1475 Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42"
1476
1477(lldb) type summary add --summary-string "the answer is ${*var.ptr}, and the question is ${var.value}" JustADemo
1478
1479 Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42 and the question is 3.14"
1480
1481)"
1482 "Alternatively, you could define formatting for all pointers to integers and \
1483rely on that when formatting JustADemo to obtain the same result:"
1484 R"(
1485
1486(lldb) type summary add --summary-string "${var%V} -> ${*var}" "int *"
1487(lldb) type summary add --summary-string "the answer is ${var.ptr}, and the question is ${var.value}" JustADemo
1489)"
1490 "Type summaries are automatically applied to derived typedefs, so the examples \
1491above apply to both JustADemo and NewDemo. The cascade option can be used to \
1492suppress this behavior:"
1493 R"(
1494
1495(lldb) type summary add --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo -C no
1496
1497 The summary will now be used for values of JustADemo but not NewDemo.
1498
1499)"
1500 "By default summaries are shown for pointers and references to values of the \
1501specified type. To suppress formatting for pointers use the -p option, or apply \
1502the corresponding -r option to suppress formatting for references:"
1503 R"(
1505(lldb) type summary add -p -r --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo
1506
1507)"
1508 "One-line summaries including all fields in a type can be inferred without supplying an \
1509explicit summary string by passing the -c option:"
1510 R"(
1511
1512(lldb) type summary add -c JustADemo
1513(lldb) frame variable demo_instance
1514(ptr=<address>, value=3.14)
1515
1516)"
1517 "Type summaries normally suppress the nested display of individual fields. To \
1518supply a summary to supplement the default structure add the -e option:"
1519 R"(
1521(lldb) type summary add -e --summary-string "*ptr = ${*var.ptr}" JustADemo
1522
1523)"
1524 "Now when displaying JustADemo values the int* is displayed, followed by the \
1525standard LLDB sequence of children, one per line:"
1526 R"(
1527
1528*ptr = 42 {
1529 ptr = <address>
1530 value = 3.14
1531}
1532
1533)"
1534 "You can also add summaries written in Python. These scripts use lldb public API to \
1535gather information from your variables and produce a meaningful summary. To start a \
1536multi-line script use the -P option. The function declaration will be displayed along with \
1537a comment describing the two arguments. End your script with the word 'DONE' on a line by \
1538itself:"
1539 R"(
1540
1541(lldb) type summary add JustADemo -P
1542def function (valobj,internal_dict): """valobj: an SBValue which you want to provide a summary for
1543internal_dict: an LLDB support object not to be used"""
1544 value = valobj.GetChildMemberWithName('value');
1545 return 'My value is ' + value.GetValue();
1546 DONE
1547
1548Alternatively, the -o option can be used when providing a simple one-line Python script:
1549
1550(lldb) type summary add JustADemo -o "value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();")");
1551}
1552
1554 CommandReturnObject &result) {
1555 WarnOnPotentialUnquotedUnsignedType(command, result);
1556
1558#if LLDB_ENABLE_PYTHON
1559 Execute_ScriptSummary(command, result);
1560#else
1561 result.AppendError("python is disabled");
1562#endif
1563 return;
1564 }
1565
1566 Execute_StringSummary(command, result);
1567}
1568
1569static bool FixArrayTypeNameWithRegex(ConstString &type_name) {
1570 llvm::StringRef type_name_ref(type_name.GetStringRef());
1571
1572 if (type_name_ref.endswith("[]")) {
1573 std::string type_name_str(type_name.GetCString());
1574 type_name_str.resize(type_name_str.length() - 2);
1575 if (type_name_str.back() != ' ')
1576 type_name_str.append(" ?\\[[0-9]+\\]");
1577 else
1578 type_name_str.append("\\[[0-9]+\\]");
1579 type_name.SetCString(type_name_str.c_str());
1580 return true;
1581 }
1582 return false;
1583}
1584
1587 Status *error) {
1588 // system named summaries do not exist (yet?)
1590 return true;
1591}
1592
1595 FormatterMatchType match_type,
1596 std::string category_name,
1597 Status *error) {
1598 lldb::TypeCategoryImplSP category;
1600 category);
1602 if (match_type == eFormatterMatchExact) {
1603 if (FixArrayTypeNameWithRegex(type_name))
1605 }
1606
1607 if (match_type == eFormatterMatchRegex) {
1608 match_type = eFormatterMatchRegex;
1609 RegularExpression typeRX(type_name.GetStringRef());
1610 if (!typeRX.IsValid()) {
1611 if (error)
1612 error->SetErrorString(
1613 "regex format error (maybe this is not really a regex?)");
1614 return false;
1615 }
1616 }
1617
1618 if (match_type == eFormatterMatchCallback) {
1619 const char *function_name = type_name.AsCString();
1621 if (interpreter && !interpreter->CheckObjectExists(function_name)) {
1622 error->SetErrorStringWithFormat(
1623 "The provided recognizer function \"%s\" does not exist - "
1624 "please define it before attempting to use this summary.\n",
1625 function_name);
1626 return false;
1628 }
1629 category->AddTypeSummary(type_name.GetStringRef(), match_type, entry);
1630 return true;
1632
1633// CommandObjectTypeSummaryDelete
1634
1636public:
1640
1641 ~CommandObjectTypeSummaryDelete() override = default;
1642
1643protected:
1644 bool FormatterSpecificDeletion(ConstString typeCS) override {
1646 return false;
1648 }
1649};
1650
1652public:
1655 "type summary clear",
1656 "Delete all existing summaries.") {}
1657
1658protected:
1659 void FormatterSpecificDeletion() override {
1661 }
1662};
1664// CommandObjectTypeSummaryList
1665
1667 : public CommandObjectTypeFormatterList<TypeSummaryImpl> {
1668public:
1670 : CommandObjectTypeFormatterList(interpreter, "type summary list",
1671 "Show a list of current summaries.") {}
1672
1673protected:
1674 bool FormatterSpecificList(CommandReturnObject &result) override {
1676 result.GetOutputStream().Printf("Named summaries:\n");
1678 [&result](const TypeMatcher &type_matcher,
1679 const TypeSummaryImplSP &summary_sp) -> bool {
1680 result.GetOutputStream().Printf(
1681 "%s: %s\n", type_matcher.GetMatchString().GetCString(),
1682 summary_sp->GetDescription().c_str());
1683 return true;
1684 });
1685 return true;
1686 }
1687 return false;
1688 }
1689};
1690
1691// CommandObjectTypeCategoryDefine
1692#define LLDB_OPTIONS_type_category_define
1693#include "CommandOptions.inc"
1694
1696 class CommandOptions : public Options {
1697 public:
1699 : m_define_enabled(false, false),
1701
1702 ~CommandOptions() override = default;
1703
1704 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1705 ExecutionContext *execution_context) override {
1706 Status error;
1707 const int short_option = m_getopt_table[option_idx].val;
1708
1709 switch (short_option) {
1710 case 'e':
1711 m_define_enabled.SetValueFromString(llvm::StringRef("true"));
1712 break;
1713 case 'l':
1715 break;
1716 default:
1717 llvm_unreachable("Unimplemented option");
1718 }
1719
1720 return error;
1721 }
1722
1723 void OptionParsingStarting(ExecutionContext *execution_context) override {
1726 }
1727
1728 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1729 return llvm::ArrayRef(g_type_category_define_options);
1731
1732 // Instance variables to hold the values for command options.
1737
1739
1740 Options *GetOptions() override { return &m_options; }
1741
1742public:
1744 : CommandObjectParsed(interpreter, "type category define",
1745 "Define a new category as a source of formatters.",
1746 nullptr) {
1747 CommandArgumentEntry type_arg;
1748 CommandArgumentData type_style_arg;
1749
1750 type_style_arg.arg_type = eArgTypeName;
1751 type_style_arg.arg_repetition = eArgRepeatPlus;
1752
1753 type_arg.push_back(type_style_arg);
1754
1755 m_arguments.push_back(type_arg);
1756 }
1757
1758 ~CommandObjectTypeCategoryDefine() override = default;
1759
1760 void
1762 OptionElementVector &opt_element_vector) override {
1765 nullptr);
1766 }
1767
1768protected:
1769 void DoExecute(Args &command, CommandReturnObject &result) override {
1770 const size_t argc = command.GetArgumentCount();
1772 if (argc < 1) {
1773 result.AppendErrorWithFormat("%s takes 1 or more args.\n",
1774 m_cmd_name.c_str());
1775 return;
1777
1778 for (auto &entry : command.entries()) {
1781 category_sp) &&
1782 category_sp) {
1783 category_sp->AddLanguage(m_options.m_cate_language.GetCurrentValue());
1787 }
1788 }
1789
1791 }
1792};
1793
1794// CommandObjectTypeCategoryEnable
1795#define LLDB_OPTIONS_type_category_enable
1796#include "CommandOptions.inc"
1799 class CommandOptions : public Options {
1800 public:
1801 CommandOptions() = default;
1802
1803 ~CommandOptions() override = default;
1804
1805 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1806 ExecutionContext *execution_context) override {
1807 Status error;
1808 const int short_option = m_getopt_table[option_idx].val;
1809
1810 switch (short_option) {
1811 case 'l':
1812 if (!option_arg.empty()) {
1815 error.SetErrorStringWithFormat("unrecognized language '%s'",
1816 option_arg.str().c_str());
1817 }
1818 break;
1819 default:
1820 llvm_unreachable("Unimplemented option");
1821 }
1822
1823 return error;
1824 }
1825
1826 void OptionParsingStarting(ExecutionContext *execution_context) override {
1828 }
1829
1830 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1831 return llvm::ArrayRef(g_type_category_enable_options);
1832 }
1833
1834 // Instance variables to hold the values for command options.
1835
1837 };
1838
1839 CommandOptions m_options;
1840
1841 Options *GetOptions() override { return &m_options; }
1842
1843public:
1845 : CommandObjectParsed(interpreter, "type category enable",
1846 "Enable a category as a source of formatters.",
1847 nullptr) {
1848 CommandArgumentEntry type_arg;
1849 CommandArgumentData type_style_arg;
1850
1851 type_style_arg.arg_type = eArgTypeName;
1852 type_style_arg.arg_repetition = eArgRepeatPlus;
1853
1854 type_arg.push_back(type_style_arg);
1855
1856 m_arguments.push_back(type_arg);
1857 }
1858
1859 ~CommandObjectTypeCategoryEnable() override = default;
1860
1861 void
1863 OptionElementVector &opt_element_vector) override {
1866 nullptr);
1867 }
1868
1869protected:
1870 void DoExecute(Args &command, CommandReturnObject &result) override {
1871 const size_t argc = command.GetArgumentCount();
1873 if (argc < 1 && m_options.m_language == lldb::eLanguageTypeUnknown) {
1874 result.AppendErrorWithFormat("%s takes arguments and/or a language",
1875 m_cmd_name.c_str());
1876 return;
1877 }
1878
1879 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0), "*") == 0) {
1881 } else if (argc > 0) {
1882 for (int i = argc - 1; i >= 0; i--) {
1883 const char *typeA = command.GetArgumentAtIndex(i);
1884 ConstString typeCS(typeA);
1885
1886 if (!typeCS) {
1887 result.AppendError("empty category name not allowed");
1888 return;
1889 }
1892 if (DataVisualization::Categories::GetCategory(typeCS, cate) && cate) {
1893 if (cate->GetCount() == 0) {
1894 result.AppendWarning("empty category enabled (typo?)");
1895 }
1896 }
1897 }
1898 }
1899
1902
1905};
1906
1907// CommandObjectTypeCategoryDelete
1910public:
1912 : CommandObjectParsed(interpreter, "type category delete",
1913 "Delete a category and all associated formatters.",
1914 nullptr) {
1915 CommandArgumentEntry type_arg;
1916 CommandArgumentData type_style_arg;
1917
1918 type_style_arg.arg_type = eArgTypeName;
1919 type_style_arg.arg_repetition = eArgRepeatPlus;
1920
1921 type_arg.push_back(type_style_arg);
1922
1923 m_arguments.push_back(type_arg);
1924 }
1925
1926 ~CommandObjectTypeCategoryDelete() override = default;
1927
1928 void
1930 OptionElementVector &opt_element_vector) override {
1933 nullptr);
1934 }
1936protected:
1937 void DoExecute(Args &command, CommandReturnObject &result) override {
1938 const size_t argc = command.GetArgumentCount();
1940 if (argc < 1) {
1941 result.AppendErrorWithFormat("%s takes 1 or more arg.\n",
1942 m_cmd_name.c_str());
1943 return;
1944 }
1946 bool success = true;
1947
1948 // the order is not relevant here
1949 for (int i = argc - 1; i >= 0; i--) {
1950 const char *typeA = command.GetArgumentAtIndex(i);
1951 ConstString typeCS(typeA);
1952
1953 if (!typeCS) {
1954 result.AppendError("empty category name not allowed");
1955 return;
1956 }
1958 success = false; // keep deleting even if we hit an error
1959 }
1960 if (success) {
1962 } else {
1963 result.AppendError("cannot delete one or more categories\n");
1964 }
1965 }
1966};
1967
1968// CommandObjectTypeCategoryDisable
1969#define LLDB_OPTIONS_type_category_disable
1970#include "CommandOptions.inc"
1973 class CommandOptions : public Options {
1974 public:
1975 CommandOptions() = default;
1976
1977 ~CommandOptions() override = default;
1978
1979 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1980 ExecutionContext *execution_context) override {
1981 Status error;
1982 const int short_option = m_getopt_table[option_idx].val;
1983
1984 switch (short_option) {
1985 case 'l':
1986 if (!option_arg.empty()) {
1989 error.SetErrorStringWithFormat("unrecognized language '%s'",
1990 option_arg.str().c_str());
1991 }
1992 break;
1993 default:
1994 llvm_unreachable("Unimplemented option");
1995 }
1996
1997 return error;
1998 }
1999
2000 void OptionParsingStarting(ExecutionContext *execution_context) override {
2002 }
2003
2004 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2005 return llvm::ArrayRef(g_type_category_disable_options);
2006 }
2007
2008 // Instance variables to hold the values for command options.
2009
2011 };
2012
2013 CommandOptions m_options;
2014
2015 Options *GetOptions() override { return &m_options; }
2016
2017public:
2019 : CommandObjectParsed(interpreter, "type category disable",
2020 "Disable a category as a source of formatters.",
2021 nullptr) {
2022 CommandArgumentEntry type_arg;
2023 CommandArgumentData type_style_arg;
2024
2025 type_style_arg.arg_type = eArgTypeName;
2026 type_style_arg.arg_repetition = eArgRepeatPlus;
2027
2028 type_arg.push_back(type_style_arg);
2029
2030 m_arguments.push_back(type_arg);
2031 }
2032
2034
2035 void
2037 OptionElementVector &opt_element_vector) override {
2040 nullptr);
2041 }
2042
2043protected:
2044 void DoExecute(Args &command, CommandReturnObject &result) override {
2045 const size_t argc = command.GetArgumentCount();
2046
2047 if (argc < 1 && m_options.m_language == lldb::eLanguageTypeUnknown) {
2048 result.AppendErrorWithFormat("%s takes arguments and/or a language",
2049 m_cmd_name.c_str());
2050 return;
2051 }
2052
2053 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0), "*") == 0) {
2055 } else if (argc > 0) {
2056 // the order is not relevant here
2057 for (int i = argc - 1; i >= 0; i--) {
2058 const char *typeA = command.GetArgumentAtIndex(i);
2059 ConstString typeCS(typeA);
2060
2061 if (!typeCS) {
2062 result.AppendError("empty category name not allowed");
2063 return;
2064 }
2066 }
2067 }
2068
2071
2073 }
2074};
2075
2076// CommandObjectTypeCategoryList
2077
2079public:
2081 : CommandObjectParsed(interpreter, "type category list",
2082 "Provide a list of all existing categories.",
2083 nullptr) {
2084 CommandArgumentEntry type_arg;
2085 CommandArgumentData type_style_arg;
2086
2087 type_style_arg.arg_type = eArgTypeName;
2088 type_style_arg.arg_repetition = eArgRepeatOptional;
2089
2090 type_arg.push_back(type_style_arg);
2092 m_arguments.push_back(type_arg);
2093 }
2094
2095 ~CommandObjectTypeCategoryList() override = default;
2096
2097 void
2099 OptionElementVector &opt_element_vector) override {
2100 if (request.GetCursorIndex())
2101 return;
2104 nullptr);
2105 }
2106
2107protected:
2108 void DoExecute(Args &command, CommandReturnObject &result) override {
2109 const size_t argc = command.GetArgumentCount();
2110
2111 std::unique_ptr<RegularExpression> regex;
2112
2113 if (argc == 1) {
2114 const char *arg = command.GetArgumentAtIndex(0);
2115 regex = std::make_unique<RegularExpression>(arg);
2116 if (!regex->IsValid()) {
2117 result.AppendErrorWithFormat(
2118 "syntax error in category regular expression '%s'", arg);
2119 return;
2121 } else if (argc != 0) {
2122 result.AppendErrorWithFormat("%s takes 0 or one arg.\n",
2123 m_cmd_name.c_str());
2124 return;
2125 }
2128 [&regex, &result](const lldb::TypeCategoryImplSP &category_sp) -> bool {
2129 if (regex) {
2130 bool escape = true;
2131 if (regex->GetText() == category_sp->GetName()) {
2132 escape = false;
2133 } else if (regex->Execute(category_sp->GetName())) {
2134 escape = false;
2135 }
2136
2137 if (escape)
2138 return true;
2139 }
2140
2141 result.GetOutputStream().Printf(
2142 "Category: %s\n", category_sp->GetDescription().c_str());
2143
2144 return true;
2145 });
2146
2148 }
2149};
2151// CommandObjectTypeFilterList
2152
2154 : public CommandObjectTypeFormatterList<TypeFilterImpl> {
2155public:
2157 : CommandObjectTypeFormatterList(interpreter, "type filter list",
2158 "Show a list of current filters.") {}
2159};
2160
2161// CommandObjectTypeSynthList
2162
2164 : public CommandObjectTypeFormatterList<SyntheticChildren> {
2165public:
2168 interpreter, "type synthetic list",
2169 "Show a list of current synthetic providers.") {}
2170};
2171
2172// CommandObjectTypeFilterDelete
2173
2175public:
2178 interpreter, eFormatCategoryItemFilter) {}
2179
2180 ~CommandObjectTypeFilterDelete() override = default;
2181};
2182
2183// CommandObjectTypeSynthDelete
2184
2186public:
2189 interpreter, eFormatCategoryItemSynth) {}
2190
2191 ~CommandObjectTypeSynthDelete() override = default;
2192};
2193
2194
2195// CommandObjectTypeFilterClear
2196
2198public:
2201 "type filter clear",
2202 "Delete all existing filter.") {}
2203};
2204
2205// CommandObjectTypeSynthClear
2206
2208public:
2211 interpreter, eFormatCategoryItemSynth, "type synthetic clear",
2212 "Delete all existing synthetic providers.") {}
2213};
2214
2216 Args &command, CommandReturnObject &result) {
2217 auto options = std::make_unique<SynthAddOptions>(
2220
2221 for (auto &entry : command.entries()) {
2222 if (entry.ref().empty()) {
2223 result.AppendError("empty typenames not allowed");
2224 return false;
2225 }
2226
2227 options->m_target_types << std::string(entry.ref());
2228 }
2229
2231 " ", // Prompt
2232 *this, // IOHandlerDelegate
2233 options.release()); // Baton for the "io_handler" that will be passed back
2234 // into our IOHandlerDelegate functions
2236 return result.Succeeded();
2237}
2238
2240 Args &command, CommandReturnObject &result) {
2241 const size_t argc = command.GetArgumentCount();
2242
2243 if (argc < 1) {
2244 result.AppendErrorWithFormat("%s takes one or more args.\n",
2245 m_cmd_name.c_str());
2246 return false;
2247 }
2248
2250 result.AppendErrorWithFormat("%s needs either a Python class name or -P to "
2251 "directly input Python code.\n",
2252 m_cmd_name.c_str());
2253 return false;
2254 }
2255
2256 SyntheticChildrenSP entry;
2257
2260 .SetCascades(m_options.m_cascade)
2263 m_options.m_class_name.c_str());
2264
2265 entry.reset(impl);
2266
2268
2269 if (interpreter &&
2270 !interpreter->CheckObjectExists(impl->GetPythonClassName()))
2271 result.AppendWarning("The provided class does not exist - please define it "
2272 "before attempting to use this synthetic provider");
2273
2274 // now I have a valid provider, let's add it to every type
2275
2276 lldb::TypeCategoryImplSP category;
2278 ConstString(m_options.m_category.c_str()), category);
2279
2280 Status error;
2281
2282 for (auto &arg_entry : command.entries()) {
2283 if (arg_entry.ref().empty()) {
2284 result.AppendError("empty typenames not allowed");
2285 return false;
2286 }
2287
2288 ConstString typeCS(arg_entry.ref());
2289 if (!AddSynth(typeCS, entry, m_options.m_match_type, m_options.m_category,
2290 &error)) {
2291 result.AppendError(error.AsCString());
2292 return false;
2293 }
2294 }
2295
2297 return result.Succeeded();
2298}
2299
2301 CommandInterpreter &interpreter)
2302 : CommandObjectParsed(interpreter, "type synthetic add",
2303 "Add a new synthetic provider for a type.", nullptr),
2304 IOHandlerDelegateMultiline("DONE"), m_options() {
2305 CommandArgumentEntry type_arg;
2306 CommandArgumentData type_style_arg;
2307
2308 type_style_arg.arg_type = eArgTypeName;
2309 type_style_arg.arg_repetition = eArgRepeatPlus;
2311 type_arg.push_back(type_style_arg);
2312
2313 m_arguments.push_back(type_arg);
2314}
2317 SyntheticChildrenSP entry,
2318 FormatterMatchType match_type,
2319 std::string category_name,
2320 Status *error) {
2323 category);
2324
2325 if (match_type == eFormatterMatchExact) {
2326 if (FixArrayTypeNameWithRegex(type_name))
2327 match_type = eFormatterMatchRegex;
2328 }
2329
2330 // Only check for conflicting filters in the same category if `type_name` is
2331 // an actual type name. Matching a regex string against registered regexes
2332 // doesn't work.
2333 if (match_type == eFormatterMatchExact) {
2334 // It's not generally possible to get a type object here. For example, this
2335 // command can be run before loading any binaries. Do just a best-effort
2336 // name-based lookup here to try to prevent conflicts.
2337 FormattersMatchCandidate candidate_type(type_name, nullptr, TypeImpl(),
2339 if (category->AnyMatches(candidate_type, eFormatCategoryItemFilter,
2340 false)) {
2341 if (error)
2342 error->SetErrorStringWithFormat("cannot add synthetic for type %s when "
2343 "filter is defined in same category!",
2344 type_name.AsCString());
2345 return false;
2346 }
2347 }
2348
2349 if (match_type == eFormatterMatchRegex) {
2350 RegularExpression typeRX(type_name.GetStringRef());
2351 if (!typeRX.IsValid()) {
2352 if (error)
2353 error->SetErrorString(
2354 "regex format error (maybe this is not really a regex?)");
2355 return false;
2356 }
2357 }
2358
2359 if (match_type == eFormatterMatchCallback) {
2360 const char *function_name = type_name.AsCString();
2362 if (interpreter && !interpreter->CheckObjectExists(function_name)) {
2363 error->SetErrorStringWithFormat(
2364 "The provided recognizer function \"%s\" does not exist - "
2365 "please define it before attempting to use this summary.\n",
2366 function_name);
2367 return false;
2368 }
2370
2371 category->AddTypeSynthetic(type_name.GetStringRef(), match_type, entry);
2372 return true;
2373}
2374
2375#define LLDB_OPTIONS_type_filter_add
2376#include "CommandOptions.inc"
2379private:
2380 class CommandOptions : public Options {
2381 typedef std::vector<std::string> option_vector;
2383 public:
2384 CommandOptions() = default;
2385
2386 ~CommandOptions() override = default;
2388 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2389 ExecutionContext *execution_context) override {
2390 Status error;
2391 const int short_option = m_getopt_table[option_idx].val;
2392 bool success;
2394 switch (short_option) {
2395 case 'C':
2396 m_cascade = OptionArgParser::ToBoolean(option_arg, true, &success);
2397 if (!success)
2398 error.SetErrorStringWithFormat("invalid value for cascade: %s",
2399 option_arg.str().c_str());
2400 break;
2401 case 'c':
2402 m_expr_paths.push_back(std::string(option_arg));
2403 has_child_list = true;
2404 break;
2405 case 'p':
2406 m_skip_pointers = true;
2407 break;
2408 case 'r':
2409 m_skip_references = true;
2410 break;
2411 case 'w':
2412 m_category = std::string(option_arg);
2413 break;
2414 case 'x':
2415 m_regex = true;
2416 break;
2417 default:
2418 llvm_unreachable("Unimplemented option");
2419 }
2420
2421 return error;
2422 }
2423
2424 void OptionParsingStarting(ExecutionContext *execution_context) override {
2425 m_cascade = true;
2426 m_skip_pointers = false;
2427 m_skip_references = false;
2428 m_category = "default";
2429 m_expr_paths.clear();
2430 has_child_list = false;
2431 m_regex = false;
2432 }
2433
2434 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2435 return llvm::ArrayRef(g_type_filter_add_options);
2436 }
2437
2438 // Instance variables to hold the values for command options.
2439
2440 bool m_cascade;
2441 bool m_skip_references;
2443 bool m_input_python;
2445 std::string m_category;
2446 bool has_child_list;
2447 bool m_regex;
2448
2449 typedef option_vector::iterator ExpressionPathsIterator;
2450 };
2451
2452 CommandOptions m_options;
2453
2454 Options *GetOptions() override { return &m_options; }
2455
2457
2458 bool AddFilter(ConstString type_name, TypeFilterImplSP entry,
2459 FilterFormatType type, std::string category_name,
2460 Status *error) {
2461 lldb::TypeCategoryImplSP category;
2463 ConstString(category_name.c_str()), category);
2464
2465 if (type == eRegularFilter) {
2466 if (FixArrayTypeNameWithRegex(type_name))
2467 type = eRegexFilter;
2469
2470 // Only check for conflicting synthetic child providers in the same category
2471 // if `type_name` is an actual type name. Matching a regex string against
2472 // registered regexes doesn't work.
2473 if (type == eRegularFilter) {
2474 // It's not generally possible to get a type object here. For example,
2475 // this command can be run before loading any binaries. Do just a
2476 // best-effort name-based lookup here to try to prevent conflicts.
2477 FormattersMatchCandidate candidate_type(
2478 type_name, nullptr, TypeImpl(), FormattersMatchCandidate::Flags());
2480 if (category->AnyMatches(candidate_type, eFormatCategoryItemSynth,
2481 false)) {
2482 if (error)
2483 error->SetErrorStringWithFormat("cannot add filter for type %s when "
2484 "synthetic is defined in same "
2485 "category!",
2486 type_name.AsCString());
2487 return false;
2488 }
2489 }
2490
2492 if (type == eRegexFilter) {
2493 match_type = eFormatterMatchRegex;
2494 RegularExpression typeRX(type_name.GetStringRef());
2495 if (!typeRX.IsValid()) {
2496 if (error)
2497 error->SetErrorString(
2498 "regex format error (maybe this is not really a regex?)");
2499 return false;
2500 }
2501 }
2502 category->AddTypeFilter(type_name.GetStringRef(), match_type, entry);
2503 return true;
2504 }
2505
2506public:
2508 : CommandObjectParsed(interpreter, "type filter add",
2509 "Add a new filter for a type.", nullptr) {
2510 CommandArgumentEntry type_arg;
2511 CommandArgumentData type_style_arg;
2512
2513 type_style_arg.arg_type = eArgTypeName;
2514 type_style_arg.arg_repetition = eArgRepeatPlus;
2515
2516 type_arg.push_back(type_style_arg);
2517
2518 m_arguments.push_back(type_arg);
2519
2521 R"(
2522The following examples of 'type filter add' refer to this code snippet for context:
2523
2524 class Foo {
2525 int a;
2526 int b;
2527 int c;
2528 int d;
2529 int e;
2530 int f;
2531 int g;
2532 int h;
2533 int i;
2534 }
2535 Foo my_foo;
2536
2537Adding a simple filter:
2538
2539(lldb) type filter add --child a --child g Foo
2540(lldb) frame variable my_foo
2541
2542)"
2543 "Produces output where only a and g are displayed. Other children of my_foo \
2544(b, c, d, e, f, h and i) are available by asking for them explicitly:"
2545 R"(
2546
2547(lldb) frame variable my_foo.b my_foo.c my_foo.i
2548
2549)"
2550 "The formatting option --raw on frame variable bypasses the filter, showing \
2551all children of my_foo as if no filter was defined:"
2552 R"(
2554(lldb) frame variable my_foo --raw)");
2555 }
2557 ~CommandObjectTypeFilterAdd() override = default;
2558
2559protected:
2560 void DoExecute(Args &command, CommandReturnObject &result) override {
2561 const size_t argc = command.GetArgumentCount();
2562
2563 if (argc < 1) {
2564 result.AppendErrorWithFormat("%s takes one or more args.\n",
2565 m_cmd_name.c_str());
2566 return;
2567 }
2568
2569 if (m_options.m_expr_paths.empty()) {
2570 result.AppendErrorWithFormat("%s needs one or more children.\n",
2571 m_cmd_name.c_str());
2572 return;
2573 }
2574
2577 .SetCascades(m_options.m_cascade)
2581 // go through the expression paths
2583 end = m_options.m_expr_paths.end();
2585 for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
2586 entry->AddExpressionPath(*begin);
2587
2588 // now I have a valid provider, let's add it to every type
2589
2590 lldb::TypeCategoryImplSP category;
2592 ConstString(m_options.m_category.c_str()), category);
2593
2594 Status error;
2595
2596 WarnOnPotentialUnquotedUnsignedType(command, result);
2597
2598 for (auto &arg_entry : command.entries()) {
2599 if (arg_entry.ref().empty()) {
2600 result.AppendError("empty typenames not allowed");
2601 return;
2602 }
2603
2604 ConstString typeCS(arg_entry.ref());
2605 if (!AddFilter(typeCS, entry,
2608 result.AppendError(error.AsCString());
2609 return;
2611 }
2612
2614 }
2615};
2616
2617// "type lookup"
2618#define LLDB_OPTIONS_type_lookup
2619#include "CommandOptions.inc"
2620
2622protected:
2623 // this function is allowed to do a more aggressive job at guessing languages
2624 // than the expression parser is comfortable with - so leave the original
2625 // call alone and add one that is specific to type lookup
2628
2629 if (!frame)
2630 return lang_type;
2631
2632 lang_type = frame->GuessLanguage();
2633 if (lang_type != lldb::eLanguageTypeUnknown)
2634 return lang_type;
2636 Symbol *s = frame->GetSymbolContext(eSymbolContextSymbol).symbol;
2637 if (s)
2638 lang_type = s->GetMangled().GuessLanguage();
2640 return lang_type;
2641 }
2642
2643 class CommandOptions : public OptionGroup {
2644 public:
2645 CommandOptions() = default;
2646
2647 ~CommandOptions() override = default;
2648
2649 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2650 return llvm::ArrayRef(g_type_lookup_options);
2651 }
2652
2653 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
2654 ExecutionContext *execution_context) override {
2655 Status error;
2656
2657 const int short_option = g_type_lookup_options[option_idx].short_option;
2658
2659 switch (short_option) {
2660 case 'h':
2661 m_show_help = true;
2662 break;
2663
2664 case 'l':
2666 break;
2667
2668 default:
2669 llvm_unreachable("Unimplemented option");
2670 }
2671
2672 return error;
2673 }
2674
2675 void OptionParsingStarting(ExecutionContext *execution_context) override {
2676 m_show_help = false;
2678 }
2679
2680 // Options table: Required for subclasses of Options.
2681
2682 bool m_show_help = false;
2684 };
2685
2687 CommandOptions m_command_options;
2688
2689public:
2691 : CommandObjectRaw(interpreter, "type lookup",
2692 "Lookup types and declarations in the current target, "
2693 "following language-specific naming conventions.",
2694 "type lookup <type-specifier>",
2695 eCommandRequiresTarget) {
2698 }
2699
2700 ~CommandObjectTypeLookup() override = default;
2701
2702 Options *GetOptions() override { return &m_option_group; }
2703
2704 llvm::StringRef GetHelpLong() override {
2705 if (!m_cmd_help_long.empty())
2706 return m_cmd_help_long;
2707
2708 StreamString stream;
2709 Language::ForEach([&](Language *lang) {
2710 if (const char *help = lang->GetLanguageSpecificTypeLookupHelp())
2711 stream.Printf("%s\n", help);
2712 return true;
2713 });
2714
2715 m_cmd_help_long = std::string(stream.GetString());
2716 return m_cmd_help_long;
2717 }
2718
2719 void DoExecute(llvm::StringRef raw_command_line,
2720 CommandReturnObject &result) override {
2721 if (raw_command_line.empty()) {
2722 result.AppendError(
2723 "type lookup cannot be invoked without a type name as argument");
2724 return;
2725 }
2726
2727 auto exe_ctx = GetCommandInterpreter().GetExecutionContext();
2729
2730 OptionsWithRaw args(raw_command_line);
2731 const char *name_of_type = args.GetRawPart().c_str();
2732
2733 if (args.HasArgs())
2734 if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group,
2735 exe_ctx))
2736 return;
2737
2738 ExecutionContextScope *best_scope = exe_ctx.GetBestExecutionContextScope();
2739
2740 bool any_found = false;
2741
2742 std::vector<Language *> languages;
2743
2744 bool is_global_search = false;
2745 LanguageType guessed_language = lldb::eLanguageTypeUnknown;
2746
2747 if ((is_global_search =
2749 Language::ForEach([&](Language *lang) {
2750 languages.push_back(lang);
2751 return true;
2752 });
2753 } else {
2756
2757 // This is not the most efficient way to do this, but we support very few
2758 // languages so the cost of the sort is going to be dwarfed by the actual
2759 // lookup anyway
2760 if (StackFrame *frame = m_exe_ctx.GetFramePtr()) {
2761 guessed_language = GuessLanguage(frame);
2762 if (guessed_language != eLanguageTypeUnknown) {
2763 llvm::sort(
2764 languages.begin(), languages.end(),
2765 [guessed_language](Language *lang1, Language *lang2) -> bool {
2766 if (!lang1 || !lang2)
2767 return false;
2768 LanguageType lt1 = lang1->GetLanguageType();
2769 LanguageType lt2 = lang2->GetLanguageType();
2770 if (lt1 == guessed_language)
2771 return true; // make the selected frame's language come first
2772 if (lt2 == guessed_language)
2773 return false; // make the selected frame's language come first
2774 return (lt1 < lt2); // normal comparison otherwise
2775 });
2776 }
2777 }
2779 bool is_first_language = true;
2780
2781 for (Language *language : languages) {
2782 if (!language)
2783 continue;
2784
2785 if (auto scavenger = language->GetTypeScavenger()) {
2787 if (scavenger->Find(best_scope, name_of_type, search_results) > 0) {
2788 for (const auto &search_result : search_results) {
2789 if (search_result && search_result->IsValid()) {
2790 any_found = true;
2791 search_result->DumpToStream(result.GetOutputStream(),
2792 this->m_command_options.m_show_help);
2793 }
2794 }
2795 }
2796 }
2797 // this is "type lookup SomeName" and we did find a match, so get out
2798 if (any_found && is_global_search)
2799 break;
2800 else if (is_first_language && is_global_search &&
2801 guessed_language != lldb::eLanguageTypeUnknown) {
2802 is_first_language = false;
2803 result.GetOutputStream().Printf(
2804 "no type was found in the current language %s matching '%s'; "
2805 "performing a global search across all languages\n",
2806 Language::GetNameForLanguageType(guessed_language), name_of_type);
2807 }
2808 }
2809
2810 if (!any_found)
2811 result.AppendMessageWithFormat("no type was found matching '%s'\n",
2812 name_of_type);
2813
2816 }
2817};
2818
2819template <typename FormatterType>
2821public:
2822 typedef std::function<typename FormatterType::SharedPointer(ValueObject &)>
2825 const char *formatter_name,
2826 DiscoveryFunction discovery_func)
2827 : CommandObjectRaw(interpreter, "", "", "", eCommandRequiresFrame),
2828 m_formatter_name(formatter_name ? formatter_name : ""),
2829 m_discovery_function(discovery_func) {
2830 StreamString name;
2831 name.Printf("type %s info", formatter_name);
2832 SetCommandName(name.GetString());
2833 StreamString help;
2834 help.Printf("This command evaluates the provided expression and shows "
2835 "which %s is applied to the resulting value (if any).",
2836 formatter_name);
2837 SetHelp(help.GetString());
2838 StreamString syntax;
2839 syntax.Printf("type %s info <expr>", formatter_name);
2840 SetSyntax(syntax.GetString());
2841 }
2842
2843 ~CommandObjectFormatterInfo() override = default;
2844
2845protected:
2846 void DoExecute(llvm::StringRef command,
2847 CommandReturnObject &result) override {
2848 TargetSP target_sp = GetDebugger().GetSelectedTarget();
2849 Thread *thread = GetDefaultThread();
2850 if (!thread) {
2851 result.AppendError("no default thread");
2852 return;
2854
2855 StackFrameSP frame_sp =
2857 ValueObjectSP result_valobj_sp;
2859 lldb::ExpressionResults expr_result = target_sp->EvaluateExpression(
2860 command, frame_sp.get(), result_valobj_sp, options);
2861 if (expr_result == eExpressionCompleted && result_valobj_sp) {
2862 result_valobj_sp =
2863 result_valobj_sp->GetQualifiedRepresentationIfAvailable(
2864 target_sp->GetPreferDynamicValue(),
2865 target_sp->GetEnableSyntheticValue());
2866 typename FormatterType::SharedPointer formatter_sp =
2867 m_discovery_function(*result_valobj_sp);
2868 if (formatter_sp) {
2869 std::string description(formatter_sp->GetDescription());
2870 result.GetOutputStream()
2871 << m_formatter_name << " applied to ("
2872 << result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>")
2873 << ") " << command << " is: " << description << "\n";
2875 } else {
2876 result.GetOutputStream()
2877 << "no " << m_formatter_name << " applies to ("
2878 << result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>")
2879 << ") " << command << "\n";
2881 }
2882 } else {
2883 result.AppendError("failed to evaluate expression");
2884 }
2885 }
2886
2887private:
2888 std::string m_formatter_name;
2890};
2891
2893public:
2896 interpreter, "type format",
2897 "Commands for customizing value display formats.",
2898 "type format [<sub-command-options>] ") {
2900 "add", CommandObjectSP(new CommandObjectTypeFormatAdd(interpreter)));
2902 new CommandObjectTypeFormatClear(interpreter)));
2904 interpreter)));
2906 "list", CommandObjectSP(new CommandObjectTypeFormatList(interpreter)));
2909 interpreter, "format",
2911 return valobj.GetValueFormat();
2912 })));
2913 }
2914
2915 ~CommandObjectTypeFormat() override = default;
2916};
2917
2919public:
2922 interpreter, "type synthetic",
2923 "Commands for operating on synthetic type representations.",
2924 "type synthetic [<sub-command-options>] ") {
2925 LoadSubCommand("add",
2928 "clear", CommandObjectSP(new CommandObjectTypeSynthClear(interpreter)));
2930 interpreter)));
2932 "list", CommandObjectSP(new CommandObjectTypeSynthList(interpreter)));
2934 "info",
2936 interpreter, "synthetic",
2938 return valobj.GetSyntheticChildren();
2939 })));
2940 }
2941
2942 ~CommandObjectTypeSynth() override = default;
2943};
2944
2946public:
2948 : CommandObjectMultiword(interpreter, "type filter",
2949 "Commands for operating on type filters.",
2950 "type filter [<sub-command-options>] ") {
2954 new CommandObjectTypeFilterClear(interpreter)));
2956 interpreter)));
2958 "list", CommandObjectSP(new CommandObjectTypeFilterList(interpreter)));
2959 }
2960
2961 ~CommandObjectTypeFilter() override = default;
2962};
2963
2965public:
2967 : CommandObjectMultiword(interpreter, "type category",
2968 "Commands for operating on type categories.",
2969 "type category [<sub-command-options>] ") {
2971 "define",
2974 "enable",
2977 "disable",
2980 "delete",
2983 new CommandObjectTypeCategoryList(interpreter)));
2984 }
2985
2986 ~CommandObjectTypeCategory() override = default;
2987};
2988
2990public:
2993 interpreter, "type summary",
2994 "Commands for editing variable summary display options.",
2995 "type summary [<sub-command-options>] ") {
2997 "add", CommandObjectSP(new CommandObjectTypeSummaryAdd(interpreter)));
2999 interpreter)));
3001 interpreter)));
3003 "list", CommandObjectSP(new CommandObjectTypeSummaryList(interpreter)));
3006 interpreter, "summary",
3008 return valobj.GetSummaryFormat();
3009 })));
3010 }
3011
3012 ~CommandObjectTypeSummary() override = default;
3013};
3014
3015// CommandObjectType
3016
3018 : CommandObjectMultiword(interpreter, "type",
3019 "Commands for operating on the type system.",
3020 "type [<sub-command-options>]") {
3021 LoadSubCommand("category",
3022 CommandObjectSP(new CommandObjectTypeCategory(interpreter)));
3023 LoadSubCommand("filter",
3024 CommandObjectSP(new CommandObjectTypeFilter(interpreter)));
3025 LoadSubCommand("format",
3026 CommandObjectSP(new CommandObjectTypeFormat(interpreter)));
3027 LoadSubCommand("summary",
3028 CommandObjectSP(new CommandObjectTypeSummary(interpreter)));
3029 LoadSubCommand("synthetic",
3030 CommandObjectSP(new CommandObjectTypeSynth(interpreter)));
3031 LoadSubCommand("lookup",
3032 CommandObjectSP(new CommandObjectTypeLookup(interpreter)));
3033}
3034
3036
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
void 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.
void 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
void DoExecute(Args &command, CommandReturnObject &result) override
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 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.
~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
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The input array contains a parsed version of the line.
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTypeCategoryEnable() override=default
void 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
void DoExecute(Args &command, CommandReturnObject &result) override
Options * GetOptions() override
bool AddFilter(ConstString type_name, TypeFilterImplSP entry, FilterFormatType type, std::string category_name, Status *error)
~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
void 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)
~CommandObjectTypeFormatterClear() override=default
void DoExecute(Args &command, CommandReturnObject &result) 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
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 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.
CommandObjectTypeFormatterDelete(CommandInterpreter &interpreter, FormatCategoryItem formatter_kind)
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
void DoExecute(Args &command, CommandReturnObject &result) override
FormatterType::SharedPointer FormatterSharedPointer
virtual bool FormatterSpecificList(CommandReturnObject &result)
static bool ShouldListItem(llvm::StringRef s, RegularExpression *regex)
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
OptionGroupOptions m_option_group
void DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override
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 DoExecute(Args &command, CommandReturnObject &result) override
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
bool Execute_StringSummary(Args &command, CommandReturnObject &result)
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
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTypeSynthAdd() override=default
bool Execute_HandwritePython(Args &command, CommandReturnObject &result)
~CommandObjectTypeSynthDelete() override=default
~CommandObjectTypeSynth() override=default
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:182
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:191
void SetString(llvm::StringRef s)
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:205
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:192
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
Definition: Debugger.cpp:1632
"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:86
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:235
virtual const char * GetLanguageSpecificTypeLookupHelp()
Definition: Language.cpp:409
static lldb::LanguageType GetLanguageTypeFromString(const char *string)=delete
static void ForEach(std::function< bool(Language *)> callback)
Definition: Language.cpp:100
lldb::LanguageType GuessLanguage() const
Try to guess the language from the mangling.
Definition: Mangled.cpp:379
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:42
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:262
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:730
lldb::TypeSummaryImplSP GetSummaryFormat()
Definition: ValueObject.h:715
lldb::SyntheticChildrenSP GetSyntheticChildren()
Definition: ValueObject.h:742
#define LLDB_OPT_SET_1
Definition: lldb-defines.h:111
@ 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
@ eTypeCategoryNameCompletion
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
Definition: lldb-forward.h:408
std::shared_ptr< lldb_private::TypeSummaryImpl > TypeSummaryImplSP
Definition: lldb-forward.h:459
std::shared_ptr< lldb_private::CommandObject > CommandObjectSP
Definition: lldb-forward.h:321
std::shared_ptr< lldb_private::TypeFormatImpl > TypeFormatImplSP
Definition: lldb-forward.h:456
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
Definition: lldb-forward.h:467
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
std::shared_ptr< lldb_private::StreamFile > StreamFileSP
Definition: lldb-forward.h:417
std::shared_ptr< lldb_private::SyntheticChildren > SyntheticChildrenSP
Definition: lldb-forward.h:429
std::shared_ptr< lldb_private::TypeCategoryImpl > TypeCategoryImplSP
Definition: lldb-forward.h:447
std::shared_ptr< lldb_private::TypeFilterImpl > TypeFilterImplSP
Definition: lldb-forward.h:452
std::shared_ptr< lldb_private::Target > TargetSP
Definition: lldb-forward.h:432
Used to build individual command argument lists.
Definition: CommandObject.h:93
static bool ToBoolean(llvm::StringRef s, bool fail_value, bool *success_ptr)