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"
29#include "lldb/Symbol/Symbol.h"
32#include "lldb/Target/Target.h"
33#include "lldb/Target/Thread.h"
37#include "lldb/lldb-forward.h"
38
39#include "llvm/ADT/STLExtras.h"
40
41#include <algorithm>
42#include <functional>
43#include <memory>
44
45using namespace lldb;
46using namespace lldb_private;
47
49public:
54 std::string m_category;
56
58 FormatterMatchType match_type, ConstString name,
59 std::string catg, uint32_t m_ptr_match_depth)
60 : m_flags(flags), m_match_type(match_type), m_name(name),
62
63 typedef std::shared_ptr<ScriptAddOptions> SharedPointer;
64};
65
67public:
74 std::string m_category;
75
76 SynthAddOptions(bool sptr, bool sref, bool casc, bool wants_deref,
77 FormatterMatchType match_type, std::string catg)
78 : m_skip_pointers(sptr), m_skip_references(sref), m_cascade(casc),
79 m_wants_deref(wants_deref), m_match_type(match_type), m_category(catg) {
80 }
81
82 typedef std::shared_ptr<SynthAddOptions> SharedPointer;
83};
84
86 CommandReturnObject &result) {
87 if (command.empty())
88 return false;
89
90 for (auto entry : llvm::enumerate(command.entries().drop_back())) {
91 if (entry.value().ref() != "unsigned")
92 continue;
93 auto next = command.entries()[entry.index() + 1].ref();
94 if (next == "int" || next == "short" || next == "char" || next == "long") {
96 "unsigned {0} being treated as two types. if you meant the combined "
97 "type name use quotes, as in \"unsigned {0}\"",
98 next);
99 return true;
100 }
101 }
102 return false;
103}
104
105const char *FormatCategoryToString(FormatCategoryItem item, bool long_name) {
106 switch (item) {
108 return "summary";
110 return "filter";
112 if (long_name)
113 return "synthetic child provider";
114 return "synthetic";
116 return "format";
117 }
118 llvm_unreachable("Fully covered switch above!");
119}
120
121#define LLDB_OPTIONS_type_summary_add
122#include "CommandOptions.inc"
123
126private:
128 public:
129 CommandOptions() = default;
130
131 ~CommandOptions() override = default;
132
133 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
134 ExecutionContext *execution_context) override;
135
136 void OptionParsingStarting(ExecutionContext *execution_context) override;
137
138 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
139 return llvm::ArrayRef(g_type_summary_add_options);
140 }
141
142 // Instance variables to hold the values for command options.
143
146 std::string m_format_string;
147 std::string m_name;
148 std::string m_python_script;
149 std::string m_python_function;
150 bool m_is_add_script = false;
151 std::string m_category;
152 uint32_t m_ptr_match_depth = 1;
153 };
154
158
159 Options *GetOptions() override { return &m_option_group; }
160
162
164
165 bool Execute_StringSummary(Args &command, CommandReturnObject &result);
166
167public:
169
170 ~CommandObjectTypeSummaryAdd() override = default;
171
172 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
173 static const char *g_summary_addreader_instructions =
174 "Enter your Python command(s). Type 'DONE' to end.\n"
175 "def function (valobj,internal_dict):\n"
176 " \"\"\"valobj: an SBValue which you want to provide a summary "
177 "for\n"
178 " internal_dict: an LLDB support object not to be used\"\"\"\n";
179
180 if (interactive) {
181 if (LockableStreamFileSP output_sp = io_handler.GetOutputStreamFileSP()) {
182 LockedStreamFile locked_stream = output_sp->Lock();
183 locked_stream.PutCString(g_summary_addreader_instructions);
184 }
185 }
186 }
187
189 std::string &data) override {
190 LockableStreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
191
192#if LLDB_ENABLE_PYTHON
194 if (interpreter) {
195 StringList lines;
196 lines.SplitIntoLines(data);
197 if (lines.GetSize() > 0) {
198 ScriptAddOptions *options_ptr =
199 ((ScriptAddOptions *)io_handler.GetUserData());
200 if (options_ptr) {
202 options_ptr); // this will ensure that we get rid of the pointer
203 // when going out of scope
204
206 if (interpreter) {
207 std::string funct_name_str;
208 if (interpreter->GenerateTypeScriptFunction(lines,
209 funct_name_str)) {
210 if (funct_name_str.empty()) {
211 LockedStreamFile locked_stream = error_sp->Lock();
212 locked_stream.Printf(
213 "unable to obtain a valid function name from "
214 "the script interpreter.\n");
215 } else {
216 // now I have a valid function name, let's add this as script
217 // for every type in the list
218
219 TypeSummaryImplSP script_format;
220 script_format = std::make_shared<ScriptSummaryFormat>(
221 options->m_flags, funct_name_str.c_str(),
222 lines.CopyList(" ").c_str(), options->m_ptr_match_depth);
223
225
226 for (const std::string &type_name : options->m_target_types) {
227 AddSummary(type_name, script_format, options->m_match_type,
228 options->m_category, &error);
229 if (error.Fail()) {
230 LockedStreamFile locked_stream = error_sp->Lock();
231 locked_stream.Printf("error: %s", error.AsCString());
232 }
233 }
234
235 if (options->m_name) {
237 options->m_name.GetStringRef().str(), script_format,
238 &error);
239 if (error.Fail()) {
241 options->m_name.GetStringRef().str(), script_format,
242 &error);
243 if (error.Fail()) {
244 LockedStreamFile locked_stream = error_sp->Lock();
245 locked_stream.Printf("error: %s", error.AsCString());
246 }
247 } else {
248 LockedStreamFile locked_stream = error_sp->Lock();
249 locked_stream.Printf("error: %s", error.AsCString());
250 }
251 } else {
252 if (error.AsCString()) {
253 LockedStreamFile locked_stream = error_sp->Lock();
254 locked_stream.Printf("error: %s", error.AsCString());
255 }
256 }
257 }
258 } else {
259 LockedStreamFile locked_stream = error_sp->Lock();
260 locked_stream.PutCString(
261 "error: unable to generate a function.\n");
262 }
263 } else {
264 LockedStreamFile locked_stream = error_sp->Lock();
265 locked_stream.PutCString("error: no script interpreter.\n");
266 }
267 } else {
268 LockedStreamFile locked_stream = error_sp->Lock();
269 locked_stream.Printf("error: internal synchronization information "
270 "missing or invalid.\n");
271 }
272 } else {
273 LockedStreamFile locked_stream = error_sp->Lock();
274 locked_stream.Printf(
275 "error: empty function, didn't add python command.\n");
276 }
277 } else {
278 LockedStreamFile locked_stream = error_sp->Lock();
279 locked_stream.Printf(
280 "error: script interpreter missing, didn't add python command.\n");
281 }
282#endif
283 io_handler.SetIsDone(true);
284 }
285
286 bool AddSummary(std::string type_name, lldb::TypeSummaryImplSP entry,
287 FormatterMatchType match_type, std::string category,
288 Status *error = nullptr);
289
290 bool AddNamedSummary(std::string summary_name, lldb::TypeSummaryImplSP entry,
291 Status *error = nullptr);
292
293protected:
294 void DoExecute(Args &command, CommandReturnObject &result) override;
295};
296
298 "Enter your Python command(s). Type 'DONE' to end.\n"
299 "You must define a Python class with these methods:\n"
300 " def __init__(self, valobj: lldb.SBValue, internal_dict):\n"
301 " def num_children(self) -> int:\n"
302 " def get_child_at_index(self, index: int) -> lldb.SBValue | None:\n"
303 " def get_child_index(self, name: str) -> int:\n"
304 " def update(self) -> bool:\n"
305 " '''Optional'''\n"
306 "class synthProvider:\n";
307
308#define LLDB_OPTIONS_type_synth_add
309#include "CommandOptions.inc"
310
313private:
314 class CommandOptions : public Options {
315 public:
316 CommandOptions() = default;
317
318 ~CommandOptions() override = default;
319
320 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
321 ExecutionContext *execution_context) override {
323 const int short_option = m_getopt_table[option_idx].val;
324 bool success;
325
326 switch (short_option) {
327 case 'C':
328 m_cascade = OptionArgParser::ToBoolean(option_arg, true, &success);
329 if (!success)
331 "invalid value for cascade: %s", option_arg.str().c_str());
332 break;
333 case 'D':
334 m_wants_deref = OptionArgParser::ToBoolean(option_arg, true, &success);
335 if (!success)
337 "invalid value for wants-dereference: %s",
338 option_arg.str().c_str());
339 break;
340 case 'P':
341 handwrite_python = true;
342 break;
343 case 'l':
344 m_class_name = std::string(option_arg);
345 is_class_based = true;
346 break;
347 case 'p':
348 m_skip_pointers = true;
349 break;
350 case 'r':
351 m_skip_references = true;
352 break;
353 case 'w':
354 m_category = std::string(option_arg);
355 break;
356 case 'x':
359 "can't use --regex and --recognizer-function at the same time");
360 else
362 break;
363 case '\x01':
366 "can't use --regex and --recognizer-function at the same time");
367 else
369 break;
370 default:
371 llvm_unreachable("Unimplemented option");
372 }
373
374 return error;
375 }
376
377 void OptionParsingStarting(ExecutionContext *execution_context) override {
378 m_cascade = true;
379 m_wants_deref = true;
380 m_class_name = "";
381 m_skip_pointers = false;
382 m_skip_references = false;
383 m_category = "default";
384 is_class_based = false;
385 handwrite_python = false;
387 }
388
389 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
390 return llvm::ArrayRef(g_type_synth_add_options);
391 }
392
393 // Instance variables to hold the values for command options.
394
399 std::string m_class_name;
401 std::string m_category;
405 };
406
408
409 Options *GetOptions() override { return &m_options; }
410
411 bool Execute_HandwritePython(Args &command, CommandReturnObject &result);
412
413 bool Execute_PythonClass(Args &command, CommandReturnObject &result);
414
415protected:
416 void DoExecute(Args &command, CommandReturnObject &result) override {
418
419 if (m_options.handwrite_python)
420 Execute_HandwritePython(command, result);
421 else if (m_options.is_class_based)
422 Execute_PythonClass(command, result);
423 else {
424 result.AppendError("must either provide a children list, a Python class "
425 "name, or use -P and type a Python class "
426 "line-by-line");
427 }
428 }
429
430 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
431 if (interactive) {
432 if (LockableStreamFileSP output_sp = io_handler.GetOutputStreamFileSP()) {
433 LockedStreamFile locked_stream = output_sp->Lock();
435 }
436 }
437 }
438
440 std::string &data) override {
441 LockableStreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
442
443#if LLDB_ENABLE_PYTHON
445 if (interpreter) {
446 StringList lines;
447 lines.SplitIntoLines(data);
448 if (lines.GetSize() > 0) {
449 SynthAddOptions *options_ptr =
450 ((SynthAddOptions *)io_handler.GetUserData());
451 if (options_ptr) {
453 options_ptr); // this will ensure that we get rid of the pointer
454 // when going out of scope
455
457 if (interpreter) {
458 std::string class_name_str;
459 if (interpreter->GenerateTypeSynthClass(lines, class_name_str)) {
460 if (class_name_str.empty()) {
461
462 LockedStreamFile locked_stream = error_sp->Lock();
463 locked_stream.Printf(
464 "error: unable to obtain a proper name for the class.\n");
465 } else {
466 // everything should be fine now, let's add the synth provider
467 // class
468
469 SyntheticChildrenSP synth_provider;
470 synth_provider = std::make_shared<ScriptedSyntheticChildren>(
472 .SetCascades(options->m_cascade)
473 .SetSkipPointers(options->m_skip_pointers)
474 .SetSkipReferences(options->m_skip_references)
475 .SetFrontEndWantsDereference(options->m_wants_deref),
476 class_name_str.c_str());
477
480 ConstString(options->m_category), category);
481
483
484 for (const std::string &type_name : options->m_target_types) {
485 if (!type_name.empty()) {
486 if (AddSynth(type_name, synth_provider,
487 options->m_match_type, options->m_category,
488 &error)) {
489 LockedStreamFile locked_stream = error_sp->Lock();
490 locked_stream.Printf("error: %s\n", error.AsCString());
491 break;
492 }
493 } else {
494 LockedStreamFile locked_stream = error_sp->Lock();
495 locked_stream.PutCString("error: invalid type name.\n");
496 break;
497 }
498 }
499 }
500 } else {
501 LockedStreamFile locked_stream = error_sp->Lock();
502 locked_stream.PutCString("error: unable to generate a class.\n");
503 }
504 } else {
505 LockedStreamFile locked_stream = error_sp->Lock();
506 locked_stream.PutCString("error: no script interpreter.\n");
507 }
508 } else {
509 LockedStreamFile locked_stream = error_sp->Lock();
510 locked_stream.Printf(
511 "error: internal synchronization data missing.\n");
512 }
513 } else {
514 LockedStreamFile locked_stream = error_sp->Lock();
515 locked_stream.Printf(
516 "error: empty function, didn't add python command.\n");
517 }
518 } else {
519 LockedStreamFile locked_stream = error_sp->Lock();
520 locked_stream.Printf(
521 "error: script interpreter missing, didn't add python command.\n");
522 }
523
524#endif
525 io_handler.SetIsDone(true);
526 }
527
528public:
530
531 ~CommandObjectTypeSynthAdd() override = default;
532
533 bool AddSynth(std::string type_name, lldb::SyntheticChildrenSP entry,
534 FormatterMatchType match_type, std::string category_name,
535 Status *error);
536};
537
538// CommandObjectTypeFormatAdd
539
540#define LLDB_OPTIONS_type_format_add
541#include "CommandOptions.inc"
542
544private:
546 public:
547 CommandOptions() = default;
548
549 ~CommandOptions() override = default;
550
551 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
552 return llvm::ArrayRef(g_type_format_add_options);
553 }
554
555 void OptionParsingStarting(ExecutionContext *execution_context) override {
556 m_cascade = true;
557 m_skip_pointers = false;
558 m_skip_references = false;
559 m_regex = false;
560 m_category.assign("default");
561 m_custom_type_name.clear();
562 }
563
564 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
565 ExecutionContext *execution_context) override {
567 const int short_option =
568 g_type_format_add_options[option_idx].short_option;
569 bool success;
570
571 switch (short_option) {
572 case 'C':
573 m_cascade = OptionArgParser::ToBoolean(option_value, true, &success);
574 if (!success)
576 "invalid value for cascade: %s", option_value.str().c_str());
577 break;
578 case 'p':
579 m_skip_pointers = true;
580 break;
581 case 'w':
582 m_category.assign(std::string(option_value));
583 break;
584 case 'r':
585 m_skip_references = true;
586 break;
587 case 'x':
588 m_regex = true;
589 break;
590 case 't':
591 m_custom_type_name.assign(std::string(option_value));
592 break;
593 default:
594 llvm_unreachable("Unimplemented option");
595 }
596
597 return error;
598 }
599
600 // Instance variables to hold the values for command options.
601
606 std::string m_category;
608 };
609
613
614 Options *GetOptions() override { return &m_option_group; }
615
616public:
618 : CommandObjectParsed(interpreter, "type format add",
619 "Add a new formatting style for a type.", nullptr),
622
624 R"(
625The following examples of 'type format add' refer to this code snippet for context:
626
627 typedef int Aint;
628 typedef float Afloat;
629 typedef Aint Bint;
630 typedef Afloat Bfloat;
631
632 Aint ix = 5;
633 Bint iy = 5;
634
635 Afloat fx = 3.14;
636 BFloat fy = 3.14;
637
638Adding default formatting:
640(lldb) type format add -f hex AInt
641(lldb) frame variable iy
643)"
644 " Produces hexadecimal display of iy, because no formatter is available for Bint and \
645the one for Aint is used instead."
646 R"(
647
648To prevent this use the cascade option '-C no' to prevent evaluation of typedef chains:
649
650
651(lldb) type format add -f hex -C no AInt
652
653Similar reasoning applies to this:
654
655(lldb) type format add -f hex -C no float -p
656
657)"
658 " All float values and float references are now formatted as hexadecimal, but not \
659pointers to floats. Nor will it change the default display for Afloat and Bfloat objects.");
660
661 // Add the "--format" to all options groups
666 m_option_group.Finalize();
667 }
668
669 ~CommandObjectTypeFormatAdd() override = default;
670
671protected:
672 void DoExecute(Args &command, CommandReturnObject &result) override {
673 const size_t argc = command.GetArgumentCount();
674
675 if (argc < 1) {
676 result.AppendErrorWithFormat("%s takes one or more args",
677 m_cmd_name.c_str());
678 return;
679 }
680
681 const Format format = m_format_options.GetFormat();
682 if (format == eFormatInvalid &&
683 m_command_options.m_custom_type_name.empty()) {
684 result.AppendErrorWithFormat("%s needs a valid format",
685 m_cmd_name.c_str());
686 return;
687 }
688
689 TypeFormatImplSP entry;
690
691 if (m_command_options.m_custom_type_name.empty())
692 entry = std::make_shared<TypeFormatImpl_Format>(
693 format, 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 else
698 entry = std::make_shared<TypeFormatImpl_EnumType>(
699 m_command_options.m_custom_type_name,
700 TypeFormatImpl::Flags()
701 .SetCascades(m_command_options.m_cascade)
702 .SetSkipPointers(m_command_options.m_skip_pointers)
703 .SetSkipReferences(m_command_options.m_skip_references));
704
705 // now I have a valid format, let's add it to every type
706
707 TypeCategoryImplSP category_sp;
709 ConstString(m_command_options.m_category), category_sp);
710 if (!category_sp)
711 return;
712
714
715 for (auto &arg_entry : command.entries()) {
716 if (arg_entry.ref().empty()) {
717 result.AppendError("empty typenames not allowed");
718 return;
719 }
720
722 if (m_command_options.m_regex) {
723 match_type = eFormatterMatchRegex;
724 RegularExpression typeRX(arg_entry.ref());
725 if (!typeRX.IsValid()) {
726 result.AppendError(
727 "regex format error (maybe this is not really a regex?)");
728 return;
729 }
730 }
731 category_sp->AddTypeFormat(arg_entry.ref(), match_type, entry);
732 }
733
735 }
736};
737
738#define LLDB_OPTIONS_type_formatter_delete
739#include "CommandOptions.inc"
740
742protected:
743 class CommandOptions : public Options {
744 public:
745 CommandOptions() = default;
746
747 ~CommandOptions() override = default;
748
749 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
750 ExecutionContext *execution_context) override {
752 const int short_option = m_getopt_table[option_idx].val;
753
754 switch (short_option) {
755 case 'a':
756 m_delete_all = true;
757 break;
758 case 'w':
759 m_category = std::string(option_arg);
760 break;
761 case 'l':
763 break;
764 default:
765 llvm_unreachable("Unimplemented option");
766 }
767
768 return error;
769 }
770
771 void OptionParsingStarting(ExecutionContext *execution_context) override {
772 m_delete_all = false;
773 m_category = "default";
775 }
776
777 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
778 return llvm::ArrayRef(g_type_formatter_delete_options);
779 }
780
781 // Instance variables to hold the values for command options.
782
784 std::string m_category;
786 };
787
790
791 Options *GetOptions() override { return &m_options; }
792
793 static constexpr const char *g_short_help_template =
794 "Delete an existing %s for a type.";
795
796 static constexpr const char *g_long_help_template =
797 "Delete an existing %s for a type. Unless you specify a "
798 "specific category or all categories, only the "
799 "'default' category is searched. The names must be exactly as "
800 "shown in the 'type %s list' output";
801
802public:
804 FormatCategoryItem formatter_kind)
805 : CommandObjectParsed(interpreter,
806 FormatCategoryToString(formatter_kind, false)),
807 m_formatter_kind(formatter_kind) {
809
810 const char *kind = FormatCategoryToString(formatter_kind, true);
811 const char *short_kind = FormatCategoryToString(formatter_kind, false);
812
813 StreamString s;
815 SetHelp(s.GetData());
816 s.Clear();
817 s.Printf(g_long_help_template, kind, short_kind);
818 SetHelpLong(s.GetData());
819 s.Clear();
820 s.Printf("type %s delete", short_kind);
822 }
823
825
826 void
828 OptionElementVector &opt_element_vector) override {
829 if (request.GetCursorIndex())
830 return;
831
833 [this, &request](const lldb::TypeCategoryImplSP &category_sp) {
834 category_sp->AutoComplete(request, m_formatter_kind);
835 return true;
836 });
837 }
838
839protected:
840 virtual bool FormatterSpecificDeletion(ConstString typeCS) { return false; }
841
842 void DoExecute(Args &command, CommandReturnObject &result) override {
843 const size_t argc = command.GetArgumentCount();
844
845 if (argc != 1) {
846 result.AppendErrorWithFormat("%s takes 1 arg", m_cmd_name.c_str());
847 return;
848 }
849
850 const char *typeA = command.GetArgumentAtIndex(0);
851 ConstString typeCS(typeA);
852
853 if (!typeCS) {
854 result.AppendError("empty typenames not allowed");
855 return;
856 }
857
858 if (m_options.m_delete_all) {
860 [this, typeCS](const lldb::TypeCategoryImplSP &category_sp) -> bool {
861 category_sp->Delete(typeCS, m_formatter_kind);
862 return true;
863 });
865 return;
866 }
867
868 bool delete_category = false;
869 bool extra_deletion = false;
870
871 if (m_options.m_language != lldb::eLanguageTypeUnknown) {
874 category);
875 if (category)
876 delete_category = category->Delete(typeCS, m_formatter_kind);
877 extra_deletion = FormatterSpecificDeletion(typeCS);
878 } else {
881 ConstString(m_options.m_category), category);
882 if (category)
883 delete_category = category->Delete(typeCS, m_formatter_kind);
884 extra_deletion = FormatterSpecificDeletion(typeCS);
885 }
886
887 if (delete_category || extra_deletion) {
889 } else {
890 result.AppendErrorWithFormat("no custom formatter for %s", typeA);
891 }
892 }
893};
894
895#define LLDB_OPTIONS_type_formatter_clear
896#include "CommandOptions.inc"
897
899private:
900 class CommandOptions : public Options {
901 public:
902 CommandOptions() = default;
903
904 ~CommandOptions() override = default;
905
906 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
907 ExecutionContext *execution_context) override {
909 const int short_option = m_getopt_table[option_idx].val;
910
911 switch (short_option) {
912 case 'a':
913 m_delete_all = true;
914 break;
915 default:
916 llvm_unreachable("Unimplemented option");
917 }
918
919 return error;
920 }
921
922 void OptionParsingStarting(ExecutionContext *execution_context) override {
923 m_delete_all = false;
924 }
925
926 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
927 return llvm::ArrayRef(g_type_formatter_clear_options);
928 }
929
930 // Instance variables to hold the values for command options.
932 };
933
936
937 Options *GetOptions() override { return &m_options; }
938
939public:
941 FormatCategoryItem formatter_kind,
942 const char *name, const char *help)
943 : CommandObjectParsed(interpreter, name, help, nullptr),
944 m_formatter_kind(formatter_kind) {
946 }
947
949
950protected:
952
953 void DoExecute(Args &command, CommandReturnObject &result) override {
954 if (m_options.m_delete_all) {
956 [this](const TypeCategoryImplSP &category_sp) -> bool {
957 category_sp->Clear(m_formatter_kind);
958 return true;
959 });
960 } else {
962 if (command.GetArgumentCount() > 0) {
963 const char *cat_name = command.GetArgumentAtIndex(0);
964 ConstString cat_nameCS(cat_name);
965 DataVisualization::Categories::GetCategory(cat_nameCS, category);
966 } else {
968 category);
969 }
970 category->Clear(m_formatter_kind);
971 }
972
974
976 }
977};
978
979// CommandObjectTypeFormatDelete
980
989
990// CommandObjectTypeFormatClear
991
993public:
996 "type format clear",
997 "Delete all existing format styles.") {}
998};
999
1000#define LLDB_OPTIONS_type_formatter_list
1001#include "CommandOptions.inc"
1002
1003template <typename FormatterType>
1005 typedef typename FormatterType::SharedPointer FormatterSharedPointer;
1006
1007 class CommandOptions : public Options {
1008 public:
1013
1014 ~CommandOptions() override = default;
1015
1016 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1017 ExecutionContext *execution_context) override {
1018 Status error;
1019 const int short_option = m_getopt_table[option_idx].val;
1020 switch (short_option) {
1021 case 'w':
1022 m_category_regex.SetCurrentValue(option_arg);
1023 m_category_regex.SetOptionWasSet();
1024 break;
1025 case 'l':
1026 error = m_category_language.SetValueFromString(option_arg);
1027 if (error.Success())
1028 m_category_language.SetOptionWasSet();
1029 break;
1030 default:
1031 llvm_unreachable("Unimplemented option");
1032 }
1033
1034 return error;
1035 }
1036
1037 void OptionParsingStarting(ExecutionContext *execution_context) override {
1038 m_category_regex.Clear();
1039 m_category_language.Clear();
1040 }
1041
1042 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1043 return llvm::ArrayRef(g_type_formatter_list_options);
1044 }
1045
1046 // Instance variables to hold the values for command options.
1047
1050 };
1051
1053
1054 Options *GetOptions() override { return &m_options; }
1055
1056public:
1058 const char *name, const char *help)
1059 : CommandObjectParsed(interpreter, name, help, nullptr), m_options() {
1061 }
1062
1064
1065protected:
1067 return false;
1068 }
1069
1070 static bool ShouldListItem(llvm::StringRef s, RegularExpression *regex) {
1071 // If we have a regex, it can match two kinds of results:
1072 // - An item created with that same regex string (exact string match), so
1073 // the user can list it using the same string it used at creation time.
1074 // - Items that match the regex.
1075 // No regex means list everything.
1076 return regex == nullptr || s == regex->GetText() || regex->Execute(s);
1077 }
1078
1079 void DoExecute(Args &command, CommandReturnObject &result) override {
1080 const size_t argc = command.GetArgumentCount();
1081
1082 std::unique_ptr<RegularExpression> category_regex;
1083 std::unique_ptr<RegularExpression> formatter_regex;
1084
1085 if (m_options.m_category_regex.OptionWasSet()) {
1086 category_regex = std::make_unique<RegularExpression>(
1087 m_options.m_category_regex.GetCurrentValueAsRef());
1088 if (!category_regex->IsValid()) {
1089 result.AppendErrorWithFormat(
1090 "syntax error in category regular expression '%s'",
1091 m_options.m_category_regex.GetCurrentValueAsRef().str().c_str());
1092 return;
1093 }
1094 }
1095
1096 if (argc == 1) {
1097 const char *arg = command.GetArgumentAtIndex(0);
1098 formatter_regex = std::make_unique<RegularExpression>(arg);
1099 if (!formatter_regex->IsValid()) {
1100 result.AppendErrorWithFormat("syntax error in regular expression '%s'",
1101 arg);
1102 return;
1103 }
1104 }
1105
1106 bool any_printed = false;
1107
1108 auto category_closure =
1109 [&result, &formatter_regex,
1110 &any_printed](const lldb::TypeCategoryImplSP &category) -> void {
1111 result.GetOutputStream().Printf(
1112 "-----------------------\nCategory: %s%s\n-----------------------\n",
1113 category->GetName(), category->IsEnabled() ? "" : " (disabled)");
1114
1116 [&result, &formatter_regex,
1117 &any_printed](const TypeMatcher &type_matcher,
1118 const FormatterSharedPointer &format_sp) -> bool {
1119 if (ShouldListItem(type_matcher.GetMatchString().GetStringRef(),
1120 formatter_regex.get())) {
1121 any_printed = true;
1122 result.GetOutputStream().Printf(
1123 "%s: %s\n", type_matcher.GetMatchString().GetCString(),
1124 format_sp->GetDescription().c_str());
1125 }
1126 return true;
1127 };
1128 category->ForEach(print_formatter);
1129 };
1130
1131 if (m_options.m_category_language.OptionWasSet()) {
1132 lldb::TypeCategoryImplSP category_sp;
1134 m_options.m_category_language.GetCurrentValue(), category_sp);
1135 if (category_sp)
1136 category_closure(category_sp);
1137 } else {
1139 [&category_regex, &category_closure](
1140 const lldb::TypeCategoryImplSP &category) -> bool {
1141 if (ShouldListItem(category->GetName(), category_regex.get())) {
1142 category_closure(category);
1143 }
1144 return true;
1145 });
1146
1147 any_printed = FormatterSpecificList(result) | any_printed;
1148 }
1149
1150 if (any_printed)
1152 else {
1153 result.GetOutputStream().PutCString("no matching results found.\n");
1155 }
1156 }
1157};
1158
1159// CommandObjectTypeFormatList
1160
1162 : public CommandObjectTypeFormatterList<TypeFormatImpl> {
1163public:
1165 : CommandObjectTypeFormatterList(interpreter, "type format list",
1166 "Show a list of current formats.") {}
1167};
1168
1170 uint32_t option_idx, llvm::StringRef option_arg,
1171 ExecutionContext *execution_context) {
1172 Status error;
1173 const int short_option = g_type_summary_add_options[option_idx].short_option;
1174 bool success;
1175
1176 switch (short_option) {
1177 case 'C':
1178 m_flags.SetCascades(OptionArgParser::ToBoolean(option_arg, true, &success));
1179 if (!success)
1180 error = Status::FromErrorStringWithFormat("invalid value for cascade: %s",
1181 option_arg.str().c_str());
1182 break;
1183 case 'e':
1184 m_flags.SetDontShowChildren(false);
1185 break;
1186 case 'h':
1187 m_flags.SetHideEmptyAggregates(true);
1188 break;
1189 case 'v':
1190 m_flags.SetDontShowValue(true);
1191 break;
1192 case 'c':
1193 m_flags.SetShowMembersOneLiner(true);
1194 break;
1195 case 's':
1196 m_format_string = std::string(option_arg);
1197 break;
1198 case 'p':
1199 m_flags.SetSkipPointers(true);
1200 break;
1201 case 'd':
1202 if (option_arg.getAsInteger(0, m_ptr_match_depth)) {
1204 "invalid integer value for option '%c': %s", short_option,
1205 option_arg.data());
1206 }
1207 break;
1208 case 'r':
1209 m_flags.SetSkipReferences(true);
1210 break;
1211 case 'x':
1214 "can't use --regex and --recognizer-function at the same time");
1215 else
1217 break;
1218 case '\x01':
1221 "can't use --regex and --recognizer-function at the same time");
1222 else
1224 break;
1225 case 'n':
1226 m_name = std::string(option_arg);
1227 break;
1228 case 'o':
1229 m_python_script = std::string(option_arg);
1230 m_is_add_script = true;
1231 break;
1232 case 'F':
1233 m_python_function = std::string(option_arg);
1234 m_is_add_script = true;
1235 break;
1236 case 'P':
1237 m_is_add_script = true;
1238 break;
1239 case 'w':
1240 m_category = std::string(option_arg);
1241 break;
1242 case 'O':
1243 m_flags.SetHideItemNames(true);
1244 break;
1245 default:
1246 llvm_unreachable("Unimplemented option");
1247 }
1248
1249 return error;
1250}
1251
1253 ExecutionContext *execution_context) {
1254 m_flags.Clear().SetCascades().SetDontShowChildren().SetDontShowValue(false);
1255 m_flags.SetShowMembersOneLiner(false)
1256 .SetSkipPointers(false)
1257 .SetSkipReferences(false)
1258 .SetHideItemNames(false);
1259
1261 m_name.clear();
1262 m_python_script = "";
1263 m_python_function = "";
1264 m_format_string = "";
1265 m_is_add_script = false;
1266 m_category = "default";
1267}
1268
1269#if LLDB_ENABLE_PYTHON
1270
1272 Args &command, CommandReturnObject &result) {
1273 const size_t argc = command.GetArgumentCount();
1274
1275 if (argc < 1 && m_options.m_name.empty()) {
1276 result.AppendErrorWithFormat("%s takes one or more args",
1277 m_cmd_name.c_str());
1278 return false;
1279 }
1280
1281 TypeSummaryImplSP script_format;
1282
1284 .empty()) // we have a Python function ready to use
1285 {
1286 const char *funct_name = m_options.m_python_function.c_str();
1287 if (!funct_name || !funct_name[0]) {
1288 result.AppendError("function name empty.\n");
1289 return false;
1290 }
1291
1292 std::string code =
1293 (" " + m_options.m_python_function + "(valobj,internal_dict)");
1294
1295 script_format = std::make_shared<ScriptSummaryFormat>(
1296 m_options.m_flags, funct_name, code.c_str(),
1297 m_options.m_ptr_match_depth);
1298
1299 ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
1300
1301 if (interpreter && !interpreter->CheckObjectExists(funct_name))
1303 "the provided function \"{0}\" does not exist - "
1304 "please define it before attempting to use this summary",
1305 funct_name);
1306 } else if (!m_options.m_python_script
1307 .empty()) // we have a quick 1-line script, just use it
1308 {
1309 ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
1310 if (!interpreter) {
1311 result.AppendError("script interpreter missing - unable to generate "
1312 "function wrapper.\n");
1313 return false;
1314 }
1315 StringList funct_sl;
1316 funct_sl << m_options.m_python_script.c_str();
1317 std::string funct_name_str;
1318 if (!interpreter->GenerateTypeScriptFunction(funct_sl, funct_name_str)) {
1319 result.AppendError("unable to generate function wrapper.\n");
1320 return false;
1321 }
1322 if (funct_name_str.empty()) {
1323 result.AppendError(
1324 "script interpreter failed to generate a valid function name.\n");
1325 return false;
1326 }
1327
1328 std::string code = " " + m_options.m_python_script;
1329
1330 script_format = std::make_shared<ScriptSummaryFormat>(
1331 m_options.m_flags, funct_name_str.c_str(), code.c_str(),
1332 m_options.m_ptr_match_depth);
1333 } else {
1334 // Use an IOHandler to grab Python code from the user
1335 auto options = std::make_unique<ScriptAddOptions>(
1336 m_options.m_flags, m_options.m_match_type,
1337 ConstString(m_options.m_name), m_options.m_category,
1338 m_options.m_ptr_match_depth);
1339
1340 for (auto &entry : command.entries()) {
1341 if (entry.ref().empty()) {
1342 result.AppendError("empty typenames not allowed");
1343 return false;
1344 }
1345
1346 options->m_target_types << std::string(entry.ref());
1347 }
1348
1349 m_interpreter.GetPythonCommandsFromIOHandler(
1350 " ", // Prompt
1351 *this, // IOHandlerDelegate
1352 options.release()); // Baton for the "io_handler" that will be passed
1353 // back into our IOHandlerDelegate functions
1355
1356 return result.Succeeded();
1357 }
1358
1359 // if I am here, script_format must point to something good, so I can add
1360 // that as a script summary to all interested parties
1361
1362 Status error;
1363
1364 for (auto &entry : command.entries()) {
1365 AddSummary(entry.ref().str(), script_format, m_options.m_match_type,
1366 m_options.m_category, &error);
1367 if (error.Fail()) {
1368 result.AppendError(error.AsCString());
1369 return false;
1370 }
1371 }
1372
1373 if (!m_options.m_name.empty()) {
1374 AddNamedSummary(m_options.m_name, script_format, &error);
1375 if (error.Fail()) {
1376 result.AppendError(error.AsCString());
1377 result.AppendError("added to types, but not given a name");
1378 return false;
1379 }
1380 }
1381
1382 return result.Succeeded();
1383}
1384
1386 Args &command, CommandReturnObject &result) {
1387 const size_t argc = command.GetArgumentCount();
1388
1389 if (argc < 1 && m_options.m_name.empty()) {
1390 result.AppendErrorWithFormat("%s takes one or more args",
1391 m_cmd_name.c_str());
1392 return false;
1393 }
1394
1395 const std::string &class_name = m_class_options.GetName();
1396 if (class_name.empty()) {
1397 result.AppendError("must provide a Python class name");
1398 return false;
1399 }
1400
1401 TypeSummaryImplSP script_format = std::make_shared<ScriptedSummaryFormat>(
1402 m_options.m_flags, class_name.c_str(), m_options.m_ptr_match_depth);
1403
1404 Status error;
1405
1406 for (auto &entry : command.entries()) {
1407 AddSummary(entry.ref().str(), script_format, m_options.m_match_type,
1408 m_options.m_category, &error);
1409 if (error.Fail()) {
1410 result.AppendError(error.AsCString());
1411 return false;
1412 }
1413 }
1414
1415 if (!m_options.m_name.empty()) {
1416 AddNamedSummary(m_options.m_name, script_format, &error);
1417 if (error.Fail()) {
1418 result.AppendError(error.AsCString());
1419 result.AppendError("added to types, but not given a name");
1420 return false;
1421 }
1422 }
1423
1424 return result.Succeeded();
1425}
1426
1427#endif
1428
1430 Args &command, CommandReturnObject &result) {
1431 const size_t argc = command.GetArgumentCount();
1432
1433 if (argc < 1 && m_options.m_name.empty()) {
1434 result.AppendErrorWithFormat("%s takes one or more args",
1435 m_cmd_name.c_str());
1436 return false;
1437 }
1438
1439 if (!m_options.m_flags.GetShowMembersOneLiner() &&
1440 m_options.m_format_string.empty()) {
1441 result.AppendError("empty summary strings not allowed");
1442 return false;
1443 }
1444
1445 const char *format_cstr = (m_options.m_flags.GetShowMembersOneLiner()
1446 ? ""
1447 : m_options.m_format_string.c_str());
1448
1449 // ${var%S} is an endless recursion, prevent it
1450 if (strcmp(format_cstr, "${var%S}") == 0) {
1451 result.AppendError("recursive summary not allowed");
1452 return false;
1453 }
1454
1455 std::unique_ptr<StringSummaryFormat> string_format(new StringSummaryFormat(
1456 m_options.m_flags, format_cstr, m_options.m_ptr_match_depth));
1457 if (!string_format) {
1458 result.AppendError("summary creation failed");
1459 return false;
1460 }
1461 if (string_format->m_error.Fail()) {
1462 result.AppendErrorWithFormat("syntax error: %s",
1463 string_format->m_error.AsCString("<unknown>"));
1464 return false;
1465 }
1466 lldb::TypeSummaryImplSP entry(string_format.release());
1467
1468 // now I have a valid format, let's add it to every type
1469 Status error;
1470 for (auto &arg_entry : command.entries()) {
1471 if (arg_entry.ref().empty()) {
1472 result.AppendError("empty typenames not allowed");
1473 return false;
1474 }
1475
1476 AddSummary(arg_entry.ref().str(), entry, m_options.m_match_type,
1477 m_options.m_category, &error);
1478
1479 if (error.Fail()) {
1480 result.AppendError(error.AsCString());
1481 return false;
1482 }
1483 }
1484
1485 if (!m_options.m_name.empty()) {
1486 AddNamedSummary(m_options.m_name, entry, &error);
1487 if (error.Fail()) {
1488 result.AppendError(error.AsCString());
1489 result.AppendError("added to types, but not given a name");
1490 return false;
1491 }
1492 }
1493
1495 return result.Succeeded();
1496}
1497
1499 CommandInterpreter &interpreter)
1500 : CommandObjectParsed(interpreter, "type summary add",
1501 "Add a new summary style for a type.", nullptr),
1503 m_class_options("scripted string summary", /*is_class=*/true, 'L', 'K',
1504 'V', /*required_options=*/0) {
1505 m_option_group.Append(&m_options);
1508 m_option_group.Finalize();
1509
1511
1513 R"(
1514The following examples of 'type summary add' refer to this code snippet for context:
1515
1516 struct JustADemo
1517 {
1518 int* ptr;
1519 float value;
1520 JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}
1521 };
1522 JustADemo demo_instance(42, 3.14);
1523
1524 typedef JustADemo NewDemo;
1525 NewDemo new_demo_instance(42, 3.14);
1526
1527(lldb) type summary add --summary-string "the answer is ${*var.ptr}" JustADemo
1528
1529 Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42"
1530
1531(lldb) type summary add --summary-string "the answer is ${*var.ptr}, and the question is ${var.value}" JustADemo
1532
1533 Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42 and the question is 3.14"
1534
1535)"
1536 "Alternatively, you could define formatting for all pointers to integers and \
1537rely on that when formatting JustADemo to obtain the same result:"
1538 R"(
1539
1540(lldb) type summary add --summary-string "${var%V} -> ${*var}" "int *"
1541(lldb) type summary add --summary-string "the answer is ${var.ptr}, and the question is ${var.value}" JustADemo
1543)"
1544 "Type summaries are automatically applied to derived typedefs, so the examples \
1545above apply to both JustADemo and NewDemo. The cascade option can be used to \
1546suppress this behavior:"
1547 R"(
1548
1549(lldb) type summary add --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo -C no
1550
1551 The summary will now be used for values of JustADemo but not NewDemo.
1552
1553)"
1554 "By default summaries are shown for pointers and references to values of the \
1555specified type. To suppress formatting for pointers use the -p option, or apply \
1556the corresponding -r option to suppress formatting for references:"
1557 R"(
1558
1559(lldb) type summary add -p -r --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo
1560
1561)"
1562 "One-line summaries including all fields in a type can be inferred without supplying an \
1563explicit summary string by passing the -c option:"
1564 R"(
1565
1566(lldb) type summary add -c JustADemo
1567(lldb) frame variable demo_instance
1568(ptr=<address>, value=3.14)
1569
1570)"
1571 "Type summaries normally suppress the nested display of individual fields. To \
1572supply a summary to supplement the default structure add the -e option:"
1573 R"(
1574
1575(lldb) type summary add -e --summary-string "*ptr = ${*var.ptr}" JustADemo
1576
1577)"
1578 "Now when displaying JustADemo values the int* is displayed, followed by the \
1579standard LLDB sequence of children, one per line:"
1580 R"(
1581
1582*ptr = 42 {
1583 ptr = <address>
1584 value = 3.14
1585}
1586
1587)"
1588 "You can also add summaries written in Python. These scripts use lldb public API to \
1589gather information from your variables and produce a meaningful summary. To start a \
1590multi-line script use the -P option. The function declaration will be displayed along with \
1591a comment describing the two arguments. End your script with the word 'DONE' on a line by \
1592itself:"
1593 R"(
1594
1595(lldb) type summary add JustADemo -P
1596def function (valobj,internal_dict): """valobj: an SBValue which you want to provide a summary for
1597internal_dict: an LLDB support object not to be used"""
1598 value = valobj.GetChildMemberWithName('value');
1599 return 'My value is ' + value.GetValue();
1600 DONE
1601
1602Alternatively, the -o option can be used when providing a simple one-line Python script:
1603
1604(lldb) type summary add JustADemo -o "value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();")");
1605}
1606
1608 CommandReturnObject &result) {
1609 WarnOnPotentialUnquotedUnsignedType(command, result);
1610
1611 if (!m_class_options.GetName().empty()) {
1612#if LLDB_ENABLE_PYTHON
1613 Execute_PythonClassSummary(command, result);
1614#else
1615 result.AppendError("python is disabled");
1616#endif
1617 } else if (m_options.m_is_add_script) {
1618#if LLDB_ENABLE_PYTHON
1619 Execute_ScriptSummary(command, result);
1620#else
1621 result.AppendError("python is disabled");
1622#endif
1623 } else {
1624 Execute_StringSummary(command, result);
1625 }
1626
1627 if (result.GetStatus() != eReturnStatusFailed)
1630
1631static bool FixArrayTypeNameWithRegex(std::string &type_name) {
1632 llvm::StringRef type_name_ref(type_name);
1633
1634 if (type_name_ref.ends_with("[]")) {
1635 type_name.resize(type_name.length() - 2);
1636 if (type_name.back() != ' ')
1637 type_name.append(" ?\\[[0-9]+\\]");
1638 else
1639 type_name.append("\\[[0-9]+\\]");
1640 return true;
1641 }
1642 return false;
1643}
1644
1646 TypeSummaryImplSP entry,
1648 // system named summaries do not exist (yet?)
1650 return true;
1651}
1652
1654 TypeSummaryImplSP entry,
1655 FormatterMatchType match_type,
1656 std::string category_name,
1657 Status *error) {
1658 lldb::TypeCategoryImplSP category;
1660 category);
1661
1662 if (match_type == eFormatterMatchExact) {
1664 match_type = eFormatterMatchRegex;
1665 }
1666
1667 if (match_type == eFormatterMatchRegex) {
1669 RegularExpression typeRX(type_name);
1670 if (!typeRX.IsValid()) {
1671 if (error)
1673 "regex format error (maybe this is not really a regex?)");
1674 return false;
1675 }
1676 }
1677
1678 if (match_type == eFormatterMatchCallback) {
1679 ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
1680 if (interpreter && !interpreter->CheckObjectExists(type_name.c_str())) {
1681 *error = Status::FromErrorStringWithFormat(
1682 "The provided recognizer function \"%s\" does not exist - "
1683 "please define it before attempting to use this summary.\n",
1684 type_name.c_str());
1685 return false;
1687 }
1688 category->AddTypeSummary(llvm::StringRef(type_name), match_type, entry);
1689 return true;
1691
1692// CommandObjectTypeSummaryDelete
1693
1695public:
1699
1700 ~CommandObjectTypeSummaryDelete() override = default;
1701
1702protected:
1703 bool FormatterSpecificDeletion(ConstString typeCS) override {
1704 if (m_options.m_language != lldb::eLanguageTypeUnknown)
1705 return false;
1707 }
1708};
1709
1711public:
1712 CommandObjectTypeSummaryClear(CommandInterpreter &interpreter)
1714 "type summary clear",
1715 "Delete all existing summaries.") {}
1716
1717protected:
1718 void FormatterSpecificDeletion() override {
1720 }
1721};
1723// CommandObjectTypeSummaryList
1724
1726 : public CommandObjectTypeFormatterList<TypeSummaryImpl> {
1727public:
1729 : CommandObjectTypeFormatterList(interpreter, "type summary list",
1730 "Show a list of current summaries.") {}
1731
1732protected:
1733 bool FormatterSpecificList(CommandReturnObject &result) override {
1735 result.GetOutputStream().Printf("Named summaries:\n");
1737 [&result](const TypeMatcher &type_matcher,
1738 const TypeSummaryImplSP &summary_sp) -> bool {
1739 result.GetOutputStream().Printf(
1740 "%s: %s\n", type_matcher.GetMatchString().GetCString(),
1741 summary_sp->GetDescription().c_str());
1742 return true;
1743 });
1744 return true;
1745 }
1746 return false;
1748};
1749
1750// CommandObjectTypeCategoryDefine
1751#define LLDB_OPTIONS_type_category_define
1752#include "CommandOptions.inc"
1753
1755 class CommandOptions : public Options {
1756 public:
1758 : m_define_enabled(false, false),
1760
1761 ~CommandOptions() override = default;
1762
1763 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1764 ExecutionContext *execution_context) override {
1765 Status error;
1766 const int short_option = m_getopt_table[option_idx].val;
1767
1768 switch (short_option) {
1769 case 'e':
1770 m_define_enabled.SetValueFromString(llvm::StringRef("true"));
1771 break;
1772 case 'l':
1774 break;
1775 default:
1776 llvm_unreachable("Unimplemented option");
1778
1779 return error;
1780 }
1782 void OptionParsingStarting(ExecutionContext *execution_context) override {
1785 }
1786
1787 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1788 return llvm::ArrayRef(g_type_category_define_options);
1789 }
1790
1791 // Instance variables to hold the values for command options.
1792
1795 };
1796
1798
1799 Options *GetOptions() override { return &m_options; }
1800
1801public:
1802 CommandObjectTypeCategoryDefine(CommandInterpreter &interpreter)
1803 : CommandObjectParsed(interpreter, "type category define",
1804 "Define a new category as a source of formatters.",
1805 nullptr) {
1807 }
1809 ~CommandObjectTypeCategoryDefine() override = default;
1810
1811protected:
1812 void DoExecute(Args &command, CommandReturnObject &result) override {
1813 const size_t argc = command.GetArgumentCount();
1815 if (argc < 1) {
1816 result.AppendErrorWithFormat("%s takes 1 or more args",
1817 m_cmd_name.c_str());
1818 return;
1820
1821 for (auto &entry : command.entries()) {
1824 category_sp) &&
1825 category_sp) {
1826 category_sp->AddLanguage(m_options.m_cate_language.GetCurrentValue());
1827 if (m_options.m_define_enabled.GetCurrentValue())
1830 }
1831 }
1834 }
1835};
1836
1837// CommandObjectTypeCategoryEnable
1838#define LLDB_OPTIONS_type_category_enable
1839#include "CommandOptions.inc"
1840
1842 class CommandOptions : public Options {
1843 public:
1844 CommandOptions() = default;
1845
1846 ~CommandOptions() override = default;
1847
1848 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1849 ExecutionContext *execution_context) override {
1850 Status error;
1851 const int short_option = m_getopt_table[option_idx].val;
1852
1853 switch (short_option) {
1854 case 'l':
1855 if (!option_arg.empty()) {
1858 error = Status::FromErrorStringWithFormat(
1859 "unrecognized language '%s'", option_arg.str().c_str());
1860 }
1861 break;
1862 default:
1863 llvm_unreachable("Unimplemented option");
1864 }
1865
1866 return error;
1867 }
1868
1869 void OptionParsingStarting(ExecutionContext *execution_context) override {
1872
1873 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1874 return llvm::ArrayRef(g_type_category_enable_options);
1875 }
1876
1877 // Instance variables to hold the values for command options.
1878
1881
1882 CommandOptions m_options;
1884 Options *GetOptions() override { return &m_options; }
1885
1886public:
1888 : CommandObjectParsed(interpreter, "type category enable",
1889 "Enable a category as a source of formatters.",
1890 nullptr) {
1892 }
1893
1894 ~CommandObjectTypeCategoryEnable() override = default;
1895
1896protected:
1897 void DoExecute(Args &command, CommandReturnObject &result) override {
1898 const size_t argc = command.GetArgumentCount();
1899
1900 if (argc < 1 && m_options.m_language == lldb::eLanguageTypeUnknown) {
1901 result.AppendErrorWithFormat("%s takes arguments and/or a language",
1902 m_cmd_name.c_str());
1903 return;
1904 }
1905
1906 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0), "*") == 0) {
1908 } else if (argc > 0) {
1909 for (int i = argc - 1; i >= 0; i--) {
1910 const char *typeA = command.GetArgumentAtIndex(i);
1911 ConstString typeCS(typeA);
1912
1913 if (!typeCS) {
1914 result.AppendError("empty category name not allowed");
1915 return;
1916 }
1920 if (cate->GetCount() == 0) {
1921 result.AppendWarning("empty category enabled (typo?)");
1922 }
1924 }
1926
1927 if (m_options.m_language != lldb::eLanguageTypeUnknown)
1929
1931 }
1932};
1933
1934// CommandObjectTypeCategoryDelete
1935
1937public:
1938 CommandObjectTypeCategoryDelete(CommandInterpreter &interpreter)
1939 : CommandObjectParsed(interpreter, "type category delete",
1940 "Delete a category and all associated formatters.",
1941 nullptr) {
1943 }
1944
1945 ~CommandObjectTypeCategoryDelete() override = default;
1947protected:
1948 void DoExecute(Args &command, CommandReturnObject &result) override {
1949 const size_t argc = command.GetArgumentCount();
1951 if (argc < 1) {
1952 result.AppendErrorWithFormat("%s takes 1 or more arg",
1953 m_cmd_name.c_str());
1954 return;
1955 }
1957 bool success = true;
1958
1959 // the order is not relevant here
1960 for (int i = argc - 1; i >= 0; i--) {
1961 const char *typeA = command.GetArgumentAtIndex(i);
1962 ConstString typeCS(typeA);
1963
1964 if (!typeCS) {
1965 result.AppendError("empty category name not allowed");
1966 return;
1967 }
1969 success = false; // keep deleting even if we hit an error
1970 }
1971 if (success) {
1973 } else {
1974 result.AppendError("cannot delete one or more categories\n");
1975 }
1976 }
1977};
1978
1979// CommandObjectTypeCategoryDisable
1980#define LLDB_OPTIONS_type_category_disable
1981#include "CommandOptions.inc"
1982
1984 class CommandOptions : public Options {
1985 public:
1986 CommandOptions() = default;
1987
1988 ~CommandOptions() override = default;
1989
1990 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1991 ExecutionContext *execution_context) override {
1992 Status error;
1993 const int short_option = m_getopt_table[option_idx].val;
1994
1995 switch (short_option) {
1996 case 'l':
1997 if (!option_arg.empty()) {
2000 error = Status::FromErrorStringWithFormat(
2001 "unrecognized language '%s'", option_arg.str().c_str());
2002 }
2003 break;
2004 default:
2005 llvm_unreachable("Unimplemented option");
2006 }
2007
2008 return error;
2009 }
2011 void OptionParsingStarting(ExecutionContext *execution_context) override {
2013 }
2014
2015 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2016 return llvm::ArrayRef(g_type_category_disable_options);
2018
2019 // Instance variables to hold the values for command options.
2022 };
2023
2024 CommandOptions m_options;
2025
2026 Options *GetOptions() override { return &m_options; }
2027
2028public:
2029 CommandObjectTypeCategoryDisable(CommandInterpreter &interpreter)
2030 : CommandObjectParsed(interpreter, "type category disable",
2031 "Disable a category as a source of formatters.",
2032 nullptr) {
2034 }
2035
2036 ~CommandObjectTypeCategoryDisable() override = default;
2037
2038protected:
2039 void DoExecute(Args &command, CommandReturnObject &result) override {
2040 const size_t argc = command.GetArgumentCount();
2041
2042 if (argc < 1 && m_options.m_language == lldb::eLanguageTypeUnknown) {
2043 result.AppendErrorWithFormat("%s takes arguments and/or a language",
2044 m_cmd_name.c_str());
2045 return;
2046 }
2047
2048 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0), "*") == 0) {
2050 } else if (argc > 0) {
2051 // the order is not relevant here
2052 for (int i = argc - 1; i >= 0; i--) {
2053 const char *typeA = command.GetArgumentAtIndex(i);
2054 ConstString typeCS(typeA);
2055
2056 if (!typeCS) {
2057 result.AppendError("empty category name not allowed");
2058 return;
2059 }
2061 }
2062 }
2063
2064 if (m_options.m_language != lldb::eLanguageTypeUnknown)
2066
2068 }
2069};
2070
2071// CommandObjectTypeCategoryList
2072
2074public:
2076 : CommandObjectParsed(interpreter, "type category list",
2077 "Provide a list of all existing categories.",
2078 nullptr) {
2080 }
2081
2082 ~CommandObjectTypeCategoryList() override = default;
2083
2092 }
2093
2094protected:
2095 void DoExecute(Args &command, CommandReturnObject &result) override {
2096 const size_t argc = command.GetArgumentCount();
2098 std::unique_ptr<RegularExpression> regex;
2099
2100 if (argc == 1) {
2101 const char *arg = command.GetArgumentAtIndex(0);
2102 regex = std::make_unique<RegularExpression>(arg);
2103 if (!regex->IsValid()) {
2104 result.AppendErrorWithFormat(
2105 "syntax error in category regular expression '%s'", arg);
2106 return;
2107 }
2108 } else if (argc != 0) {
2109 result.AppendErrorWithFormat("%s takes 0 or one arg", m_cmd_name.c_str());
2110 return;
2111 }
2114 [&regex, &result](const lldb::TypeCategoryImplSP &category_sp) -> bool {
2115 if (regex) {
2116 bool escape = true;
2117 if (regex->GetText() == category_sp->GetName()) {
2118 escape = false;
2119 } else if (regex->Execute(category_sp->GetName())) {
2120 escape = false;
2121 }
2122
2123 if (escape)
2124 return true;
2125 }
2126
2128 "Category: %s\n", category_sp->GetDescription().c_str());
2130 return true;
2131 });
2132
2134 }
2136
2137// CommandObjectTypeFilterList
2138
2140 : public CommandObjectTypeFormatterList<TypeFilterImpl> {
2141public:
2143 : CommandObjectTypeFormatterList(interpreter, "type filter list",
2144 "Show a list of current filters.") {}
2145};
2146
2147// CommandObjectTypeSynthList
2148
2150 : public CommandObjectTypeFormatterList<SyntheticChildren> {
2151public:
2152 CommandObjectTypeSynthList(CommandInterpreter &interpreter)
2154 interpreter, "type synthetic list",
2155 "Show a list of current synthetic providers.") {}
2156};
2157
2158// CommandObjectTypeFilterDelete
2159
2161public:
2165
2166 ~CommandObjectTypeFilterDelete() override = default;
2167};
2168
2169// CommandObjectTypeSynthDelete
2170
2172public:
2176
2177 ~CommandObjectTypeSynthDelete() override = default;
2178};
2179
2180// CommandObjectTypeFilterClear
2181
2183public:
2184 CommandObjectTypeFilterClear(CommandInterpreter &interpreter)
2186 "type filter clear",
2187 "Delete all existing filter.") {}
2188};
2189
2190// CommandObjectTypeSynthClear
2191
2193public:
2194 CommandObjectTypeSynthClear(CommandInterpreter &interpreter)
2196 interpreter, eFormatCategoryItemSynth, "type synthetic clear",
2197 "Delete all existing synthetic providers.") {}
2198};
2199
2201 Args &command, CommandReturnObject &result) {
2202 auto options = std::make_unique<SynthAddOptions>(
2203 m_options.m_skip_pointers, m_options.m_skip_references,
2204 m_options.m_cascade, m_options.m_wants_deref, m_options.m_match_type,
2205 m_options.m_category);
2206
2207 for (auto &entry : command.entries()) {
2208 if (entry.ref().empty()) {
2209 result.AppendError("empty typenames not allowed");
2210 return false;
2211 }
2212
2213 options->m_target_types << std::string(entry.ref());
2214 }
2215
2216 m_interpreter.GetPythonCommandsFromIOHandler(
2217 " ", // Prompt
2218 *this, // IOHandlerDelegate
2219 options.release()); // Baton for the "io_handler" that will be passed back
2220 // into our IOHandlerDelegate functions
2222 return result.Succeeded();
2224
2226 Args &command, CommandReturnObject &result) {
2227 const size_t argc = command.GetArgumentCount();
2228
2229 if (argc < 1) {
2230 result.AppendErrorWithFormat("%s takes one or more args",
2231 m_cmd_name.c_str());
2232 return false;
2233 }
2234
2236 result.AppendErrorWithFormat("%s needs either a Python class name or -P to "
2237 "directly input Python code",
2238 m_cmd_name.c_str());
2239 return false;
2240 }
2241
2242 SyntheticChildrenSP entry;
2243
2244 ScriptedSyntheticChildren *impl = new ScriptedSyntheticChildren(
2245 SyntheticChildren::Flags()
2246 .SetCascades(m_options.m_cascade)
2247 .SetFrontEndWantsDereference(m_options.m_wants_deref)
2248 .SetSkipPointers(m_options.m_skip_pointers)
2249 .SetSkipReferences(m_options.m_skip_references),
2250 m_options.m_class_name.c_str());
2251
2252 entry.reset(impl);
2253
2254 ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
2255
2256 const char *python_class_name = impl->GetPythonClassName();
2257 if (interpreter && !interpreter->CheckObjectExists(python_class_name))
2259 "the provided class '{0}' does not exist - please define it "
2260 "before attempting to use this synthetic provider",
2261 llvm::StringRef(python_class_name));
2262
2263 // now I have a valid provider, let's add it to every type
2264
2265 lldb::TypeCategoryImplSP category;
2267 category);
2268
2269 Status error;
2270
2271 for (auto &arg_entry : command.entries()) {
2272 if (arg_entry.ref().empty()) {
2273 result.AppendError("empty typenames not allowed");
2274 return false;
2275 }
2276
2277 if (!AddSynth(arg_entry.ref().str(), entry, m_options.m_match_type,
2278 m_options.m_category, &error)) {
2279 result.AppendError(error.AsCString());
2280 return false;
2281 }
2282 }
2283
2285 return result.Succeeded();
2286}
2287
2289 CommandInterpreter &interpreter)
2290 : CommandObjectParsed(interpreter, "type synthetic add",
2291 "Add a new synthetic provider for a type.", nullptr),
2292 IOHandlerDelegateMultiline("DONE"), m_options() {
2294}
2296bool CommandObjectTypeSynthAdd::AddSynth(std::string type_name,
2297 SyntheticChildrenSP entry,
2298 FormatterMatchType match_type,
2299 std::string category_name,
2300 Status *error) {
2303 category);
2304
2305 if (match_type == eFormatterMatchExact) {
2306 if (FixArrayTypeNameWithRegex(type_name))
2307 match_type = eFormatterMatchRegex;
2308 }
2309
2310 // Only check for conflicting filters in the same category if `type_name` is
2311 // an actual type name. Matching a regex string against registered regexes
2312 // doesn't work.
2313 if (match_type == eFormatterMatchExact) {
2314 // It's not generally possible to get a type object here. For example, this
2315 // command can be run before loading any binaries. Do just a best-effort
2316 // name-based lookup here to try to prevent conflicts.
2317 FormattersMatchCandidate candidate_type(ConstString(type_name), nullptr,
2318 TypeImpl(),
2320 if (category->AnyMatches(candidate_type, eFormatCategoryItemFilter)) {
2321 if (error)
2323 "cannot add synthetic for type {0} when "
2324 "filter is defined in same category!",
2325 type_name);
2326 return false;
2327 }
2328 }
2329
2330 if (match_type == eFormatterMatchRegex) {
2331 RegularExpression typeRX(type_name);
2332 if (!typeRX.IsValid()) {
2333 if (error)
2334 *error = Status::FromErrorString(
2335 "regex format error (maybe this is not really a regex?)");
2336 return false;
2337 }
2338 }
2340 if (match_type == eFormatterMatchCallback) {
2342 if (interpreter && !interpreter->CheckObjectExists(type_name.c_str())) {
2344 "The provided recognizer function \"%s\" does not exist - "
2345 "please define it before attempting to use this summary.\n",
2346 type_name.c_str());
2347 return false;
2348 }
2350
2351 category->AddTypeSynthetic(type_name, match_type, entry);
2352 return true;
2353}
2354
2355#define LLDB_OPTIONS_type_filter_add
2356#include "CommandOptions.inc"
2359private:
2360 class CommandOptions : public Options {
2361 typedef std::vector<std::string> option_vector;
2363 public:
2364 CommandOptions() = default;
2365
2366 ~CommandOptions() override = default;
2368 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2369 ExecutionContext *execution_context) override {
2370 Status error;
2371 const int short_option = m_getopt_table[option_idx].val;
2372 bool success;
2374 switch (short_option) {
2375 case 'C':
2376 m_cascade = OptionArgParser::ToBoolean(option_arg, true, &success);
2377 if (!success)
2379 "invalid value for cascade: %s", option_arg.str().c_str());
2380 break;
2381 case 'c':
2382 m_expr_paths.push_back(std::string(option_arg));
2383 has_child_list = true;
2384 break;
2385 case 'p':
2386 m_skip_pointers = true;
2387 break;
2388 case 'r':
2389 m_skip_references = true;
2390 break;
2391 case 'w':
2392 m_category = std::string(option_arg);
2393 break;
2394 case 'x':
2395 m_regex = true;
2396 break;
2397 default:
2398 llvm_unreachable("Unimplemented option");
2399 }
2400
2401 return error;
2402 }
2403
2404 void OptionParsingStarting(ExecutionContext *execution_context) override {
2405 m_cascade = true;
2406 m_skip_pointers = false;
2407 m_skip_references = false;
2408 m_category = "default";
2409 m_expr_paths.clear();
2410 has_child_list = false;
2411 m_regex = false;
2412 }
2413
2414 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2415 return llvm::ArrayRef(g_type_filter_add_options);
2416 }
2417
2418 // Instance variables to hold the values for command options.
2419
2420 bool m_cascade;
2421 bool m_skip_references;
2422 bool m_skip_pointers;
2425 std::string m_category;
2426 bool has_child_list;
2427 bool m_regex;
2428
2429 typedef option_vector::iterator ExpressionPathsIterator;
2430 };
2431
2432 CommandOptions m_options;
2433
2434 Options *GetOptions() override { return &m_options; }
2435
2437
2438 bool AddFilter(std::string type_name, TypeFilterImplSP entry,
2439 FilterFormatType type, std::string category_name,
2440 Status *error) {
2443 category);
2444
2445 if (type == eRegularFilter) {
2446 if (FixArrayTypeNameWithRegex(type_name))
2447 type = eRegexFilter;
2448 }
2449
2450 // Only check for conflicting synthetic child providers in the same category
2451 // if `type_name` is an actual type name. Matching a regex string against
2452 // registered regexes doesn't work.
2453 if (type == eRegularFilter) {
2454 // It's not generally possible to get a type object here. For example,
2455 // this command can be run before loading any binaries. Do just a
2456 // best-effort name-based lookup here to try to prevent conflicts.
2457 FormattersMatchCandidate candidate_type(
2458 ConstString(type_name), nullptr, TypeImpl(),
2461 if (category->AnyMatches(candidate_type, eFormatCategoryItemSynth)) {
2462 if (error)
2464 "cannot add filter for type {0} when "
2465 "synthetic is defined in same "
2466 "category!",
2467 type_name);
2468 return false;
2469 }
2470 }
2471
2473 if (type == eRegexFilter) {
2474 match_type = eFormatterMatchRegex;
2475 RegularExpression typeRX(type_name);
2476 if (!typeRX.IsValid()) {
2477 if (error)
2478 *error = Status::FromErrorString(
2479 "regex format error (maybe this is not really a regex?)");
2480 return false;
2481 }
2482 }
2483 category->AddTypeFilter(llvm::StringRef(type_name), match_type, entry);
2484 return true;
2485 }
2486
2487public:
2488 CommandObjectTypeFilterAdd(CommandInterpreter &interpreter)
2489 : CommandObjectParsed(interpreter, "type filter add",
2490 "Add a new filter for a type.", nullptr) {
2492
2494 R"(
2495The following examples of 'type filter add' refer to this code snippet for context:
2496
2497 class Foo {
2498 int a;
2499 int b;
2500 int c;
2501 int d;
2502 int e;
2503 int f;
2504 int g;
2505 int h;
2506 int i;
2507 }
2508 Foo my_foo;
2509
2510Adding a simple filter:
2511
2512(lldb) type filter add --child a --child g Foo
2513(lldb) frame variable my_foo
2514
2515)"
2516 "Produces output where only a and g are displayed. Other children of my_foo \
2517(b, c, d, e, f, h and i) are available by asking for them explicitly:"
2518 R"(
2519
2520(lldb) frame variable my_foo.b my_foo.c my_foo.i
2521
2522)"
2523 "The formatting option --raw on frame variable bypasses the filter, showing \
2524all children of my_foo as if no filter was defined:"
2525 R"(
2526
2527(lldb) frame variable my_foo --raw)");
2529
2530 ~CommandObjectTypeFilterAdd() override = default;
2531
2532protected:
2533 void DoExecute(Args &command, CommandReturnObject &result) override {
2534 const size_t argc = command.GetArgumentCount();
2535
2536 if (argc < 1) {
2537 result.AppendErrorWithFormat("%s takes one or more args",
2538 m_cmd_name.c_str());
2539 return;
2540 }
2541
2542 if (m_options.m_expr_paths.empty()) {
2543 result.AppendErrorWithFormat("%s needs one or more children",
2544 m_cmd_name.c_str());
2545 return;
2546 }
2547
2550 .SetCascades(m_options.m_cascade)
2553
2554 // go through the expression paths
2557
2558 for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
2559 entry->AddExpressionPath(*begin);
2561 // now I have a valid provider, let's add it to every type
2562
2563 lldb::TypeCategoryImplSP category;
2565 ConstString(m_options.m_category), category);
2566
2567 Status error;
2568
2569 WarnOnPotentialUnquotedUnsignedType(command, result);
2570
2571 for (auto &arg_entry : command.entries()) {
2572 if (arg_entry.ref().empty()) {
2573 result.AppendError("empty typenames not allowed");
2574 return;
2575 }
2576
2577 if (!AddFilter(arg_entry.ref().str(), entry,
2580 result.AppendError(error.AsCString());
2581 return;
2586 }
2587};
2588
2589// "type lookup"
2590#define LLDB_OPTIONS_type_lookup
2591#include "CommandOptions.inc"
2592
2594protected:
2595 // this function is allowed to do a more aggressive job at guessing languages
2596 // than the expression parser is comfortable with - so leave the original
2597 // call alone and add one that is specific to type lookup
2600
2601 if (!frame)
2602 return lang_type;
2603
2604 lang_type = frame->GuessLanguage().AsLanguageType();
2605 if (lang_type != lldb::eLanguageTypeUnknown)
2606 return lang_type;
2608 const Symbol *s = frame->GetSymbolContext(eSymbolContextSymbol).symbol;
2609 if (s)
2610 lang_type = s->GetMangled().GuessLanguage();
2612 return lang_type;
2613 }
2614
2615 class CommandOptions : public OptionGroup {
2616 public:
2617 CommandOptions() = default;
2618
2619 ~CommandOptions() override = default;
2620
2621 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2622 return llvm::ArrayRef(g_type_lookup_options);
2623 }
2624
2625 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
2626 ExecutionContext *execution_context) override {
2627 Status error;
2628
2629 const int short_option = g_type_lookup_options[option_idx].short_option;
2630
2631 switch (short_option) {
2632 case 'h':
2633 m_show_help = true;
2634 break;
2635
2636 case 'l':
2638 break;
2639
2640 default:
2641 llvm_unreachable("Unimplemented option");
2642 }
2643
2644 return error;
2645 }
2646
2647 void OptionParsingStarting(ExecutionContext *execution_context) override {
2648 m_show_help = false;
2650 }
2651
2652 // Options table: Required for subclasses of Options.
2653
2654 bool m_show_help = false;
2656 };
2657
2658 OptionGroupOptions m_option_group;
2660
2661public:
2662 CommandObjectTypeLookup(CommandInterpreter &interpreter)
2663 : CommandObjectRaw(interpreter, "type lookup",
2664 "Lookup types and declarations in the current target, "
2665 "following language-specific naming conventions.",
2666 "type lookup <type-specifier>",
2667 eCommandRequiresTarget) {
2669 m_option_group.Finalize();
2670 }
2671
2672 ~CommandObjectTypeLookup() override = default;
2673
2674 Options *GetOptions() override { return &m_option_group; }
2675
2676 llvm::StringRef GetHelpLong() override {
2677 if (!m_cmd_help_long.empty())
2678 return m_cmd_help_long;
2679
2680 StreamString stream;
2681 Language::ForEach([&](Language *lang) {
2682 if (const char *help = lang->GetLanguageSpecificTypeLookupHelp())
2683 stream.Printf("%s\n", help);
2684 return IterationAction::Continue;
2685 });
2686
2687 m_cmd_help_long = std::string(stream.GetString());
2688 return m_cmd_help_long;
2689 }
2690
2691 void DoExecute(llvm::StringRef raw_command_line,
2692 CommandReturnObject &result) override {
2693 if (raw_command_line.empty()) {
2694 result.AppendError(
2695 "type lookup cannot be invoked without a type name as argument");
2696 return;
2697 }
2698
2699 auto exe_ctx = GetCommandInterpreter().GetExecutionContext();
2700 m_option_group.NotifyOptionParsingStarting(&exe_ctx);
2701
2702 OptionsWithRaw args(raw_command_line);
2703 const char *name_of_type = args.GetRawPart().c_str();
2704
2705 if (args.HasArgs())
2706 if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group,
2707 exe_ctx))
2708 return;
2709
2710 ExecutionContextScope *best_scope = exe_ctx.GetBestExecutionContextScope();
2711
2712 bool any_found = false;
2713
2714 std::vector<Language *> languages;
2715
2716 bool is_global_search = false;
2717 LanguageType guessed_language = lldb::eLanguageTypeUnknown;
2718
2719 if ((is_global_search =
2720 (m_command_options.m_language == eLanguageTypeUnknown))) {
2721 Language::ForEach([&](Language *lang) {
2722 languages.push_back(lang);
2723 return IterationAction::Continue;
2724 });
2725 } else {
2726 languages.push_back(Language::FindPlugin(m_command_options.m_language));
2727 }
2728
2729 // This is not the most efficient way to do this, but we support very few
2730 // languages so the cost of the sort is going to be dwarfed by the actual
2731 // lookup anyway
2732 if (StackFrame *frame = m_exe_ctx.GetFramePtr()) {
2733 guessed_language = GuessLanguage(frame);
2734 if (guessed_language != eLanguageTypeUnknown) {
2735 llvm::sort(
2736 languages.begin(), languages.end(),
2737 [guessed_language](Language *lang1, Language *lang2) -> bool {
2738 if (!lang1 || !lang2)
2739 return false;
2740 LanguageType lt1 = lang1->GetLanguageType();
2741 LanguageType lt2 = lang2->GetLanguageType();
2742 if (lt1 == lt2)
2743 return false;
2744 if (lt1 == guessed_language)
2745 return true; // make the selected frame's language come first
2746 if (lt2 == guessed_language)
2747 return false; // make the selected frame's language come first
2748 return (lt1 < lt2); // normal comparison otherwise
2749 });
2750 }
2751 }
2753 bool is_first_language = true;
2754
2755 for (Language *language : languages) {
2756 if (!language)
2757 continue;
2758
2759 if (auto scavenger = language->GetTypeScavenger()) {
2761 if (scavenger->Find(best_scope, name_of_type, search_results) > 0) {
2762 for (const auto &search_result : search_results) {
2763 if (search_result && search_result->IsValid()) {
2764 any_found = true;
2765 search_result->DumpToStream(result.GetOutputStream(),
2766 this->m_command_options.m_show_help);
2767 }
2768 }
2769 }
2770 }
2771 // this is "type lookup SomeName" and we did find a match, so get out
2772 if (any_found && is_global_search)
2773 break;
2774 else if (is_first_language && is_global_search &&
2775 guessed_language != lldb::eLanguageTypeUnknown) {
2776 is_first_language = false;
2777 result.GetOutputStream().Printf(
2778 "no type was found in the current language %s matching '%s'; "
2779 "performing a global search across all languages\n",
2780 Language::GetNameForLanguageType(guessed_language), name_of_type);
2781 }
2782 }
2783
2784 if (!any_found)
2785 result.AppendMessageWithFormatv("no type was found matching '{0}'",
2786 name_of_type);
2787
2790 }
2791};
2792
2793template <typename FormatterType>
2795public:
2796 typedef std::function<typename FormatterType::SharedPointer(ValueObject &)>
2799 const char *formatter_name,
2800 DiscoveryFunction discovery_func)
2801 : CommandObjectRaw(interpreter, "", "", "", eCommandRequiresFrame),
2802 m_formatter_name(formatter_name ? formatter_name : ""),
2803 m_discovery_function(discovery_func) {
2805 name.Printf("type %s info", formatter_name);
2806 SetCommandName(name.GetString());
2807 StreamString help;
2808 help.Printf("This command evaluates the provided expression and shows "
2809 "which %s is applied to the resulting value (if any).",
2810 formatter_name);
2811 SetHelp(help.GetString());
2812 StreamString syntax;
2813 syntax.Printf("type %s info <expr>", formatter_name);
2814 SetSyntax(syntax.GetString());
2815 }
2816
2817 ~CommandObjectFormatterInfo() override = default;
2818
2819protected:
2820 void DoExecute(llvm::StringRef command,
2821 CommandReturnObject &result) override {
2822 Target *target = GetTarget();
2823 assert(target && "target guaranteed by eCommandRequiresFrame");
2824 Thread *thread = GetDefaultThread();
2825 if (!thread) {
2826 result.AppendError("no default thread");
2827 return;
2829
2830 StackFrameSP frame_sp =
2831 thread->GetSelectedFrame(DoNoSelectMostRelevantFrame);
2832 ValueObjectSP result_valobj_sp;
2834 lldb::ExpressionResults expr_result = target->EvaluateExpression(
2835 command, frame_sp.get(), result_valobj_sp, options);
2836 if (expr_result == eExpressionCompleted && result_valobj_sp) {
2837 result_valobj_sp =
2838 result_valobj_sp->GetQualifiedRepresentationIfAvailable(
2839 target->GetPreferDynamicValue(),
2840 target->GetEnableSyntheticValue());
2841 typename FormatterType::SharedPointer formatter_sp =
2842 m_discovery_function(*result_valobj_sp);
2843 if (formatter_sp) {
2844 std::string description(formatter_sp->GetDescription());
2845 result.GetOutputStream()
2846 << m_formatter_name << " applied to ("
2847 << result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>")
2848 << ") " << command << " is: " << description << "\n";
2850 } else {
2851 result.GetOutputStream()
2852 << "no " << m_formatter_name << " applies to ("
2853 << result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>")
2854 << ") " << command << "\n";
2856 }
2857 } else {
2858 result.AppendError("failed to evaluate expression");
2859 }
2860 }
2861
2862private:
2863 std::string m_formatter_name;
2865};
2866
2868public:
2871 interpreter, "type format",
2872 "Commands for customizing value display formats.",
2873 "type format [<sub-command-options>] ") {
2875 "add", CommandObjectSP(new CommandObjectTypeFormatAdd(interpreter)));
2877 new CommandObjectTypeFormatClear(interpreter)));
2879 interpreter)));
2881 "list", CommandObjectSP(new CommandObjectTypeFormatList(interpreter)));
2884 interpreter, "format",
2886 return valobj.GetValueFormat();
2887 })));
2888 }
2889
2890 ~CommandObjectTypeFormat() override = default;
2891};
2892
2894public:
2897 interpreter, "type synthetic",
2898 "Commands for operating on synthetic type representations.",
2899 "type synthetic [<sub-command-options>] ") {
2900 LoadSubCommand("add",
2903 "clear", CommandObjectSP(new CommandObjectTypeSynthClear(interpreter)));
2905 interpreter)));
2907 "list", CommandObjectSP(new CommandObjectTypeSynthList(interpreter)));
2909 "info",
2911 interpreter, "synthetic",
2913 return valobj.GetSyntheticChildren();
2914 })));
2915 }
2916
2917 ~CommandObjectTypeSynth() override = default;
2918};
2919
2921public:
2923 : CommandObjectMultiword(interpreter, "type filter",
2924 "Commands for operating on type filters.",
2925 "type filter [<sub-command-options>] ") {
2929 new CommandObjectTypeFilterClear(interpreter)));
2931 interpreter)));
2933 "list", CommandObjectSP(new CommandObjectTypeFilterList(interpreter)));
2934 }
2935
2936 ~CommandObjectTypeFilter() override = default;
2937};
2938
2940public:
2942 : CommandObjectMultiword(interpreter, "type category",
2943 "Commands for operating on type categories.",
2944 "type category [<sub-command-options>] ") {
2946 "define",
2949 "enable",
2952 "disable",
2955 "delete",
2958 new CommandObjectTypeCategoryList(interpreter)));
2959 }
2960
2961 ~CommandObjectTypeCategory() override = default;
2962};
2963
2965public:
2968 interpreter, "type summary",
2969 "Commands for editing variable summary display options.",
2970 "type summary [<sub-command-options>] ") {
2972 "add", CommandObjectSP(new CommandObjectTypeSummaryAdd(interpreter)));
2973 LoadSubCommand("clear", CommandObjectSP(new CommandObjectTypeSummaryClear(
2974 interpreter)));
2975 LoadSubCommand("delete", CommandObjectSP(new CommandObjectTypeSummaryDelete(
2976 interpreter)));
2978 "list", CommandObjectSP(new CommandObjectTypeSummaryList(interpreter)));
2980 "info", CommandObjectSP(new CommandObjectFormatterInfo<TypeSummaryImpl>(
2981 interpreter, "summary",
2982 [](ValueObject &valobj) -> TypeSummaryImpl::SharedPointer {
2983 return valobj.GetSummaryFormat();
2984 })));
2985 }
2986
2987 ~CommandObjectTypeSummary() override = default;
2988};
2989
2990// CommandObjectType
2991
2993 : CommandObjectMultiword(interpreter, "type",
2994 "Commands for operating on the type system.",
2995 "type [<sub-command-options>]") {
2996 LoadSubCommand("category",
2997 CommandObjectSP(new CommandObjectTypeCategory(interpreter)));
2998 LoadSubCommand("filter",
2999 CommandObjectSP(new CommandObjectTypeFilter(interpreter)));
3000 LoadSubCommand("format",
3001 CommandObjectSP(new CommandObjectTypeFormat(interpreter)));
3002 LoadSubCommand("summary",
3003 CommandObjectSP(new CommandObjectTypeSummary(interpreter)));
3004 LoadSubCommand("synthetic",
3005 CommandObjectSP(new CommandObjectTypeSynth(interpreter)));
3006 LoadSubCommand("lookup",
3007 CommandObjectSP(new CommandObjectTypeLookup(interpreter)));
3008}
3009
3011
static const char * g_synth_addreader_instructions
static bool WarnOnPotentialUnquotedUnsignedType(Args &command, CommandReturnObject &result)
static bool FixArrayTypeNameWithRegex(std::string &type_name)
const char * FormatCategoryToString(FormatCategoryItem item, bool long_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
bool AddFilter(std::string type_name, TypeFilterImplSP entry, FilterFormatType type, std::string category_name, Status *error)
CommandObjectTypeFilterAdd(CommandInterpreter &interpreter)
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
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
~CommandObjectTypeSummaryAdd() override=default
bool Execute_ScriptSummary(Args &command, CommandReturnObject &result)
bool AddSummary(std::string type_name, lldb::TypeSummaryImplSP entry, FormatterMatchType match_type, std::string category, Status *error=nullptr)
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(std::string summary_name, lldb::TypeSummaryImplSP entry, Status *error=nullptr)
bool Execute_PythonClassSummary(Args &command, CommandReturnObject &result)
OptionGroupPythonClassWithDict m_class_options
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 AddSynth(std::string type_name, lldb::SyntheticChildrenSP entry, FormatterMatchType match_type, std::string category_name, Status *error)
bool Execute_PythonClass(Args &command, CommandReturnObject &result)
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
const char * GetCString() const
Get the string value as a C string.
static bool Delete(ConstString category)
static void Disable(ConstString category)
static void ForEach(TypeCategoryMap::ForEachCallback callback)
static void Enable(ConstString category, TypeCategoryMap::Position=TypeCategoryMap::Default)
static bool GetCategory(ConstString category, lldb::TypeCategoryImplSP &entry, bool allow_create=true)
static void Add(ConstString type, const lldb::TypeSummaryImplSP &entry)
static void ForEach(std::function< bool(const TypeMatcher &, const lldb::TypeSummaryImplSP &)> callback)
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:497
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 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:162
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:5598
lldb::DynamicValueType GetPreferDynamicValue() const
Definition Target.cpp:5242
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:2951
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
#define LLDB_OPT_SET_2
#define LLDB_OPT_SET_ALL
@ 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:628