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