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",
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",
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", 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", 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",
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",
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"(
1502
1503(lldb) type summary add -p -r --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo
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"(
1518
1519(lldb) type summary add -e --summary-string "*ptr = ${*var.ptr}" JustADemo
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 } else {
1562 Execute_StringSummary(command, result);
1563 }
1564
1565 if (result.GetStatus() != eReturnStatusFailed)
1567}
1568
1569static bool FixArrayTypeNameWithRegex(ConstString &type_name) {
1570 llvm::StringRef type_name_ref(type_name.GetStringRef());
1571
1572 if (type_name_ref.ends_with("[]")) {
1573 std::string type_name_str(type_name.GetCString());
1574 type_name_str.resize(type_name_str.length() - 2);
1575 if (type_name_str.back() != ' ')
1576 type_name_str.append(" ?\\[[0-9]+\\]");
1577 else
1578 type_name_str.append("\\[[0-9]+\\]");
1579 type_name.SetCString(type_name_str.c_str());
1580 return true;
1581 }
1582 return false;
1583}
1584
1587 Status *error) {
1588 // system named summaries do not exist (yet?)
1590 return true;
1591}
1592
1595 FormatterMatchType match_type,
1596 std::string category_name,
1597 Status *error) {
1598 lldb::TypeCategoryImplSP category;
1600 category);
1602 if (match_type == eFormatterMatchExact) {
1603 if (FixArrayTypeNameWithRegex(type_name))
1605 }
1606
1607 if (match_type == eFormatterMatchRegex) {
1608 match_type = eFormatterMatchRegex;
1609 RegularExpression typeRX(type_name.GetStringRef());
1610 if (!typeRX.IsValid()) {
1611 if (error)
1613 "regex format error (maybe this is not really a regex?)");
1614 return false;
1615 }
1616 }
1617
1618 if (match_type == eFormatterMatchCallback) {
1619 const char *function_name = type_name.AsCString(nullptr);
1620 ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
1621 if (interpreter && !interpreter->CheckObjectExists(function_name)) {
1622 *error = Status::FromErrorStringWithFormat(
1623 "The provided recognizer function \"%s\" does not exist - "
1624 "please define it before attempting to use this summary.\n",
1625 function_name);
1626 return false;
1628 }
1629 category->AddTypeSummary(type_name.GetStringRef(), match_type, entry);
1630 return true;
1632
1633// CommandObjectTypeSummaryDelete
1634
1636public:
1640
1641 ~CommandObjectTypeSummaryDelete() override = default;
1642
1643protected:
1644 bool FormatterSpecificDeletion(ConstString typeCS) override {
1645 if (m_options.m_language != lldb::eLanguageTypeUnknown)
1646 return false;
1648 }
1649};
1650
1652public:
1653 CommandObjectTypeSummaryClear(CommandInterpreter &interpreter)
1655 "type summary clear",
1656 "Delete all existing summaries.") {}
1657
1658protected:
1659 void FormatterSpecificDeletion() override {
1661 }
1662};
1664// CommandObjectTypeSummaryList
1665
1667 : public CommandObjectTypeFormatterList<TypeSummaryImpl> {
1668public:
1670 : CommandObjectTypeFormatterList(interpreter, "type summary list",
1671 "Show a list of current summaries.") {}
1672
1673protected:
1674 bool FormatterSpecificList(CommandReturnObject &result) override {
1676 result.GetOutputStream().Printf("Named summaries:\n");
1678 [&result](const TypeMatcher &type_matcher,
1679 const TypeSummaryImplSP &summary_sp) -> bool {
1680 result.GetOutputStream().Printf(
1681 "%s: %s\n", type_matcher.GetMatchString().GetCString(),
1682 summary_sp->GetDescription().c_str());
1683 return true;
1684 });
1685 return true;
1686 }
1687 return false;
1689};
1690
1691// CommandObjectTypeCategoryDefine
1692#define LLDB_OPTIONS_type_category_define
1693#include "CommandOptions.inc"
1694
1696 class CommandOptions : public Options {
1697 public:
1699 : m_define_enabled(false, false),
1701
1702 ~CommandOptions() override = default;
1703
1704 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1705 ExecutionContext *execution_context) override {
1706 Status error;
1707 const int short_option = m_getopt_table[option_idx].val;
1708
1709 switch (short_option) {
1710 case 'e':
1711 m_define_enabled.SetValueFromString(llvm::StringRef("true"));
1712 break;
1713 case 'l':
1715 break;
1716 default:
1717 llvm_unreachable("Unimplemented option");
1719
1720 return error;
1721 }
1723 void OptionParsingStarting(ExecutionContext *execution_context) override {
1726 }
1727
1728 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1729 return llvm::ArrayRef(g_type_category_define_options);
1730 }
1731
1732 // Instance variables to hold the values for command options.
1733
1736 };
1737
1739
1740 Options *GetOptions() override { return &m_options; }
1741
1742public:
1743 CommandObjectTypeCategoryDefine(CommandInterpreter &interpreter)
1744 : CommandObjectParsed(interpreter, "type category define",
1745 "Define a new category as a source of formatters.",
1746 nullptr) {
1748 }
1750 ~CommandObjectTypeCategoryDefine() override = default;
1751
1752protected:
1753 void DoExecute(Args &command, CommandReturnObject &result) override {
1754 const size_t argc = command.GetArgumentCount();
1756 if (argc < 1) {
1757 result.AppendErrorWithFormat("%s takes 1 or more args",
1758 m_cmd_name.c_str());
1759 return;
1761
1762 for (auto &entry : command.entries()) {
1765 category_sp) &&
1766 category_sp) {
1767 category_sp->AddLanguage(m_options.m_cate_language.GetCurrentValue());
1768 if (m_options.m_define_enabled.GetCurrentValue())
1771 }
1772 }
1775 }
1776};
1777
1778// CommandObjectTypeCategoryEnable
1779#define LLDB_OPTIONS_type_category_enable
1780#include "CommandOptions.inc"
1781
1783 class CommandOptions : public Options {
1784 public:
1785 CommandOptions() = default;
1786
1787 ~CommandOptions() override = default;
1788
1789 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1790 ExecutionContext *execution_context) override {
1791 Status error;
1792 const int short_option = m_getopt_table[option_idx].val;
1793
1794 switch (short_option) {
1795 case 'l':
1796 if (!option_arg.empty()) {
1799 error = Status::FromErrorStringWithFormat(
1800 "unrecognized language '%s'", option_arg.str().c_str());
1801 }
1802 break;
1803 default:
1804 llvm_unreachable("Unimplemented option");
1805 }
1806
1807 return error;
1808 }
1809
1810 void OptionParsingStarting(ExecutionContext *execution_context) override {
1813
1814 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1815 return llvm::ArrayRef(g_type_category_enable_options);
1816 }
1817
1818 // Instance variables to hold the values for command options.
1819
1822
1823 CommandOptions m_options;
1825 Options *GetOptions() override { return &m_options; }
1826
1827public:
1829 : CommandObjectParsed(interpreter, "type category enable",
1830 "Enable a category as a source of formatters.",
1831 nullptr) {
1833 }
1834
1835 ~CommandObjectTypeCategoryEnable() override = default;
1836
1837protected:
1838 void DoExecute(Args &command, CommandReturnObject &result) override {
1839 const size_t argc = command.GetArgumentCount();
1840
1841 if (argc < 1 && m_options.m_language == lldb::eLanguageTypeUnknown) {
1842 result.AppendErrorWithFormat("%s takes arguments and/or a language",
1843 m_cmd_name.c_str());
1844 return;
1845 }
1846
1847 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0), "*") == 0) {
1849 } else if (argc > 0) {
1850 for (int i = argc - 1; i >= 0; i--) {
1851 const char *typeA = command.GetArgumentAtIndex(i);
1852 ConstString typeCS(typeA);
1853
1854 if (!typeCS) {
1855 result.AppendError("empty category name not allowed");
1856 return;
1857 }
1861 if (cate->GetCount() == 0) {
1862 result.AppendWarning("empty category enabled (typo?)");
1863 }
1865 }
1867
1868 if (m_options.m_language != lldb::eLanguageTypeUnknown)
1870
1872 }
1873};
1874
1875// CommandObjectTypeCategoryDelete
1876
1878public:
1879 CommandObjectTypeCategoryDelete(CommandInterpreter &interpreter)
1880 : CommandObjectParsed(interpreter, "type category delete",
1881 "Delete a category and all associated formatters.",
1882 nullptr) {
1884 }
1885
1886 ~CommandObjectTypeCategoryDelete() override = default;
1888protected:
1889 void DoExecute(Args &command, CommandReturnObject &result) override {
1890 const size_t argc = command.GetArgumentCount();
1892 if (argc < 1) {
1893 result.AppendErrorWithFormat("%s takes 1 or more arg",
1894 m_cmd_name.c_str());
1895 return;
1896 }
1898 bool success = true;
1899
1900 // the order is not relevant here
1901 for (int i = argc - 1; i >= 0; i--) {
1902 const char *typeA = command.GetArgumentAtIndex(i);
1903 ConstString typeCS(typeA);
1904
1905 if (!typeCS) {
1906 result.AppendError("empty category name not allowed");
1907 return;
1908 }
1910 success = false; // keep deleting even if we hit an error
1911 }
1912 if (success) {
1914 } else {
1915 result.AppendError("cannot delete one or more categories\n");
1916 }
1917 }
1918};
1919
1920// CommandObjectTypeCategoryDisable
1921#define LLDB_OPTIONS_type_category_disable
1922#include "CommandOptions.inc"
1923
1925 class CommandOptions : public Options {
1926 public:
1927 CommandOptions() = default;
1928
1929 ~CommandOptions() override = default;
1930
1931 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1932 ExecutionContext *execution_context) override {
1933 Status error;
1934 const int short_option = m_getopt_table[option_idx].val;
1935
1936 switch (short_option) {
1937 case 'l':
1938 if (!option_arg.empty()) {
1941 error = Status::FromErrorStringWithFormat(
1942 "unrecognized language '%s'", option_arg.str().c_str());
1943 }
1944 break;
1945 default:
1946 llvm_unreachable("Unimplemented option");
1947 }
1948
1949 return error;
1950 }
1952 void OptionParsingStarting(ExecutionContext *execution_context) override {
1954 }
1955
1956 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1957 return llvm::ArrayRef(g_type_category_disable_options);
1959
1960 // Instance variables to hold the values for command options.
1963 };
1964
1965 CommandOptions m_options;
1966
1967 Options *GetOptions() override { return &m_options; }
1968
1969public:
1970 CommandObjectTypeCategoryDisable(CommandInterpreter &interpreter)
1971 : CommandObjectParsed(interpreter, "type category disable",
1972 "Disable a category as a source of formatters.",
1973 nullptr) {
1975 }
1976
1977 ~CommandObjectTypeCategoryDisable() override = default;
1978
1979protected:
1980 void DoExecute(Args &command, CommandReturnObject &result) override {
1981 const size_t argc = command.GetArgumentCount();
1982
1983 if (argc < 1 && m_options.m_language == lldb::eLanguageTypeUnknown) {
1984 result.AppendErrorWithFormat("%s takes arguments and/or a language",
1985 m_cmd_name.c_str());
1986 return;
1987 }
1988
1989 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0), "*") == 0) {
1991 } else if (argc > 0) {
1992 // the order is not relevant here
1993 for (int i = argc - 1; i >= 0; i--) {
1994 const char *typeA = command.GetArgumentAtIndex(i);
1995 ConstString typeCS(typeA);
1996
1997 if (!typeCS) {
1998 result.AppendError("empty category name not allowed");
1999 return;
2000 }
2002 }
2003 }
2004
2005 if (m_options.m_language != lldb::eLanguageTypeUnknown)
2007
2009 }
2010};
2011
2012// CommandObjectTypeCategoryList
2013
2015public:
2017 : CommandObjectParsed(interpreter, "type category list",
2018 "Provide a list of all existing categories.",
2019 nullptr) {
2021 }
2022
2023 ~CommandObjectTypeCategoryList() override = default;
2024
2033 }
2034
2035protected:
2036 void DoExecute(Args &command, CommandReturnObject &result) override {
2037 const size_t argc = command.GetArgumentCount();
2039 std::unique_ptr<RegularExpression> regex;
2040
2041 if (argc == 1) {
2042 const char *arg = command.GetArgumentAtIndex(0);
2043 regex = std::make_unique<RegularExpression>(arg);
2044 if (!regex->IsValid()) {
2045 result.AppendErrorWithFormat(
2046 "syntax error in category regular expression '%s'", arg);
2047 return;
2048 }
2049 } else if (argc != 0) {
2050 result.AppendErrorWithFormat("%s takes 0 or one arg", m_cmd_name.c_str());
2051 return;
2052 }
2055 [&regex, &result](const lldb::TypeCategoryImplSP &category_sp) -> bool {
2056 if (regex) {
2057 bool escape = true;
2058 if (regex->GetText() == category_sp->GetName()) {
2059 escape = false;
2060 } else if (regex->Execute(category_sp->GetName())) {
2061 escape = false;
2062 }
2063
2064 if (escape)
2065 return true;
2066 }
2067
2069 "Category: %s\n", category_sp->GetDescription().c_str());
2071 return true;
2072 });
2073
2075 }
2077
2078// CommandObjectTypeFilterList
2079
2081 : public CommandObjectTypeFormatterList<TypeFilterImpl> {
2082public:
2084 : CommandObjectTypeFormatterList(interpreter, "type filter list",
2085 "Show a list of current filters.") {}
2086};
2087
2088// CommandObjectTypeSynthList
2089
2091 : public CommandObjectTypeFormatterList<SyntheticChildren> {
2092public:
2093 CommandObjectTypeSynthList(CommandInterpreter &interpreter)
2095 interpreter, "type synthetic list",
2096 "Show a list of current synthetic providers.") {}
2097};
2098
2099// CommandObjectTypeFilterDelete
2100
2102public:
2106
2107 ~CommandObjectTypeFilterDelete() override = default;
2108};
2109
2110// CommandObjectTypeSynthDelete
2111
2113public:
2117
2118 ~CommandObjectTypeSynthDelete() override = default;
2119};
2120
2121// CommandObjectTypeFilterClear
2122
2124public:
2125 CommandObjectTypeFilterClear(CommandInterpreter &interpreter)
2127 "type filter clear",
2128 "Delete all existing filter.") {}
2129};
2130
2131// CommandObjectTypeSynthClear
2132
2134public:
2135 CommandObjectTypeSynthClear(CommandInterpreter &interpreter)
2137 interpreter, eFormatCategoryItemSynth, "type synthetic clear",
2138 "Delete all existing synthetic providers.") {}
2139};
2140
2142 Args &command, CommandReturnObject &result) {
2143 auto options = std::make_unique<SynthAddOptions>(
2144 m_options.m_skip_pointers, m_options.m_skip_references,
2145 m_options.m_cascade, m_options.m_wants_deref, m_options.m_match_type,
2146 m_options.m_category);
2147
2148 for (auto &entry : command.entries()) {
2149 if (entry.ref().empty()) {
2150 result.AppendError("empty typenames not allowed");
2151 return false;
2152 }
2153
2154 options->m_target_types << std::string(entry.ref());
2155 }
2156
2157 m_interpreter.GetPythonCommandsFromIOHandler(
2158 " ", // Prompt
2159 *this, // IOHandlerDelegate
2160 options.release()); // Baton for the "io_handler" that will be passed back
2161 // into our IOHandlerDelegate functions
2163 return result.Succeeded();
2164}
2167 Args &command, CommandReturnObject &result) {
2168 const size_t argc = command.GetArgumentCount();
2169
2170 if (argc < 1) {
2171 result.AppendErrorWithFormat("%s takes one or more args",
2172 m_cmd_name.c_str());
2173 return false;
2174 }
2175
2177 result.AppendErrorWithFormat("%s needs either a Python class name or -P to "
2178 "directly input Python code",
2179 m_cmd_name.c_str());
2180 return false;
2181 }
2182
2183 SyntheticChildrenSP entry;
2184
2185 ScriptedSyntheticChildren *impl = new ScriptedSyntheticChildren(
2186 SyntheticChildren::Flags()
2187 .SetCascades(m_options.m_cascade)
2188 .SetFrontEndWantsDereference(m_options.m_wants_deref)
2189 .SetSkipPointers(m_options.m_skip_pointers)
2190 .SetSkipReferences(m_options.m_skip_references),
2191 m_options.m_class_name.c_str());
2192
2193 entry.reset(impl);
2194
2195 ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
2196
2197 const char *python_class_name = impl->GetPythonClassName();
2198 if (interpreter && !interpreter->CheckObjectExists(python_class_name))
2200 "the provided class '{0}' does not exist - please define it "
2201 "before attempting to use this synthetic provider",
2202 llvm::StringRef(python_class_name));
2203
2204 // now I have a valid provider, let's add it to every type
2205
2206 lldb::TypeCategoryImplSP category;
2208 ConstString(m_options.m_category.c_str()), category);
2209
2210 Status error;
2211
2212 for (auto &arg_entry : command.entries()) {
2213 if (arg_entry.ref().empty()) {
2214 result.AppendError("empty typenames not allowed");
2215 return false;
2216 }
2217
2218 ConstString typeCS(arg_entry.ref());
2219 if (!AddSynth(typeCS, entry, m_options.m_match_type, m_options.m_category,
2220 &error)) {
2221 result.AppendError(error.AsCString());
2222 return false;
2223 }
2224 }
2225
2227 return result.Succeeded();
2228}
2229
2231 CommandInterpreter &interpreter)
2232 : CommandObjectParsed(interpreter, "type synthetic add",
2233 "Add a new synthetic provider for a type.", nullptr),
2234 IOHandlerDelegateMultiline("DONE"), m_options() {
2235 AddSimpleArgumentList(eArgTypeName, eArgRepeatPlus);
2237
2240 FormatterMatchType match_type,
2241 std::string category_name,
2243 lldb::TypeCategoryImplSP category;
2245 category);
2247 if (match_type == eFormatterMatchExact) {
2248 if (FixArrayTypeNameWithRegex(type_name))
2249 match_type = eFormatterMatchRegex;
2250 }
2251
2252 // Only check for conflicting filters in the same category if `type_name` is
2253 // an actual type name. Matching a regex string against registered regexes
2254 // doesn't work.
2255 if (match_type == eFormatterMatchExact) {
2256 // It's not generally possible to get a type object here. For example, this
2257 // command can be run before loading any binaries. Do just a best-effort
2258 // name-based lookup here to try to prevent conflicts.
2259 FormattersMatchCandidate candidate_type(type_name, nullptr, TypeImpl(),
2261 if (category->AnyMatches(candidate_type, eFormatCategoryItemFilter,
2262 false)) {
2263 if (error)
2265 "cannot add synthetic for type {0} when "
2266 "filter is defined in same category!",
2267 type_name);
2268 return false;
2269 }
2270 }
2271
2272 if (match_type == eFormatterMatchRegex) {
2273 RegularExpression typeRX(type_name.GetStringRef());
2274 if (!typeRX.IsValid()) {
2275 if (error)
2276 *error = Status::FromErrorString(
2277 "regex format error (maybe this is not really a regex?)");
2278 return false;
2279 }
2280 }
2281
2282 if (match_type == eFormatterMatchCallback) {
2283 const char *function_name = type_name.AsCString(nullptr);
2285 if (interpreter && !interpreter->CheckObjectExists(function_name)) {
2287 "The provided recognizer function \"%s\" does not exist - "
2288 "please define it before attempting to use this summary.\n",
2289 function_name);
2290 return false;
2291 }
2293
2294 category->AddTypeSynthetic(type_name.GetStringRef(), match_type, entry);
2295 return true;
2296}
2297
2298#define LLDB_OPTIONS_type_filter_add
2299#include "CommandOptions.inc"
2302private:
2303 class CommandOptions : public Options {
2304 typedef std::vector<std::string> option_vector;
2306 public:
2307 CommandOptions() = default;
2308
2309 ~CommandOptions() override = default;
2311 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2312 ExecutionContext *execution_context) override {
2313 Status error;
2314 const int short_option = m_getopt_table[option_idx].val;
2315 bool success;
2317 switch (short_option) {
2318 case 'C':
2319 m_cascade = OptionArgParser::ToBoolean(option_arg, true, &success);
2320 if (!success)
2322 "invalid value for cascade: %s", option_arg.str().c_str());
2323 break;
2324 case 'c':
2325 m_expr_paths.push_back(std::string(option_arg));
2326 has_child_list = true;
2327 break;
2328 case 'p':
2329 m_skip_pointers = true;
2330 break;
2331 case 'r':
2332 m_skip_references = true;
2333 break;
2334 case 'w':
2335 m_category = std::string(option_arg);
2336 break;
2337 case 'x':
2338 m_regex = true;
2339 break;
2340 default:
2341 llvm_unreachable("Unimplemented option");
2342 }
2343
2344 return error;
2345 }
2346
2347 void OptionParsingStarting(ExecutionContext *execution_context) override {
2348 m_cascade = true;
2349 m_skip_pointers = false;
2350 m_skip_references = false;
2351 m_category = "default";
2352 m_expr_paths.clear();
2353 has_child_list = false;
2354 m_regex = false;
2355 }
2356
2357 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2358 return llvm::ArrayRef(g_type_filter_add_options);
2359 }
2360
2361 // Instance variables to hold the values for command options.
2362
2363 bool m_cascade;
2364 bool m_skip_references;
2365 bool m_skip_pointers;
2368 std::string m_category;
2369 bool has_child_list;
2370 bool m_regex;
2371
2372 typedef option_vector::iterator ExpressionPathsIterator;
2373 };
2374
2375 CommandOptions m_options;
2376
2377 Options *GetOptions() override { return &m_options; }
2378
2380
2382 FilterFormatType type, std::string category_name,
2383 Status *error) {
2386 ConstString(category_name.c_str()), category);
2387
2388 if (type == eRegularFilter) {
2389 if (FixArrayTypeNameWithRegex(type_name))
2390 type = eRegexFilter;
2391 }
2392
2393 // Only check for conflicting synthetic child providers in the same category
2394 // if `type_name` is an actual type name. Matching a regex string against
2395 // registered regexes doesn't work.
2396 if (type == eRegularFilter) {
2397 // It's not generally possible to get a type object here. For example,
2398 // this command can be run before loading any binaries. Do just a
2399 // best-effort name-based lookup here to try to prevent conflicts.
2400 FormattersMatchCandidate candidate_type(
2401 type_name, nullptr, TypeImpl(), FormattersMatchCandidate::Flags());
2403 if (category->AnyMatches(candidate_type, eFormatCategoryItemSynth,
2404 false)) {
2405 if (error)
2407 "cannot add filter for type {0} when "
2408 "synthetic is defined in same "
2409 "category!",
2410 type_name);
2411 return false;
2412 }
2413 }
2414
2416 if (type == eRegexFilter) {
2417 match_type = eFormatterMatchRegex;
2418 RegularExpression typeRX(type_name.GetStringRef());
2419 if (!typeRX.IsValid()) {
2420 if (error)
2421 *error = Status::FromErrorString(
2422 "regex format error (maybe this is not really a regex?)");
2423 return false;
2424 }
2425 }
2426 category->AddTypeFilter(type_name.GetStringRef(), match_type, entry);
2427 return true;
2428 }
2429
2430public:
2431 CommandObjectTypeFilterAdd(CommandInterpreter &interpreter)
2432 : CommandObjectParsed(interpreter, "type filter add",
2433 "Add a new filter for a type.", nullptr) {
2435
2437 R"(
2438The following examples of 'type filter add' refer to this code snippet for context:
2439
2440 class Foo {
2441 int a;
2442 int b;
2443 int c;
2444 int d;
2445 int e;
2446 int f;
2447 int g;
2448 int h;
2449 int i;
2450 }
2451 Foo my_foo;
2452
2453Adding a simple filter:
2454
2455(lldb) type filter add --child a --child g Foo
2456(lldb) frame variable my_foo
2457
2458)"
2459 "Produces output where only a and g are displayed. Other children of my_foo \
2460(b, c, d, e, f, h and i) are available by asking for them explicitly:"
2461 R"(
2462
2463(lldb) frame variable my_foo.b my_foo.c my_foo.i
2464
2465)"
2466 "The formatting option --raw on frame variable bypasses the filter, showing \
2467all children of my_foo as if no filter was defined:"
2468 R"(
2470(lldb) frame variable my_foo --raw)");
2471 }
2473 ~CommandObjectTypeFilterAdd() override = default;
2474
2475protected:
2476 void DoExecute(Args &command, CommandReturnObject &result) override {
2477 const size_t argc = command.GetArgumentCount();
2478
2479 if (argc < 1) {
2480 result.AppendErrorWithFormat("%s takes one or more args",
2481 m_cmd_name.c_str());
2482 return;
2483 }
2484
2485 if (m_options.m_expr_paths.empty()) {
2486 result.AppendErrorWithFormat("%s needs one or more children",
2487 m_cmd_name.c_str());
2488 return;
2489 }
2490
2491 TypeFilterImplSP entry(new TypeFilterImpl(
2492 SyntheticChildren::Flags()
2493 .SetCascades(m_options.m_cascade)
2494 .SetSkipPointers(m_options.m_skip_pointers)
2495 .SetSkipReferences(m_options.m_skip_references)));
2497 // go through the expression paths
2499 end = m_options.m_expr_paths.end();
2501 for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
2502 entry->AddExpressionPath(*begin);
2503
2504 // now I have a valid provider, let's add it to every type
2505
2506 lldb::TypeCategoryImplSP category;
2508 ConstString(m_options.m_category.c_str()), category);
2509
2510 Status error;
2511
2512 WarnOnPotentialUnquotedUnsignedType(command, result);
2513
2514 for (auto &arg_entry : command.entries()) {
2515 if (arg_entry.ref().empty()) {
2516 result.AppendError("empty typenames not allowed");
2517 return;
2518 }
2519
2520 ConstString typeCS(arg_entry.ref());
2521 if (!AddFilter(typeCS, entry,
2524 result.AppendError(error.AsCString());
2525 return;
2530 }
2531};
2532
2533// "type lookup"
2534#define LLDB_OPTIONS_type_lookup
2535#include "CommandOptions.inc"
2536
2538protected:
2539 // this function is allowed to do a more aggressive job at guessing languages
2540 // than the expression parser is comfortable with - so leave the original
2541 // call alone and add one that is specific to type lookup
2544
2545 if (!frame)
2546 return lang_type;
2547
2548 lang_type = frame->GuessLanguage().AsLanguageType();
2549 if (lang_type != lldb::eLanguageTypeUnknown)
2550 return lang_type;
2552 const Symbol *s = frame->GetSymbolContext(eSymbolContextSymbol).symbol;
2553 if (s)
2554 lang_type = s->GetMangled().GuessLanguage();
2556 return lang_type;
2557 }
2558
2559 class CommandOptions : public OptionGroup {
2560 public:
2561 CommandOptions() = default;
2562
2563 ~CommandOptions() override = default;
2564
2565 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2566 return llvm::ArrayRef(g_type_lookup_options);
2567 }
2568
2569 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
2570 ExecutionContext *execution_context) override {
2571 Status error;
2572
2573 const int short_option = g_type_lookup_options[option_idx].short_option;
2574
2575 switch (short_option) {
2576 case 'h':
2577 m_show_help = true;
2578 break;
2579
2580 case 'l':
2582 break;
2583
2584 default:
2585 llvm_unreachable("Unimplemented option");
2586 }
2587
2588 return error;
2589 }
2590
2591 void OptionParsingStarting(ExecutionContext *execution_context) override {
2592 m_show_help = false;
2594 }
2595
2596 // Options table: Required for subclasses of Options.
2597
2598 bool m_show_help = false;
2600 };
2601
2602 OptionGroupOptions m_option_group;
2604
2605public:
2606 CommandObjectTypeLookup(CommandInterpreter &interpreter)
2607 : CommandObjectRaw(interpreter, "type lookup",
2608 "Lookup types and declarations in the current target, "
2609 "following language-specific naming conventions.",
2610 "type lookup <type-specifier>",
2611 eCommandRequiresTarget) {
2613 m_option_group.Finalize();
2614 }
2615
2616 ~CommandObjectTypeLookup() override = default;
2617
2618 Options *GetOptions() override { return &m_option_group; }
2619
2620 llvm::StringRef GetHelpLong() override {
2621 if (!m_cmd_help_long.empty())
2622 return m_cmd_help_long;
2623
2624 StreamString stream;
2625 Language::ForEach([&](Language *lang) {
2626 if (const char *help = lang->GetLanguageSpecificTypeLookupHelp())
2627 stream.Printf("%s\n", help);
2628 return IterationAction::Continue;
2629 });
2630
2631 m_cmd_help_long = std::string(stream.GetString());
2632 return m_cmd_help_long;
2633 }
2634
2635 void DoExecute(llvm::StringRef raw_command_line,
2636 CommandReturnObject &result) override {
2637 if (raw_command_line.empty()) {
2638 result.AppendError(
2639 "type lookup cannot be invoked without a type name as argument");
2640 return;
2641 }
2642
2643 auto exe_ctx = GetCommandInterpreter().GetExecutionContext();
2644 m_option_group.NotifyOptionParsingStarting(&exe_ctx);
2645
2646 OptionsWithRaw args(raw_command_line);
2647 const char *name_of_type = args.GetRawPart().c_str();
2648
2649 if (args.HasArgs())
2650 if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group,
2651 exe_ctx))
2652 return;
2653
2654 ExecutionContextScope *best_scope = exe_ctx.GetBestExecutionContextScope();
2655
2656 bool any_found = false;
2657
2658 std::vector<Language *> languages;
2659
2660 bool is_global_search = false;
2661 LanguageType guessed_language = lldb::eLanguageTypeUnknown;
2662
2663 if ((is_global_search =
2664 (m_command_options.m_language == eLanguageTypeUnknown))) {
2665 Language::ForEach([&](Language *lang) {
2666 languages.push_back(lang);
2667 return IterationAction::Continue;
2668 });
2669 } else {
2670 languages.push_back(Language::FindPlugin(m_command_options.m_language));
2671 }
2672
2673 // This is not the most efficient way to do this, but we support very few
2674 // languages so the cost of the sort is going to be dwarfed by the actual
2675 // lookup anyway
2676 if (StackFrame *frame = m_exe_ctx.GetFramePtr()) {
2677 guessed_language = GuessLanguage(frame);
2678 if (guessed_language != eLanguageTypeUnknown) {
2679 llvm::sort(
2680 languages.begin(), languages.end(),
2681 [guessed_language](Language *lang1, Language *lang2) -> bool {
2682 if (!lang1 || !lang2)
2683 return false;
2684 LanguageType lt1 = lang1->GetLanguageType();
2685 LanguageType lt2 = lang2->GetLanguageType();
2686 if (lt1 == lt2)
2687 return false;
2688 if (lt1 == guessed_language)
2689 return true; // make the selected frame's language come first
2690 if (lt2 == guessed_language)
2691 return false; // make the selected frame's language come first
2692 return (lt1 < lt2); // normal comparison otherwise
2693 });
2694 }
2695 }
2697 bool is_first_language = true;
2698
2699 for (Language *language : languages) {
2700 if (!language)
2701 continue;
2702
2703 if (auto scavenger = language->GetTypeScavenger()) {
2705 if (scavenger->Find(best_scope, name_of_type, search_results) > 0) {
2706 for (const auto &search_result : search_results) {
2707 if (search_result && search_result->IsValid()) {
2708 any_found = true;
2709 search_result->DumpToStream(result.GetOutputStream(),
2710 this->m_command_options.m_show_help);
2711 }
2712 }
2713 }
2714 }
2715 // this is "type lookup SomeName" and we did find a match, so get out
2716 if (any_found && is_global_search)
2717 break;
2718 else if (is_first_language && is_global_search &&
2719 guessed_language != lldb::eLanguageTypeUnknown) {
2720 is_first_language = false;
2721 result.GetOutputStream().Printf(
2722 "no type was found in the current language %s matching '%s'; "
2723 "performing a global search across all languages\n",
2724 Language::GetNameForLanguageType(guessed_language), name_of_type);
2725 }
2726 }
2727
2728 if (!any_found)
2729 result.AppendMessageWithFormatv("no type was found matching '{0}'",
2730 name_of_type);
2731
2734 }
2735};
2736
2737template <typename FormatterType>
2739public:
2740 typedef std::function<typename FormatterType::SharedPointer(ValueObject &)>
2743 const char *formatter_name,
2744 DiscoveryFunction discovery_func)
2745 : CommandObjectRaw(interpreter, "", "", "", eCommandRequiresFrame),
2746 m_formatter_name(formatter_name ? formatter_name : ""),
2747 m_discovery_function(discovery_func) {
2748 StreamString name;
2749 name.Printf("type %s info", formatter_name);
2750 SetCommandName(name.GetString());
2751 StreamString help;
2752 help.Printf("This command evaluates the provided expression and shows "
2753 "which %s is applied to the resulting value (if any).",
2754 formatter_name);
2755 SetHelp(help.GetString());
2756 StreamString syntax;
2757 syntax.Printf("type %s info <expr>", formatter_name);
2758 SetSyntax(syntax.GetString());
2759 }
2760
2761 ~CommandObjectFormatterInfo() override = default;
2762
2763protected:
2764 void DoExecute(llvm::StringRef command,
2765 CommandReturnObject &result) override {
2766 TargetSP target_sp = GetDebugger().GetSelectedTarget();
2767 Thread *thread = GetDefaultThread();
2768 if (!thread) {
2769 result.AppendError("no default thread");
2770 return;
2772
2773 StackFrameSP frame_sp =
2774 thread->GetSelectedFrame(DoNoSelectMostRelevantFrame);
2775 ValueObjectSP result_valobj_sp;
2777 lldb::ExpressionResults expr_result = target_sp->EvaluateExpression(
2778 command, frame_sp.get(), result_valobj_sp, options);
2779 if (expr_result == eExpressionCompleted && result_valobj_sp) {
2780 result_valobj_sp =
2781 result_valobj_sp->GetQualifiedRepresentationIfAvailable(
2782 target_sp->GetPreferDynamicValue(),
2783 target_sp->GetEnableSyntheticValue());
2784 typename FormatterType::SharedPointer formatter_sp =
2785 m_discovery_function(*result_valobj_sp);
2786 if (formatter_sp) {
2787 std::string description(formatter_sp->GetDescription());
2788 result.GetOutputStream()
2789 << m_formatter_name << " applied to ("
2790 << result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>")
2791 << ") " << command << " is: " << description << "\n";
2793 } else {
2794 result.GetOutputStream()
2795 << "no " << m_formatter_name << " applies to ("
2796 << result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>")
2797 << ") " << command << "\n";
2799 }
2800 } else {
2801 result.AppendError("failed to evaluate expression");
2802 }
2803 }
2804
2805private:
2806 std::string m_formatter_name;
2808};
2809
2811public:
2814 interpreter, "type format",
2815 "Commands for customizing value display formats.",
2816 "type format [<sub-command-options>] ") {
2818 "add", CommandObjectSP(new CommandObjectTypeFormatAdd(interpreter)));
2820 new CommandObjectTypeFormatClear(interpreter)));
2822 interpreter)));
2824 "list", CommandObjectSP(new CommandObjectTypeFormatList(interpreter)));
2827 interpreter, "format",
2829 return valobj.GetValueFormat();
2830 })));
2831 }
2832
2833 ~CommandObjectTypeFormat() override = default;
2834};
2835
2837public:
2840 interpreter, "type synthetic",
2841 "Commands for operating on synthetic type representations.",
2842 "type synthetic [<sub-command-options>] ") {
2843 LoadSubCommand("add",
2846 "clear", CommandObjectSP(new CommandObjectTypeSynthClear(interpreter)));
2848 interpreter)));
2850 "list", CommandObjectSP(new CommandObjectTypeSynthList(interpreter)));
2852 "info",
2854 interpreter, "synthetic",
2856 return valobj.GetSyntheticChildren();
2857 })));
2858 }
2859
2860 ~CommandObjectTypeSynth() override = default;
2861};
2862
2864public:
2866 : CommandObjectMultiword(interpreter, "type filter",
2867 "Commands for operating on type filters.",
2868 "type filter [<sub-command-options>] ") {
2872 new CommandObjectTypeFilterClear(interpreter)));
2874 interpreter)));
2876 "list", CommandObjectSP(new CommandObjectTypeFilterList(interpreter)));
2877 }
2878
2879 ~CommandObjectTypeFilter() override = default;
2880};
2881
2883public:
2885 : CommandObjectMultiword(interpreter, "type category",
2886 "Commands for operating on type categories.",
2887 "type category [<sub-command-options>] ") {
2889 "define",
2892 "enable",
2895 "disable",
2898 "delete",
2901 new CommandObjectTypeCategoryList(interpreter)));
2902 }
2903
2904 ~CommandObjectTypeCategory() override = default;
2905};
2906
2908public:
2911 interpreter, "type summary",
2912 "Commands for editing variable summary display options.",
2913 "type summary [<sub-command-options>] ") {
2915 "add", CommandObjectSP(new CommandObjectTypeSummaryAdd(interpreter)));
2916 LoadSubCommand("clear", CommandObjectSP(new CommandObjectTypeSummaryClear(
2917 interpreter)));
2918 LoadSubCommand("delete", CommandObjectSP(new CommandObjectTypeSummaryDelete(
2919 interpreter)));
2921 "list", CommandObjectSP(new CommandObjectTypeSummaryList(interpreter)));
2923 "info", CommandObjectSP(new CommandObjectFormatterInfo<TypeSummaryImpl>(
2924 interpreter, "summary",
2925 [](ValueObject &valobj) -> TypeSummaryImpl::SharedPointer {
2926 return valobj.GetSummaryFormat();
2927 })));
2928 }
2929
2930 ~CommandObjectTypeSummary() override = default;
2931};
2932
2933// CommandObjectType
2934
2936 : CommandObjectMultiword(interpreter, "type",
2937 "Commands for operating on the type system.",
2938 "type [<sub-command-options>]") {
2939 LoadSubCommand("category",
2940 CommandObjectSP(new CommandObjectTypeCategory(interpreter)));
2941 LoadSubCommand("filter",
2942 CommandObjectSP(new CommandObjectTypeFilter(interpreter)));
2943 LoadSubCommand("format",
2944 CommandObjectSP(new CommandObjectTypeFormat(interpreter)));
2945 LoadSubCommand("summary",
2946 CommandObjectSP(new CommandObjectTypeSummary(interpreter)));
2947 LoadSubCommand("synthetic",
2948 CommandObjectSP(new CommandObjectTypeSynth(interpreter)));
2949 LoadSubCommand("lookup",
2950 CommandObjectSP(new CommandObjectTypeLookup(interpreter)));
2951}
2952
2954
static const char * g_synth_addreader_instructions
static bool WarnOnPotentialUnquotedUnsignedType(Args &command, CommandReturnObject &result)
const char * FormatCategoryToString(FormatCategoryItem item, bool long_name)
static bool FixArrayTypeNameWithRegex(ConstString &type_name)
static llvm::raw_ostream & error(Stream &strm)
~CommandObjectFormatterInfo() override=default
CommandObjectFormatterInfo(CommandInterpreter &interpreter, const char *formatter_name, DiscoveryFunction discovery_func)
void DoExecute(llvm::StringRef command, CommandReturnObject &result) override
std::function< typename FormatterType::SharedPointer(ValueObject &)> DiscoveryFunction
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
CommandObjectTypeCategoryDefine(CommandInterpreter &interpreter)
~CommandObjectTypeCategoryDefine() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTypeCategoryDelete(CommandInterpreter &interpreter)
~CommandObjectTypeCategoryDelete() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
CommandObjectTypeCategoryDisable(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTypeCategoryDisable() override=default
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectTypeCategoryEnable(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTypeCategoryEnable() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTypeCategoryList(CommandInterpreter &interpreter)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
~CommandObjectTypeCategoryList() override=default
CommandObjectTypeCategory(CommandInterpreter &interpreter)
~CommandObjectTypeCategory() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
~CommandObjectTypeFilterAdd() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTypeFilterAdd(CommandInterpreter &interpreter)
bool AddFilter(ConstString type_name, TypeFilterImplSP entry, FilterFormatType type, std::string category_name, Status *error)
CommandObjectTypeFilterClear(CommandInterpreter &interpreter)
CommandObjectTypeFilterDelete(CommandInterpreter &interpreter)
~CommandObjectTypeFilterDelete() override=default
CommandObjectTypeFilterList(CommandInterpreter &interpreter)
~CommandObjectTypeFilter() override=default
CommandObjectTypeFilter(CommandInterpreter &interpreter)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Options * GetOptions() override
CommandObjectTypeFormatAdd(CommandInterpreter &interpreter)
~CommandObjectTypeFormatAdd() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTypeFormatClear(CommandInterpreter &interpreter)
CommandObjectTypeFormatDelete(CommandInterpreter &interpreter)
~CommandObjectTypeFormatDelete() override=default
CommandObjectTypeFormatList(CommandInterpreter &interpreter)
CommandObjectTypeFormat(CommandInterpreter &interpreter)
~CommandObjectTypeFormat() override=default
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectTypeFormatterClear(CommandInterpreter &interpreter, FormatCategoryItem formatter_kind, const char *name, const char *help)
~CommandObjectTypeFormatterClear() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
static constexpr const char * g_long_help_template
virtual bool FormatterSpecificDeletion(ConstString typeCS)
static constexpr const char * g_short_help_template
~CommandObjectTypeFormatterDelete() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
CommandObjectTypeFormatterDelete(CommandInterpreter &interpreter, FormatCategoryItem formatter_kind)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
void DoExecute(Args &command, CommandReturnObject &result) override
FormatterType::SharedPointer FormatterSharedPointer
virtual bool FormatterSpecificList(CommandReturnObject &result)
static bool ShouldListItem(llvm::StringRef s, RegularExpression *regex)
CommandObjectTypeFormatterList(CommandInterpreter &interpreter, const char *name, const char *help)
~CommandObjectTypeFormatterList() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override
OptionGroupOptions m_option_group
void DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override
lldb::LanguageType GuessLanguage(StackFrame *frame)
~CommandObjectTypeLookup() override=default
llvm::StringRef GetHelpLong() override
CommandObjectTypeLookup(CommandInterpreter &interpreter)
Options * GetOptions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandOptions(CommandInterpreter &interpreter)
~CommandObjectTypeSummaryAdd() override=default
bool Execute_ScriptSummary(Args &command, CommandReturnObject &result)
void DoExecute(Args &command, CommandReturnObject &result) override
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
bool Execute_StringSummary(Args &command, CommandReturnObject &result)
CommandObjectTypeSummaryAdd(CommandInterpreter &interpreter)
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
bool AddNamedSummary(ConstString summary_name, lldb::TypeSummaryImplSP entry, Status *error=nullptr)
bool AddSummary(ConstString type_name, lldb::TypeSummaryImplSP entry, FormatterMatchType match_type, std::string category, Status *error=nullptr)
CommandObjectTypeSummaryClear(CommandInterpreter &interpreter)
~CommandObjectTypeSummaryDelete() override=default
CommandObjectTypeSummaryDelete(CommandInterpreter &interpreter)
bool FormatterSpecificDeletion(ConstString typeCS) override
CommandObjectTypeSummaryList(CommandInterpreter &interpreter)
bool FormatterSpecificList(CommandReturnObject &result) override
CommandObjectTypeSummary(CommandInterpreter &interpreter)
~CommandObjectTypeSummary() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
CommandObjectTypeSynthAdd(CommandInterpreter &interpreter)
bool Execute_PythonClass(Args &command, CommandReturnObject &result)
bool AddSynth(ConstString type_name, lldb::SyntheticChildrenSP entry, FormatterMatchType match_type, std::string category_name, Status *error)
Options * GetOptions() override
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTypeSynthAdd() override=default
bool Execute_HandwritePython(Args &command, CommandReturnObject &result)
CommandObjectTypeSynthClear(CommandInterpreter &interpreter)
CommandObjectTypeSynthDelete(CommandInterpreter &interpreter)
~CommandObjectTypeSynthDelete() override=default
CommandObjectTypeSynthList(CommandInterpreter &interpreter)
~CommandObjectTypeSynth() override=default
CommandObjectTypeSynth(CommandInterpreter &interpreter)
std::shared_ptr< ScriptAddOptions > SharedPointer
ScriptAddOptions(const TypeSummaryImpl::Flags &flags, FormatterMatchType match_type, ConstString name, std::string catg, uint32_t m_ptr_match_depth)
TypeSummaryImpl::Flags m_flags
FormatterMatchType m_match_type
SynthAddOptions(bool sptr, bool sref, bool casc, bool wants_deref, FormatterMatchType match_type, std::string catg)
FormatterMatchType m_match_type
std::shared_ptr< SynthAddOptions > SharedPointer
A command line argument class.
Definition Args.h:33
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition Args.h:120
llvm::ArrayRef< ArgEntry > entries() const
Definition Args.h:132
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Definition Args.cpp:273
bool empty() const
Definition Args.h:122
static bool InvokeCommonCompletionCallbacks(CommandInterpreter &interpreter, uint32_t completion_mask, lldb_private::CompletionRequest &request, SearchFilter *searcher)
ExecutionContext GetExecutionContext() const
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
CommandObjectMultiword(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectParsed(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectRaw(CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help="", llvm::StringRef syntax="", uint32_t flags=0)
CommandObjectType(CommandInterpreter &interpreter)
virtual void SetHelpLong(llvm::StringRef str)
void AddSimpleArgumentList(lldb::CommandArgumentType arg_type, ArgumentRepetitionType repetition_type=eArgRepeatPlain)
bool ParseOptionsAndNotify(Args &args, CommandReturnObject &result, OptionGroupOptions &group_options, ExecutionContext &exe_ctx)
CommandInterpreter & GetCommandInterpreter()
CommandInterpreter & m_interpreter
void SetSyntax(llvm::StringRef str)
void SetCommandName(llvm::StringRef name)
virtual void SetHelp(llvm::StringRef str)
void 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:134
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
@ eReturnStatusFailed
@ 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