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