LLDB mainline
CommandObjectType.cpp
Go to the documentation of this file.
1//===-- CommandObjectType.cpp ---------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "CommandObjectType.h"
10
11#include "lldb/Core/Debugger.h"
12#include "lldb/Core/IOHandler.h"
15#include "lldb/Host/Config.h"
28#include "lldb/Symbol/Symbol.h"
31#include "lldb/Target/Target.h"
32#include "lldb/Target/Thread.h"
36#include "lldb/lldb-forward.h"
37
38#include "llvm/ADT/STLExtras.h"
39
40#include <algorithm>
41#include <functional>
42#include <memory>
43
44using namespace lldb;
45using namespace lldb_private;
46
48public:
53 std::string m_category;
55
57 FormatterMatchType match_type, ConstString name,
58 std::string catg, uint32_t m_ptr_match_depth)
59 : m_flags(flags), m_match_type(match_type), m_name(name),
61
62 typedef std::shared_ptr<ScriptAddOptions> SharedPointer;
63};
64
66public:
72 std::string m_category;
73
74 SynthAddOptions(bool sptr, bool sref, bool casc,
75 FormatterMatchType match_type, std::string catg)
76 : m_skip_pointers(sptr), m_skip_references(sref), m_cascade(casc),
77 m_match_type(match_type), m_category(catg) {}
78
79 typedef std::shared_ptr<SynthAddOptions> SharedPointer;
80};
81
83 CommandReturnObject &result) {
84 if (command.empty())
85 return false;
86
87 for (auto entry : llvm::enumerate(command.entries().drop_back())) {
88 if (entry.value().ref() != "unsigned")
89 continue;
90 auto next = command.entries()[entry.index() + 1].ref();
91 if (next == "int" || next == "short" || next == "char" || next == "long") {
93 "unsigned %s being treated as two types. if you meant the combined "
94 "type "
95 "name use quotes, as in \"unsigned %s\"\n",
96 next.str().c_str(), next.str().c_str());
97 return true;
98 }
99 }
100 return false;
101}
102
103const char *FormatCategoryToString(FormatCategoryItem item, bool long_name) {
104 switch (item) {
106 return "summary";
108 return "filter";
110 if (long_name)
111 return "synthetic child provider";
112 return "synthetic";
114 return "format";
115 }
116 llvm_unreachable("Fully covered switch above!");
117}
118
119#define LLDB_OPTIONS_type_summary_add
120#include "CommandOptions.inc"
121
124private:
125 class CommandOptions : public Options {
126 public:
128
129 ~CommandOptions() override = default;
130
131 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
132 ExecutionContext *execution_context) override;
133
134 void OptionParsingStarting(ExecutionContext *execution_context) override;
135
136 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
137 return llvm::ArrayRef(g_type_summary_add_options);
138 }
139
140 // Instance variables to hold the values for command options.
141
144 std::string m_format_string;
146 std::string m_python_script;
147 std::string m_python_function;
148 bool m_is_add_script = false;
149 std::string m_category;
150 uint32_t m_ptr_match_depth = 1;
151 };
152
154
155 Options *GetOptions() override { return &m_options; }
156
158
159 bool Execute_StringSummary(Args &command, CommandReturnObject &result);
160
161public:
163
164 ~CommandObjectTypeSummaryAdd() override = default;
165
166 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
167 static const char *g_summary_addreader_instructions =
168 "Enter your Python command(s). Type 'DONE' to end.\n"
169 "def function (valobj,internal_dict):\n"
170 " \"\"\"valobj: an SBValue which you want to provide a summary "
171 "for\n"
172 " internal_dict: an LLDB support object not to be used\"\"\"\n";
173
174 if (interactive) {
175 if (LockableStreamFileSP output_sp = io_handler.GetOutputStreamFileSP()) {
176 LockedStreamFile locked_stream = output_sp->Lock();
177 locked_stream.PutCString(g_summary_addreader_instructions);
178 }
179 }
180 }
181
183 std::string &data) override {
184 LockableStreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
185
186#if LLDB_ENABLE_PYTHON
188 if (interpreter) {
189 StringList lines;
190 lines.SplitIntoLines(data);
191 if (lines.GetSize() > 0) {
192 ScriptAddOptions *options_ptr =
193 ((ScriptAddOptions *)io_handler.GetUserData());
194 if (options_ptr) {
196 options_ptr); // this will ensure that we get rid of the pointer
197 // when going out of scope
198
200 if (interpreter) {
201 std::string funct_name_str;
202 if (interpreter->GenerateTypeScriptFunction(lines,
203 funct_name_str)) {
204 if (funct_name_str.empty()) {
205 LockedStreamFile locked_stream = error_sp->Lock();
206 locked_stream.Printf(
207 "unable to obtain a valid function name from "
208 "the script interpreter.\n");
209 } else {
210 // now I have a valid function name, let's add this as script
211 // for every type in the list
212
213 TypeSummaryImplSP script_format;
214 script_format = std::make_shared<ScriptSummaryFormat>(
215 options->m_flags, funct_name_str.c_str(),
216 lines.CopyList(" ").c_str(), options->m_ptr_match_depth);
217
219
220 for (const std::string &type_name : options->m_target_types) {
221 AddSummary(ConstString(type_name), script_format,
222 options->m_match_type, options->m_category,
223 &error);
224 if (error.Fail()) {
225 LockedStreamFile locked_stream = error_sp->Lock();
226 locked_stream.Printf("error: %s", error.AsCString());
227 }
228 }
229
230 if (options->m_name) {
232 options->m_name, script_format, &error);
233 if (error.Fail()) {
235 options->m_name, script_format, &error);
236 if (error.Fail()) {
237 LockedStreamFile locked_stream = error_sp->Lock();
238 locked_stream.Printf("error: %s", error.AsCString());
239 }
240 } else {
241 LockedStreamFile locked_stream = error_sp->Lock();
242 locked_stream.Printf("error: %s", error.AsCString());
243 }
244 } else {
245 if (error.AsCString()) {
246 LockedStreamFile locked_stream = error_sp->Lock();
247 locked_stream.Printf("error: %s", error.AsCString());
248 }
249 }
250 }
251 } else {
252 LockedStreamFile locked_stream = error_sp->Lock();
253 locked_stream.Printf("error: unable to generate a function.\n");
254 }
255 } else {
256 LockedStreamFile locked_stream = error_sp->Lock();
257 locked_stream.Printf("error: no script interpreter.\n");
258 }
259 } else {
260 LockedStreamFile locked_stream = error_sp->Lock();
261 locked_stream.Printf("error: internal synchronization information "
262 "missing or invalid.\n");
263 }
264 } else {
265 LockedStreamFile locked_stream = error_sp->Lock();
266 locked_stream.Printf(
267 "error: empty function, didn't add python command.\n");
268 }
269 } else {
270 LockedStreamFile locked_stream = error_sp->Lock();
271 locked_stream.Printf(
272 "error: script interpreter missing, didn't add python command.\n");
273 }
274#endif
275 io_handler.SetIsDone(true);
276 }
277
278 bool AddSummary(ConstString type_name, lldb::TypeSummaryImplSP entry,
279 FormatterMatchType match_type, std::string category,
280 Status *error = nullptr);
281
282 bool AddNamedSummary(ConstString summary_name, lldb::TypeSummaryImplSP entry,
283 Status *error = nullptr);
284
285protected:
286 void DoExecute(Args &command, CommandReturnObject &result) override;
287};
288
290 "Enter your Python command(s). Type 'DONE' to end.\n"
291 "You must define a Python class with these methods:\n"
292 " def __init__(self, valobj, internal_dict):\n"
293 " def num_children(self):\n"
294 " def get_child_at_index(self, index):\n"
295 " def get_child_index(self, name):\n"
296 " def update(self):\n"
297 " '''Optional'''\n"
298 "class synthProvider:\n";
299
300#define LLDB_OPTIONS_type_synth_add
301#include "CommandOptions.inc"
302
305private:
306 class CommandOptions : public Options {
307 public:
308 CommandOptions() = default;
309
310 ~CommandOptions() override = default;
311
312 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
313 ExecutionContext *execution_context) override {
315 const int short_option = m_getopt_table[option_idx].val;
316 bool success;
317
318 switch (short_option) {
319 case 'C':
320 m_cascade = OptionArgParser::ToBoolean(option_arg, true, &success);
321 if (!success)
323 "invalid value for cascade: %s", option_arg.str().c_str());
324 break;
325 case 'P':
326 handwrite_python = true;
327 break;
328 case 'l':
329 m_class_name = std::string(option_arg);
330 is_class_based = true;
331 break;
332 case 'p':
333 m_skip_pointers = true;
334 break;
335 case 'r':
336 m_skip_references = true;
337 break;
338 case 'w':
339 m_category = std::string(option_arg);
340 break;
341 case 'x':
344 "can't use --regex and --recognizer-function at the same time");
345 else
347 break;
348 case '\x01':
351 "can't use --regex and --recognizer-function at the same time");
352 else
354 break;
355 default:
356 llvm_unreachable("Unimplemented option");
357 }
358
359 return error;
360 }
361
362 void OptionParsingStarting(ExecutionContext *execution_context) override {
363 m_cascade = true;
364 m_class_name = "";
365 m_skip_pointers = false;
366 m_skip_references = false;
367 m_category = "default";
368 is_class_based = false;
369 handwrite_python = false;
371 }
372
373 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
374 return llvm::ArrayRef(g_type_synth_add_options);
375 }
376
377 // Instance variables to hold the values for command options.
378
382 std::string m_class_name;
384 std::string m_category;
388 };
389
391
392 Options *GetOptions() override { return &m_options; }
393
394 bool Execute_HandwritePython(Args &command, CommandReturnObject &result);
395
396 bool Execute_PythonClass(Args &command, CommandReturnObject &result);
397
398protected:
399 void DoExecute(Args &command, CommandReturnObject &result) override {
401
402 if (m_options.handwrite_python)
403 Execute_HandwritePython(command, result);
404 else if (m_options.is_class_based)
405 Execute_PythonClass(command, result);
406 else {
407 result.AppendError("must either provide a children list, a Python class "
408 "name, or use -P and type a Python class "
409 "line-by-line");
410 }
411 }
412
413 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
414 if (interactive) {
415 if (LockableStreamFileSP output_sp = io_handler.GetOutputStreamFileSP()) {
416 LockedStreamFile locked_stream = output_sp->Lock();
418 }
419 }
420 }
421
423 std::string &data) override {
424 LockableStreamFileSP error_sp = io_handler.GetErrorStreamFileSP();
425
426#if LLDB_ENABLE_PYTHON
428 if (interpreter) {
429 StringList lines;
430 lines.SplitIntoLines(data);
431 if (lines.GetSize() > 0) {
432 SynthAddOptions *options_ptr =
433 ((SynthAddOptions *)io_handler.GetUserData());
434 if (options_ptr) {
436 options_ptr); // this will ensure that we get rid of the pointer
437 // when going out of scope
438
440 if (interpreter) {
441 std::string class_name_str;
442 if (interpreter->GenerateTypeSynthClass(lines, class_name_str)) {
443 if (class_name_str.empty()) {
444
445 LockedStreamFile locked_stream = error_sp->Lock();
446 locked_stream.Printf(
447 "error: unable to obtain a proper name for the class.\n");
448 } else {
449 // everything should be fine now, let's add the synth provider
450 // class
451
452 SyntheticChildrenSP synth_provider;
453 synth_provider = std::make_shared<ScriptedSyntheticChildren>(
455 .SetCascades(options->m_cascade)
456 .SetSkipPointers(options->m_skip_pointers)
457 .SetSkipReferences(options->m_skip_references),
458 class_name_str.c_str());
459
462 ConstString(options->m_category.c_str()), category);
463
465
466 for (const std::string &type_name : options->m_target_types) {
467 if (!type_name.empty()) {
468 if (AddSynth(ConstString(type_name), synth_provider,
469 options->m_match_type, options->m_category,
470 &error)) {
471 LockedStreamFile locked_stream = error_sp->Lock();
472 locked_stream.Printf("error: %s\n", error.AsCString());
473 break;
474 }
475 } else {
476 LockedStreamFile locked_stream = error_sp->Lock();
477 locked_stream.Printf("error: invalid type name.\n");
478 break;
479 }
480 }
481 }
482 } else {
483 LockedStreamFile locked_stream = error_sp->Lock();
484 locked_stream.Printf("error: unable to generate a class.\n");
485 }
486 } else {
487 LockedStreamFile locked_stream = error_sp->Lock();
488 locked_stream.Printf("error: no script interpreter.\n");
489 }
490 } else {
491 LockedStreamFile locked_stream = error_sp->Lock();
492 locked_stream.Printf(
493 "error: internal synchronization data missing.\n");
494 }
495 } else {
496 LockedStreamFile locked_stream = error_sp->Lock();
497 locked_stream.Printf(
498 "error: empty function, didn't add python command.\n");
499 }
500 } else {
501 LockedStreamFile locked_stream = error_sp->Lock();
502 locked_stream.Printf(
503 "error: script interpreter missing, didn't add python command.\n");
504 }
505
506#endif
507 io_handler.SetIsDone(true);
508 }
509
510public:
512
513 ~CommandObjectTypeSynthAdd() override = default;
514
515 bool AddSynth(ConstString type_name, lldb::SyntheticChildrenSP entry,
516 FormatterMatchType match_type, std::string category_name,
517 Status *error);
518};
519
520// CommandObjectTypeFormatAdd
521
522#define LLDB_OPTIONS_type_format_add
523#include "CommandOptions.inc"
524
526private:
528 public:
529 CommandOptions() = default;
530
531 ~CommandOptions() override = default;
532
533 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
534 return llvm::ArrayRef(g_type_format_add_options);
535 }
536
537 void OptionParsingStarting(ExecutionContext *execution_context) override {
538 m_cascade = true;
539 m_skip_pointers = false;
540 m_skip_references = false;
541 m_regex = false;
542 m_category.assign("default");
543 m_custom_type_name.clear();
544 }
545
546 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
547 ExecutionContext *execution_context) override {
549 const int short_option =
550 g_type_format_add_options[option_idx].short_option;
551 bool success;
552
553 switch (short_option) {
554 case 'C':
555 m_cascade = OptionArgParser::ToBoolean(option_value, true, &success);
556 if (!success)
558 "invalid value for cascade: %s", option_value.str().c_str());
559 break;
560 case 'p':
561 m_skip_pointers = true;
562 break;
563 case 'w':
564 m_category.assign(std::string(option_value));
565 break;
566 case 'r':
567 m_skip_references = true;
568 break;
569 case 'x':
570 m_regex = true;
571 break;
572 case 't':
573 m_custom_type_name.assign(std::string(option_value));
574 break;
575 default:
576 llvm_unreachable("Unimplemented option");
577 }
578
579 return error;
580 }
581
582 // Instance variables to hold the values for command options.
583
588 std::string m_category;
590 };
591
595
596 Options *GetOptions() override { return &m_option_group; }
597
598public:
600 : CommandObjectParsed(interpreter, "type format add",
601 "Add a new formatting style for a type.", nullptr),
604
606 R"(
607The following examples of 'type format add' refer to this code snippet for context:
608
609 typedef int Aint;
610 typedef float Afloat;
611 typedef Aint Bint;
612 typedef Afloat Bfloat;
613
614 Aint ix = 5;
615 Bint iy = 5;
616
617 Afloat fx = 3.14;
618 BFloat fy = 3.14;
619
620Adding default formatting:
622(lldb) type format add -f hex AInt
623(lldb) frame variable iy
625)"
626 " Produces hexadecimal display of iy, because no formatter is available for Bint and \
627the one for Aint is used instead."
628 R"(
629
630To prevent this use the cascade option '-C no' to prevent evaluation of typedef chains:
631
632
633(lldb) type format add -f hex -C no AInt
634
635Similar reasoning applies to this:
636
637(lldb) type format add -f hex -C no float -p
638
639)"
640 " All float values and float references are now formatted as hexadecimal, but not \
641pointers to floats. Nor will it change the default display for Afloat and Bfloat objects.");
642
643 // Add the "--format" to all options groups
648 m_option_group.Finalize();
649 }
650
651 ~CommandObjectTypeFormatAdd() override = default;
652
653protected:
654 void DoExecute(Args &command, CommandReturnObject &result) override {
655 const size_t argc = command.GetArgumentCount();
656
657 if (argc < 1) {
658 result.AppendErrorWithFormat("%s takes one or more args.\n",
659 m_cmd_name.c_str());
660 return;
661 }
662
663 const Format format = m_format_options.GetFormat();
664 if (format == eFormatInvalid &&
665 m_command_options.m_custom_type_name.empty()) {
666 result.AppendErrorWithFormat("%s needs a valid format.\n",
667 m_cmd_name.c_str());
668 return;
669 }
670
671 TypeFormatImplSP entry;
672
673 if (m_command_options.m_custom_type_name.empty())
674 entry = std::make_shared<TypeFormatImpl_Format>(
675 format, TypeFormatImpl::Flags()
676 .SetCascades(m_command_options.m_cascade)
677 .SetSkipPointers(m_command_options.m_skip_pointers)
678 .SetSkipReferences(m_command_options.m_skip_references));
679 else
680 entry = std::make_shared<TypeFormatImpl_EnumType>(
681 ConstString(m_command_options.m_custom_type_name.c_str()),
682 TypeFormatImpl::Flags()
683 .SetCascades(m_command_options.m_cascade)
684 .SetSkipPointers(m_command_options.m_skip_pointers)
685 .SetSkipReferences(m_command_options.m_skip_references));
686
687 // now I have a valid format, let's add it to every type
688
689 TypeCategoryImplSP category_sp;
691 ConstString(m_command_options.m_category), category_sp);
692 if (!category_sp)
693 return;
694
696
697 for (auto &arg_entry : command.entries()) {
698 if (arg_entry.ref().empty()) {
699 result.AppendError("empty typenames not allowed");
700 return;
701 }
702
704 if (m_command_options.m_regex) {
705 match_type = eFormatterMatchRegex;
706 RegularExpression typeRX(arg_entry.ref());
707 if (!typeRX.IsValid()) {
708 result.AppendError(
709 "regex format error (maybe this is not really a regex?)");
710 return;
711 }
712 }
713 category_sp->AddTypeFormat(arg_entry.ref(), match_type, entry);
714 }
715
717 }
718};
719
720#define LLDB_OPTIONS_type_formatter_delete
721#include "CommandOptions.inc"
722
724protected:
725 class CommandOptions : public Options {
726 public:
727 CommandOptions() = default;
728
729 ~CommandOptions() override = default;
730
731 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
732 ExecutionContext *execution_context) override {
734 const int short_option = m_getopt_table[option_idx].val;
735
736 switch (short_option) {
737 case 'a':
738 m_delete_all = true;
739 break;
740 case 'w':
741 m_category = std::string(option_arg);
742 break;
743 case 'l':
745 break;
746 default:
747 llvm_unreachable("Unimplemented option");
748 }
749
750 return error;
751 }
752
753 void OptionParsingStarting(ExecutionContext *execution_context) override {
754 m_delete_all = false;
755 m_category = "default";
757 }
758
759 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
760 return llvm::ArrayRef(g_type_formatter_delete_options);
761 }
762
763 // Instance variables to hold the values for command options.
764
766 std::string m_category;
768 };
769
772
773 Options *GetOptions() override { return &m_options; }
774
775 static constexpr const char *g_short_help_template =
776 "Delete an existing %s for a type.";
777
778 static constexpr const char *g_long_help_template =
779 "Delete an existing %s for a type. Unless you specify a "
780 "specific category or all categories, only the "
781 "'default' category is searched. The names must be exactly as "
782 "shown in the 'type %s list' output";
783
784public:
786 FormatCategoryItem formatter_kind)
787 : CommandObjectParsed(interpreter,
788 FormatCategoryToString(formatter_kind, false)),
789 m_formatter_kind(formatter_kind) {
791
792 const char *kind = FormatCategoryToString(formatter_kind, true);
793 const char *short_kind = FormatCategoryToString(formatter_kind, false);
794
795 StreamString s;
797 SetHelp(s.GetData());
798 s.Clear();
799 s.Printf(g_long_help_template, kind, short_kind);
800 SetHelpLong(s.GetData());
801 s.Clear();
802 s.Printf("type %s delete", short_kind);
804 }
805
807
808 void
810 OptionElementVector &opt_element_vector) override {
811 if (request.GetCursorIndex())
812 return;
813
815 [this, &request](const lldb::TypeCategoryImplSP &category_sp) {
816 category_sp->AutoComplete(request, m_formatter_kind);
817 return true;
818 });
819 }
820
821protected:
822 virtual bool FormatterSpecificDeletion(ConstString typeCS) { return false; }
823
824 void DoExecute(Args &command, CommandReturnObject &result) override {
825 const size_t argc = command.GetArgumentCount();
826
827 if (argc != 1) {
828 result.AppendErrorWithFormat("%s takes 1 arg.\n", m_cmd_name.c_str());
829 return;
830 }
831
832 const char *typeA = command.GetArgumentAtIndex(0);
833 ConstString typeCS(typeA);
834
835 if (!typeCS) {
836 result.AppendError("empty typenames not allowed");
837 return;
838 }
839
840 if (m_options.m_delete_all) {
842 [this, typeCS](const lldb::TypeCategoryImplSP &category_sp) -> bool {
843 category_sp->Delete(typeCS, m_formatter_kind);
844 return true;
845 });
847 return;
848 }
849
850 bool delete_category = false;
851 bool extra_deletion = false;
852
853 if (m_options.m_language != lldb::eLanguageTypeUnknown) {
856 category);
857 if (category)
858 delete_category = category->Delete(typeCS, m_formatter_kind);
859 extra_deletion = FormatterSpecificDeletion(typeCS);
860 } else {
863 ConstString(m_options.m_category.c_str()), category);
864 if (category)
865 delete_category = category->Delete(typeCS, m_formatter_kind);
866 extra_deletion = FormatterSpecificDeletion(typeCS);
867 }
868
869 if (delete_category || extra_deletion) {
871 } else {
872 result.AppendErrorWithFormat("no custom formatter for %s.\n", typeA);
873 }
874 }
875};
876
877#define LLDB_OPTIONS_type_formatter_clear
878#include "CommandOptions.inc"
879
881private:
882 class CommandOptions : public Options {
883 public:
884 CommandOptions() = default;
885
886 ~CommandOptions() override = default;
887
888 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
889 ExecutionContext *execution_context) override {
891 const int short_option = m_getopt_table[option_idx].val;
892
893 switch (short_option) {
894 case 'a':
895 m_delete_all = true;
896 break;
897 default:
898 llvm_unreachable("Unimplemented option");
899 }
900
901 return error;
902 }
903
904 void OptionParsingStarting(ExecutionContext *execution_context) override {
905 m_delete_all = false;
906 }
907
908 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
909 return llvm::ArrayRef(g_type_formatter_clear_options);
910 }
911
912 // Instance variables to hold the values for command options.
914 };
915
918
919 Options *GetOptions() override { return &m_options; }
920
921public:
923 FormatCategoryItem formatter_kind,
924 const char *name, const char *help)
925 : CommandObjectParsed(interpreter, name, help, nullptr),
926 m_formatter_kind(formatter_kind) {
928 }
929
931
932protected:
934
935 void DoExecute(Args &command, CommandReturnObject &result) override {
936 if (m_options.m_delete_all) {
938 [this](const TypeCategoryImplSP &category_sp) -> bool {
939 category_sp->Clear(m_formatter_kind);
940 return true;
941 });
942 } else {
944 if (command.GetArgumentCount() > 0) {
945 const char *cat_name = command.GetArgumentAtIndex(0);
946 ConstString cat_nameCS(cat_name);
947 DataVisualization::Categories::GetCategory(cat_nameCS, category);
948 } else {
950 category);
951 }
952 category->Clear(m_formatter_kind);
953 }
954
956
958 }
959};
960
961// CommandObjectTypeFormatDelete
962
971
972// CommandObjectTypeFormatClear
973
975public:
978 "type format clear",
979 "Delete all existing format styles.") {}
980};
981
982#define LLDB_OPTIONS_type_formatter_list
983#include "CommandOptions.inc"
984
985template <typename FormatterType>
987 typedef typename FormatterType::SharedPointer FormatterSharedPointer;
988
989 class CommandOptions : public Options {
990 public:
995
996 ~CommandOptions() override = default;
997
998 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
999 ExecutionContext *execution_context) override {
1000 Status error;
1001 const int short_option = m_getopt_table[option_idx].val;
1002 switch (short_option) {
1003 case 'w':
1004 m_category_regex.SetCurrentValue(option_arg);
1005 m_category_regex.SetOptionWasSet();
1006 break;
1007 case 'l':
1008 error = m_category_language.SetValueFromString(option_arg);
1009 if (error.Success())
1010 m_category_language.SetOptionWasSet();
1011 break;
1012 default:
1013 llvm_unreachable("Unimplemented option");
1014 }
1015
1016 return error;
1017 }
1018
1019 void OptionParsingStarting(ExecutionContext *execution_context) override {
1020 m_category_regex.Clear();
1021 m_category_language.Clear();
1022 }
1023
1024 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1025 return llvm::ArrayRef(g_type_formatter_list_options);
1026 }
1027
1028 // Instance variables to hold the values for command options.
1029
1032 };
1033
1035
1036 Options *GetOptions() override { return &m_options; }
1037
1038public:
1040 const char *name, const char *help)
1041 : CommandObjectParsed(interpreter, name, help, nullptr), m_options() {
1043 }
1044
1046
1047protected:
1049 return false;
1050 }
1051
1052 static bool ShouldListItem(llvm::StringRef s, RegularExpression *regex) {
1053 // If we have a regex, it can match two kinds of results:
1054 // - An item created with that same regex string (exact string match), so
1055 // the user can list it using the same string it used at creation time.
1056 // - Items that match the regex.
1057 // No regex means list everything.
1058 return regex == nullptr || s == regex->GetText() || regex->Execute(s);
1059 }
1060
1061 void DoExecute(Args &command, CommandReturnObject &result) override {
1062 const size_t argc = command.GetArgumentCount();
1063
1064 std::unique_ptr<RegularExpression> category_regex;
1065 std::unique_ptr<RegularExpression> formatter_regex;
1066
1067 if (m_options.m_category_regex.OptionWasSet()) {
1068 category_regex = std::make_unique<RegularExpression>(
1069 m_options.m_category_regex.GetCurrentValueAsRef());
1070 if (!category_regex->IsValid()) {
1071 result.AppendErrorWithFormat(
1072 "syntax error in category regular expression '%s'",
1073 m_options.m_category_regex.GetCurrentValueAsRef().str().c_str());
1074 return;
1075 }
1076 }
1077
1078 if (argc == 1) {
1079 const char *arg = command.GetArgumentAtIndex(0);
1080 formatter_regex = std::make_unique<RegularExpression>(arg);
1081 if (!formatter_regex->IsValid()) {
1082 result.AppendErrorWithFormat("syntax error in regular expression '%s'",
1083 arg);
1084 return;
1085 }
1086 }
1087
1088 bool any_printed = false;
1089
1090 auto category_closure =
1091 [&result, &formatter_regex,
1092 &any_printed](const lldb::TypeCategoryImplSP &category) -> void {
1093 result.GetOutputStream().Printf(
1094 "-----------------------\nCategory: %s%s\n-----------------------\n",
1095 category->GetName(), category->IsEnabled() ? "" : " (disabled)");
1096
1098 [&result, &formatter_regex,
1099 &any_printed](const TypeMatcher &type_matcher,
1100 const FormatterSharedPointer &format_sp) -> bool {
1101 if (ShouldListItem(type_matcher.GetMatchString().GetStringRef(),
1102 formatter_regex.get())) {
1103 any_printed = true;
1104 result.GetOutputStream().Printf(
1105 "%s: %s\n", type_matcher.GetMatchString().GetCString(),
1106 format_sp->GetDescription().c_str());
1107 }
1108 return true;
1109 };
1110 category->ForEach(print_formatter);
1111 };
1112
1113 if (m_options.m_category_language.OptionWasSet()) {
1114 lldb::TypeCategoryImplSP category_sp;
1116 m_options.m_category_language.GetCurrentValue(), category_sp);
1117 if (category_sp)
1118 category_closure(category_sp);
1119 } else {
1121 [&category_regex, &category_closure](
1122 const lldb::TypeCategoryImplSP &category) -> bool {
1123 if (ShouldListItem(category->GetName(), category_regex.get())) {
1124 category_closure(category);
1125 }
1126 return true;
1127 });
1128
1129 any_printed = FormatterSpecificList(result) | any_printed;
1130 }
1131
1132 if (any_printed)
1134 else {
1135 result.GetOutputStream().PutCString("no matching results found.\n");
1137 }
1138 }
1139};
1140
1141// CommandObjectTypeFormatList
1142
1144 : public CommandObjectTypeFormatterList<TypeFormatImpl> {
1145public:
1147 : CommandObjectTypeFormatterList(interpreter, "type format list",
1148 "Show a list of current formats.") {}
1149};
1150
1152 uint32_t option_idx, llvm::StringRef option_arg,
1153 ExecutionContext *execution_context) {
1154 Status error;
1155 const int short_option = m_getopt_table[option_idx].val;
1156 bool success;
1157
1158 switch (short_option) {
1159 case 'C':
1160 m_flags.SetCascades(OptionArgParser::ToBoolean(option_arg, true, &success));
1161 if (!success)
1162 error = Status::FromErrorStringWithFormat("invalid value for cascade: %s",
1163 option_arg.str().c_str());
1164 break;
1165 case 'e':
1166 m_flags.SetDontShowChildren(false);
1167 break;
1168 case 'h':
1169 m_flags.SetHideEmptyAggregates(true);
1170 break;
1171 case 'v':
1172 m_flags.SetDontShowValue(true);
1173 break;
1174 case 'c':
1175 m_flags.SetShowMembersOneLiner(true);
1176 break;
1177 case 's':
1178 m_format_string = std::string(option_arg);
1179 break;
1180 case 'p':
1181 m_flags.SetSkipPointers(true);
1182 break;
1183 case 'd':
1184 if (option_arg.getAsInteger(0, m_ptr_match_depth)) {
1186 "invalid integer value for option '%c': %s", short_option,
1187 option_arg.data());
1188 }
1189 break;
1190 case 'r':
1191 m_flags.SetSkipReferences(true);
1192 break;
1193 case 'x':
1196 "can't use --regex and --recognizer-function at the same time");
1197 else
1199 break;
1200 case '\x01':
1203 "can't use --regex and --recognizer-function at the same time");
1204 else
1206 break;
1207 case 'n':
1208 m_name.SetString(option_arg);
1209 break;
1210 case 'o':
1211 m_python_script = std::string(option_arg);
1212 m_is_add_script = true;
1213 break;
1214 case 'F':
1215 m_python_function = std::string(option_arg);
1216 m_is_add_script = true;
1217 break;
1218 case 'P':
1219 m_is_add_script = true;
1220 break;
1221 case 'w':
1222 m_category = std::string(option_arg);
1223 break;
1224 case 'O':
1225 m_flags.SetHideItemNames(true);
1226 break;
1227 default:
1228 llvm_unreachable("Unimplemented option");
1229 }
1230
1231 return error;
1232}
1233
1235 ExecutionContext *execution_context) {
1236 m_flags.Clear().SetCascades().SetDontShowChildren().SetDontShowValue(false);
1237 m_flags.SetShowMembersOneLiner(false)
1238 .SetSkipPointers(false)
1239 .SetSkipReferences(false)
1240 .SetHideItemNames(false);
1241
1243 m_name.Clear();
1244 m_python_script = "";
1245 m_python_function = "";
1246 m_format_string = "";
1247 m_is_add_script = false;
1248 m_category = "default";
1249}
1250
1251#if LLDB_ENABLE_PYTHON
1252
1254 Args &command, CommandReturnObject &result) {
1255 const size_t argc = command.GetArgumentCount();
1256
1257 if (argc < 1 && !m_options.m_name) {
1258 result.AppendErrorWithFormat("%s takes one or more args.\n",
1259 m_cmd_name.c_str());
1260 return false;
1261 }
1262
1263 TypeSummaryImplSP script_format;
1264
1266 .empty()) // we have a Python function ready to use
1267 {
1268 const char *funct_name = m_options.m_python_function.c_str();
1269 if (!funct_name || !funct_name[0]) {
1270 result.AppendError("function name empty.\n");
1271 return false;
1272 }
1273
1274 std::string code =
1275 (" " + m_options.m_python_function + "(valobj,internal_dict)");
1276
1277 script_format = std::make_shared<ScriptSummaryFormat>(
1278 m_options.m_flags, funct_name, code.c_str(),
1279 m_options.m_ptr_match_depth);
1280
1281 ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
1282
1283 if (interpreter && !interpreter->CheckObjectExists(funct_name))
1285 "The provided function \"%s\" does not exist - "
1286 "please define it before attempting to use this summary.\n",
1287 funct_name);
1288 } else if (!m_options.m_python_script
1289 .empty()) // we have a quick 1-line script, just use it
1290 {
1291 ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
1292 if (!interpreter) {
1293 result.AppendError("script interpreter missing - unable to generate "
1294 "function wrapper.\n");
1295 return false;
1296 }
1297 StringList funct_sl;
1298 funct_sl << m_options.m_python_script.c_str();
1299 std::string funct_name_str;
1300 if (!interpreter->GenerateTypeScriptFunction(funct_sl, funct_name_str)) {
1301 result.AppendError("unable to generate function wrapper.\n");
1302 return false;
1303 }
1304 if (funct_name_str.empty()) {
1305 result.AppendError(
1306 "script interpreter failed to generate a valid function name.\n");
1307 return false;
1308 }
1309
1310 std::string code = " " + m_options.m_python_script;
1311
1312 script_format = std::make_shared<ScriptSummaryFormat>(
1313 m_options.m_flags, funct_name_str.c_str(), code.c_str(),
1314 m_options.m_ptr_match_depth);
1315 } else {
1316 // Use an IOHandler to grab Python code from the user
1317 auto options = std::make_unique<ScriptAddOptions>(
1318 m_options.m_flags, m_options.m_match_type, m_options.m_name,
1319 m_options.m_category, m_options.m_ptr_match_depth);
1320
1321 for (auto &entry : command.entries()) {
1322 if (entry.ref().empty()) {
1323 result.AppendError("empty typenames not allowed");
1324 return false;
1325 }
1326
1327 options->m_target_types << std::string(entry.ref());
1328 }
1329
1330 m_interpreter.GetPythonCommandsFromIOHandler(
1331 " ", // Prompt
1332 *this, // IOHandlerDelegate
1333 options.release()); // Baton for the "io_handler" that will be passed
1334 // back into our IOHandlerDelegate functions
1336
1337 return result.Succeeded();
1338 }
1339
1340 // if I am here, script_format must point to something good, so I can add
1341 // that as a script summary to all interested parties
1342
1343 Status error;
1344
1345 for (auto &entry : command.entries()) {
1346 AddSummary(ConstString(entry.ref()), script_format, m_options.m_match_type,
1347 m_options.m_category, &error);
1348 if (error.Fail()) {
1349 result.AppendError(error.AsCString());
1350 return false;
1351 }
1352 }
1353
1354 if (m_options.m_name) {
1355 AddNamedSummary(m_options.m_name, script_format, &error);
1356 if (error.Fail()) {
1357 result.AppendError(error.AsCString());
1358 result.AppendError("added to types, but not given a name");
1359 return false;
1360 }
1361 }
1362
1363 return result.Succeeded();
1364}
1365
1366#endif
1367
1369 Args &command, CommandReturnObject &result) {
1370 const size_t argc = command.GetArgumentCount();
1371
1372 if (argc < 1 && !m_options.m_name) {
1373 result.AppendErrorWithFormat("%s takes one or more args.\n",
1374 m_cmd_name.c_str());
1375 return false;
1376 }
1377
1378 if (!m_options.m_flags.GetShowMembersOneLiner() &&
1379 m_options.m_format_string.empty()) {
1380 result.AppendError("empty summary strings not allowed");
1381 return false;
1382 }
1383
1384 const char *format_cstr = (m_options.m_flags.GetShowMembersOneLiner()
1385 ? ""
1386 : m_options.m_format_string.c_str());
1387
1388 // ${var%S} is an endless recursion, prevent it
1389 if (strcmp(format_cstr, "${var%S}") == 0) {
1390 result.AppendError("recursive summary not allowed");
1391 return false;
1392 }
1393
1394 std::unique_ptr<StringSummaryFormat> string_format(new StringSummaryFormat(
1395 m_options.m_flags, format_cstr, m_options.m_ptr_match_depth));
1396 if (!string_format) {
1397 result.AppendError("summary creation failed");
1398 return false;
1399 }
1400 if (string_format->m_error.Fail()) {
1401 result.AppendErrorWithFormat("syntax error: %s",
1402 string_format->m_error.AsCString("<unknown>"));
1403 return false;
1404 }
1405 lldb::TypeSummaryImplSP entry(string_format.release());
1406
1407 // now I have a valid format, let's add it to every type
1408 Status error;
1409 for (auto &arg_entry : command.entries()) {
1410 if (arg_entry.ref().empty()) {
1411 result.AppendError("empty typenames not allowed");
1412 return false;
1413 }
1414 ConstString typeCS(arg_entry.ref());
1415
1416 AddSummary(typeCS, entry, m_options.m_match_type, m_options.m_category,
1417 &error);
1418
1419 if (error.Fail()) {
1420 result.AppendError(error.AsCString());
1421 return false;
1422 }
1423 }
1424
1425 if (m_options.m_name) {
1426 AddNamedSummary(m_options.m_name, entry, &error);
1427 if (error.Fail()) {
1428 result.AppendError(error.AsCString());
1429 result.AppendError("added to types, but not given a name");
1430 return false;
1431 }
1432 }
1433
1435 return result.Succeeded();
1436}
1437
1439 CommandInterpreter &interpreter)
1440 : CommandObjectParsed(interpreter, "type summary add",
1441 "Add a new summary style for a type.", nullptr),
1442 IOHandlerDelegateMultiline("DONE"), m_options(interpreter) {
1444
1446 R"(
1447The following examples of 'type summary add' refer to this code snippet for context:
1448
1449 struct JustADemo
1450 {
1451 int* ptr;
1452 float value;
1453 JustADemo(int p = 1, float v = 0.1) : ptr(new int(p)), value(v) {}
1454 };
1455 JustADemo demo_instance(42, 3.14);
1456
1457 typedef JustADemo NewDemo;
1458 NewDemo new_demo_instance(42, 3.14);
1459
1460(lldb) type summary add --summary-string "the answer is ${*var.ptr}" JustADemo
1461
1462 Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42"
1463
1464(lldb) type summary add --summary-string "the answer is ${*var.ptr}, and the question is ${var.value}" JustADemo
1465
1466 Subsequently displaying demo_instance with 'frame variable' or 'expression' will display "the answer is 42 and the question is 3.14"
1467
1468)"
1469 "Alternatively, you could define formatting for all pointers to integers and \
1470rely on that when formatting JustADemo to obtain the same result:"
1471 R"(
1472
1473(lldb) type summary add --summary-string "${var%V} -> ${*var}" "int *"
1474(lldb) type summary add --summary-string "the answer is ${var.ptr}, and the question is ${var.value}" JustADemo
1476)"
1477 "Type summaries are automatically applied to derived typedefs, so the examples \
1478above apply to both JustADemo and NewDemo. The cascade option can be used to \
1479suppress this behavior:"
1480 R"(
1481
1482(lldb) type summary add --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo -C no
1483
1484 The summary will now be used for values of JustADemo but not NewDemo.
1485
1486)"
1487 "By default summaries are shown for pointers and references to values of the \
1488specified type. To suppress formatting for pointers use the -p option, or apply \
1489the corresponding -r option to suppress formatting for references:"
1490 R"(
1492(lldb) type summary add -p -r --summary-string "${var.ptr}, ${var.value},{${var.byte}}" JustADemo
1493
1494)"
1495 "One-line summaries including all fields in a type can be inferred without supplying an \
1496explicit summary string by passing the -c option:"
1497 R"(
1498
1499(lldb) type summary add -c JustADemo
1500(lldb) frame variable demo_instance
1501(ptr=<address>, value=3.14)
1502
1503)"
1504 "Type summaries normally suppress the nested display of individual fields. To \
1505supply a summary to supplement the default structure add the -e option:"
1506 R"(
1508(lldb) type summary add -e --summary-string "*ptr = ${*var.ptr}" JustADemo
1509
1510)"
1511 "Now when displaying JustADemo values the int* is displayed, followed by the \
1512standard LLDB sequence of children, one per line:"
1513 R"(
1514
1515*ptr = 42 {
1516 ptr = <address>
1517 value = 3.14
1518}
1519
1520)"
1521 "You can also add summaries written in Python. These scripts use lldb public API to \
1522gather information from your variables and produce a meaningful summary. To start a \
1523multi-line script use the -P option. The function declaration will be displayed along with \
1524a comment describing the two arguments. End your script with the word 'DONE' on a line by \
1525itself:"
1526 R"(
1527
1528(lldb) type summary add JustADemo -P
1529def function (valobj,internal_dict): """valobj: an SBValue which you want to provide a summary for
1530internal_dict: an LLDB support object not to be used"""
1531 value = valobj.GetChildMemberWithName('value');
1532 return 'My value is ' + value.GetValue();
1533 DONE
1534
1535Alternatively, the -o option can be used when providing a simple one-line Python script:
1536
1537(lldb) type summary add JustADemo -o "value = valobj.GetChildMemberWithName('value'); return 'My value is ' + value.GetValue();")");
1538}
1539
1541 CommandReturnObject &result) {
1542 WarnOnPotentialUnquotedUnsignedType(command, result);
1543
1545#if LLDB_ENABLE_PYTHON
1546 Execute_ScriptSummary(command, result);
1547#else
1548 result.AppendError("python is disabled");
1549#endif
1550 return;
1551 }
1552
1553 Execute_StringSummary(command, result);
1554}
1555
1556static bool FixArrayTypeNameWithRegex(ConstString &type_name) {
1557 llvm::StringRef type_name_ref(type_name.GetStringRef());
1558
1559 if (type_name_ref.ends_with("[]")) {
1560 std::string type_name_str(type_name.GetCString());
1561 type_name_str.resize(type_name_str.length() - 2);
1562 if (type_name_str.back() != ' ')
1563 type_name_str.append(" ?\\[[0-9]+\\]");
1564 else
1565 type_name_str.append("\\[[0-9]+\\]");
1566 type_name.SetCString(type_name_str.c_str());
1567 return true;
1568 }
1569 return false;
1570}
1571
1574 Status *error) {
1575 // system named summaries do not exist (yet?)
1577 return true;
1578}
1579
1582 FormatterMatchType match_type,
1583 std::string category_name,
1584 Status *error) {
1585 lldb::TypeCategoryImplSP category;
1587 category);
1589 if (match_type == eFormatterMatchExact) {
1590 if (FixArrayTypeNameWithRegex(type_name))
1592 }
1593
1594 if (match_type == eFormatterMatchRegex) {
1595 match_type = eFormatterMatchRegex;
1596 RegularExpression typeRX(type_name.GetStringRef());
1597 if (!typeRX.IsValid()) {
1598 if (error)
1600 "regex format error (maybe this is not really a regex?)");
1601 return false;
1602 }
1603 }
1604
1605 if (match_type == eFormatterMatchCallback) {
1606 const char *function_name = type_name.AsCString();
1607 ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
1608 if (interpreter && !interpreter->CheckObjectExists(function_name)) {
1609 *error = Status::FromErrorStringWithFormat(
1610 "The provided recognizer function \"%s\" does not exist - "
1611 "please define it before attempting to use this summary.\n",
1612 function_name);
1613 return false;
1615 }
1616 category->AddTypeSummary(type_name.GetStringRef(), match_type, entry);
1617 return true;
1619
1620// CommandObjectTypeSummaryDelete
1621
1623public:
1627
1628 ~CommandObjectTypeSummaryDelete() override = default;
1629
1630protected:
1631 bool FormatterSpecificDeletion(ConstString typeCS) override {
1632 if (m_options.m_language != lldb::eLanguageTypeUnknown)
1633 return false;
1635 }
1636};
1637
1639public:
1640 CommandObjectTypeSummaryClear(CommandInterpreter &interpreter)
1642 "type summary clear",
1643 "Delete all existing summaries.") {}
1644
1645protected:
1646 void FormatterSpecificDeletion() override {
1648 }
1649};
1651// CommandObjectTypeSummaryList
1652
1654 : public CommandObjectTypeFormatterList<TypeSummaryImpl> {
1655public:
1657 : CommandObjectTypeFormatterList(interpreter, "type summary list",
1658 "Show a list of current summaries.") {}
1659
1660protected:
1661 bool FormatterSpecificList(CommandReturnObject &result) override {
1663 result.GetOutputStream().Printf("Named summaries:\n");
1665 [&result](const TypeMatcher &type_matcher,
1666 const TypeSummaryImplSP &summary_sp) -> bool {
1667 result.GetOutputStream().Printf(
1668 "%s: %s\n", type_matcher.GetMatchString().GetCString(),
1669 summary_sp->GetDescription().c_str());
1670 return true;
1671 });
1672 return true;
1673 }
1674 return false;
1676};
1677
1678// CommandObjectTypeCategoryDefine
1679#define LLDB_OPTIONS_type_category_define
1680#include "CommandOptions.inc"
1681
1683 class CommandOptions : public Options {
1684 public:
1686 : m_define_enabled(false, false),
1688
1689 ~CommandOptions() override = default;
1690
1691 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1692 ExecutionContext *execution_context) override {
1693 Status error;
1694 const int short_option = m_getopt_table[option_idx].val;
1695
1696 switch (short_option) {
1697 case 'e':
1698 m_define_enabled.SetValueFromString(llvm::StringRef("true"));
1699 break;
1700 case 'l':
1702 break;
1703 default:
1704 llvm_unreachable("Unimplemented option");
1706
1707 return error;
1708 }
1710 void OptionParsingStarting(ExecutionContext *execution_context) override {
1713 }
1714
1715 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1716 return llvm::ArrayRef(g_type_category_define_options);
1717 }
1718
1719 // Instance variables to hold the values for command options.
1720
1723 };
1724
1726
1727 Options *GetOptions() override { return &m_options; }
1728
1729public:
1730 CommandObjectTypeCategoryDefine(CommandInterpreter &interpreter)
1731 : CommandObjectParsed(interpreter, "type category define",
1732 "Define a new category as a source of formatters.",
1733 nullptr) {
1735 }
1737 ~CommandObjectTypeCategoryDefine() override = default;
1738
1739protected:
1740 void DoExecute(Args &command, CommandReturnObject &result) override {
1741 const size_t argc = command.GetArgumentCount();
1743 if (argc < 1) {
1744 result.AppendErrorWithFormat("%s takes 1 or more args.\n",
1745 m_cmd_name.c_str());
1746 return;
1748
1749 for (auto &entry : command.entries()) {
1752 category_sp) &&
1753 category_sp) {
1754 category_sp->AddLanguage(m_options.m_cate_language.GetCurrentValue());
1755 if (m_options.m_define_enabled.GetCurrentValue())
1758 }
1759 }
1762 }
1763};
1764
1765// CommandObjectTypeCategoryEnable
1766#define LLDB_OPTIONS_type_category_enable
1767#include "CommandOptions.inc"
1768
1770 class CommandOptions : public Options {
1771 public:
1772 CommandOptions() = default;
1773
1774 ~CommandOptions() override = default;
1775
1776 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1777 ExecutionContext *execution_context) override {
1778 Status error;
1779 const int short_option = m_getopt_table[option_idx].val;
1780
1781 switch (short_option) {
1782 case 'l':
1783 if (!option_arg.empty()) {
1786 error = Status::FromErrorStringWithFormat(
1787 "unrecognized language '%s'", option_arg.str().c_str());
1788 }
1789 break;
1790 default:
1791 llvm_unreachable("Unimplemented option");
1792 }
1793
1794 return error;
1795 }
1796
1797 void OptionParsingStarting(ExecutionContext *execution_context) override {
1800
1801 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1802 return llvm::ArrayRef(g_type_category_enable_options);
1803 }
1804
1805 // Instance variables to hold the values for command options.
1806
1809
1810 CommandOptions m_options;
1812 Options *GetOptions() override { return &m_options; }
1813
1814public:
1816 : CommandObjectParsed(interpreter, "type category enable",
1817 "Enable a category as a source of formatters.",
1818 nullptr) {
1820 }
1821
1822 ~CommandObjectTypeCategoryEnable() override = default;
1823
1824protected:
1825 void DoExecute(Args &command, CommandReturnObject &result) override {
1826 const size_t argc = command.GetArgumentCount();
1827
1828 if (argc < 1 && m_options.m_language == lldb::eLanguageTypeUnknown) {
1829 result.AppendErrorWithFormat("%s takes arguments and/or a language",
1830 m_cmd_name.c_str());
1831 return;
1832 }
1833
1834 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0), "*") == 0) {
1836 } else if (argc > 0) {
1837 for (int i = argc - 1; i >= 0; i--) {
1838 const char *typeA = command.GetArgumentAtIndex(i);
1839 ConstString typeCS(typeA);
1840
1841 if (!typeCS) {
1842 result.AppendError("empty category name not allowed");
1843 return;
1844 }
1848 if (cate->GetCount() == 0) {
1849 result.AppendWarning("empty category enabled (typo?)");
1850 }
1852 }
1854
1855 if (m_options.m_language != lldb::eLanguageTypeUnknown)
1857
1859 }
1860};
1861
1862// CommandObjectTypeCategoryDelete
1863
1865public:
1866 CommandObjectTypeCategoryDelete(CommandInterpreter &interpreter)
1867 : CommandObjectParsed(interpreter, "type category delete",
1868 "Delete a category and all associated formatters.",
1869 nullptr) {
1871 }
1872
1873 ~CommandObjectTypeCategoryDelete() override = default;
1875protected:
1876 void DoExecute(Args &command, CommandReturnObject &result) override {
1877 const size_t argc = command.GetArgumentCount();
1879 if (argc < 1) {
1880 result.AppendErrorWithFormat("%s takes 1 or more arg.\n",
1881 m_cmd_name.c_str());
1882 return;
1883 }
1885 bool success = true;
1886
1887 // the order is not relevant here
1888 for (int i = argc - 1; i >= 0; i--) {
1889 const char *typeA = command.GetArgumentAtIndex(i);
1890 ConstString typeCS(typeA);
1891
1892 if (!typeCS) {
1893 result.AppendError("empty category name not allowed");
1894 return;
1895 }
1897 success = false; // keep deleting even if we hit an error
1898 }
1899 if (success) {
1901 } else {
1902 result.AppendError("cannot delete one or more categories\n");
1903 }
1904 }
1905};
1906
1907// CommandObjectTypeCategoryDisable
1908#define LLDB_OPTIONS_type_category_disable
1909#include "CommandOptions.inc"
1910
1912 class CommandOptions : public Options {
1913 public:
1914 CommandOptions() = default;
1915
1916 ~CommandOptions() override = default;
1917
1918 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
1919 ExecutionContext *execution_context) override {
1920 Status error;
1921 const int short_option = m_getopt_table[option_idx].val;
1922
1923 switch (short_option) {
1924 case 'l':
1925 if (!option_arg.empty()) {
1928 error = Status::FromErrorStringWithFormat(
1929 "unrecognized language '%s'", option_arg.str().c_str());
1930 }
1931 break;
1932 default:
1933 llvm_unreachable("Unimplemented option");
1934 }
1935
1936 return error;
1937 }
1939 void OptionParsingStarting(ExecutionContext *execution_context) override {
1941 }
1942
1943 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1944 return llvm::ArrayRef(g_type_category_disable_options);
1946
1947 // Instance variables to hold the values for command options.
1950 };
1951
1952 CommandOptions m_options;
1953
1954 Options *GetOptions() override { return &m_options; }
1955
1956public:
1957 CommandObjectTypeCategoryDisable(CommandInterpreter &interpreter)
1958 : CommandObjectParsed(interpreter, "type category disable",
1959 "Disable a category as a source of formatters.",
1960 nullptr) {
1962 }
1963
1964 ~CommandObjectTypeCategoryDisable() override = default;
1965
1966protected:
1967 void DoExecute(Args &command, CommandReturnObject &result) override {
1968 const size_t argc = command.GetArgumentCount();
1969
1970 if (argc < 1 && m_options.m_language == lldb::eLanguageTypeUnknown) {
1971 result.AppendErrorWithFormat("%s takes arguments and/or a language",
1972 m_cmd_name.c_str());
1973 return;
1974 }
1975
1976 if (argc == 1 && strcmp(command.GetArgumentAtIndex(0), "*") == 0) {
1978 } else if (argc > 0) {
1979 // the order is not relevant here
1980 for (int i = argc - 1; i >= 0; i--) {
1981 const char *typeA = command.GetArgumentAtIndex(i);
1982 ConstString typeCS(typeA);
1983
1984 if (!typeCS) {
1985 result.AppendError("empty category name not allowed");
1986 return;
1987 }
1989 }
1990 }
1991
1992 if (m_options.m_language != lldb::eLanguageTypeUnknown)
1994
1996 }
1997};
1998
1999// CommandObjectTypeCategoryList
2000
2002public:
2004 : CommandObjectParsed(interpreter, "type category list",
2005 "Provide a list of all existing categories.",
2009
2010 ~CommandObjectTypeCategoryList() override = default;
2011
2012 void
2021
2022protected:
2023 void DoExecute(Args &command, CommandReturnObject &result) override {
2024 const size_t argc = command.GetArgumentCount();
2025
2026 std::unique_ptr<RegularExpression> regex;
2027
2028 if (argc == 1) {
2029 const char *arg = command.GetArgumentAtIndex(0);
2030 regex = std::make_unique<RegularExpression>(arg);
2031 if (!regex->IsValid()) {
2032 result.AppendErrorWithFormat(
2033 "syntax error in category regular expression '%s'", arg);
2034 return;
2036 } else if (argc != 0) {
2037 result.AppendErrorWithFormat("%s takes 0 or one arg.\n",
2038 m_cmd_name.c_str());
2039 return;
2040 }
2043 [&regex, &result](const lldb::TypeCategoryImplSP &category_sp) -> bool {
2044 if (regex) {
2045 bool escape = true;
2046 if (regex->GetText() == category_sp->GetName()) {
2047 escape = false;
2048 } else if (regex->Execute(category_sp->GetName())) {
2049 escape = false;
2050 }
2051
2052 if (escape)
2053 return true;
2054 }
2055
2057 "Category: %s\n", category_sp->GetDescription().c_str());
2059 return true;
2060 });
2061
2063 }
2065
2066// CommandObjectTypeFilterList
2067
2069 : public CommandObjectTypeFormatterList<TypeFilterImpl> {
2070public:
2072 : CommandObjectTypeFormatterList(interpreter, "type filter list",
2073 "Show a list of current filters.") {}
2074};
2075
2076// CommandObjectTypeSynthList
2077
2079 : public CommandObjectTypeFormatterList<SyntheticChildren> {
2080public:
2081 CommandObjectTypeSynthList(CommandInterpreter &interpreter)
2083 interpreter, "type synthetic list",
2084 "Show a list of current synthetic providers.") {}
2085};
2086
2087// CommandObjectTypeFilterDelete
2090public:
2094
2095 ~CommandObjectTypeFilterDelete() override = default;
2096};
2097
2098// CommandObjectTypeSynthDelete
2099
2101public:
2105
2106 ~CommandObjectTypeSynthDelete() override = default;
2107};
2108
2109// CommandObjectTypeFilterClear
2110
2112public:
2113 CommandObjectTypeFilterClear(CommandInterpreter &interpreter)
2115 "type filter clear",
2116 "Delete all existing filter.") {}
2117};
2118
2119// CommandObjectTypeSynthClear
2120
2122public:
2123 CommandObjectTypeSynthClear(CommandInterpreter &interpreter)
2125 interpreter, eFormatCategoryItemSynth, "type synthetic clear",
2126 "Delete all existing synthetic providers.") {}
2127};
2128
2130 Args &command, CommandReturnObject &result) {
2131 auto options = std::make_unique<SynthAddOptions>(
2132 m_options.m_skip_pointers, m_options.m_skip_references,
2133 m_options.m_cascade, m_options.m_match_type, m_options.m_category);
2134
2135 for (auto &entry : command.entries()) {
2136 if (entry.ref().empty()) {
2137 result.AppendError("empty typenames not allowed");
2138 return false;
2139 }
2140
2141 options->m_target_types << std::string(entry.ref());
2142 }
2143
2144 m_interpreter.GetPythonCommandsFromIOHandler(
2145 " ", // Prompt
2146 *this, // IOHandlerDelegate
2147 options.release()); // Baton for the "io_handler" that will be passed back
2148 // into our IOHandlerDelegate functions
2150 return result.Succeeded();
2151}
2152
2154 Args &command, CommandReturnObject &result) {
2155 const size_t argc = command.GetArgumentCount();
2156
2157 if (argc < 1) {
2158 result.AppendErrorWithFormat("%s takes one or more args.\n",
2159 m_cmd_name.c_str());
2160 return false;
2161 }
2162
2164 result.AppendErrorWithFormat("%s needs either a Python class name or -P to "
2165 "directly input Python code.\n",
2166 m_cmd_name.c_str());
2167 return false;
2168 }
2169
2170 SyntheticChildrenSP entry;
2171
2172 ScriptedSyntheticChildren *impl = new ScriptedSyntheticChildren(
2173 SyntheticChildren::Flags()
2174 .SetCascades(m_options.m_cascade)
2175 .SetSkipPointers(m_options.m_skip_pointers)
2176 .SetSkipReferences(m_options.m_skip_references),
2177 m_options.m_class_name.c_str());
2178
2179 entry.reset(impl);
2180
2181 ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter();
2182
2183 if (interpreter &&
2184 !interpreter->CheckObjectExists(impl->GetPythonClassName()))
2185 result.AppendWarning("The provided class does not exist - please define it "
2186 "before attempting to use this synthetic provider");
2187
2188 // now I have a valid provider, let's add it to every type
2189
2190 lldb::TypeCategoryImplSP category;
2192 ConstString(m_options.m_category.c_str()), category);
2193
2194 Status error;
2195
2196 for (auto &arg_entry : command.entries()) {
2197 if (arg_entry.ref().empty()) {
2198 result.AppendError("empty typenames not allowed");
2199 return false;
2200 }
2201
2202 ConstString typeCS(arg_entry.ref());
2203 if (!AddSynth(typeCS, entry, m_options.m_match_type, m_options.m_category,
2204 &error)) {
2205 result.AppendError(error.AsCString());
2206 return false;
2207 }
2208 }
2209
2211 return result.Succeeded();
2212}
2213
2215 CommandInterpreter &interpreter)
2216 : CommandObjectParsed(interpreter, "type synthetic add",
2217 "Add a new synthetic provider for a type.", nullptr),
2218 IOHandlerDelegateMultiline("DONE"), m_options() {
2219 AddSimpleArgumentList(eArgTypeName, eArgRepeatPlus);
2221
2224 FormatterMatchType match_type,
2225 std::string category_name,
2227 lldb::TypeCategoryImplSP category;
2229 category);
2231 if (match_type == eFormatterMatchExact) {
2232 if (FixArrayTypeNameWithRegex(type_name))
2233 match_type = eFormatterMatchRegex;
2234 }
2235
2236 // Only check for conflicting filters in the same category if `type_name` is
2237 // an actual type name. Matching a regex string against registered regexes
2238 // doesn't work.
2239 if (match_type == eFormatterMatchExact) {
2240 // It's not generally possible to get a type object here. For example, this
2241 // command can be run before loading any binaries. Do just a best-effort
2242 // name-based lookup here to try to prevent conflicts.
2243 FormattersMatchCandidate candidate_type(type_name, nullptr, TypeImpl(),
2245 if (category->AnyMatches(candidate_type, eFormatCategoryItemFilter,
2246 false)) {
2247 if (error)
2249 "cannot add synthetic for type %s when "
2250 "filter is defined in same category!",
2251 type_name.AsCString());
2252 return false;
2253 }
2254 }
2255
2256 if (match_type == eFormatterMatchRegex) {
2257 RegularExpression typeRX(type_name.GetStringRef());
2258 if (!typeRX.IsValid()) {
2259 if (error)
2260 *error = Status::FromErrorString(
2261 "regex format error (maybe this is not really a regex?)");
2262 return false;
2263 }
2264 }
2265
2266 if (match_type == eFormatterMatchCallback) {
2267 const char *function_name = type_name.AsCString();
2269 if (interpreter && !interpreter->CheckObjectExists(function_name)) {
2271 "The provided recognizer function \"%s\" does not exist - "
2272 "please define it before attempting to use this summary.\n",
2273 function_name);
2274 return false;
2275 }
2277
2278 category->AddTypeSynthetic(type_name.GetStringRef(), match_type, entry);
2279 return true;
2280}
2281
2282#define LLDB_OPTIONS_type_filter_add
2283#include "CommandOptions.inc"
2286private:
2287 class CommandOptions : public Options {
2288 typedef std::vector<std::string> option_vector;
2290 public:
2291 CommandOptions() = default;
2292
2293 ~CommandOptions() override = default;
2295 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2296 ExecutionContext *execution_context) override {
2297 Status error;
2298 const int short_option = m_getopt_table[option_idx].val;
2299 bool success;
2301 switch (short_option) {
2302 case 'C':
2303 m_cascade = OptionArgParser::ToBoolean(option_arg, true, &success);
2304 if (!success)
2306 "invalid value for cascade: %s", option_arg.str().c_str());
2307 break;
2308 case 'c':
2309 m_expr_paths.push_back(std::string(option_arg));
2310 has_child_list = true;
2311 break;
2312 case 'p':
2313 m_skip_pointers = true;
2314 break;
2315 case 'r':
2316 m_skip_references = true;
2317 break;
2318 case 'w':
2319 m_category = std::string(option_arg);
2320 break;
2321 case 'x':
2322 m_regex = true;
2323 break;
2324 default:
2325 llvm_unreachable("Unimplemented option");
2326 }
2327
2328 return error;
2329 }
2330
2331 void OptionParsingStarting(ExecutionContext *execution_context) override {
2332 m_cascade = true;
2333 m_skip_pointers = false;
2334 m_skip_references = false;
2335 m_category = "default";
2336 m_expr_paths.clear();
2337 has_child_list = false;
2338 m_regex = false;
2339 }
2340
2341 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2342 return llvm::ArrayRef(g_type_filter_add_options);
2343 }
2344
2345 // Instance variables to hold the values for command options.
2346
2347 bool m_cascade;
2348 bool m_skip_references;
2349 bool m_skip_pointers;
2352 std::string m_category;
2353 bool has_child_list;
2354 bool m_regex;
2355
2356 typedef option_vector::iterator ExpressionPathsIterator;
2357 };
2358
2359 CommandOptions m_options;
2360
2361 Options *GetOptions() override { return &m_options; }
2362
2364
2366 FilterFormatType type, std::string category_name,
2367 Status *error) {
2370 ConstString(category_name.c_str()), category);
2371
2372 if (type == eRegularFilter) {
2373 if (FixArrayTypeNameWithRegex(type_name))
2374 type = eRegexFilter;
2375 }
2376
2377 // Only check for conflicting synthetic child providers in the same category
2378 // if `type_name` is an actual type name. Matching a regex string against
2379 // registered regexes doesn't work.
2380 if (type == eRegularFilter) {
2381 // It's not generally possible to get a type object here. For example,
2382 // this command can be run before loading any binaries. Do just a
2383 // best-effort name-based lookup here to try to prevent conflicts.
2384 FormattersMatchCandidate candidate_type(
2385 type_name, nullptr, TypeImpl(), FormattersMatchCandidate::Flags());
2387 if (category->AnyMatches(candidate_type, eFormatCategoryItemSynth,
2388 false)) {
2389 if (error)
2391 "cannot add filter for type %s when "
2392 "synthetic is defined in same "
2393 "category!",
2394 type_name.AsCString());
2395 return false;
2396 }
2397 }
2398
2400 if (type == eRegexFilter) {
2401 match_type = eFormatterMatchRegex;
2402 RegularExpression typeRX(type_name.GetStringRef());
2403 if (!typeRX.IsValid()) {
2404 if (error)
2405 *error = Status::FromErrorString(
2406 "regex format error (maybe this is not really a regex?)");
2407 return false;
2408 }
2409 }
2410 category->AddTypeFilter(type_name.GetStringRef(), match_type, entry);
2411 return true;
2412 }
2413
2414public:
2415 CommandObjectTypeFilterAdd(CommandInterpreter &interpreter)
2416 : CommandObjectParsed(interpreter, "type filter add",
2417 "Add a new filter for a type.", nullptr) {
2419
2421 R"(
2422The following examples of 'type filter add' refer to this code snippet for context:
2423
2424 class Foo {
2425 int a;
2426 int b;
2427 int c;
2428 int d;
2429 int e;
2430 int f;
2431 int g;
2432 int h;
2433 int i;
2434 }
2435 Foo my_foo;
2436
2437Adding a simple filter:
2438
2439(lldb) type filter add --child a --child g Foo
2440(lldb) frame variable my_foo
2441
2442)"
2443 "Produces output where only a and g are displayed. Other children of my_foo \
2444(b, c, d, e, f, h and i) are available by asking for them explicitly:"
2445 R"(
2446
2447(lldb) frame variable my_foo.b my_foo.c my_foo.i
2448
2449)"
2450 "The formatting option --raw on frame variable bypasses the filter, showing \
2451all children of my_foo as if no filter was defined:"
2452 R"(
2454(lldb) frame variable my_foo --raw)");
2455 }
2457 ~CommandObjectTypeFilterAdd() override = default;
2458
2459protected:
2460 void DoExecute(Args &command, CommandReturnObject &result) override {
2461 const size_t argc = command.GetArgumentCount();
2462
2463 if (argc < 1) {
2464 result.AppendErrorWithFormat("%s takes one or more args.\n",
2465 m_cmd_name.c_str());
2466 return;
2467 }
2468
2469 if (m_options.m_expr_paths.empty()) {
2470 result.AppendErrorWithFormat("%s needs one or more children.\n",
2471 m_cmd_name.c_str());
2472 return;
2473 }
2474
2475 TypeFilterImplSP entry(new TypeFilterImpl(
2476 SyntheticChildren::Flags()
2477 .SetCascades(m_options.m_cascade)
2478 .SetSkipPointers(m_options.m_skip_pointers)
2479 .SetSkipReferences(m_options.m_skip_references)));
2481 // go through the expression paths
2483 end = m_options.m_expr_paths.end();
2485 for (begin = m_options.m_expr_paths.begin(); begin != end; begin++)
2486 entry->AddExpressionPath(*begin);
2487
2488 // now I have a valid provider, let's add it to every type
2489
2490 lldb::TypeCategoryImplSP category;
2492 ConstString(m_options.m_category.c_str()), category);
2493
2494 Status error;
2495
2496 WarnOnPotentialUnquotedUnsignedType(command, result);
2497
2498 for (auto &arg_entry : command.entries()) {
2499 if (arg_entry.ref().empty()) {
2500 result.AppendError("empty typenames not allowed");
2501 return;
2502 }
2503
2504 ConstString typeCS(arg_entry.ref());
2505 if (!AddFilter(typeCS, entry,
2508 result.AppendError(error.AsCString());
2509 return;
2514 }
2515};
2516
2517// "type lookup"
2518#define LLDB_OPTIONS_type_lookup
2519#include "CommandOptions.inc"
2520
2522protected:
2523 // this function is allowed to do a more aggressive job at guessing languages
2524 // than the expression parser is comfortable with - so leave the original
2525 // call alone and add one that is specific to type lookup
2528
2529 if (!frame)
2530 return lang_type;
2531
2532 lang_type = frame->GuessLanguage().AsLanguageType();
2533 if (lang_type != lldb::eLanguageTypeUnknown)
2534 return lang_type;
2536 Symbol *s = frame->GetSymbolContext(eSymbolContextSymbol).symbol;
2537 if (s)
2538 lang_type = s->GetMangled().GuessLanguage();
2540 return lang_type;
2541 }
2542
2543 class CommandOptions : public OptionGroup {
2544 public:
2545 CommandOptions() = default;
2546
2547 ~CommandOptions() override = default;
2548
2549 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2550 return llvm::ArrayRef(g_type_lookup_options);
2551 }
2552
2553 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
2554 ExecutionContext *execution_context) override {
2555 Status error;
2556
2557 const int short_option = g_type_lookup_options[option_idx].short_option;
2558
2559 switch (short_option) {
2560 case 'h':
2561 m_show_help = true;
2562 break;
2563
2564 case 'l':
2566 break;
2567
2568 default:
2569 llvm_unreachable("Unimplemented option");
2570 }
2571
2572 return error;
2573 }
2574
2575 void OptionParsingStarting(ExecutionContext *execution_context) override {
2576 m_show_help = false;
2578 }
2579
2580 // Options table: Required for subclasses of Options.
2581
2582 bool m_show_help = false;
2584 };
2585
2586 OptionGroupOptions m_option_group;
2588
2589public:
2590 CommandObjectTypeLookup(CommandInterpreter &interpreter)
2591 : CommandObjectRaw(interpreter, "type lookup",
2592 "Lookup types and declarations in the current target, "
2593 "following language-specific naming conventions.",
2594 "type lookup <type-specifier>",
2595 eCommandRequiresTarget) {
2597 m_option_group.Finalize();
2598 }
2599
2600 ~CommandObjectTypeLookup() override = default;
2601
2602 Options *GetOptions() override { return &m_option_group; }
2603
2604 llvm::StringRef GetHelpLong() override {
2605 if (!m_cmd_help_long.empty())
2606 return m_cmd_help_long;
2607
2608 StreamString stream;
2609 Language::ForEach([&](Language *lang) {
2610 if (const char *help = lang->GetLanguageSpecificTypeLookupHelp())
2611 stream.Printf("%s\n", help);
2612 return true;
2613 });
2614
2615 m_cmd_help_long = std::string(stream.GetString());
2616 return m_cmd_help_long;
2617 }
2618
2619 void DoExecute(llvm::StringRef raw_command_line,
2620 CommandReturnObject &result) override {
2621 if (raw_command_line.empty()) {
2622 result.AppendError(
2623 "type lookup cannot be invoked without a type name as argument");
2624 return;
2625 }
2626
2627 auto exe_ctx = GetCommandInterpreter().GetExecutionContext();
2628 m_option_group.NotifyOptionParsingStarting(&exe_ctx);
2629
2630 OptionsWithRaw args(raw_command_line);
2631 const char *name_of_type = args.GetRawPart().c_str();
2632
2633 if (args.HasArgs())
2634 if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group,
2635 exe_ctx))
2636 return;
2637
2638 ExecutionContextScope *best_scope = exe_ctx.GetBestExecutionContextScope();
2639
2640 bool any_found = false;
2641
2642 std::vector<Language *> languages;
2643
2644 bool is_global_search = false;
2645 LanguageType guessed_language = lldb::eLanguageTypeUnknown;
2646
2647 if ((is_global_search =
2648 (m_command_options.m_language == eLanguageTypeUnknown))) {
2649 Language::ForEach([&](Language *lang) {
2650 languages.push_back(lang);
2651 return true;
2652 });
2653 } else {
2654 languages.push_back(Language::FindPlugin(m_command_options.m_language));
2655 }
2656
2657 // This is not the most efficient way to do this, but we support very few
2658 // languages so the cost of the sort is going to be dwarfed by the actual
2659 // lookup anyway
2660 if (StackFrame *frame = m_exe_ctx.GetFramePtr()) {
2661 guessed_language = GuessLanguage(frame);
2662 if (guessed_language != eLanguageTypeUnknown) {
2663 llvm::sort(
2664 languages.begin(), languages.end(),
2665 [guessed_language](Language *lang1, Language *lang2) -> bool {
2666 if (!lang1 || !lang2)
2667 return false;
2668 LanguageType lt1 = lang1->GetLanguageType();
2669 LanguageType lt2 = lang2->GetLanguageType();
2670 if (lt1 == lt2)
2671 return false;
2672 if (lt1 == guessed_language)
2673 return true; // make the selected frame's language come first
2674 if (lt2 == guessed_language)
2675 return false; // make the selected frame's language come first
2676 return (lt1 < lt2); // normal comparison otherwise
2677 });
2678 }
2679 }
2681 bool is_first_language = true;
2682
2683 for (Language *language : languages) {
2684 if (!language)
2685 continue;
2686
2687 if (auto scavenger = language->GetTypeScavenger()) {
2689 if (scavenger->Find(best_scope, name_of_type, search_results) > 0) {
2690 for (const auto &search_result : search_results) {
2691 if (search_result && search_result->IsValid()) {
2692 any_found = true;
2693 search_result->DumpToStream(result.GetOutputStream(),
2694 this->m_command_options.m_show_help);
2695 }
2696 }
2697 }
2698 }
2699 // this is "type lookup SomeName" and we did find a match, so get out
2700 if (any_found && is_global_search)
2701 break;
2702 else if (is_first_language && is_global_search &&
2703 guessed_language != lldb::eLanguageTypeUnknown) {
2704 is_first_language = false;
2705 result.GetOutputStream().Printf(
2706 "no type was found in the current language %s matching '%s'; "
2707 "performing a global search across all languages\n",
2708 Language::GetNameForLanguageType(guessed_language), name_of_type);
2709 }
2710 }
2711
2712 if (!any_found)
2713 result.AppendMessageWithFormat("no type was found matching '%s'\n",
2714 name_of_type);
2715
2718 }
2719};
2720
2721template <typename FormatterType>
2723public:
2724 typedef std::function<typename FormatterType::SharedPointer(ValueObject &)>
2727 const char *formatter_name,
2728 DiscoveryFunction discovery_func)
2729 : CommandObjectRaw(interpreter, "", "", "", eCommandRequiresFrame),
2730 m_formatter_name(formatter_name ? formatter_name : ""),
2731 m_discovery_function(discovery_func) {
2732 StreamString name;
2733 name.Printf("type %s info", formatter_name);
2734 SetCommandName(name.GetString());
2735 StreamString help;
2736 help.Printf("This command evaluates the provided expression and shows "
2737 "which %s is applied to the resulting value (if any).",
2738 formatter_name);
2739 SetHelp(help.GetString());
2740 StreamString syntax;
2741 syntax.Printf("type %s info <expr>", formatter_name);
2742 SetSyntax(syntax.GetString());
2743 }
2744
2745 ~CommandObjectFormatterInfo() override = default;
2746
2747protected:
2748 void DoExecute(llvm::StringRef command,
2749 CommandReturnObject &result) override {
2750 TargetSP target_sp = GetDebugger().GetSelectedTarget();
2751 Thread *thread = GetDefaultThread();
2752 if (!thread) {
2753 result.AppendError("no default thread");
2754 return;
2756
2757 StackFrameSP frame_sp =
2758 thread->GetSelectedFrame(DoNoSelectMostRelevantFrame);
2759 ValueObjectSP result_valobj_sp;
2761 lldb::ExpressionResults expr_result = target_sp->EvaluateExpression(
2762 command, frame_sp.get(), result_valobj_sp, options);
2763 if (expr_result == eExpressionCompleted && result_valobj_sp) {
2764 result_valobj_sp =
2765 result_valobj_sp->GetQualifiedRepresentationIfAvailable(
2766 target_sp->GetPreferDynamicValue(),
2767 target_sp->GetEnableSyntheticValue());
2768 typename FormatterType::SharedPointer formatter_sp =
2769 m_discovery_function(*result_valobj_sp);
2770 if (formatter_sp) {
2771 std::string description(formatter_sp->GetDescription());
2772 result.GetOutputStream()
2773 << m_formatter_name << " applied to ("
2774 << result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>")
2775 << ") " << command << " is: " << description << "\n";
2777 } else {
2778 result.GetOutputStream()
2779 << "no " << m_formatter_name << " applies to ("
2780 << result_valobj_sp->GetDisplayTypeName().AsCString("<unknown>")
2781 << ") " << command << "\n";
2783 }
2784 } else {
2785 result.AppendError("failed to evaluate expression");
2786 }
2787 }
2788
2789private:
2790 std::string m_formatter_name;
2792};
2793
2795public:
2798 interpreter, "type format",
2799 "Commands for customizing value display formats.",
2800 "type format [<sub-command-options>] ") {
2802 "add", CommandObjectSP(new CommandObjectTypeFormatAdd(interpreter)));
2804 new CommandObjectTypeFormatClear(interpreter)));
2806 interpreter)));
2808 "list", CommandObjectSP(new CommandObjectTypeFormatList(interpreter)));
2811 interpreter, "format",
2813 return valobj.GetValueFormat();
2814 })));
2815 }
2816
2817 ~CommandObjectTypeFormat() override = default;
2818};
2819
2821public:
2824 interpreter, "type synthetic",
2825 "Commands for operating on synthetic type representations.",
2826 "type synthetic [<sub-command-options>] ") {
2827 LoadSubCommand("add",
2830 "clear", CommandObjectSP(new CommandObjectTypeSynthClear(interpreter)));
2832 interpreter)));
2834 "list", CommandObjectSP(new CommandObjectTypeSynthList(interpreter)));
2836 "info",
2838 interpreter, "synthetic",
2840 return valobj.GetSyntheticChildren();
2841 })));
2842 }
2843
2844 ~CommandObjectTypeSynth() override = default;
2845};
2846
2848public:
2850 : CommandObjectMultiword(interpreter, "type filter",
2851 "Commands for operating on type filters.",
2852 "type filter [<sub-command-options>] ") {
2856 new CommandObjectTypeFilterClear(interpreter)));
2858 interpreter)));
2860 "list", CommandObjectSP(new CommandObjectTypeFilterList(interpreter)));
2861 }
2862
2863 ~CommandObjectTypeFilter() override = default;
2864};
2865
2867public:
2869 : CommandObjectMultiword(interpreter, "type category",
2870 "Commands for operating on type categories.",
2871 "type category [<sub-command-options>] ") {
2873 "define",
2876 "enable",
2879 "disable",
2882 "delete",
2885 new CommandObjectTypeCategoryList(interpreter)));
2886 }
2887
2888 ~CommandObjectTypeCategory() override = default;
2889};
2890
2892public:
2895 interpreter, "type summary",
2896 "Commands for editing variable summary display options.",
2897 "type summary [<sub-command-options>] ") {
2899 "add", CommandObjectSP(new CommandObjectTypeSummaryAdd(interpreter)));
2900 LoadSubCommand("clear", CommandObjectSP(new CommandObjectTypeSummaryClear(
2901 interpreter)));
2902 LoadSubCommand("delete", CommandObjectSP(new CommandObjectTypeSummaryDelete(
2903 interpreter)));
2905 "list", CommandObjectSP(new CommandObjectTypeSummaryList(interpreter)));
2907 "info", CommandObjectSP(new CommandObjectFormatterInfo<TypeSummaryImpl>(
2908 interpreter, "summary",
2909 [](ValueObject &valobj) -> TypeSummaryImpl::SharedPointer {
2910 return valobj.GetSummaryFormat();
2911 })));
2912 }
2913
2914 ~CommandObjectTypeSummary() override = default;
2915};
2916
2917// CommandObjectType
2918
2920 : CommandObjectMultiword(interpreter, "type",
2921 "Commands for operating on the type system.",
2922 "type [<sub-command-options>]") {
2923 LoadSubCommand("category",
2924 CommandObjectSP(new CommandObjectTypeCategory(interpreter)));
2925 LoadSubCommand("filter",
2926 CommandObjectSP(new CommandObjectTypeFilter(interpreter)));
2927 LoadSubCommand("format",
2928 CommandObjectSP(new CommandObjectTypeFormat(interpreter)));
2929 LoadSubCommand("summary",
2930 CommandObjectSP(new CommandObjectTypeSummary(interpreter)));
2931 LoadSubCommand("synthetic",
2932 CommandObjectSP(new CommandObjectTypeSynth(interpreter)));
2933 LoadSubCommand("lookup",
2934 CommandObjectSP(new CommandObjectTypeLookup(interpreter)));
2935}
2936
2938
static const char * g_synth_addreader_instructions
static bool WarnOnPotentialUnquotedUnsignedType(Args &command, CommandReturnObject &result)
const char * FormatCategoryToString(FormatCategoryItem item, bool long_name)
static bool FixArrayTypeNameWithRegex(ConstString &type_name)
static llvm::raw_ostream & error(Stream &strm)
~CommandObjectFormatterInfo() override=default
CommandObjectFormatterInfo(CommandInterpreter &interpreter, const char *formatter_name, DiscoveryFunction discovery_func)
void DoExecute(llvm::StringRef command, CommandReturnObject &result) override
std::function< typename FormatterType::SharedPointer(ValueObject &)> DiscoveryFunction
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
CommandObjectTypeCategoryDefine(CommandInterpreter &interpreter)
~CommandObjectTypeCategoryDefine() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTypeCategoryDelete(CommandInterpreter &interpreter)
~CommandObjectTypeCategoryDelete() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
CommandObjectTypeCategoryDisable(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTypeCategoryDisable() override=default
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectTypeCategoryEnable(CommandInterpreter &interpreter)
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTypeCategoryEnable() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTypeCategoryList(CommandInterpreter &interpreter)
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
~CommandObjectTypeCategoryList() override=default
CommandObjectTypeCategory(CommandInterpreter &interpreter)
~CommandObjectTypeCategory() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
~CommandObjectTypeFilterAdd() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTypeFilterAdd(CommandInterpreter &interpreter)
bool AddFilter(ConstString type_name, TypeFilterImplSP entry, FilterFormatType type, std::string category_name, Status *error)
CommandObjectTypeFilterClear(CommandInterpreter &interpreter)
CommandObjectTypeFilterDelete(CommandInterpreter &interpreter)
~CommandObjectTypeFilterDelete() override=default
CommandObjectTypeFilterList(CommandInterpreter &interpreter)
~CommandObjectTypeFilter() override=default
CommandObjectTypeFilter(CommandInterpreter &interpreter)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Options * GetOptions() override
CommandObjectTypeFormatAdd(CommandInterpreter &interpreter)
~CommandObjectTypeFormatAdd() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
CommandObjectTypeFormatClear(CommandInterpreter &interpreter)
CommandObjectTypeFormatDelete(CommandInterpreter &interpreter)
~CommandObjectTypeFormatDelete() override=default
CommandObjectTypeFormatList(CommandInterpreter &interpreter)
CommandObjectTypeFormat(CommandInterpreter &interpreter)
~CommandObjectTypeFormat() override=default
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandObjectTypeFormatterClear(CommandInterpreter &interpreter, FormatCategoryItem formatter_kind, const char *name, const char *help)
~CommandObjectTypeFormatterClear() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
static constexpr const char * g_long_help_template
virtual bool FormatterSpecificDeletion(ConstString typeCS)
static constexpr const char * g_short_help_template
~CommandObjectTypeFormatterDelete() override=default
void DoExecute(Args &command, CommandReturnObject &result) override
void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override
The default version handles argument definitions that have only one argument type,...
CommandObjectTypeFormatterDelete(CommandInterpreter &interpreter, FormatCategoryItem formatter_kind)
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
void DoExecute(Args &command, CommandReturnObject &result) override
FormatterType::SharedPointer FormatterSharedPointer
virtual bool FormatterSpecificList(CommandReturnObject &result)
static bool ShouldListItem(llvm::StringRef s, RegularExpression *regex)
CommandObjectTypeFormatterList(CommandInterpreter &interpreter, const char *name, const char *help)
~CommandObjectTypeFormatterList() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, ExecutionContext *execution_context) override
OptionGroupOptions m_option_group
void DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override
lldb::LanguageType GuessLanguage(StackFrame *frame)
~CommandObjectTypeLookup() override=default
llvm::StringRef GetHelpLong() override
CommandObjectTypeLookup(CommandInterpreter &interpreter)
Options * GetOptions() override
void OptionParsingStarting(ExecutionContext *execution_context) override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
CommandOptions(CommandInterpreter &interpreter)
~CommandObjectTypeSummaryAdd() override=default
bool Execute_ScriptSummary(Args &command, CommandReturnObject &result)
void DoExecute(Args &command, CommandReturnObject &result) override
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
bool Execute_StringSummary(Args &command, CommandReturnObject &result)
CommandObjectTypeSummaryAdd(CommandInterpreter &interpreter)
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
bool AddNamedSummary(ConstString summary_name, lldb::TypeSummaryImplSP entry, Status *error=nullptr)
bool AddSummary(ConstString type_name, lldb::TypeSummaryImplSP entry, FormatterMatchType match_type, std::string category, Status *error=nullptr)
CommandObjectTypeSummaryClear(CommandInterpreter &interpreter)
~CommandObjectTypeSummaryDelete() override=default
CommandObjectTypeSummaryDelete(CommandInterpreter &interpreter)
bool FormatterSpecificDeletion(ConstString typeCS) override
CommandObjectTypeSummaryList(CommandInterpreter &interpreter)
bool FormatterSpecificList(CommandReturnObject &result) override
CommandObjectTypeSummary(CommandInterpreter &interpreter)
~CommandObjectTypeSummary() override=default
llvm::ArrayRef< OptionDefinition > GetDefinitions() override
Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, ExecutionContext *execution_context) override
Set the value of an option.
void OptionParsingStarting(ExecutionContext *execution_context) override
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
CommandObjectTypeSynthAdd(CommandInterpreter &interpreter)
bool Execute_PythonClass(Args &command, CommandReturnObject &result)
bool AddSynth(ConstString type_name, lldb::SyntheticChildrenSP entry, FormatterMatchType match_type, std::string category_name, Status *error)
Options * GetOptions() override
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
void DoExecute(Args &command, CommandReturnObject &result) override
~CommandObjectTypeSynthAdd() override=default
bool Execute_HandwritePython(Args &command, CommandReturnObject &result)
CommandObjectTypeSynthClear(CommandInterpreter &interpreter)
CommandObjectTypeSynthDelete(CommandInterpreter &interpreter)
~CommandObjectTypeSynthDelete() override=default
CommandObjectTypeSynthList(CommandInterpreter &interpreter)
~CommandObjectTypeSynth() override=default
CommandObjectTypeSynth(CommandInterpreter &interpreter)
std::shared_ptr< ScriptAddOptions > SharedPointer
ScriptAddOptions(const TypeSummaryImpl::Flags &flags, FormatterMatchType match_type, ConstString name, std::string catg, uint32_t m_ptr_match_depth)
TypeSummaryImpl::Flags m_flags
FormatterMatchType m_match_type
FormatterMatchType m_match_type
std::shared_ptr< SynthAddOptions > SharedPointer
SynthAddOptions(bool sptr, bool sref, bool casc, FormatterMatchType match_type, std::string catg)
A command line argument class.
Definition Args.h:33
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition Args.h:120
llvm::ArrayRef< ArgEntry > entries() const
Definition Args.h:132
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Definition Args.cpp:273
bool empty() const
Definition Args.h:122
static bool InvokeCommonCompletionCallbacks(CommandInterpreter &interpreter, uint32_t completion_mask, lldb_private::CompletionRequest &request, SearchFilter *searcher)
ExecutionContext GetExecutionContext() const
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
CommandObjectMultiword(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectParsed(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectRaw(CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help="", llvm::StringRef syntax="", uint32_t flags=0)
CommandObjectType(CommandInterpreter &interpreter)
virtual void SetHelpLong(llvm::StringRef str)
void AddSimpleArgumentList(lldb::CommandArgumentType arg_type, ArgumentRepetitionType repetition_type=eArgRepeatPlain)
bool ParseOptionsAndNotify(Args &args, CommandReturnObject &result, OptionGroupOptions &group_options, ExecutionContext &exe_ctx)
CommandInterpreter & GetCommandInterpreter()
CommandInterpreter & m_interpreter
void SetSyntax(llvm::StringRef str)
void SetCommandName(llvm::StringRef name)
virtual void SetHelp(llvm::StringRef str)
void void AppendError(llvm::StringRef in_string)
void AppendWarningWithFormat(const char *format,...) __attribute__((format(printf
void SetStatus(lldb::ReturnStatus status)
void AppendErrorWithFormat(const char *format,...) __attribute__((format(printf
void AppendMessageWithFormat(const char *format,...) __attribute__((format(printf
void void AppendWarning(llvm::StringRef in_string)
"lldb/Utility/ArgCompletionRequest.h"
A uniqued constant string class.
Definition ConstString.h:40
void SetCString(const char *cstr)
Set the C string value.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
const char * GetCString() const
Get the string value as a C string.
static bool Delete(ConstString category)
static void Disable(ConstString category)
static void ForEach(TypeCategoryMap::ForEachCallback callback)
static void Enable(ConstString category, TypeCategoryMap::Position=TypeCategoryMap::Default)
static bool GetCategory(ConstString category, lldb::TypeCategoryImplSP &entry, bool allow_create=true)
static void Add(ConstString type, const lldb::TypeSummaryImplSP &entry)
static void ForEach(std::function< bool(const TypeMatcher &, const lldb::TypeSummaryImplSP &)> callback)
lldb::TargetSP GetSelectedTarget()
Definition Debugger.h:180
ScriptInterpreter * GetScriptInterpreter(bool can_create=true, std::optional< lldb::ScriptLanguage > language={})
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
IOHandlerDelegateMultiline(llvm::StringRef end_line, Completion completion=Completion::None)
Definition IOHandler.h:289
lldb::LockableStreamFileSP GetErrorStreamFileSP()
Definition IOHandler.cpp:95
lldb::LockableStreamFileSP GetOutputStreamFileSP()
Definition IOHandler.cpp:93
void SetIsDone(bool b)
Definition IOHandler.h:81
std::set< std::unique_ptr< Result > > ResultSet
Definition Language.h:53
static Language * FindPlugin(lldb::LanguageType language)
Definition Language.cpp:84
static const char * GetNameForLanguageType(lldb::LanguageType language)
Definition Language.cpp:266
virtual const char * GetLanguageSpecificTypeLookupHelp()
Definition Language.cpp:440
static lldb::LanguageType GetLanguageTypeFromString(const char *string)=delete
static void ForEach(std::function< bool(Language *)> callback)
Definition Language.cpp:131
lldb::LanguageType GuessLanguage() const
Try to guess the language from the mangling.
Definition Mangled.cpp:425
static const uint32_t OPTION_GROUP_FORMAT
Status SetValueFromString(llvm::StringRef value, VarSetOperationType op=eVarSetOperationAssign) override
A command line option parsing protocol class.
Definition Options.h:58
std::vector< Option > m_getopt_table
Definition Options.h:198
bool Execute(llvm::StringRef string, llvm::SmallVectorImpl< llvm::StringRef > *matches=nullptr) const
Execute a regular expression match using the compiled regular expression that is already in this obje...
llvm::StringRef GetText() const
Access the regular expression text.
virtual bool GenerateTypeScriptFunction(const char *oneliner, std::string &output, const void *name_token=nullptr)
virtual bool GenerateTypeSynthClass(StringList &input, std::string &output, const void *name_token=nullptr)
virtual bool CheckObjectExists(const char *name)
This base class provides an interface to stack frames.
Definition StackFrame.h:44
SourceLanguage GuessLanguage()
Similar to GetLanguage(), but is allowed to take a potentially incorrect guess if exact information i...
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
const char * GetData() const
llvm::StringRef GetString() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition Stream.cpp:65
std::string CopyList(const char *item_preamble=nullptr, const char *items_sep="\n") const
size_t SplitIntoLines(const std::string &lines)
Symbol * symbol
The Symbol for a given query.
Mangled & GetMangled()
Definition Symbol.h:147
Flags & SetSkipReferences(bool value=true)
Flags & SetSkipPointers(bool value=true)
std::shared_ptr< SyntheticChildren > SharedPointer
static const Position Default
std::shared_ptr< TypeFormatImpl > SharedPointer
Definition TypeFormat.h:112
Class for matching type names.
ConstString GetMatchString() const
Returns the underlying match string for this TypeMatcher.
std::shared_ptr< TypeSummaryImpl > SharedPointer
lldb::TypeFormatImplSP GetValueFormat()
lldb::TypeSummaryImplSP GetSummaryFormat()
lldb::SyntheticChildrenSP GetSyntheticChildren()
#define LLDB_OPT_SET_1
@ DoNoSelectMostRelevantFrame
A class that represents a running process on the host machine.
std::vector< OptionArgElement > OptionElementVector
Definition Options.h:43
FormatCategoryItem
Format category entry types.
@ eTypeCategoryNameCompletion
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::TypeSummaryImpl > TypeSummaryImplSP
std::shared_ptr< lldb_private::CommandObject > CommandObjectSP
std::shared_ptr< lldb_private::TypeFormatImpl > TypeFormatImplSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
Format
Display format definitions.
LanguageType
Programming language type.
@ eLanguageTypeUnknown
Unknown or invalid language value.
FormatterMatchType
Type of match to be performed when looking for a formatter for a data type.
@ eFormatterMatchExact
@ eFormatterMatchRegex
@ eFormatterMatchCallback
ExpressionResults
The results of expression evaluation.
@ eExpressionCompleted
@ eReturnStatusSuccessFinishResult
@ eReturnStatusSuccessFinishNoResult
std::shared_ptr< lldb_private::SyntheticChildren > SyntheticChildrenSP
std::shared_ptr< lldb_private::TypeCategoryImpl > TypeCategoryImplSP
std::shared_ptr< lldb_private::LockableStreamFile > LockableStreamFileSP
std::shared_ptr< lldb_private::TypeFilterImpl > TypeFilterImplSP
std::shared_ptr< lldb_private::Target > TargetSP
static bool ToBoolean(llvm::StringRef s, bool fail_value, bool *success_ptr)
lldb::LanguageType AsLanguageType() const
Definition Language.cpp:554