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;
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(ConstString(type_name), script_format,
228 options->m_match_type, options->m_category,
229 &error);
230 if (error.Fail()) {
231 LockedStreamFile locked_stream = error_sp->Lock();
232 locked_stream.Printf("error: %s", error.AsCString());
233 }
234 }
235
236 if (options->m_name) {
238 options->m_name, script_format, &error);
239 if (error.Fail()) {
241 options->m_name, script_format, &error);
242 if (error.Fail()) {
243 LockedStreamFile locked_stream = error_sp->Lock();
244 locked_stream.Printf("error: %s", error.AsCString());
245 }
246 } else {
247 LockedStreamFile locked_stream = error_sp->Lock();
248 locked_stream.Printf("error: %s", error.AsCString());
249 }
250 } else {
251 if (error.AsCString()) {
252 LockedStreamFile locked_stream = error_sp->Lock();
253 locked_stream.Printf("error: %s", error.AsCString());
254 }
255 }
256 }
257 } else {
258 LockedStreamFile locked_stream = error_sp->Lock();
259 locked_stream.PutCString(
260 "error: unable to generate a function.\n");
261 }
262 } else {
263 LockedStreamFile locked_stream = error_sp->Lock();
264 locked_stream.PutCString("error: no script interpreter.\n");
265 }
266 } else {
267 LockedStreamFile locked_stream = error_sp->Lock();
268 locked_stream.Printf("error: internal synchronization information "
269 "missing or invalid.\n");
270 }
271 } else {
272 LockedStreamFile locked_stream = error_sp->Lock();
273 locked_stream.Printf(
274 "error: empty function, didn't add python command.\n");
275 }
276 } else {
277 LockedStreamFile locked_stream = error_sp->Lock();
278 locked_stream.Printf(
279 "error: script interpreter missing, didn't add python command.\n");
280 }
281#endif
282 io_handler.SetIsDone(true);
283 }
284
285 bool AddSummary(ConstString type_name, lldb::TypeSummaryImplSP entry,
286 FormatterMatchType match_type, std::string category,
287 Status *error = nullptr);
288
289 bool AddNamedSummary(ConstString summary_name, lldb::TypeSummaryImplSP entry,
290 Status *error = nullptr);
291
292protected:
293 void DoExecute(Args &command, CommandReturnObject &result) override;
294};
295
297 "Enter your Python command(s). Type 'DONE' to end.\n"
298 "You must define a Python class with these methods:\n"
299 " def __init__(self, valobj: lldb.SBValue, internal_dict):\n"
300 " def num_children(self) -> int:\n"
301 " def get_child_at_index(self, index: int) -> lldb.SBValue | None:\n"
302 " def get_child_index(self, name: str) -> int:\n"
303 " def update(self) -> bool:\n"
304 " '''Optional'''\n"
305 "class synthProvider:\n";
306
307#define LLDB_OPTIONS_type_synth_add
308#include "CommandOptions.inc"
309
312private:
313 class CommandOptions : public Options {
314 public:
315 CommandOptions() = default;
316
317 ~CommandOptions() override = default;
318
319 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
320 ExecutionContext *execution_context) override {
322 const int short_option = m_getopt_table[option_idx].val;
323 bool success;
324
325 switch (short_option) {
326 case 'C':
327 m_cascade = OptionArgParser::ToBoolean(option_arg, true, &success);
328 if (!success)
330 "invalid value for cascade: %s", option_arg.str().c_str());
331 break;
332 case 'D':
333 m_wants_deref = OptionArgParser::ToBoolean(option_arg, true, &success);
334 if (!success)
336 "invalid value for wants-dereference: %s",
337 option_arg.str().c_str());
338 break;
339 case 'P':
340 handwrite_python = true;
341 break;
342 case 'l':
343 m_class_name = std::string(option_arg);
344 is_class_based = true;
345 break;
346 case 'p':
347 m_skip_pointers = true;
348 break;
349 case 'r':
350 m_skip_references = true;
351 break;
352 case 'w':
353 m_category = std::string(option_arg);
354 break;
355 case 'x':
358 "can't use --regex and --recognizer-function at the same time");
359 else
361 break;
362 case '\x01':
365 "can't use --regex and --recognizer-function at the same time");
366 else
368 break;
369 default:
370 llvm_unreachable("Unimplemented option");
371 }
372
373 return error;
374 }
375
376 void OptionParsingStarting(ExecutionContext *execution_context) override {
377 m_cascade = true;
378 m_wants_deref = true;
379 m_class_name = "";
380 m_skip_pointers = false;
381 m_skip_references = false;
382 m_category = "default";
383 is_class_based = false;
384 handwrite_python = false;
386 }
387
388 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
389 return llvm::ArrayRef(g_type_synth_add_options);
390 }
391
392 // Instance variables to hold the values for command options.
393
398 std::string m_class_name;
400 std::string m_category;
404 };
405
407
408 Options *GetOptions() override { return &m_options; }
409
410 bool Execute_HandwritePython(Args &command, CommandReturnObject &result);
411
412 bool Execute_PythonClass(Args &command, CommandReturnObject &result);
413
414protected:
415 void DoExecute(Args &command, CommandReturnObject &result) override {
417
418 if (m_options.handwrite_python)
419 Execute_HandwritePython(command, result);
420 else if (m_options.is_class_based)
421 Execute_PythonClass(command, result);
422 else {
423 result.AppendError("must either provide a children list, a Python class "
424 "name, or use -P and type a Python class "
425 "line-by-line");
426 }
427 }
428
429 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
430 if (interactive) {
431 if (LockableStreamFileSP output_sp = io_handler.GetOutputStreamFileSP()) {
432 LockedStreamFile locked_stream = output_sp->Lock();
434 }
435 }
436 }
437
439 std::string &data) override {
440 LockableStreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
441
442#if LLDB_ENABLE_PYTHON
444 if (interpreter) {
445 StringList lines;
446 lines.SplitIntoLines(data);
447 if (lines.GetSize() > 0) {
448 SynthAddOptions *options_ptr =
449 ((SynthAddOptions *)io_handler.GetUserData());
450 if (options_ptr) {
452 options_ptr); // this will ensure that we get rid of the pointer
453 // when going out of scope
454
456 if (interpreter) {
457 std::string class_name_str;
458 if (interpreter->GenerateTypeSynthClass(lines, class_name_str)) {
459 if (class_name_str.empty()) {
460
461 LockedStreamFile locked_stream = error_sp->Lock();
462 locked_stream.Printf(
463 "error: unable to obtain a proper name for the class.\n");
464 } else {
465 // everything should be fine now, let's add the synth provider
466 // class
467
468 SyntheticChildrenSP synth_provider;
469 synth_provider = std::make_shared<ScriptedSyntheticChildren>(
471 .SetCascades(options->m_cascade)
472 .SetSkipPointers(options->m_skip_pointers)
473 .SetSkipReferences(options->m_skip_references)
474 .SetFrontEndWantsDereference(options->m_wants_deref),
475 class_name_str.c_str());
476
479 ConstString(options->m_category), category);
480
482
483 for (const std::string &type_name : options->m_target_types) {
484 if (!type_name.empty()) {
485 if (AddSynth(ConstString(type_name), synth_provider,
486 options->m_match_type, options->m_category,
487 &error)) {
488 LockedStreamFile locked_stream = error_sp->Lock();
489 locked_stream.Printf("error: %s\n", error.AsCString());
490 break;
491 }
492 } else {
493 LockedStreamFile locked_stream = error_sp->Lock();
494 locked_stream.PutCString("error: invalid type name.\n");
495 break;
496 }
497 }
498 }
499 } else {
500 LockedStreamFile locked_stream = error_sp->Lock();
501 locked_stream.PutCString("error: unable to generate a class.\n");
502 }
503 } else {
504 LockedStreamFile locked_stream = error_sp->Lock();
505 locked_stream.PutCString("error: no script interpreter.\n");
506 }
507 } else {
508 LockedStreamFile locked_stream = error_sp->Lock();
509 locked_stream.Printf(
510 "error: internal synchronization data missing.\n");
511 }
512 } else {
513 LockedStreamFile locked_stream = error_sp->Lock();
514 locked_stream.Printf(
515 "error: empty function, didn't add python command.\n");
516 }
517 } else {
518 LockedStreamFile locked_stream = error_sp->Lock();
519 locked_stream.Printf(
520 "error: script interpreter missing, didn't add python command.\n");
521 }
522
523#endif
524 io_handler.SetIsDone(true);
525 }
526
527public:
529
530 ~CommandObjectTypeSynthAdd() override = default;
531
532 bool AddSynth(ConstString type_name, lldb::SyntheticChildrenSP entry,
533 FormatterMatchType match_type, std::string category_name,
534 Status *error);
535};
536
537// CommandObjectTypeFormatAdd
538
539#define LLDB_OPTIONS_type_format_add
540#include "CommandOptions.inc"
541
543private:
545 public:
546 CommandOptions() = default;
547
548 ~CommandOptions() override = default;
549
550 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
551 return llvm::ArrayRef(g_type_format_add_options);
552 }
553
554 void OptionParsingStarting(ExecutionContext *execution_context) override {
555 m_cascade = true;
556 m_skip_pointers = false;
557 m_skip_references = false;
558 m_regex = false;
559 m_category.assign("default");
560 m_custom_type_name.clear();
561 }
562
563 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
564 ExecutionContext *execution_context) override {
566 const int short_option =
567 g_type_format_add_options[option_idx].short_option;
568 bool success;
569
570 switch (short_option) {
571 case 'C':
572 m_cascade = OptionArgParser::ToBoolean(option_value, true, &success);
573 if (!success)
575 "invalid value for cascade: %s", option_value.str().c_str());
576 break;
577 case 'p':
578 m_skip_pointers = true;
579 break;
580 case 'w':
581 m_category.assign(std::string(option_value));
582 break;
583 case 'r':
584 m_skip_references = true;
585 break;
586 case 'x':
587 m_regex = true;
588 break;
589 case 't':
590 m_custom_type_name.assign(std::string(option_value));
591 break;
592 default:
593 llvm_unreachable("Unimplemented option");
594 }
595
596 return error;
597 }
598
599 // Instance variables to hold the values for command options.
600
605 std::string m_category;
607 };
608
612
613 Options *GetOptions() override { return &m_option_group; }
614
615public:
617 : CommandObjectParsed(interpreter, "type format add",
618 "Add a new formatting style for a type.", nullptr),
621
623 R"(
624The following examples of 'type format add' refer to this code snippet for context:
625
626 typedef int Aint;
627 typedef float Afloat;
628 typedef Aint Bint;
629 typedef Afloat Bfloat;
630
631 Aint ix = 5;
632 Bint iy = 5;
633
634 Afloat fx = 3.14;
635 BFloat fy = 3.14;
636
637Adding default formatting:
639(lldb) type format add -f hex AInt
640(lldb) frame variable iy
642)"
643 " Produces hexadecimal display of iy, because no formatter is available for Bint and \
644the one for Aint is used instead."
645 R"(
646
647To prevent this use the cascade option '-C no' to prevent evaluation of typedef chains:
648
649
650(lldb) type format add -f hex -C no AInt
651
652Similar reasoning applies to this:
653
654(lldb) type format add -f hex -C no float -p
655
656)"
657 " All float values and float references are now formatted as hexadecimal, but not \
658pointers to floats. Nor will it change the default display for Afloat and Bfloat objects.");
659
660 // Add the "--format" to all options groups
665 m_option_group.Finalize();
666 }
667
668 ~CommandObjectTypeFormatAdd() override = default;
669
670protected:
671 void DoExecute(Args &command, CommandReturnObject &result) override {
672 const size_t argc = command.GetArgumentCount();
673
674 if (argc < 1) {
675 result.AppendErrorWithFormat("%s takes one or more args",
676 m_cmd_name.c_str());
677 return;
678 }
679
680 const Format format = m_format_options.GetFormat();
681 if (format == eFormatInvalid &&
682 m_command_options.m_custom_type_name.empty()) {
683 result.AppendErrorWithFormat("%s needs a valid format",
684 m_cmd_name.c_str());
685 return;
686 }
687
688 TypeFormatImplSP entry;
689
690 if (m_command_options.m_custom_type_name.empty())
691 entry = std::make_shared<TypeFormatImpl_Format>(
692 format, TypeFormatImpl::Flags()
693 .SetCascades(m_command_options.m_cascade)
694 .SetSkipPointers(m_command_options.m_skip_pointers)
695 .SetSkipReferences(m_command_options.m_skip_references));
696 else
697 entry = std::make_shared<TypeFormatImpl_EnumType>(
698 ConstString(m_command_options.m_custom_type_name),
699 TypeFormatImpl::Flags()
700 .SetCascades(m_command_options.m_cascade)
701 .SetSkipPointers(m_command_options.m_skip_pointers)
702 .SetSkipReferences(m_command_options.m_skip_references));
703
704 // now I have a valid format, let's add it to every type
705
706 TypeCategoryImplSP category_sp;
708 ConstString(m_command_options.m_category), category_sp);
709 if (!category_sp)
710 return;
711
713
714 for (auto &arg_entry : command.entries()) {
715 if (arg_entry.ref().empty()) {
716 result.AppendError("empty typenames not allowed");
717 return;
718 }
719
721 if (m_command_options.m_regex) {
722 match_type = eFormatterMatchRegex;
723 RegularExpression typeRX(arg_entry.ref());
724 if (!typeRX.IsValid()) {
725 result.AppendError(
726 "regex format error (maybe this is not really a regex?)");
727 return;
728 }
729 }
730 category_sp->AddTypeFormat(arg_entry.ref(), match_type, entry);
731 }
732
734 }
735};
736
737#define LLDB_OPTIONS_type_formatter_delete
738#include "CommandOptions.inc"
739
741protected:
742 class CommandOptions : public Options {
743 public:
744 CommandOptions() = default;
745
746 ~CommandOptions() override = default;
747
748 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
749 ExecutionContext *execution_context) override {
751 const int short_option = m_getopt_table[option_idx].val;
752
753 switch (short_option) {
754 case 'a':
755 m_delete_all = true;
756 break;
757 case 'w':
758 m_category = std::string(option_arg);
759 break;
760 case 'l':
762 break;
763 default:
764 llvm_unreachable("Unimplemented option");
765 }
766
767 return error;
768 }
769
770 void OptionParsingStarting(ExecutionContext *execution_context) override {
771 m_delete_all = false;
772 m_category = "default";
774 }
775
776 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
777 return llvm::ArrayRef(g_type_formatter_delete_options);
778 }
779
780 // Instance variables to hold the values for command options.
781
783 std::string m_category;
785 };
786
789
790 Options *GetOptions() override { return &m_options; }
791
792 static constexpr const char *g_short_help_template =
793 "Delete an existing %s for a type.";
794
795 static constexpr const char *g_long_help_template =
796 "Delete an existing %s for a type. Unless you specify a "
797 "specific category or all categories, only the "
798 "'default' category is searched. The names must be exactly as "
799 "shown in the 'type %s list' output";
800
801public:
803 FormatCategoryItem formatter_kind)
804 : CommandObjectParsed(interpreter,
805 FormatCategoryToString(formatter_kind, false)),
806 m_formatter_kind(formatter_kind) {
808
809 const char *kind = FormatCategoryToString(formatter_kind, true);
810 const char *short_kind = FormatCategoryToString(formatter_kind, false);
811
812 StreamString s;
814 SetHelp(s.GetData());
815 s.Clear();
816 s.Printf(g_long_help_template, kind, short_kind);
817 SetHelpLong(s.GetData());
818 s.Clear();
819 s.Printf("type %s delete", short_kind);
821 }
822
824
825 void
827 OptionElementVector &opt_element_vector) override {
828 if (request.GetCursorIndex())
829 return;
830
832 [this, &request](const lldb::TypeCategoryImplSP &category_sp) {
833 category_sp->AutoComplete(request, m_formatter_kind);
834 return true;
835 });
836 }
837
838protected:
839 virtual bool FormatterSpecificDeletion(ConstString typeCS) { return false; }
840
841 void DoExecute(Args &command, CommandReturnObject &result) override {
842 const size_t argc = command.GetArgumentCount();
843
844 if (argc != 1) {
845 result.AppendErrorWithFormat("%s takes 1 arg", m_cmd_name.c_str());
846 return;
847 }
848
849 const char *typeA = command.GetArgumentAtIndex(0);
850 ConstString typeCS(typeA);
851
852 if (!typeCS) {
853 result.AppendError("empty typenames not allowed");
854 return;
855 }
856
857 if (m_options.m_delete_all) {
859 [this, typeCS](const lldb::TypeCategoryImplSP &category_sp) -> bool {
860 category_sp->Delete(typeCS, m_formatter_kind);
861 return true;
862 });
864 return;
865 }
866
867 bool delete_category = false;
868 bool extra_deletion = false;
869
870 if (m_options.m_language != lldb::eLanguageTypeUnknown) {
873 category);
874 if (category)
875 delete_category = category->Delete(typeCS, m_formatter_kind);
876 extra_deletion = FormatterSpecificDeletion(typeCS);
877 } else {
880 ConstString(m_options.m_category.c_str()), category);
881 if (category)
882 delete_category = category->Delete(typeCS, m_formatter_kind);
883 extra_deletion = FormatterSpecificDeletion(typeCS);
884 }
885
886 if (delete_category || extra_deletion) {
888 } else {
889 result.AppendErrorWithFormat("no custom formatter for %s", typeA);
890 }
891 }
892};
893
894#define LLDB_OPTIONS_type_formatter_clear
895#include "CommandOptions.inc"
896
898private:
899 class CommandOptions : public Options {
900 public:
901 CommandOptions() = default;
902
903 ~CommandOptions() override = default;
904
905 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
906 ExecutionContext *execution_context) override {
908 const int short_option = m_getopt_table[option_idx].val;
909
910 switch (short_option) {
911 case 'a':
912 m_delete_all = true;
913 break;
914 default:
915 llvm_unreachable("Unimplemented option");
916 }
917
918 return error;
919 }
920
921 void OptionParsingStarting(ExecutionContext *execution_context) override {
922 m_delete_all = false;
923 }
924
925 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
926 return llvm::ArrayRef(g_type_formatter_clear_options);
927 }
928
929 // Instance variables to hold the values for command options.
931 };
932
935
936 Options *GetOptions() override { return &m_options; }
937
938public:
940 FormatCategoryItem formatter_kind,
941 const char *name, const char *help)
942 : CommandObjectParsed(interpreter, name, help, nullptr),
943 m_formatter_kind(formatter_kind) {
945 }
946
948
949protected:
951
952 void DoExecute(Args &command, CommandReturnObject &result) override {
953 if (m_options.m_delete_all) {
955 [this](const TypeCategoryImplSP &category_sp) -> bool {
956 category_sp->Clear(m_formatter_kind);
957 return true;
958 });
959 } else {
961 if (command.GetArgumentCount() > 0) {
962 const char *cat_name = command.GetArgumentAtIndex(0);
963 ConstString cat_nameCS(cat_name);
964 DataVisualization::Categories::GetCategory(cat_nameCS, category);
965 } else {
967 category);
968 }
969 category->Clear(m_formatter_kind);
970 }
971
973
975 }
976};
977
978// CommandObjectTypeFormatDelete
979
988
989// CommandObjectTypeFormatClear
990
992public:
995 "type format clear",
996 "Delete all existing format styles.") {}
997};
998
999#define LLDB_OPTIONS_type_formatter_list
1000#include "CommandOptions.inc"
1001
1002template <typename FormatterType>
1004 typedef typename FormatterType::SharedPointer FormatterSharedPointer;
1005
1006 class CommandOptions : public Options {
1007 public:
1012
1013 ~CommandOptions() override = default;
1014
1015 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1016 ExecutionContext *execution_context) override {
1017 Status error;
1018 const int short_option = m_getopt_table[option_idx].val;
1019 switch (short_option) {
1020 case 'w':
1021 m_category_regex.SetCurrentValue(option_arg);
1022 m_category_regex.SetOptionWasSet();
1023 break;
1024 case 'l':
1025 error = m_category_language.SetValueFromString(option_arg);
1026 if (error.Success())
1027 m_category_language.SetOptionWasSet();
1028 break;
1029 default:
1030 llvm_unreachable("Unimplemented option");
1031 }
1032
1033 return error;
1034 }
1035
1036 void OptionParsingStarting(ExecutionContext *execution_context) override {
1037 m_category_regex.Clear();
1038 m_category_language.Clear();
1039 }
1040
1041 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1042 return llvm::ArrayRef(g_type_formatter_list_options);
1043 }
1044
1045 // Instance variables to hold the values for command options.
1046
1049 };
1050
1052
1053 Options *GetOptions() override { return &m_options; }
1054
1055public:
1057 const char *name, const char *help)
1058 : CommandObjectParsed(interpreter, name, help, nullptr), m_options() {
1060 }
1061
1063
1064protected:
1066 return false;
1067 }
1068
1069 static bool ShouldListItem(llvm::StringRef s, RegularExpression *regex) {
1070 // If we have a regex, it can match two kinds of results:
1071 // - An item created with that same regex string (exact string match), so
1072 // the user can list it using the same string it used at creation time.
1073 // - Items that match the regex.
1074 // No regex means list everything.
1075 return regex == nullptr || s == regex->GetText() || regex->Execute(s);
1076 }
1077
1078 void DoExecute(Args &command, CommandReturnObject &result) override {
1079 const size_t argc = command.GetArgumentCount();
1080
1081 std::unique_ptr<RegularExpression> category_regex;
1082 std::unique_ptr<RegularExpression> formatter_regex;
1083
1084 if (m_options.m_category_regex.OptionWasSet()) {
1085 category_regex = std::make_unique<RegularExpression>(
1086 m_options.m_category_regex.GetCurrentValueAsRef());
1087 if (!category_regex->IsValid()) {
1088 result.AppendErrorWithFormat(
1089 "syntax error in category regular expression '%s'",
1090 m_options.m_category_regex.GetCurrentValueAsRef().str().c_str());
1091 return;
1092 }
1093 }
1094
1095 if (argc == 1) {
1096 const char *arg = command.GetArgumentAtIndex(0);
1097 formatter_regex = std::make_unique<RegularExpression>(arg);
1098 if (!formatter_regex->IsValid()) {
1099 result.AppendErrorWithFormat("syntax error in regular expression '%s'",
1100 arg);
1101 return;
1102 }
1103 }
1104
1105 bool any_printed = false;
1106
1107 auto category_closure =
1108 [&result, &formatter_regex,
1109 &any_printed](const lldb::TypeCategoryImplSP &category) -> void {
1110 result.GetOutputStream().Printf(
1111 "-----------------------\nCategory: %s%s\n-----------------------\n",
1112 category->GetName(), category->IsEnabled() ? "" : " (disabled)");
1113
1115 [&result, &formatter_regex,
1116 &any_printed](const TypeMatcher &type_matcher,
1117 const FormatterSharedPointer &format_sp) -> bool {
1118 if (ShouldListItem(type_matcher.GetMatchString().GetStringRef(),
1119 formatter_regex.get())) {
1120 any_printed = true;
1121 result.GetOutputStream().Printf(
1122 "%s: %s\n", type_matcher.GetMatchString().GetCString(),
1123 format_sp->GetDescription().c_str());
1124 }
1125 return true;
1126 };
1127 category->ForEach(print_formatter);
1128 };
1129
1130 if (m_options.m_category_language.OptionWasSet()) {
1131 lldb::TypeCategoryImplSP category_sp;
1133 m_options.m_category_language.GetCurrentValue(), category_sp);
1134 if (category_sp)
1135 category_closure(category_sp);
1136 } else {
1138 [&category_regex, &category_closure](
1139 const lldb::TypeCategoryImplSP &category) -> bool {
1140 if (ShouldListItem(category->GetName(), category_regex.get())) {
1141 category_closure(category);
1142 }
1143 return true;
1144 });
1145
1146 any_printed = FormatterSpecificList(result) | any_printed;
1147 }
1148
1149 if (any_printed)
1151 else {
1152 result.GetOutputStream().PutCString("no matching results found.\n");
1154 }
1155 }
1156};
1157
1158// CommandObjectTypeFormatList
1159
1161 : public CommandObjectTypeFormatterList<TypeFormatImpl> {
1162public:
1164 : CommandObjectTypeFormatterList(interpreter, "type format list",
1165 "Show a list of current formats.") {}
1166};
1167
1169 uint32_t option_idx, llvm::StringRef option_arg,
1170 ExecutionContext *execution_context) {
1171 Status error;
1172 const int short_option = g_type_summary_add_options[option_idx].short_option;
1173 bool success;
1174
1175 switch (short_option) {
1176 case 'C':
1177 m_flags.SetCascades(OptionArgParser::ToBoolean(option_arg, true, &success));
1178 if (!success)
1179 error = Status::FromErrorStringWithFormat("invalid value for cascade: %s",
1180 option_arg.str().c_str());
1181 break;
1182 case 'e':
1183 m_flags.SetDontShowChildren(false);
1184 break;
1185 case 'h':
1186 m_flags.SetHideEmptyAggregates(true);
1187 break;
1188 case 'v':
1189 m_flags.SetDontShowValue(true);
1190 break;
1191 case 'c':
1192 m_flags.SetShowMembersOneLiner(true);
1193 break;
1194 case 's':
1195 m_format_string = std::string(option_arg);
1196 break;
1197 case 'p':
1198 m_flags.SetSkipPointers(true);
1199 break;
1200 case 'd':
1201 if (option_arg.getAsInteger(0, m_ptr_match_depth)) {
1203 "invalid integer value for option '%c': %s", short_option,
1204 option_arg.data());
1205 }
1206 break;
1207 case 'r':
1208 m_flags.SetSkipReferences(true);
1209 break;
1210 case 'x':
1213 "can't use --regex and --recognizer-function at the same time");
1214 else
1216 break;
1217 case '\x01':
1220 "can't use --regex and --recognizer-function at the same time");
1221 else
1223 break;
1224 case 'n':
1225 m_name.SetString(option_arg);
1226 break;
1227 case 'o':
1228 m_python_script = std::string(option_arg);
1229 m_is_add_script = true;
1230 break;
1231 case 'F':
1232 m_python_function = std::string(option_arg);
1233 m_is_add_script = true;
1234 break;
1235 case 'P':
1236 m_is_add_script = true;
1237 break;
1238 case 'w':
1239 m_category = std::string(option_arg);
1240 break;
1241 case 'O':
1242 m_flags.SetHideItemNames(true);
1243 break;
1244 default:
1245 llvm_unreachable("Unimplemented option");
1246 }
1247
1248 return error;
1249}
1250
1252 ExecutionContext *execution_context) {
1253 m_flags.Clear().SetCascades().SetDontShowChildren().SetDontShowValue(false);
1254 m_flags.SetShowMembersOneLiner(false)
1255 .SetSkipPointers(false)
1256 .SetSkipReferences(false)
1257 .SetHideItemNames(false);
1258
1260 m_name.Clear();
1261 m_python_script = "";
1262 m_python_function = "";
1263 m_format_string = "";
1264 m_is_add_script = false;
1265 m_category = "default";
1266}
1267
1268#if LLDB_ENABLE_PYTHON
1269
1271 Args &command, CommandReturnObject &result) {
1272 const size_t argc = command.GetArgumentCount();
1273
1274 if (argc < 1 && !m_options.m_name) {
1275 result.AppendErrorWithFormat("%s takes one or more args",
1276 m_cmd_name.c_str());
1277 return false;
1278 }
1279
1280 TypeSummaryImplSP script_format;
1281
1283 .empty()) // we have a Python function ready to use
1284 {
1285 const char *funct_name = m_options.m_python_function.c_str();
1286 if (!funct_name || !funct_name[0]) {
1287 result.AppendError("function name empty.\n");
1288 return false;
1289 }
1290
1291 std::string code =
1292 (" " + m_options.m_python_function + "(valobj,internal_dict)");
1293
1294 script_format = std::make_shared<ScriptSummaryFormat>(
1295 m_options.m_flags, funct_name, code.c_str(),
1296 m_options.m_ptr_match_depth);
1297
1298 ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
1299
1300 if (interpreter && !interpreter->CheckObjectExists(funct_name))
1302 "the provided function \"{0}\" does not exist - "
1303 "please define it before attempting to use this summary",
1304 funct_name);
1305 } else if (!m_options.m_python_script
1306 .empty()) // we have a quick 1-line script, just use it
1307 {
1308 ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
1309 if (!interpreter) {
1310 result.AppendError("script interpreter missing - unable to generate "
1311 "function wrapper.\n");
1312 return false;
1313 }
1314 StringList funct_sl;
1315 funct_sl << m_options.m_python_script.c_str();
1316 std::string funct_name_str;
1317 if (!interpreter->GenerateTypeScriptFunction(funct_sl, funct_name_str)) {
1318 result.AppendError("unable to generate function wrapper.\n");
1319 return false;
1320 }
1321 if (funct_name_str.empty()) {
1322 result.AppendError(
1323 "script interpreter failed to generate a valid function name.\n");
1324 return false;
1325 }
1326
1327 std::string code = " " + m_options.m_python_script;
1328
1329 script_format = std::make_shared<ScriptSummaryFormat>(
1330 m_options.m_flags, funct_name_str.c_str(), code.c_str(),
1331 m_options.m_ptr_match_depth);
1332 } else {
1333 // Use an IOHandler to grab Python code from the user
1334 auto options = std::make_unique<ScriptAddOptions>(
1335 m_options.m_flags, m_options.m_match_type, m_options.m_name,
1336 m_options.m_category, m_options.m_ptr_match_depth);
1337
1338 for (auto &entry : command.entries()) {
1339 if (entry.ref().empty()) {
1340 result.AppendError("empty typenames not allowed");
1341 return false;
1342 }
1343
1344 options->m_target_types << std::string(entry.ref());
1345 }
1346
1347 m_interpreter.GetPythonCommandsFromIOHandler(
1348 " ", // Prompt
1349 *this, // IOHandlerDelegate
1350 options.release()); // Baton for the "io_handler" that will be passed
1351 // back into our IOHandlerDelegate functions
1353
1354 return result.Succeeded();
1355 }
1356
1357 // if I am here, script_format must point to something good, so I can add
1358 // that as a script summary to all interested parties
1359
1360 Status error;
1361
1362 for (auto &entry : command.entries()) {
1363 AddSummary(ConstString(entry.ref()), script_format, m_options.m_match_type,
1364 m_options.m_category, &error);
1365 if (error.Fail()) {
1366 result.AppendError(error.AsCString());
1367 return false;
1368 }
1369 }
1370
1371 if (m_options.m_name) {
1372 AddNamedSummary(m_options.m_name, script_format, &error);
1373 if (error.Fail()) {
1374 result.AppendError(error.AsCString());
1375 result.AppendError("added to types, but not given a name");
1376 return false;
1377 }
1378 }
1379
1380 return result.Succeeded();
1381}
1382
1384 Args &command, CommandReturnObject &result) {
1385 const size_t argc = command.GetArgumentCount();
1386
1387 if (argc < 1 && !m_options.m_name) {
1388 result.AppendErrorWithFormat("%s takes one or more args",
1389 m_cmd_name.c_str());
1390 return false;
1391 }
1392
1393 const std::string &class_name = m_class_options.GetName();
1394 if (class_name.empty()) {
1395 result.AppendError("must provide a Python class name");
1396 return false;
1397 }
1398
1399 TypeSummaryImplSP script_format = std::make_shared<ScriptedSummaryFormat>(
1400 m_options.m_flags, class_name.c_str(), m_options.m_ptr_match_depth);
1401
1402 Status error;
1403
1404 for (auto &entry : command.entries()) {
1405 AddSummary(ConstString(entry.ref()), script_format, m_options.m_match_type,
1406 m_options.m_category, &error);
1407 if (error.Fail()) {
1408 result.AppendError(error.AsCString());
1409 return false;
1410 }
1411 }
1412
1413 if (m_options.m_name) {
1414 AddNamedSummary(m_options.m_name, script_format, &error);
1415 if (error.Fail()) {
1416 result.AppendError(error.AsCString());
1417 result.AppendError("added to types, but not given a name");
1418 return false;
1419 }
1420 }
1421
1422 return result.Succeeded();
1423}
1424
1425#endif
1426
1428 Args &command, CommandReturnObject &result) {
1429 const size_t argc = command.GetArgumentCount();
1430
1431 if (argc < 1 && !m_options.m_name) {
1432 result.AppendErrorWithFormat("%s takes one or more args",
1433 m_cmd_name.c_str());
1434 return false;
1435 }
1436
1437 if (!m_options.m_flags.GetShowMembersOneLiner() &&
1438 m_options.m_format_string.empty()) {
1439 result.AppendError("empty summary strings not allowed");
1440 return false;
1441 }
1442
1443 const char *format_cstr = (m_options.m_flags.GetShowMembersOneLiner()
1444 ? ""
1445 : m_options.m_format_string.c_str());
1446
1447 // ${var%S} is an endless recursion, prevent it
1448 if (strcmp(format_cstr, "${var%S}") == 0) {
1449 result.AppendError("recursive summary not allowed");
1450 return false;
1451 }
1452
1453 std::unique_ptr<StringSummaryFormat> string_format(new StringSummaryFormat(
1454 m_options.m_flags, format_cstr, m_options.m_ptr_match_depth));
1455 if (!string_format) {
1456 result.AppendError("summary creation failed");
1457 return false;
1458 }
1459 if (string_format->m_error.Fail()) {
1460 result.AppendErrorWithFormat("syntax error: %s",
1461 string_format->m_error.AsCString("<unknown>"));
1462 return false;
1463 }
1464 lldb::TypeSummaryImplSP entry(string_format.release());
1465
1466 // now I have a valid format, let's add it to every type
1467 Status error;
1468 for (auto &arg_entry : command.entries()) {
1469 if (arg_entry.ref().empty()) {
1470 result.AppendError("empty typenames not allowed");
1471 return false;
1472 }
1473 ConstString typeCS(arg_entry.ref());
1474
1475 AddSummary(typeCS, entry, m_options.m_match_type, m_options.m_category,
1476 &error);
1477
1478 if (error.Fail()) {
1479 result.AppendError(error.AsCString());
1480 return false;
1481 }
1482 }
1483
1484 if (m_options.m_name) {
1485 AddNamedSummary(m_options.m_name, entry, &error);
1486 if (error.Fail()) {
1487 result.AppendError(error.AsCString());
1488 result.AppendError("added to types, but not given a name");
1489 return false;
1490 }
1491 }
1492
1494 return result.Succeeded();
1495}
1496
1498 CommandInterpreter &interpreter)
1499 : CommandObjectParsed(interpreter, "type summary add",
1500 "Add a new summary style for a type.", nullptr),
1502 m_class_options("scripted string summary", /*is_class=*/true, 'L', 'K',
1503 'V', /*required_options=*/0) {
1504 m_option_group.Append(&m_options);
1507 m_option_group.Finalize();
1508
1510
1512 R"(
1513The following examples of 'type summary add' refer to this code snippet for context:
1514
1515 struct JustADemo
1516 {
1517 int* ptr;
1518 float value;
1519 JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}
1520 };
1521 JustADemo demo_instance(42, 3.14);
1522
1523 typedef JustADemo NewDemo;
1524 NewDemo new_demo_instance(42, 3.14);
1525
1526(lldb) type summary add --summary-string "the answer is ${*var.ptr}" JustADemo
1527
1528 Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42"
1529
1530(lldb) type summary add --summary-string "the answer is ${*var.ptr}, and the question is ${var.value}" JustADemo
1531
1532 Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42 and the question is 3.14"
1533
1534)"
1535 "Alternatively, you could define formatting for all pointers to integers and \
1536rely on that when formatting JustADemo to obtain the same result:"
1537 R"(
1538
1539(lldb) type summary add --summary-string "${var%V} -> ${*var}" "int *"
1540(lldb) type summary add --summary-string "the answer is ${var.ptr}, and the question is ${var.value}" JustADemo
1542)"
1543 "Type summaries are automatically applied to derived typedefs, so the examples \
1544above apply to both JustADemo and NewDemo. The cascade option can be used to \
1545suppress this behavior:"
1546 R"(
1547
1548(lldb) type summary add --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo -C no
1549
1550 The summary will now be used for values of JustADemo but not NewDemo.
1551
1552)"
1553 "By default summaries are shown for pointers and references to values of the \
1554specified type. To suppress formatting for pointers use the -p option, or apply \
1555the corresponding -r option to suppress formatting for references:"
1556 R"(
1557
1558(lldb) type summary add -p -r --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo
1559
1560)"
1561 "One-line summaries including all fields in a type can be inferred without supplying an \
1562explicit summary string by passing the -c option:"
1563 R"(
1564
1565(lldb) type summary add -c JustADemo
1566(lldb) frame variable demo_instance
1567(ptr=<address>, value=3.14)
1568
1569)"
1570 "Type summaries normally suppress the nested display of individual fields. To \
1571supply a summary to supplement the default structure add the -e option:"
1572 R"(
1573
1574(lldb) type summary add -e --summary-string "*ptr = ${*var.ptr}" JustADemo
1575
1576)"
1577 "Now when displaying JustADemo values the int* is displayed, followed by the \
1578standard LLDB sequence of children, one per line:"
1579 R"(
1580
1581*ptr = 42 {
1582 ptr = <address>
1583 value = 3.14
1584}
1585
1586)"
1587 "You can also add summaries written in Python. These scripts use lldb public API to \
1588gather information from your variables and produce a meaningful summary. To start a \
1589multi-line script use the -P option. The function declaration will be displayed along with \
1590a comment describing the two arguments. End your script with the word 'DONE' on a line by \
1591itself:"
1592 R"(
1593
1594(lldb) type summary add JustADemo -P
1595def function (valobj,internal_dict): """valobj: an SBValue which you want to provide a summary for
1596internal_dict: an LLDB support object not to be used"""
1597 value = valobj.GetChildMemberWithName('value');
1598 return 'My value is ' + value.GetValue();
1599 DONE
1600
1601Alternatively, the -o option can be used when providing a simple one-line Python script:
1602
1603(lldb) type summary add JustADemo -o "value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();")");
1604}
1605
1607 CommandReturnObject &result) {
1608 WarnOnPotentialUnquotedUnsignedType(command, result);
1609
1610 if (!m_class_options.GetName().empty()) {
1611#if LLDB_ENABLE_PYTHON
1612 Execute_PythonClassSummary(command, result);
1613#else
1614 result.AppendError("python is disabled");
1615#endif
1616 } else if (m_options.m_is_add_script) {
1617#if LLDB_ENABLE_PYTHON
1618 Execute_ScriptSummary(command, result);
1619#else
1620 result.AppendError("python is disabled");
1621#endif
1622 } else {
1623 Execute_StringSummary(command, result);
1624 }
1625
1626 if (result.GetStatus() != eReturnStatusFailed)
1628}
1629
1630static bool FixArrayTypeNameWithRegex(ConstString &type_name) {
1631 llvm::StringRef type_name_ref(type_name.GetStringRef());
1632
1633 if (type_name_ref.ends_with("[]")) {
1634 std::string type_name_str(type_name.GetCString());
1635 type_name_str.resize(type_name_str.length() - 2);
1636 if (type_name_str.back() != ' ')
1637 type_name_str.append(" ?\\[[0-9]+\\]");
1638 else
1639 type_name_str.append("\\[[0-9]+\\]");
1640 type_name.SetCString(type_name_str.c_str());
1641 return true;
1642 }
1643 return false;
1644}
1645
1648 Status *error) {
1649 // system named summaries do not exist (yet?)
1651 return true;
1652}
1653
1656 FormatterMatchType match_type,
1657 std::string category_name,
1658 Status *error) {
1659 lldb::TypeCategoryImplSP category;
1661 category);
1663 if (match_type == eFormatterMatchExact) {
1664 if (FixArrayTypeNameWithRegex(type_name))
1666 }
1667
1668 if (match_type == eFormatterMatchRegex) {
1669 match_type = eFormatterMatchRegex;
1670 RegularExpression typeRX(type_name.GetStringRef());
1671 if (!typeRX.IsValid()) {
1672 if (error)
1674 "regex format error (maybe this is not really a regex?)");
1675 return false;
1676 }
1677 }
1678
1679 if (match_type == eFormatterMatchCallback) {
1680 const char *function_name = type_name.AsCString(nullptr);
1681 ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
1682 if (interpreter && !interpreter->CheckObjectExists(function_name)) {
1683 *error = Status::FromErrorStringWithFormat(
1684 "The provided recognizer function \"%s\" does not exist - "
1685 "please define it before attempting to use this summary.\n",
1686 function_name);
1687 return false;
1689 }
1690 category->AddTypeSummary(type_name.GetStringRef(), match_type, entry);
1691 return true;
1693
1694// CommandObjectTypeSummaryDelete
1695
1697public:
1701
1702 ~CommandObjectTypeSummaryDelete() override = default;
1703
1704protected:
1705 bool FormatterSpecificDeletion(ConstString typeCS) override {
1706 if (m_options.m_language != lldb::eLanguageTypeUnknown)
1707 return false;
1709 }
1710};
1711
1713public:
1714 CommandObjectTypeSummaryClear(CommandInterpreter &interpreter)
1716 "type summary clear",
1717 "Delete all existing summaries.") {}
1718
1719protected:
1720 void FormatterSpecificDeletion() override {
1722 }
1723};
1725// CommandObjectTypeSummaryList
1726
1728 : public CommandObjectTypeFormatterList<TypeSummaryImpl> {
1729public:
1731 : CommandObjectTypeFormatterList(interpreter, "type summary list",
1732 "Show a list of current summaries.") {}
1733
1734protected:
1735 bool FormatterSpecificList(CommandReturnObject &result) override {
1737 result.GetOutputStream().Printf("Named summaries:\n");
1739 [&result](const TypeMatcher &type_matcher,
1740 const TypeSummaryImplSP &summary_sp) -> bool {
1741 result.GetOutputStream().Printf(
1742 "%s: %s\n", type_matcher.GetMatchString().GetCString(),
1743 summary_sp->GetDescription().c_str());
1744 return true;
1745 });
1746 return true;
1747 }
1748 return false;
1750};
1751
1752// CommandObjectTypeCategoryDefine
1753#define LLDB_OPTIONS_type_category_define
1754#include "CommandOptions.inc"
1755
1757 class CommandOptions : public Options {
1758 public:
1760 : m_define_enabled(false, false),
1762
1763 ~CommandOptions() override = default;
1764
1765 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1766 ExecutionContext *execution_context) override {
1767 Status error;
1768 const int short_option = m_getopt_table[option_idx].val;
1769
1770 switch (short_option) {
1771 case 'e':
1772 m_define_enabled.SetValueFromString(llvm::StringRef("true"));
1773 break;
1774 case 'l':
1776 break;
1777 default:
1778 llvm_unreachable("Unimplemented option");
1780
1781 return error;
1782 }
1784 void OptionParsingStarting(ExecutionContext *execution_context) override {
1787 }
1788
1789 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1790 return llvm::ArrayRef(g_type_category_define_options);
1791 }
1792
1793 // Instance variables to hold the values for command options.
1794
1797 };
1798
1800
1801 Options *GetOptions() override { return &m_options; }
1802
1803public:
1804 CommandObjectTypeCategoryDefine(CommandInterpreter &interpreter)
1805 : CommandObjectParsed(interpreter, "type category define",
1806 "Define a new category as a source of formatters.",
1807 nullptr) {
1809 }
1811 ~CommandObjectTypeCategoryDefine() override = default;
1812
1813protected:
1814 void DoExecute(Args &command, CommandReturnObject &result) override {
1815 const size_t argc = command.GetArgumentCount();
1817 if (argc < 1) {
1818 result.AppendErrorWithFormat("%s takes 1 or more args",
1819 m_cmd_name.c_str());
1820 return;
1822
1823 for (auto &entry : command.entries()) {
1826 category_sp) &&
1827 category_sp) {
1828 category_sp->AddLanguage(m_options.m_cate_language.GetCurrentValue());
1829 if (m_options.m_define_enabled.GetCurrentValue())
1832 }
1833 }
1836 }
1837};
1838
1839// CommandObjectTypeCategoryEnable
1840#define LLDB_OPTIONS_type_category_enable
1841#include "CommandOptions.inc"
1842
1844 class CommandOptions : public Options {
1845 public:
1846 CommandOptions() = default;
1847
1848 ~CommandOptions() override = default;
1849
1850 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1851 ExecutionContext *execution_context) override {
1852 Status error;
1853 const int short_option = m_getopt_table[option_idx].val;
1854
1855 switch (short_option) {
1856 case 'l':
1857 if (!option_arg.empty()) {
1860 error = Status::FromErrorStringWithFormat(
1861 "unrecognized language '%s'", option_arg.str().c_str());
1862 }
1863 break;
1864 default:
1865 llvm_unreachable("Unimplemented option");
1866 }
1867
1868 return error;
1869 }
1870
1871 void OptionParsingStarting(ExecutionContext *execution_context) override {
1874
1875 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1876 return llvm::ArrayRef(g_type_category_enable_options);
1877 }
1878
1879 // Instance variables to hold the values for command options.
1880
1883
1884 CommandOptions m_options;
1886 Options *GetOptions() override { return &m_options; }
1887
1888public:
1890 : CommandObjectParsed(interpreter, "type category enable",
1891 "Enable a category as a source of formatters.",
1892 nullptr) {
1894 }
1895
1896 ~CommandObjectTypeCategoryEnable() override = default;
1897
1898protected:
1899 void DoExecute(Args &command, CommandReturnObject &result) override {
1900 const size_t argc = command.GetArgumentCount();
1901
1902 if (argc < 1 && m_options.m_language == lldb::eLanguageTypeUnknown) {
1903 result.AppendErrorWithFormat("%s takes arguments and/or a language",
1904 m_cmd_name.c_str());
1905 return;
1906 }
1907
1908 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0), "*") == 0) {
1910 } else if (argc > 0) {
1911 for (int i = argc - 1; i >= 0; i--) {
1912 const char *typeA = command.GetArgumentAtIndex(i);
1913 ConstString typeCS(typeA);
1914
1915 if (!typeCS) {
1916 result.AppendError("empty category name not allowed");
1917 return;
1918 }
1922 if (cate->GetCount() == 0) {
1923 result.AppendWarning("empty category enabled (typo?)");
1924 }
1926 }
1928
1929 if (m_options.m_language != lldb::eLanguageTypeUnknown)
1931
1933 }
1934};
1935
1936// CommandObjectTypeCategoryDelete
1937
1939public:
1940 CommandObjectTypeCategoryDelete(CommandInterpreter &interpreter)
1941 : CommandObjectParsed(interpreter, "type category delete",
1942 "Delete a category and all associated formatters.",
1943 nullptr) {
1945 }
1946
1947 ~CommandObjectTypeCategoryDelete() override = default;
1949protected:
1950 void DoExecute(Args &command, CommandReturnObject &result) override {
1951 const size_t argc = command.GetArgumentCount();
1953 if (argc < 1) {
1954 result.AppendErrorWithFormat("%s takes 1 or more arg",
1955 m_cmd_name.c_str());
1956 return;
1957 }
1959 bool success = true;
1960
1961 // the order is not relevant here
1962 for (int i = argc - 1; i >= 0; i--) {
1963 const char *typeA = command.GetArgumentAtIndex(i);
1964 ConstString typeCS(typeA);
1965
1966 if (!typeCS) {
1967 result.AppendError("empty category name not allowed");
1968 return;
1969 }
1971 success = false; // keep deleting even if we hit an error
1972 }
1973 if (success) {
1975 } else {
1976 result.AppendError("cannot delete one or more categories\n");
1977 }
1978 }
1979};
1980
1981// CommandObjectTypeCategoryDisable
1982#define LLDB_OPTIONS_type_category_disable
1983#include "CommandOptions.inc"
1984
1986 class CommandOptions : public Options {
1987 public:
1988 CommandOptions() = default;
1989
1990 ~CommandOptions() override = default;
1991
1992 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1993 ExecutionContext *execution_context) override {
1994 Status error;
1995 const int short_option = m_getopt_table[option_idx].val;
1996
1997 switch (short_option) {
1998 case 'l':
1999 if (!option_arg.empty()) {
2002 error = Status::FromErrorStringWithFormat(
2003 "unrecognized language '%s'", option_arg.str().c_str());
2004 }
2005 break;
2006 default:
2007 llvm_unreachable("Unimplemented option");
2008 }
2009
2010 return error;
2011 }
2013 void OptionParsingStarting(ExecutionContext *execution_context) override {
2015 }
2016
2017 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2018 return llvm::ArrayRef(g_type_category_disable_options);
2020
2021 // Instance variables to hold the values for command options.
2024 };
2025
2026 CommandOptions m_options;
2027
2028 Options *GetOptions() override { return &m_options; }
2029
2030public:
2031 CommandObjectTypeCategoryDisable(CommandInterpreter &interpreter)
2032 : CommandObjectParsed(interpreter, "type category disable",
2033 "Disable a category as a source of formatters.",
2034 nullptr) {
2036 }
2037
2038 ~CommandObjectTypeCategoryDisable() override = default;
2039
2040protected:
2041 void DoExecute(Args &command, CommandReturnObject &result) override {
2042 const size_t argc = command.GetArgumentCount();
2043
2044 if (argc < 1 && m_options.m_language == lldb::eLanguageTypeUnknown) {
2045 result.AppendErrorWithFormat("%s takes arguments and/or a language",
2046 m_cmd_name.c_str());
2047 return;
2048 }
2049
2050 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0), "*") == 0) {
2052 } else if (argc > 0) {
2053 // the order is not relevant here
2054 for (int i = argc - 1; i >= 0; i--) {
2055 const char *typeA = command.GetArgumentAtIndex(i);
2056 ConstString typeCS(typeA);
2057
2058 if (!typeCS) {
2059 result.AppendError("empty category name not allowed");
2060 return;
2061 }
2063 }
2064 }
2065
2066 if (m_options.m_language != lldb::eLanguageTypeUnknown)
2068
2070 }
2071};
2072
2073// CommandObjectTypeCategoryList
2074
2076public:
2078 : CommandObjectParsed(interpreter, "type category list",
2079 "Provide a list of all existing categories.",
2080 nullptr) {
2082 }
2083
2084 ~CommandObjectTypeCategoryList() override = default;
2085
2094 }
2095
2096protected:
2097 void DoExecute(Args &command, CommandReturnObject &result) override {
2098 const size_t argc = command.GetArgumentCount();
2100 std::unique_ptr<RegularExpression> regex;
2101
2102 if (argc == 1) {
2103 const char *arg = command.GetArgumentAtIndex(0);
2104 regex = std::make_unique<RegularExpression>(arg);
2105 if (!regex->IsValid()) {
2106 result.AppendErrorWithFormat(
2107 "syntax error in category regular expression '%s'", arg);
2108 return;
2109 }
2110 } else if (argc != 0) {
2111 result.AppendErrorWithFormat("%s takes 0 or one arg", m_cmd_name.c_str());
2112 return;
2113 }
2116 [&regex, &result](const lldb::TypeCategoryImplSP &category_sp) -> bool {
2117 if (regex) {
2118 bool escape = true;
2119 if (regex->GetText() == category_sp->GetName()) {
2120 escape = false;
2121 } else if (regex->Execute(category_sp->GetName())) {
2122 escape = false;
2123 }
2124
2125 if (escape)
2126 return true;
2127 }
2128
2130 "Category: %s\n", category_sp->GetDescription().c_str());
2132 return true;
2133 });
2134
2136 }
2138
2139// CommandObjectTypeFilterList
2140
2142 : public CommandObjectTypeFormatterList<TypeFilterImpl> {
2143public:
2145 : CommandObjectTypeFormatterList(interpreter, "type filter list",
2146 "Show a list of current filters.") {}
2147};
2148
2149// CommandObjectTypeSynthList
2150
2152 : public CommandObjectTypeFormatterList<SyntheticChildren> {
2153public:
2154 CommandObjectTypeSynthList(CommandInterpreter &interpreter)
2156 interpreter, "type synthetic list",
2157 "Show a list of current synthetic providers.") {}
2158};
2159
2160// CommandObjectTypeFilterDelete
2161
2163public:
2167
2168 ~CommandObjectTypeFilterDelete() override = default;
2169};
2170
2171// CommandObjectTypeSynthDelete
2172
2174public:
2178
2179 ~CommandObjectTypeSynthDelete() override = default;
2180};
2181
2182// CommandObjectTypeFilterClear
2183
2185public:
2186 CommandObjectTypeFilterClear(CommandInterpreter &interpreter)
2188 "type filter clear",
2189 "Delete all existing filter.") {}
2190};
2191
2192// CommandObjectTypeSynthClear
2193
2195public:
2196 CommandObjectTypeSynthClear(CommandInterpreter &interpreter)
2198 interpreter, eFormatCategoryItemSynth, "type synthetic clear",
2199 "Delete all existing synthetic providers.") {}
2200};
2201
2203 Args &command, CommandReturnObject &result) {
2204 auto options = std::make_unique<SynthAddOptions>(
2205 m_options.m_skip_pointers, m_options.m_skip_references,
2206 m_options.m_cascade, m_options.m_wants_deref, m_options.m_match_type,
2207 m_options.m_category);
2208
2209 for (auto &entry : command.entries()) {
2210 if (entry.ref().empty()) {
2211 result.AppendError("empty typenames not allowed");
2212 return false;
2213 }
2214
2215 options->m_target_types << std::string(entry.ref());
2216 }
2217
2218 m_interpreter.GetPythonCommandsFromIOHandler(
2219 " ", // Prompt
2220 *this, // IOHandlerDelegate
2221 options.release()); // Baton for the "io_handler" that will be passed back
2222 // into our IOHandlerDelegate functions
2224 return result.Succeeded();
2225}
2228 Args &command, CommandReturnObject &result) {
2229 const size_t argc = command.GetArgumentCount();
2230
2231 if (argc < 1) {
2232 result.AppendErrorWithFormat("%s takes one or more args",
2233 m_cmd_name.c_str());
2234 return false;
2235 }
2236
2238 result.AppendErrorWithFormat("%s needs either a Python class name or -P to "
2239 "directly input Python code",
2240 m_cmd_name.c_str());
2241 return false;
2242 }
2243
2244 SyntheticChildrenSP entry;
2245
2246 ScriptedSyntheticChildren *impl = new ScriptedSyntheticChildren(
2247 SyntheticChildren::Flags()
2248 .SetCascades(m_options.m_cascade)
2249 .SetFrontEndWantsDereference(m_options.m_wants_deref)
2250 .SetSkipPointers(m_options.m_skip_pointers)
2251 .SetSkipReferences(m_options.m_skip_references),
2252 m_options.m_class_name.c_str());
2253
2254 entry.reset(impl);
2255
2256 ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
2257
2258 const char *python_class_name = impl->GetPythonClassName();
2259 if (interpreter && !interpreter->CheckObjectExists(python_class_name))
2261 "the provided class '{0}' does not exist - please define it "
2262 "before attempting to use this synthetic provider",
2263 llvm::StringRef(python_class_name));
2264
2265 // now I have a valid provider, let's add it to every type
2266
2267 lldb::TypeCategoryImplSP category;
2269 category);
2270
2271 Status error;
2272
2273 for (auto &arg_entry : command.entries()) {
2274 if (arg_entry.ref().empty()) {
2275 result.AppendError("empty typenames not allowed");
2276 return false;
2277 }
2278
2279 ConstString typeCS(arg_entry.ref());
2280 if (!AddSynth(typeCS, entry, m_options.m_match_type, m_options.m_category,
2281 &error)) {
2282 result.AppendError(error.AsCString());
2283 return false;
2284 }
2285 }
2286
2288 return result.Succeeded();
2289}
2290
2292 CommandInterpreter &interpreter)
2293 : CommandObjectParsed(interpreter, "type synthetic add",
2294 "Add a new synthetic provider for a type.", nullptr),
2295 IOHandlerDelegateMultiline("DONE"), m_options() {
2297}
2300 SyntheticChildrenSP entry,
2301 FormatterMatchType match_type,
2302 std::string category_name,
2303 Status *error) {
2306 category);
2307
2308 if (match_type == eFormatterMatchExact) {
2309 if (FixArrayTypeNameWithRegex(type_name))
2310 match_type = eFormatterMatchRegex;
2311 }
2312
2313 // Only check for conflicting filters in the same category if `type_name` is
2314 // an actual type name. Matching a regex string against registered regexes
2315 // doesn't work.
2316 if (match_type == eFormatterMatchExact) {
2317 // It's not generally possible to get a type object here. For example, this
2318 // command can be run before loading any binaries. Do just a best-effort
2319 // name-based lookup here to try to prevent conflicts.
2320 FormattersMatchCandidate candidate_type(type_name, nullptr, TypeImpl(),
2322 if (category->AnyMatches(candidate_type, eFormatCategoryItemFilter)) {
2323 if (error)
2325 "cannot add synthetic for type {0} when "
2326 "filter is defined in same category!",
2327 type_name);
2328 return false;
2329 }
2330 }
2331
2332 if (match_type == eFormatterMatchRegex) {
2333 RegularExpression typeRX(type_name.GetStringRef());
2334 if (!typeRX.IsValid()) {
2335 if (error)
2336 *error = Status::FromErrorString(
2337 "regex format error (maybe this is not really a regex?)");
2338 return false;
2339 }
2340 }
2341
2342 if (match_type == eFormatterMatchCallback) {
2343 const char *function_name = type_name.AsCString(nullptr);
2345 if (interpreter && !interpreter->CheckObjectExists(function_name)) {
2347 "The provided recognizer function \"%s\" does not exist - "
2348 "please define it before attempting to use this summary.\n",
2349 function_name);
2350 return false;
2351 }
2353
2354 category->AddTypeSynthetic(type_name.GetStringRef(), match_type, entry);
2355 return true;
2356}
2357
2358#define LLDB_OPTIONS_type_filter_add
2359#include "CommandOptions.inc"
2362private:
2363 class CommandOptions : public Options {
2364 typedef std::vector<std::string> option_vector;
2366 public:
2367 CommandOptions() = default;
2368
2369 ~CommandOptions() override = default;
2371 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2372 ExecutionContext *execution_context) override {
2373 Status error;
2374 const int short_option = m_getopt_table[option_idx].val;
2375 bool success;
2377 switch (short_option) {
2378 case 'C':
2379 m_cascade = OptionArgParser::ToBoolean(option_arg, true, &success);
2380 if (!success)
2382 "invalid value for cascade: %s", option_arg.str().c_str());
2383 break;
2384 case 'c':
2385 m_expr_paths.push_back(std::string(option_arg));
2386 has_child_list = true;
2387 break;
2388 case 'p':
2389 m_skip_pointers = true;
2390 break;
2391 case 'r':
2392 m_skip_references = true;
2393 break;
2394 case 'w':
2395 m_category = std::string(option_arg);
2396 break;
2397 case 'x':
2398 m_regex = true;
2399 break;
2400 default:
2401 llvm_unreachable("Unimplemented option");
2402 }
2403
2404 return error;
2405 }
2406
2407 void OptionParsingStarting(ExecutionContext *execution_context) override {
2408 m_cascade = true;
2409 m_skip_pointers = false;
2410 m_skip_references = false;
2411 m_category = "default";
2412 m_expr_paths.clear();
2413 has_child_list = false;
2414 m_regex = false;
2415 }
2416
2417 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2418 return llvm::ArrayRef(g_type_filter_add_options);
2419 }
2420
2421 // Instance variables to hold the values for command options.
2422
2423 bool m_cascade;
2424 bool m_skip_references;
2426 bool m_input_python;
2428 std::string m_category;
2429 bool has_child_list;
2430 bool m_regex;
2431
2432 typedef option_vector::iterator ExpressionPathsIterator;
2433 };
2434
2435 CommandOptions m_options;
2436
2437 Options *GetOptions() override { return &m_options; }
2438
2441 bool AddFilter(ConstString type_name, TypeFilterImplSP entry,
2442 FilterFormatType type, std::string category_name,
2444 lldb::TypeCategoryImplSP category;
2446 category);
2447
2448 if (type == eRegularFilter) {
2449 if (FixArrayTypeNameWithRegex(type_name))
2450 type = eRegexFilter;
2451 }
2452
2453 // Only check for conflicting synthetic child providers in the same category
2454 // if `type_name` is an actual type name. Matching a regex string against
2455 // registered regexes doesn't work.
2456 if (type == eRegularFilter) {
2457 // It's not generally possible to get a type object here. For example,
2458 // this command can be run before loading any binaries. Do just a
2459 // best-effort name-based lookup here to try to prevent conflicts.
2460 FormattersMatchCandidate candidate_type(
2461 type_name, nullptr, TypeImpl(), FormattersMatchCandidate::Flags());
2463 if (category->AnyMatches(candidate_type, eFormatCategoryItemSynth)) {
2464 if (error)
2466 "cannot add filter for type {0} when "
2467 "synthetic is defined in same "
2468 "category!",
2469 type_name);
2470 return false;
2471 }
2472 }
2473
2475 if (type == eRegexFilter) {
2476 match_type = eFormatterMatchRegex;
2477 RegularExpression typeRX(type_name.GetStringRef());
2478 if (!typeRX.IsValid()) {
2479 if (error)
2481 "regex format error (maybe this is not really a regex?)");
2482 return false;
2483 }
2484 }
2485 category->AddTypeFilter(type_name.GetStringRef(), match_type, entry);
2486 return true;
2487 }
2488
2489public:
2491 : CommandObjectParsed(interpreter, "type filter add",
2492 "Add a new filter for a type.", nullptr) {
2494
2496 R"(
2497The following examples of 'type filter add' refer to this code snippet for context:
2498
2499 class Foo {
2500 int a;
2501 int b;
2502 int c;
2503 int d;
2504 int e;
2505 int f;
2506 int g;
2507 int h;
2508 int i;
2509 }
2510 Foo my_foo;
2511
2512Adding a simple filter:
2513
2514(lldb) type filter add --child a --child g Foo
2515(lldb) frame variable my_foo
2516
2517)"
2518 "Produces output where only a and g are displayed. Other children of my_foo \
2519(b, c, d, e, f, h and i) are available by asking for them explicitly:"
2520 R"(
2521
2522(lldb) frame variable my_foo.b my_foo.c my_foo.i
2523
2524)"
2525 "The formatting option --raw on frame variable bypasses the filter, showing \
2526all children of my_foo as if no filter was defined:"
2527 R"(
2529(lldb) frame variable my_foo --raw)");
2530 }
2532 ~CommandObjectTypeFilterAdd() override = default;
2533
2534protected:
2535 void DoExecute(Args &command, CommandReturnObject &result) override {
2536 const size_t argc = command.GetArgumentCount();
2537
2538 if (argc < 1) {
2539 result.AppendErrorWithFormat("%s takes one or more args",
2540 m_cmd_name.c_str());
2541 return;
2542 }
2543
2544 if (m_options.m_expr_paths.empty()) {
2545 result.AppendErrorWithFormat("%s needs one or more children",
2546 m_cmd_name.c_str());
2547 return;
2548 }
2549
2550 TypeFilterImplSP entry(new TypeFilterImpl(
2551 SyntheticChildren::Flags()
2552 .SetCascades(m_options.m_cascade)
2553 .SetSkipPointers(m_options.m_skip_pointers)
2554 .SetSkipReferences(m_options.m_skip_references)));
2556 // go through the expression paths
2558 end = m_options.m_expr_paths.end();
2560 for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
2561 entry->AddExpressionPath(*begin);
2562
2563 // now I have a valid provider, let's add it to every type
2564
2565 lldb::TypeCategoryImplSP category;
2567 ConstString(m_options.m_category), category);
2568
2569 Status error;
2570
2571 WarnOnPotentialUnquotedUnsignedType(command, result);
2572
2573 for (auto &arg_entry : command.entries()) {
2574 if (arg_entry.ref().empty()) {
2575 result.AppendError("empty typenames not allowed");
2576 return;
2577 }
2578
2579 ConstString typeCS(arg_entry.ref());
2580 if (!AddFilter(typeCS, entry,
2583 result.AppendError(error.AsCString());
2584 return;
2589 }
2590};
2591
2592// "type lookup"
2593#define LLDB_OPTIONS_type_lookup
2594#include "CommandOptions.inc"
2595
2597protected:
2598 // this function is allowed to do a more aggressive job at guessing languages
2599 // than the expression parser is comfortable with - so leave the original
2600 // call alone and add one that is specific to type lookup
2603
2604 if (!frame)
2605 return lang_type;
2606
2607 lang_type = frame->GuessLanguage().AsLanguageType();
2608 if (lang_type != lldb::eLanguageTypeUnknown)
2609 return lang_type;
2611 const Symbol *s = frame->GetSymbolContext(eSymbolContextSymbol).symbol;
2612 if (s)
2613 lang_type = s->GetMangled().GuessLanguage();
2615 return lang_type;
2616 }
2617
2618 class CommandOptions : public OptionGroup {
2619 public:
2620 CommandOptions() = default;
2621
2622 ~CommandOptions() override = default;
2623
2624 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2625 return llvm::ArrayRef(g_type_lookup_options);
2626 }
2627
2628 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
2629 ExecutionContext *execution_context) override {
2630 Status error;
2631
2632 const int short_option = g_type_lookup_options[option_idx].short_option;
2633
2634 switch (short_option) {
2635 case 'h':
2636 m_show_help = true;
2637 break;
2638
2639 case 'l':
2641 break;
2642
2643 default:
2644 llvm_unreachable("Unimplemented option");
2645 }
2646
2647 return error;
2648 }
2649
2650 void OptionParsingStarting(ExecutionContext *execution_context) override {
2651 m_show_help = false;
2653 }
2654
2655 // Options table: Required for subclasses of Options.
2656
2657 bool m_show_help = false;
2659 };
2660
2661 OptionGroupOptions m_option_group;
2663
2664public:
2665 CommandObjectTypeLookup(CommandInterpreter &interpreter)
2666 : CommandObjectRaw(interpreter, "type lookup",
2667 "Lookup types and declarations in the current target, "
2668 "following language-specific naming conventions.",
2669 "type lookup <type-specifier>",
2670 eCommandRequiresTarget) {
2672 m_option_group.Finalize();
2673 }
2674
2675 ~CommandObjectTypeLookup() override = default;
2676
2677 Options *GetOptions() override { return &m_option_group; }
2678
2679 llvm::StringRef GetHelpLong() override {
2680 if (!m_cmd_help_long.empty())
2681 return m_cmd_help_long;
2682
2683 StreamString stream;
2684 Language::ForEach([&](Language *lang) {
2685 if (const char *help = lang->GetLanguageSpecificTypeLookupHelp())
2686 stream.Printf("%s\n", help);
2687 return IterationAction::Continue;
2688 });
2689
2690 m_cmd_help_long = std::string(stream.GetString());
2691 return m_cmd_help_long;
2692 }
2693
2694 void DoExecute(llvm::StringRef raw_command_line,
2695 CommandReturnObject &result) override {
2696 if (raw_command_line.empty()) {
2697 result.AppendError(
2698 "type lookup cannot be invoked without a type name as argument");
2699 return;
2700 }
2701
2702 auto exe_ctx = GetCommandInterpreter().GetExecutionContext();
2703 m_option_group.NotifyOptionParsingStarting(&exe_ctx);
2704
2705 OptionsWithRaw args(raw_command_line);
2706 const char *name_of_type = args.GetRawPart().c_str();
2707
2708 if (args.HasArgs())
2709 if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group,
2710 exe_ctx))
2711 return;
2712
2713 ExecutionContextScope *best_scope = exe_ctx.GetBestExecutionContextScope();
2714
2715 bool any_found = false;
2716
2717 std::vector<Language *> languages;
2718
2719 bool is_global_search = false;
2720 LanguageType guessed_language = lldb::eLanguageTypeUnknown;
2721
2722 if ((is_global_search =
2723 (m_command_options.m_language == eLanguageTypeUnknown))) {
2724 Language::ForEach([&](Language *lang) {
2725 languages.push_back(lang);
2726 return IterationAction::Continue;
2727 });
2728 } else {
2729 languages.push_back(Language::FindPlugin(m_command_options.m_language));
2730 }
2731
2732 // This is not the most efficient way to do this, but we support very few
2733 // languages so the cost of the sort is going to be dwarfed by the actual
2734 // lookup anyway
2735 if (StackFrame *frame = m_exe_ctx.GetFramePtr()) {
2736 guessed_language = GuessLanguage(frame);
2737 if (guessed_language != eLanguageTypeUnknown) {
2738 llvm::sort(
2739 languages.begin(), languages.end(),
2740 [guessed_language](Language *lang1, Language *lang2) -> bool {
2741 if (!lang1 || !lang2)
2742 return false;
2743 LanguageType lt1 = lang1->GetLanguageType();
2744 LanguageType lt2 = lang2->GetLanguageType();
2745 if (lt1 == lt2)
2746 return false;
2747 if (lt1 == guessed_language)
2748 return true; // make the selected frame's language come first
2749 if (lt2 == guessed_language)
2750 return false; // make the selected frame's language come first
2751 return (lt1 < lt2); // normal comparison otherwise
2752 });
2753 }
2754 }
2756 bool is_first_language = true;
2757
2758 for (Language *language : languages) {
2759 if (!language)
2760 continue;
2761
2762 if (auto scavenger = language->GetTypeScavenger()) {
2764 if (scavenger->Find(best_scope, name_of_type, search_results) > 0) {
2765 for (const auto &search_result : search_results) {
2766 if (search_result && search_result->IsValid()) {
2767 any_found = true;
2768 search_result->DumpToStream(result.GetOutputStream(),
2769 this->m_command_options.m_show_help);
2770 }
2771 }
2772 }
2773 }
2774 // this is "type lookup SomeName" and we did find a match, so get out
2775 if (any_found && is_global_search)
2776 break;
2777 else if (is_first_language && is_global_search &&
2778 guessed_language != lldb::eLanguageTypeUnknown) {
2779 is_first_language = false;
2780 result.GetOutputStream().Printf(
2781 "no type was found in the current language %s matching '%s'; "
2782 "performing a global search across all languages\n",
2783 Language::GetNameForLanguageType(guessed_language), name_of_type);
2784 }
2785 }
2786
2787 if (!any_found)
2788 result.AppendMessageWithFormatv("no type was found matching '{0}'",
2789 name_of_type);
2790
2793 }
2794};
2795
2796template <typename FormatterType>
2798public:
2799 typedef std::function<typename FormatterType::SharedPointer(ValueObject &)>
2802 const char *formatter_name,
2803 DiscoveryFunction discovery_func)
2804 : CommandObjectRaw(interpreter, "", "", "", eCommandRequiresFrame),
2805 m_formatter_name(formatter_name ? formatter_name : ""),
2806 m_discovery_function(discovery_func) {
2808 name.Printf("type %s info", formatter_name);
2809 SetCommandName(name.GetString());
2810 StreamString help;
2811 help.Printf("This command evaluates the provided expression and shows "
2812 "which %s is applied to the resulting value (if any).",
2813 formatter_name);
2814 SetHelp(help.GetString());
2815 StreamString syntax;
2816 syntax.Printf("type %s info <expr>", formatter_name);
2817 SetSyntax(syntax.GetString());
2818 }
2819
2820 ~CommandObjectFormatterInfo() override = default;
2821
2822protected:
2823 void DoExecute(llvm::StringRef command,
2824 CommandReturnObject &result) override {
2825 Target *target = GetTarget();
2826 assert(target && "target guaranteed by eCommandRequiresFrame");
2827 Thread *thread = GetDefaultThread();
2828 if (!thread) {
2829 result.AppendError("no default thread");
2830 return;
2832
2833 StackFrameSP frame_sp =
2834 thread->GetSelectedFrame(DoNoSelectMostRelevantFrame);
2835 ValueObjectSP result_valobj_sp;
2837 lldb::ExpressionResults expr_result = target->EvaluateExpression(
2838 command, frame_sp.get(), result_valobj_sp, options);
2839 if (expr_result == eExpressionCompleted && result_valobj_sp) {
2840 result_valobj_sp =
2841 result_valobj_sp->GetQualifiedRepresentationIfAvailable(
2842 target->GetPreferDynamicValue(),
2843 target->GetEnableSyntheticValue());
2844 typename FormatterType::SharedPointer formatter_sp =
2845 m_discovery_function(*result_valobj_sp);
2846 if (formatter_sp) {
2847 std::string description(formatter_sp->GetDescription());
2848 result.GetOutputStream()
2849 << m_formatter_name << " applied to ("
2850 << result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>")
2851 << ") " << command << " is: " << description << "\n";
2853 } else {
2854 result.GetOutputStream()
2855 << "no " << m_formatter_name << " applies to ("
2856 << result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>")
2857 << ") " << command << "\n";
2859 }
2860 } else {
2861 result.AppendError("failed to evaluate expression");
2862 }
2863 }
2864
2865private:
2866 std::string m_formatter_name;
2868};
2869
2871public:
2874 interpreter, "type format",
2875 "Commands for customizing value display formats.",
2876 "type format [<sub-command-options>] ") {
2878 "add", CommandObjectSP(new CommandObjectTypeFormatAdd(interpreter)));
2880 new CommandObjectTypeFormatClear(interpreter)));
2882 interpreter)));
2884 "list", CommandObjectSP(new CommandObjectTypeFormatList(interpreter)));
2887 interpreter, "format",
2889 return valobj.GetValueFormat();
2890 })));
2891 }
2892
2893 ~CommandObjectTypeFormat() override = default;
2894};
2895
2897public:
2900 interpreter, "type synthetic",
2901 "Commands for operating on synthetic type representations.",
2902 "type synthetic [<sub-command-options>] ") {
2903 LoadSubCommand("add",
2906 "clear", CommandObjectSP(new CommandObjectTypeSynthClear(interpreter)));
2908 interpreter)));
2910 "list", CommandObjectSP(new CommandObjectTypeSynthList(interpreter)));
2912 "info",
2914 interpreter, "synthetic",
2916 return valobj.GetSyntheticChildren();
2917 })));
2918 }
2919
2920 ~CommandObjectTypeSynth() override = default;
2921};
2922
2924public:
2926 : CommandObjectMultiword(interpreter, "type filter",
2927 "Commands for operating on type filters.",
2928 "type filter [<sub-command-options>] ") {
2932 new CommandObjectTypeFilterClear(interpreter)));
2934 interpreter)));
2936 "list", CommandObjectSP(new CommandObjectTypeFilterList(interpreter)));
2937 }
2938
2939 ~CommandObjectTypeFilter() override = default;
2940};
2941
2943public:
2945 : CommandObjectMultiword(interpreter, "type category",
2946 "Commands for operating on type categories.",
2947 "type category [<sub-command-options>] ") {
2949 "define",
2952 "enable",
2955 "disable",
2958 "delete",
2961 new CommandObjectTypeCategoryList(interpreter)));
2962 }
2963
2964 ~CommandObjectTypeCategory() override = default;
2965};
2966
2968public:
2971 interpreter, "type summary",
2972 "Commands for editing variable summary display options.",
2973 "type summary [<sub-command-options>] ") {
2975 "add", CommandObjectSP(new CommandObjectTypeSummaryAdd(interpreter)));
2976 LoadSubCommand("clear", CommandObjectSP(new CommandObjectTypeSummaryClear(
2977 interpreter)));
2978 LoadSubCommand("delete", CommandObjectSP(new CommandObjectTypeSummaryDelete(
2979 interpreter)));
2981 "list", CommandObjectSP(new CommandObjectTypeSummaryList(interpreter)));
2983 "info", CommandObjectSP(new CommandObjectFormatterInfo<TypeSummaryImpl>(
2984 interpreter, "summary",
2985 [](ValueObject &valobj) -> TypeSummaryImpl::SharedPointer {
2986 return valobj.GetSummaryFormat();
2987 })));
2988 }
2989
2990 ~CommandObjectTypeSummary() override = default;
2991};
2992
2993// CommandObjectType
2994
2996 : CommandObjectMultiword(interpreter, "type",
2997 "Commands for operating on the type system.",
2998 "type [<sub-command-options>]") {
2999 LoadSubCommand("category",
3000 CommandObjectSP(new CommandObjectTypeCategory(interpreter)));
3001 LoadSubCommand("filter",
3002 CommandObjectSP(new CommandObjectTypeFilter(interpreter)));
3003 LoadSubCommand("format",
3004 CommandObjectSP(new CommandObjectTypeFormat(interpreter)));
3005 LoadSubCommand("summary",
3006 CommandObjectSP(new CommandObjectTypeSummary(interpreter)));
3007 LoadSubCommand("synthetic",
3008 CommandObjectSP(new CommandObjectTypeSynth(interpreter)));
3009 LoadSubCommand("lookup",
3010 CommandObjectSP(new CommandObjectTypeLookup(interpreter)));
3011}
3012
3014
static const char * g_synth_addreader_instructions
static bool WarnOnPotentialUnquotedUnsignedType(Args &command, CommandReturnObject &result)
const char * FormatCategoryToString(FormatCategoryItem item, bool long_name)
static bool FixArrayTypeNameWithRegex(ConstString &type_name)
static llvm::raw_ostream & error(Stream &strm)
~CommandObjectFormatterInfo() override=default
CommandObjectFormatterInfo(CommandInterpreter &interpreter, const char *formatter_name, DiscoveryFunction discovery_func)
void DoExecute(llvm::StringRef command, CommandReturnObject &result) override
std::function< typename FormatterType::SharedPointer(ValueObject &)> DiscoveryFunction
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
CommandObjectTypeCategoryDefine(CommandInterpreter &interpreter)
~CommandObjectTypeCategoryDefine() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTypeCategoryDelete(CommandInterpreter &interpreter)
~CommandObjectTypeCategoryDelete() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
CommandObjectTypeCategoryDisable(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTypeCategoryDisable() override=default
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectTypeCategoryEnable(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTypeCategoryEnable() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTypeCategoryList(CommandInterpreter &interpreter)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
~CommandObjectTypeCategoryList() override=default
CommandObjectTypeCategory(CommandInterpreter &interpreter)
~CommandObjectTypeCategory() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
~CommandObjectTypeFilterAdd() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTypeFilterAdd(CommandInterpreter &interpreter)
bool AddFilter(ConstString type_name, TypeFilterImplSP entry, FilterFormatType type, std::string category_name, Status *error)
CommandObjectTypeFilterClear(CommandInterpreter &interpreter)
CommandObjectTypeFilterDelete(CommandInterpreter &interpreter)
~CommandObjectTypeFilterDelete() override=default
CommandObjectTypeFilterList(CommandInterpreter &interpreter)
~CommandObjectTypeFilter() override=default
CommandObjectTypeFilter(CommandInterpreter &interpreter)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Options * GetOptions() override
CommandObjectTypeFormatAdd(CommandInterpreter &interpreter)
~CommandObjectTypeFormatAdd() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTypeFormatClear(CommandInterpreter &interpreter)
CommandObjectTypeFormatDelete(CommandInterpreter &interpreter)
~CommandObjectTypeFormatDelete() override=default
CommandObjectTypeFormatList(CommandInterpreter &interpreter)
CommandObjectTypeFormat(CommandInterpreter &interpreter)
~CommandObjectTypeFormat() override=default
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectTypeFormatterClear(CommandInterpreter &interpreter, FormatCategoryItem formatter_kind, const char *name, const char *help)
~CommandObjectTypeFormatterClear() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
static constexpr const char * g_long_help_template
virtual bool FormatterSpecificDeletion(ConstString typeCS)
static constexpr const char * g_short_help_template
~CommandObjectTypeFormatterDelete() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
CommandObjectTypeFormatterDelete(CommandInterpreter &interpreter, FormatCategoryItem formatter_kind)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
void DoExecute(Args &command, CommandReturnObject &result) override
FormatterType::SharedPointer FormatterSharedPointer
virtual bool FormatterSpecificList(CommandReturnObject &result)
static bool ShouldListItem(llvm::StringRef s, RegularExpression *regex)
CommandObjectTypeFormatterList(CommandInterpreter &interpreter, const char *name, const char *help)
~CommandObjectTypeFormatterList() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override
OptionGroupOptions m_option_group
void DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override
lldb::LanguageType GuessLanguage(StackFrame *frame)
~CommandObjectTypeLookup() override=default
llvm::StringRef GetHelpLong() override
CommandObjectTypeLookup(CommandInterpreter &interpreter)
Options * GetOptions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
~CommandObjectTypeSummaryAdd() override=default
bool Execute_ScriptSummary(Args &command, CommandReturnObject &result)
void DoExecute(Args &command, CommandReturnObject &result) override
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
bool Execute_StringSummary(Args &command, CommandReturnObject &result)
CommandObjectTypeSummaryAdd(CommandInterpreter &interpreter)
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
bool AddNamedSummary(ConstString summary_name, lldb::TypeSummaryImplSP entry, Status *error=nullptr)
bool Execute_PythonClassSummary(Args &command, CommandReturnObject &result)
bool AddSummary(ConstString type_name, lldb::TypeSummaryImplSP entry, FormatterMatchType match_type, std::string category, Status *error=nullptr)
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 Execute_PythonClass(Args &command, CommandReturnObject &result)
bool AddSynth(ConstString type_name, lldb::SyntheticChildrenSP entry, FormatterMatchType match_type, std::string category_name, Status *error)
Options * GetOptions() override
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTypeSynthAdd() override=default
bool Execute_HandwritePython(Args &command, CommandReturnObject &result)
CommandObjectTypeSynthClear(CommandInterpreter &interpreter)
CommandObjectTypeSynthDelete(CommandInterpreter &interpreter)
~CommandObjectTypeSynthDelete() override=default
CommandObjectTypeSynthList(CommandInterpreter &interpreter)
~CommandObjectTypeSynth() override=default
CommandObjectTypeSynth(CommandInterpreter &interpreter)
std::shared_ptr< ScriptAddOptions > SharedPointer
ScriptAddOptions(const TypeSummaryImpl::Flags &flags, FormatterMatchType match_type, ConstString name, std::string catg, uint32_t m_ptr_match_depth)
TypeSummaryImpl::Flags m_flags
FormatterMatchType m_match_type
SynthAddOptions(bool sptr, bool sref, bool casc, bool wants_deref, FormatterMatchType match_type, std::string catg)
FormatterMatchType m_match_type
std::shared_ptr< SynthAddOptions > SharedPointer
A command line argument class.
Definition Args.h:33
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition Args.h:120
llvm::ArrayRef< ArgEntry > entries() const
Definition Args.h:132
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Definition Args.cpp:273
bool empty() const
Definition Args.h:122
static bool InvokeCommonCompletionCallbacks(CommandInterpreter &interpreter, uint32_t completion_mask, lldb_private::CompletionRequest &request, SearchFilter *searcher)
ExecutionContext GetExecutionContext(bool adopt_dummy_target=true) const
Returns the execution context the interpreter should run a command in.
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
CommandObjectMultiword(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectParsed(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectRaw(CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help="", llvm::StringRef syntax="", uint32_t flags=0)
CommandObjectType(CommandInterpreter &interpreter)
virtual void SetHelpLong(llvm::StringRef str)
void AddSimpleArgumentList(lldb::CommandArgumentType arg_type, ArgumentRepetitionType repetition_type=eArgRepeatPlain)
bool ParseOptionsAndNotify(Args &args, CommandReturnObject &result, OptionGroupOptions &group_options, ExecutionContext &exe_ctx)
CommandInterpreter & GetCommandInterpreter()
CommandInterpreter & m_interpreter
void SetSyntax(llvm::StringRef str)
void SetCommandName(llvm::StringRef name)
Target * GetTarget()
Get the target this command should operate on.
virtual void SetHelp(llvm::StringRef str)
void AppendError(llvm::StringRef in_string)
void AppendWarningWithFormatv(const char *format, Args &&...args)
void SetStatus(lldb::ReturnStatus status)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
void void AppendMessageWithFormatv(const char *format, Args &&...args)
void AppendWarning(llvm::StringRef in_string)
"lldb/Utility/ArgCompletionRequest.h"
A uniqued constant string class.
Definition ConstString.h:40
void SetCString(const char *cstr)
Set the C string value.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const char * GetCString() const
Get the string value as a C string.
const char * AsCString(const char *value_if_empty) const
Get the string value as a C string.
static bool Delete(ConstString category)
static void Disable(ConstString category)
static void ForEach(TypeCategoryMap::ForEachCallback callback)
static void Enable(ConstString category, TypeCategoryMap::Position=TypeCategoryMap::Default)
static bool GetCategory(ConstString category, lldb::TypeCategoryImplSP &entry, bool allow_create=true)
static void Add(ConstString type, const lldb::TypeSummaryImplSP &entry)
static void ForEach(std::function< bool(const TypeMatcher &, const lldb::TypeSummaryImplSP &)> callback)
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
IOHandlerDelegateMultiline(llvm::StringRef end_line, Completion completion=Completion::None)
Definition IOHandler.h:289
lldb::LockableStreamFileSP GetErrorStreamFileSP()
Definition IOHandler.cpp:95
lldb::LockableStreamFileSP GetOutputStreamFileSP()
Definition IOHandler.cpp:93
void SetIsDone(bool b)
Definition IOHandler.h:81
std::set< std::unique_ptr< Result > > ResultSet
Definition Language.h:55
static void ForEach(llvm::function_ref< IterationAction(Language *)> callback)
Definition Language.cpp:127
static Language * FindPlugin(lldb::LanguageType language)
Definition Language.cpp:84
static const char * GetNameForLanguageType(lldb::LanguageType language)
Returns the internal LLDB name for the specified language.
Definition Language.cpp:305
virtual const char * GetLanguageSpecificTypeLookupHelp()
Definition Language.cpp:483
static lldb::LanguageType GetLanguageTypeFromString(const char *string)=delete
lldb::LanguageType GuessLanguage() const
Try to guess the language from the mangling.
Definition Mangled.cpp:416
static const uint32_t OPTION_GROUP_FORMAT
Status SetValueFromString(llvm::StringRef value, VarSetOperationType op=eVarSetOperationAssign) override
A command line option parsing protocol class.
Definition Options.h:58
std::vector< Option > m_getopt_table
Definition Options.h:198
bool IsValid() const
Test if this object contains a valid regular expression.
bool Execute(llvm::StringRef string, llvm::SmallVectorImpl< llvm::StringRef > *matches=nullptr) const
Execute a regular expression match using the compiled regular expression that is already in this obje...
llvm::StringRef GetText() const
Access the regular expression text.
virtual bool GenerateTypeScriptFunction(const char *oneliner, std::string &output, const void *name_token=nullptr)
virtual bool GenerateTypeSynthClass(StringList &input, std::string &output, const void *name_token=nullptr)
virtual bool CheckObjectExists(const char *name)
This base class provides an interface to stack frames.
Definition StackFrame.h:44
virtual SourceLanguage GuessLanguage()
Similar to GetLanguage(), but is allowed to take a potentially incorrect guess if exact information i...
virtual const SymbolContext & GetSymbolContext(lldb::SymbolContextItem resolve_scope)
Provide a SymbolContext for this StackFrame's current pc value.
An error handling class.
Definition Status.h:118
static Status FromErrorStringWithFormat(const char *format,...) __attribute__((format(printf
Definition Status.cpp:106
static Status FromErrorString(const char *str)
Definition Status.h:141
static Status static Status FromErrorStringWithFormatv(const char *format, Args &&...args)
Definition Status.h:151
const char * GetData() const
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:63
std::string CopyList(const char *item_preamble=nullptr, const char *items_sep="\n") const
size_t SplitIntoLines(const std::string &lines)
Symbol * symbol
The Symbol for a given query.
Mangled & GetMangled()
Definition Symbol.h:147
Flags & SetSkipReferences(bool value=true)
Flags & SetFrontEndWantsDereference(bool value=true)
Flags & SetSkipPointers(bool value=true)
std::shared_ptr< SyntheticChildren > SharedPointer
bool GetEnableSyntheticValue() const
Definition Target.cpp:5587
lldb::DynamicValueType GetPreferDynamicValue() const
Definition Target.cpp:5231
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:2940
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:614