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