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), 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),
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 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() {
2236}
2239 SyntheticChildrenSP entry,
2240 FormatterMatchType match_type,
2241 std::string category_name,
2242 Status *error) {
2245 category);
2246
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 if (error)
2264 "cannot add synthetic for type {0} when "
2265 "filter is defined in same category!",
2266 type_name);
2267 return false;
2268 }
2269 }
2270
2271 if (match_type == eFormatterMatchRegex) {
2272 RegularExpression typeRX(type_name.GetStringRef());
2273 if (!typeRX.IsValid()) {
2274 if (error)
2275 *error = Status::FromErrorString(
2276 "regex format error (maybe this is not really a regex?)");
2277 return false;
2278 }
2279 }
2280
2281 if (match_type == eFormatterMatchCallback) {
2282 const char *function_name = type_name.AsCString(nullptr);
2284 if (interpreter && !interpreter->CheckObjectExists(function_name)) {
2286 "The provided recognizer function \"%s\" does not exist - "
2287 "please define it before attempting to use this summary.\n",
2288 function_name);
2289 return false;
2290 }
2292
2293 category->AddTypeSynthetic(type_name.GetStringRef(), match_type, entry);
2294 return true;
2295}
2296
2297#define LLDB_OPTIONS_type_filter_add
2298#include "CommandOptions.inc"
2301private:
2302 class CommandOptions : public Options {
2303 typedef std::vector<std::string> option_vector;
2305 public:
2306 CommandOptions() = default;
2307
2308 ~CommandOptions() override = default;
2310 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2311 ExecutionContext *execution_context) override {
2312 Status error;
2313 const int short_option = m_getopt_table[option_idx].val;
2314 bool success;
2316 switch (short_option) {
2317 case 'C':
2318 m_cascade = OptionArgParser::ToBoolean(option_arg, true, &success);
2319 if (!success)
2321 "invalid value for cascade: %s", option_arg.str().c_str());
2322 break;
2323 case 'c':
2324 m_expr_paths.push_back(std::string(option_arg));
2325 has_child_list = true;
2326 break;
2327 case 'p':
2328 m_skip_pointers = true;
2329 break;
2330 case 'r':
2331 m_skip_references = true;
2332 break;
2333 case 'w':
2334 m_category = std::string(option_arg);
2335 break;
2336 case 'x':
2337 m_regex = true;
2338 break;
2339 default:
2340 llvm_unreachable("Unimplemented option");
2341 }
2342
2343 return error;
2344 }
2345
2346 void OptionParsingStarting(ExecutionContext *execution_context) override {
2347 m_cascade = true;
2348 m_skip_pointers = false;
2349 m_skip_references = false;
2350 m_category = "default";
2351 m_expr_paths.clear();
2352 has_child_list = false;
2353 m_regex = false;
2354 }
2355
2356 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2357 return llvm::ArrayRef(g_type_filter_add_options);
2358 }
2359
2360 // Instance variables to hold the values for command options.
2361
2362 bool m_cascade;
2363 bool m_skip_references;
2365 bool m_input_python;
2367 std::string m_category;
2368 bool has_child_list;
2369 bool m_regex;
2370
2371 typedef option_vector::iterator ExpressionPathsIterator;
2372 };
2373
2374 CommandOptions m_options;
2375
2376 Options *GetOptions() override { return &m_options; }
2377
2380 bool AddFilter(ConstString type_name, TypeFilterImplSP entry,
2381 FilterFormatType type, std::string category_name,
2383 lldb::TypeCategoryImplSP category;
2385 category);
2386
2387 if (type == eRegularFilter) {
2388 if (FixArrayTypeNameWithRegex(type_name))
2389 type = eRegexFilter;
2390 }
2391
2392 // Only check for conflicting synthetic child providers in the same category
2393 // if `type_name` is an actual type name. Matching a regex string against
2394 // registered regexes doesn't work.
2395 if (type == eRegularFilter) {
2396 // It's not generally possible to get a type object here. For example,
2397 // this command can be run before loading any binaries. Do just a
2398 // best-effort name-based lookup here to try to prevent conflicts.
2399 FormattersMatchCandidate candidate_type(
2400 type_name, nullptr, TypeImpl(), FormattersMatchCandidate::Flags());
2402 if (category->AnyMatches(candidate_type, eFormatCategoryItemSynth)) {
2403 if (error)
2405 "cannot add filter for type {0} when "
2406 "synthetic is defined in same "
2407 "category!",
2408 type_name);
2409 return false;
2410 }
2411 }
2412
2414 if (type == eRegexFilter) {
2415 match_type = eFormatterMatchRegex;
2416 RegularExpression typeRX(type_name.GetStringRef());
2417 if (!typeRX.IsValid()) {
2418 if (error)
2420 "regex format error (maybe this is not really a regex?)");
2421 return false;
2422 }
2423 }
2424 category->AddTypeFilter(type_name.GetStringRef(), match_type, entry);
2425 return true;
2426 }
2427
2428public:
2430 : CommandObjectParsed(interpreter, "type filter add",
2431 "Add a new filter for a type.", nullptr) {
2433
2435 R"(
2436The following examples of 'type filter add' refer to this code snippet for context:
2437
2438 class Foo {
2439 int a;
2440 int b;
2441 int c;
2442 int d;
2443 int e;
2444 int f;
2445 int g;
2446 int h;
2447 int i;
2448 }
2449 Foo my_foo;
2450
2451Adding a simple filter:
2452
2453(lldb) type filter add --child a --child g Foo
2454(lldb) frame variable my_foo
2455
2456)"
2457 "Produces output where only a and g are displayed. Other children of my_foo \
2458(b, c, d, e, f, h and i) are available by asking for them explicitly:"
2459 R"(
2460
2461(lldb) frame variable my_foo.b my_foo.c my_foo.i
2462
2463)"
2464 "The formatting option --raw on frame variable bypasses the filter, showing \
2465all children of my_foo as if no filter was defined:"
2466 R"(
2468(lldb) frame variable my_foo --raw)");
2469 }
2471 ~CommandObjectTypeFilterAdd() override = default;
2472
2473protected:
2474 void DoExecute(Args &command, CommandReturnObject &result) override {
2475 const size_t argc = command.GetArgumentCount();
2476
2477 if (argc < 1) {
2478 result.AppendErrorWithFormat("%s takes one or more args",
2479 m_cmd_name.c_str());
2480 return;
2481 }
2482
2483 if (m_options.m_expr_paths.empty()) {
2484 result.AppendErrorWithFormat("%s needs one or more children",
2485 m_cmd_name.c_str());
2486 return;
2487 }
2488
2489 TypeFilterImplSP entry(new TypeFilterImpl(
2490 SyntheticChildren::Flags()
2491 .SetCascades(m_options.m_cascade)
2492 .SetSkipPointers(m_options.m_skip_pointers)
2493 .SetSkipReferences(m_options.m_skip_references)));
2495 // go through the expression paths
2497 end = m_options.m_expr_paths.end();
2499 for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
2500 entry->AddExpressionPath(*begin);
2501
2502 // now I have a valid provider, let's add it to every type
2503
2504 lldb::TypeCategoryImplSP category;
2506 ConstString(m_options.m_category), category);
2507
2508 Status error;
2509
2510 WarnOnPotentialUnquotedUnsignedType(command, result);
2511
2512 for (auto &arg_entry : command.entries()) {
2513 if (arg_entry.ref().empty()) {
2514 result.AppendError("empty typenames not allowed");
2515 return;
2516 }
2517
2518 ConstString typeCS(arg_entry.ref());
2519 if (!AddFilter(typeCS, entry,
2522 result.AppendError(error.AsCString());
2523 return;
2528 }
2529};
2530
2531// "type lookup"
2532#define LLDB_OPTIONS_type_lookup
2533#include "CommandOptions.inc"
2534
2536protected:
2537 // this function is allowed to do a more aggressive job at guessing languages
2538 // than the expression parser is comfortable with - so leave the original
2539 // call alone and add one that is specific to type lookup
2542
2543 if (!frame)
2544 return lang_type;
2545
2546 lang_type = frame->GuessLanguage().AsLanguageType();
2547 if (lang_type != lldb::eLanguageTypeUnknown)
2548 return lang_type;
2550 const Symbol *s = frame->GetSymbolContext(eSymbolContextSymbol).symbol;
2551 if (s)
2552 lang_type = s->GetMangled().GuessLanguage();
2554 return lang_type;
2555 }
2556
2557 class CommandOptions : public OptionGroup {
2558 public:
2559 CommandOptions() = default;
2560
2561 ~CommandOptions() override = default;
2562
2563 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2564 return llvm::ArrayRef(g_type_lookup_options);
2565 }
2566
2567 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
2568 ExecutionContext *execution_context) override {
2569 Status error;
2570
2571 const int short_option = g_type_lookup_options[option_idx].short_option;
2572
2573 switch (short_option) {
2574 case 'h':
2575 m_show_help = true;
2576 break;
2577
2578 case 'l':
2580 break;
2581
2582 default:
2583 llvm_unreachable("Unimplemented option");
2584 }
2585
2586 return error;
2587 }
2588
2589 void OptionParsingStarting(ExecutionContext *execution_context) override {
2590 m_show_help = false;
2592 }
2593
2594 // Options table: Required for subclasses of Options.
2595
2596 bool m_show_help = false;
2598 };
2599
2600 OptionGroupOptions m_option_group;
2602
2603public:
2604 CommandObjectTypeLookup(CommandInterpreter &interpreter)
2605 : CommandObjectRaw(interpreter, "type lookup",
2606 "Lookup types and declarations in the current target, "
2607 "following language-specific naming conventions.",
2608 "type lookup <type-specifier>",
2609 eCommandRequiresTarget) {
2611 m_option_group.Finalize();
2612 }
2613
2614 ~CommandObjectTypeLookup() override = default;
2615
2616 Options *GetOptions() override { return &m_option_group; }
2617
2618 llvm::StringRef GetHelpLong() override {
2619 if (!m_cmd_help_long.empty())
2620 return m_cmd_help_long;
2621
2622 StreamString stream;
2623 Language::ForEach([&](Language *lang) {
2624 if (const char *help = lang->GetLanguageSpecificTypeLookupHelp())
2625 stream.Printf("%s\n", help);
2626 return IterationAction::Continue;
2627 });
2628
2629 m_cmd_help_long = std::string(stream.GetString());
2630 return m_cmd_help_long;
2631 }
2632
2633 void DoExecute(llvm::StringRef raw_command_line,
2634 CommandReturnObject &result) override {
2635 if (raw_command_line.empty()) {
2636 result.AppendError(
2637 "type lookup cannot be invoked without a type name as argument");
2638 return;
2639 }
2640
2641 auto exe_ctx = GetCommandInterpreter().GetExecutionContext();
2642 m_option_group.NotifyOptionParsingStarting(&exe_ctx);
2643
2644 OptionsWithRaw args(raw_command_line);
2645 const char *name_of_type = args.GetRawPart().c_str();
2646
2647 if (args.HasArgs())
2648 if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group,
2649 exe_ctx))
2650 return;
2651
2652 ExecutionContextScope *best_scope = exe_ctx.GetBestExecutionContextScope();
2653
2654 bool any_found = false;
2655
2656 std::vector<Language *> languages;
2657
2658 bool is_global_search = false;
2659 LanguageType guessed_language = lldb::eLanguageTypeUnknown;
2660
2661 if ((is_global_search =
2662 (m_command_options.m_language == eLanguageTypeUnknown))) {
2663 Language::ForEach([&](Language *lang) {
2664 languages.push_back(lang);
2665 return IterationAction::Continue;
2666 });
2667 } else {
2668 languages.push_back(Language::FindPlugin(m_command_options.m_language));
2669 }
2670
2671 // This is not the most efficient way to do this, but we support very few
2672 // languages so the cost of the sort is going to be dwarfed by the actual
2673 // lookup anyway
2674 if (StackFrame *frame = m_exe_ctx.GetFramePtr()) {
2675 guessed_language = GuessLanguage(frame);
2676 if (guessed_language != eLanguageTypeUnknown) {
2677 llvm::sort(
2678 languages.begin(), languages.end(),
2679 [guessed_language](Language *lang1, Language *lang2) -> bool {
2680 if (!lang1 || !lang2)
2681 return false;
2682 LanguageType lt1 = lang1->GetLanguageType();
2683 LanguageType lt2 = lang2->GetLanguageType();
2684 if (lt1 == lt2)
2685 return false;
2686 if (lt1 == guessed_language)
2687 return true; // make the selected frame's language come first
2688 if (lt2 == guessed_language)
2689 return false; // make the selected frame's language come first
2690 return (lt1 < lt2); // normal comparison otherwise
2691 });
2692 }
2693 }
2695 bool is_first_language = true;
2696
2697 for (Language *language : languages) {
2698 if (!language)
2699 continue;
2700
2701 if (auto scavenger = language->GetTypeScavenger()) {
2703 if (scavenger->Find(best_scope, name_of_type, search_results) > 0) {
2704 for (const auto &search_result : search_results) {
2705 if (search_result && search_result->IsValid()) {
2706 any_found = true;
2707 search_result->DumpToStream(result.GetOutputStream(),
2708 this->m_command_options.m_show_help);
2709 }
2710 }
2711 }
2712 }
2713 // this is "type lookup SomeName" and we did find a match, so get out
2714 if (any_found && is_global_search)
2715 break;
2716 else if (is_first_language && is_global_search &&
2717 guessed_language != lldb::eLanguageTypeUnknown) {
2718 is_first_language = false;
2719 result.GetOutputStream().Printf(
2720 "no type was found in the current language %s matching '%s'; "
2721 "performing a global search across all languages\n",
2722 Language::GetNameForLanguageType(guessed_language), name_of_type);
2723 }
2724 }
2725
2726 if (!any_found)
2727 result.AppendMessageWithFormatv("no type was found matching '{0}'",
2728 name_of_type);
2729
2732 }
2733};
2734
2735template <typename FormatterType>
2737public:
2738 typedef std::function<typename FormatterType::SharedPointer(ValueObject &)>
2741 const char *formatter_name,
2742 DiscoveryFunction discovery_func)
2743 : CommandObjectRaw(interpreter, "", "", "", eCommandRequiresFrame),
2744 m_formatter_name(formatter_name ? formatter_name : ""),
2745 m_discovery_function(discovery_func) {
2747 name.Printf("type %s info", formatter_name);
2748 SetCommandName(name.GetString());
2749 StreamString help;
2750 help.Printf("This command evaluates the provided expression and shows "
2751 "which %s is applied to the resulting value (if any).",
2752 formatter_name);
2753 SetHelp(help.GetString());
2754 StreamString syntax;
2755 syntax.Printf("type %s info <expr>", formatter_name);
2756 SetSyntax(syntax.GetString());
2757 }
2758
2759 ~CommandObjectFormatterInfo() override = default;
2760
2761protected:
2762 void DoExecute(llvm::StringRef command,
2763 CommandReturnObject &result) override {
2764 Target *target = GetTarget();
2765 assert(target && "target guaranteed by eCommandRequiresFrame");
2766 Thread *thread = GetDefaultThread();
2767 if (!thread) {
2768 result.AppendError("no default thread");
2769 return;
2771
2772 StackFrameSP frame_sp =
2773 thread->GetSelectedFrame(DoNoSelectMostRelevantFrame);
2774 ValueObjectSP result_valobj_sp;
2776 lldb::ExpressionResults expr_result = target->EvaluateExpression(
2777 command, frame_sp.get(), result_valobj_sp, options);
2778 if (expr_result == eExpressionCompleted && result_valobj_sp) {
2779 result_valobj_sp =
2780 result_valobj_sp->GetQualifiedRepresentationIfAvailable(
2781 target->GetPreferDynamicValue(),
2782 target->GetEnableSyntheticValue());
2783 typename FormatterType::SharedPointer formatter_sp =
2784 m_discovery_function(*result_valobj_sp);
2785 if (formatter_sp) {
2786 std::string description(formatter_sp->GetDescription());
2787 result.GetOutputStream()
2788 << m_formatter_name << " applied to ("
2789 << result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>")
2790 << ") " << command << " is: " << description << "\n";
2792 } else {
2793 result.GetOutputStream()
2794 << "no " << m_formatter_name << " applies to ("
2795 << result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>")
2796 << ") " << command << "\n";
2798 }
2799 } else {
2800 result.AppendError("failed to evaluate expression");
2801 }
2802 }
2803
2804private:
2805 std::string m_formatter_name;
2807};
2808
2810public:
2813 interpreter, "type format",
2814 "Commands for customizing value display formats.",
2815 "type format [<sub-command-options>] ") {
2817 "add", CommandObjectSP(new CommandObjectTypeFormatAdd(interpreter)));
2819 new CommandObjectTypeFormatClear(interpreter)));
2821 interpreter)));
2823 "list", CommandObjectSP(new CommandObjectTypeFormatList(interpreter)));
2826 interpreter, "format",
2828 return valobj.GetValueFormat();
2829 })));
2830 }
2831
2832 ~CommandObjectTypeFormat() override = default;
2833};
2834
2836public:
2839 interpreter, "type synthetic",
2840 "Commands for operating on synthetic type representations.",
2841 "type synthetic [<sub-command-options>] ") {
2842 LoadSubCommand("add",
2845 "clear", CommandObjectSP(new CommandObjectTypeSynthClear(interpreter)));
2847 interpreter)));
2849 "list", CommandObjectSP(new CommandObjectTypeSynthList(interpreter)));
2851 "info",
2853 interpreter, "synthetic",
2855 return valobj.GetSyntheticChildren();
2856 })));
2857 }
2858
2859 ~CommandObjectTypeSynth() override = default;
2860};
2861
2863public:
2865 : CommandObjectMultiword(interpreter, "type filter",
2866 "Commands for operating on type filters.",
2867 "type filter [<sub-command-options>] ") {
2871 new CommandObjectTypeFilterClear(interpreter)));
2873 interpreter)));
2875 "list", CommandObjectSP(new CommandObjectTypeFilterList(interpreter)));
2876 }
2877
2878 ~CommandObjectTypeFilter() override = default;
2879};
2880
2882public:
2884 : CommandObjectMultiword(interpreter, "type category",
2885 "Commands for operating on type categories.",
2886 "type category [<sub-command-options>] ") {
2888 "define",
2891 "enable",
2894 "disable",
2897 "delete",
2900 new CommandObjectTypeCategoryList(interpreter)));
2901 }
2902
2903 ~CommandObjectTypeCategory() override = default;
2904};
2905
2907public:
2910 interpreter, "type summary",
2911 "Commands for editing variable summary display options.",
2912 "type summary [<sub-command-options>] ") {
2914 "add", CommandObjectSP(new CommandObjectTypeSummaryAdd(interpreter)));
2915 LoadSubCommand("clear", CommandObjectSP(new CommandObjectTypeSummaryClear(
2916 interpreter)));
2917 LoadSubCommand("delete", CommandObjectSP(new CommandObjectTypeSummaryDelete(
2918 interpreter)));
2920 "list", CommandObjectSP(new CommandObjectTypeSummaryList(interpreter)));
2922 "info", CommandObjectSP(new CommandObjectFormatterInfo<TypeSummaryImpl>(
2923 interpreter, "summary",
2924 [](ValueObject &valobj) -> TypeSummaryImpl::SharedPointer {
2925 return valobj.GetSummaryFormat();
2926 })));
2927 }
2928
2929 ~CommandObjectTypeSummary() override = default;
2930};
2931
2932// CommandObjectType
2933
2935 : CommandObjectMultiword(interpreter, "type",
2936 "Commands for operating on the type system.",
2937 "type [<sub-command-options>]") {
2938 LoadSubCommand("category",
2939 CommandObjectSP(new CommandObjectTypeCategory(interpreter)));
2940 LoadSubCommand("filter",
2941 CommandObjectSP(new CommandObjectTypeFilter(interpreter)));
2942 LoadSubCommand("format",
2943 CommandObjectSP(new CommandObjectTypeFormat(interpreter)));
2944 LoadSubCommand("summary",
2945 CommandObjectSP(new CommandObjectTypeSummary(interpreter)));
2946 LoadSubCommand("synthetic",
2947 CommandObjectSP(new CommandObjectTypeSynth(interpreter)));
2948 LoadSubCommand("lookup",
2949 CommandObjectSP(new CommandObjectTypeLookup(interpreter)));
2950}
2951
2953
static const char * g_synth_addreader_instructions
static bool WarnOnPotentialUnquotedUnsignedType(Args &command, CommandReturnObject &result)
const char * FormatCategoryToString(FormatCategoryItem item, bool long_name)
static bool FixArrayTypeNameWithRegex(ConstString &type_name)
static llvm::raw_ostream & error(Stream &strm)
~CommandObjectFormatterInfo() override=default
CommandObjectFormatterInfo(CommandInterpreter &interpreter, const char *formatter_name, DiscoveryFunction discovery_func)
void DoExecute(llvm::StringRef command, CommandReturnObject &result) override
std::function< typename FormatterType::SharedPointer(ValueObject &)> DiscoveryFunction
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
CommandObjectTypeCategoryDefine(CommandInterpreter &interpreter)
~CommandObjectTypeCategoryDefine() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTypeCategoryDelete(CommandInterpreter &interpreter)
~CommandObjectTypeCategoryDelete() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
CommandObjectTypeCategoryDisable(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTypeCategoryDisable() override=default
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectTypeCategoryEnable(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTypeCategoryEnable() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTypeCategoryList(CommandInterpreter &interpreter)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
~CommandObjectTypeCategoryList() override=default
CommandObjectTypeCategory(CommandInterpreter &interpreter)
~CommandObjectTypeCategory() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
~CommandObjectTypeFilterAdd() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTypeFilterAdd(CommandInterpreter &interpreter)
bool AddFilter(ConstString type_name, TypeFilterImplSP entry, FilterFormatType type, std::string category_name, Status *error)
CommandObjectTypeFilterClear(CommandInterpreter &interpreter)
CommandObjectTypeFilterDelete(CommandInterpreter &interpreter)
~CommandObjectTypeFilterDelete() override=default
CommandObjectTypeFilterList(CommandInterpreter &interpreter)
~CommandObjectTypeFilter() override=default
CommandObjectTypeFilter(CommandInterpreter &interpreter)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Options * GetOptions() override
CommandObjectTypeFormatAdd(CommandInterpreter &interpreter)
~CommandObjectTypeFormatAdd() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTypeFormatClear(CommandInterpreter &interpreter)
CommandObjectTypeFormatDelete(CommandInterpreter &interpreter)
~CommandObjectTypeFormatDelete() override=default
CommandObjectTypeFormatList(CommandInterpreter &interpreter)
CommandObjectTypeFormat(CommandInterpreter &interpreter)
~CommandObjectTypeFormat() override=default
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectTypeFormatterClear(CommandInterpreter &interpreter, FormatCategoryItem formatter_kind, const char *name, const char *help)
~CommandObjectTypeFormatterClear() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
static constexpr const char * g_long_help_template
virtual bool FormatterSpecificDeletion(ConstString typeCS)
static constexpr const char * g_short_help_template
~CommandObjectTypeFormatterDelete() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
CommandObjectTypeFormatterDelete(CommandInterpreter &interpreter, FormatCategoryItem formatter_kind)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
void DoExecute(Args &command, CommandReturnObject &result) override
FormatterType::SharedPointer FormatterSharedPointer
virtual bool FormatterSpecificList(CommandReturnObject &result)
static bool ShouldListItem(llvm::StringRef s, RegularExpression *regex)
CommandObjectTypeFormatterList(CommandInterpreter &interpreter, const char *name, const char *help)
~CommandObjectTypeFormatterList() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override
OptionGroupOptions m_option_group
void DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override
lldb::LanguageType GuessLanguage(StackFrame *frame)
~CommandObjectTypeLookup() override=default
llvm::StringRef GetHelpLong() override
CommandObjectTypeLookup(CommandInterpreter &interpreter)
Options * GetOptions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandOptions(CommandInterpreter &interpreter)
~CommandObjectTypeSummaryAdd() override=default
bool Execute_ScriptSummary(Args &command, CommandReturnObject &result)
void DoExecute(Args &command, CommandReturnObject &result) override
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
bool Execute_StringSummary(Args &command, CommandReturnObject &result)
CommandObjectTypeSummaryAdd(CommandInterpreter &interpreter)
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
bool AddNamedSummary(ConstString summary_name, lldb::TypeSummaryImplSP entry, Status *error=nullptr)
bool AddSummary(ConstString type_name, lldb::TypeSummaryImplSP entry, FormatterMatchType match_type, std::string category, Status *error=nullptr)
CommandObjectTypeSummaryClear(CommandInterpreter &interpreter)
~CommandObjectTypeSummaryDelete() override=default
CommandObjectTypeSummaryDelete(CommandInterpreter &interpreter)
bool FormatterSpecificDeletion(ConstString typeCS) override
CommandObjectTypeSummaryList(CommandInterpreter &interpreter)
bool FormatterSpecificList(CommandReturnObject &result) override
CommandObjectTypeSummary(CommandInterpreter &interpreter)
~CommandObjectTypeSummary() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
CommandObjectTypeSynthAdd(CommandInterpreter &interpreter)
bool Execute_PythonClass(Args &command, CommandReturnObject &result)
bool AddSynth(ConstString type_name, lldb::SyntheticChildrenSP entry, FormatterMatchType match_type, std::string category_name, Status *error)
Options * GetOptions() override
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTypeSynthAdd() override=default
bool Execute_HandwritePython(Args &command, CommandReturnObject &result)
CommandObjectTypeSynthClear(CommandInterpreter &interpreter)
CommandObjectTypeSynthDelete(CommandInterpreter &interpreter)
~CommandObjectTypeSynthDelete() override=default
CommandObjectTypeSynthList(CommandInterpreter &interpreter)
~CommandObjectTypeSynth() override=default
CommandObjectTypeSynth(CommandInterpreter &interpreter)
std::shared_ptr< ScriptAddOptions > SharedPointer
ScriptAddOptions(const TypeSummaryImpl::Flags &flags, FormatterMatchType match_type, ConstString name, std::string catg, uint32_t m_ptr_match_depth)
TypeSummaryImpl::Flags m_flags
FormatterMatchType m_match_type
SynthAddOptions(bool sptr, bool sref, bool casc, bool wants_deref, FormatterMatchType match_type, std::string catg)
FormatterMatchType m_match_type
std::shared_ptr< SynthAddOptions > SharedPointer
A command line argument class.
Definition Args.h:33
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition Args.h:120
llvm::ArrayRef< ArgEntry > entries() const
Definition Args.h:132
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Definition Args.cpp:273
bool empty() const
Definition Args.h:122
static bool InvokeCommonCompletionCallbacks(CommandInterpreter &interpreter, uint32_t completion_mask, lldb_private::CompletionRequest &request, SearchFilter *searcher)
ExecutionContext GetExecutionContext(bool adopt_dummy_target=true) const
Returns the execution context the interpreter should run a command in.
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)
Target * GetTarget()
Get the target this command should operate on.
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)
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:55
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:416
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 IsValid() const
Test if this object contains a valid regular expression.
bool Execute(llvm::StringRef string, llvm::SmallVectorImpl< llvm::StringRef > *matches=nullptr) const
Execute a regular expression match using the compiled regular expression that is already in this obje...
llvm::StringRef GetText() const
Access the regular expression text.
virtual bool GenerateTypeScriptFunction(const char *oneliner, std::string &output, const void *name_token=nullptr)
virtual bool GenerateTypeSynthClass(StringList &input, std::string &output, const void *name_token=nullptr)
virtual bool CheckObjectExists(const char *name)
This base class provides an interface to stack frames.
Definition StackFrame.h: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
bool GetEnableSyntheticValue() const
Definition Target.cpp:5565
lldb::DynamicValueType GetPreferDynamicValue() const
Definition Target.cpp:5215
lldb::ExpressionResults EvaluateExpression(llvm::StringRef expression, ExecutionContextScope *exe_scope, lldb::ValueObjectSP &result_valobj_sp, const EvaluateExpressionOptions &options=EvaluateExpressionOptions(), std::string *fixed_expression=nullptr, ValueObject *ctx_obj=nullptr)
Definition Target.cpp:2941
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.
@ 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
static bool ToBoolean(llvm::StringRef s, bool fail_value, bool *success_ptr)
lldb::LanguageType AsLanguageType() const
Definition Language.cpp:614