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