xref: /llvm-project/lldb/source/Commands/CommandObjectFrame.cpp (revision 68ebae61d1e51c2741c14bc9f1995270c84f51a6)
1 //===-- CommandObjectFrame.cpp ----------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "CommandObjectFrame.h"
11 
12 // C Includes
13 // C++ Includes
14 // Other libraries and framework includes
15 // Project includes
16 #include "lldb/Core/Debugger.h"
17 #include "lldb/Core/Module.h"
18 #include "lldb/Core/StreamFile.h"
19 #include "lldb/Core/Timer.h"
20 #include "lldb/Core/Value.h"
21 #include "lldb/Core/ValueObject.h"
22 #include "lldb/Core/ValueObjectVariable.h"
23 #include "lldb/Host/Host.h"
24 #include "lldb/Interpreter/Args.h"
25 #include "lldb/Interpreter/CommandInterpreter.h"
26 #include "lldb/Interpreter/CommandReturnObject.h"
27 #include "lldb/Interpreter/Options.h"
28 #include "lldb/Symbol/ClangASTType.h"
29 #include "lldb/Symbol/ClangASTContext.h"
30 #include "lldb/Symbol/ObjectFile.h"
31 #include "lldb/Symbol/SymbolContext.h"
32 #include "lldb/Symbol/Type.h"
33 #include "lldb/Symbol/Variable.h"
34 #include "lldb/Symbol/VariableList.h"
35 #include "lldb/Target/Process.h"
36 #include "lldb/Target/StackFrame.h"
37 #include "lldb/Target/Thread.h"
38 #include "lldb/Target/Target.h"
39 
40 using namespace lldb;
41 using namespace lldb_private;
42 
43 #pragma mark CommandObjectFrameInfo
44 
45 //-------------------------------------------------------------------------
46 // CommandObjectFrameInfo
47 //-------------------------------------------------------------------------
48 
49 class CommandObjectFrameInfo : public CommandObject
50 {
51 public:
52 
53     CommandObjectFrameInfo (CommandInterpreter &interpreter) :
54         CommandObject (interpreter,
55                        "frame info",
56                        "List information about the currently selected frame in the current thread.",
57                        "frame info",
58                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
59     {
60     }
61 
62     ~CommandObjectFrameInfo ()
63     {
64     }
65 
66     bool
67     Execute (Args& command,
68              CommandReturnObject &result)
69     {
70         ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
71         if (exe_ctx.frame)
72         {
73             exe_ctx.frame->DumpUsingSettingsFormat (&result.GetOutputStream());
74             result.GetOutputStream().EOL();
75             result.SetStatus (eReturnStatusSuccessFinishResult);
76         }
77         else
78         {
79             result.AppendError ("no current frame");
80             result.SetStatus (eReturnStatusFailed);
81         }
82         return result.Succeeded();
83     }
84 };
85 
86 #pragma mark CommandObjectFrameSelect
87 
88 //-------------------------------------------------------------------------
89 // CommandObjectFrameSelect
90 //-------------------------------------------------------------------------
91 
92 class CommandObjectFrameSelect : public CommandObject
93 {
94 public:
95 
96    class CommandOptions : public Options
97     {
98     public:
99 
100         CommandOptions (CommandInterpreter &interpreter) :
101             Options(interpreter)
102         {
103             OptionParsingStarting ();
104         }
105 
106         virtual
107         ~CommandOptions ()
108         {
109         }
110 
111         virtual Error
112         SetOptionValue (uint32_t option_idx, const char *option_arg)
113         {
114             Error error;
115             bool success = false;
116             char short_option = (char) m_getopt_table[option_idx].val;
117             switch (short_option)
118             {
119             case 'r':
120                 relative_frame_offset = Args::StringToSInt32 (option_arg, INT32_MIN, 0, &success);
121                 if (!success)
122                     error.SetErrorStringWithFormat ("invalid frame offset argument '%s'.\n", option_arg);
123                 break;
124 
125             default:
126                 error.SetErrorStringWithFormat ("Invalid short option character '%c'.\n", short_option);
127                 break;
128             }
129 
130             return error;
131         }
132 
133         void
134         OptionParsingStarting ()
135         {
136             relative_frame_offset = INT32_MIN;
137         }
138 
139         const OptionDefinition*
140         GetDefinitions ()
141         {
142             return g_option_table;
143         }
144 
145         // Options table: Required for subclasses of Options.
146 
147         static OptionDefinition g_option_table[];
148         int32_t relative_frame_offset;
149     };
150 
151     CommandObjectFrameSelect (CommandInterpreter &interpreter) :
152         CommandObject (interpreter,
153                        "frame select",
154                        "Select a frame by index from within the current thread and make it the current frame.",
155                        NULL,
156                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
157         m_options (interpreter)
158     {
159         CommandArgumentEntry arg;
160         CommandArgumentData index_arg;
161 
162         // Define the first (and only) variant of this arg.
163         index_arg.arg_type = eArgTypeFrameIndex;
164         index_arg.arg_repetition = eArgRepeatOptional;
165 
166         // There is only one variant this argument could be; put it into the argument entry.
167         arg.push_back (index_arg);
168 
169         // Push the data for the first argument into the m_arguments vector.
170         m_arguments.push_back (arg);
171     }
172 
173     ~CommandObjectFrameSelect ()
174     {
175     }
176 
177     virtual
178     Options *
179     GetOptions ()
180     {
181         return &m_options;
182     }
183 
184 
185     bool
186     Execute (Args& command,
187              CommandReturnObject &result)
188     {
189         ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
190         if (exe_ctx.thread)
191         {
192             const uint32_t num_frames = exe_ctx.thread->GetStackFrameCount();
193             uint32_t frame_idx = UINT32_MAX;
194             if (m_options.relative_frame_offset != INT32_MIN)
195             {
196                 // The one and only argument is a signed relative frame index
197                 frame_idx = exe_ctx.thread->GetSelectedFrameIndex ();
198                 if (frame_idx == UINT32_MAX)
199                     frame_idx = 0;
200 
201                 if (m_options.relative_frame_offset < 0)
202                 {
203                     if (frame_idx >= -m_options.relative_frame_offset)
204                         frame_idx += m_options.relative_frame_offset;
205                     else
206                         frame_idx = 0;
207                 }
208                 else if (m_options.relative_frame_offset > 0)
209                 {
210                     if (num_frames - frame_idx > m_options.relative_frame_offset)
211                         frame_idx += m_options.relative_frame_offset;
212                     else
213                         frame_idx = num_frames - 1;
214                 }
215             }
216             else
217             {
218                 if (command.GetArgumentCount() == 1)
219                 {
220                     const char *frame_idx_cstr = command.GetArgumentAtIndex(0);
221                     frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0);
222                 }
223                 else
224                 {
225                     result.AppendError ("invalid arguments.\n");
226                     m_options.GenerateOptionUsage (result.GetErrorStream(), this);
227                 }
228             }
229 
230             if (frame_idx < num_frames)
231             {
232                 exe_ctx.thread->SetSelectedFrameByIndex (frame_idx);
233                 exe_ctx.frame = exe_ctx.thread->GetSelectedFrame ().get();
234 
235                 if (exe_ctx.frame)
236                 {
237                     bool already_shown = false;
238                     SymbolContext frame_sc(exe_ctx.frame->GetSymbolContext(eSymbolContextLineEntry));
239                     if (m_interpreter.GetDebugger().GetUseExternalEditor() && frame_sc.line_entry.file && frame_sc.line_entry.line != 0)
240                     {
241                         already_shown = Host::OpenFileInExternalEditor (frame_sc.line_entry.file, frame_sc.line_entry.line);
242                     }
243 
244                     bool show_frame_info = true;
245                     bool show_source = !already_shown;
246                     uint32_t source_lines_before = 3;
247                     uint32_t source_lines_after = 3;
248                     if (exe_ctx.frame->GetStatus(result.GetOutputStream(),
249                                                  show_frame_info,
250                                                  show_source,
251                                                  source_lines_before,
252                                                  source_lines_after))
253                     {
254                         result.SetStatus (eReturnStatusSuccessFinishResult);
255                         return result.Succeeded();
256                     }
257                 }
258             }
259             result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx);
260         }
261         else
262         {
263             result.AppendError ("no current thread");
264         }
265         result.SetStatus (eReturnStatusFailed);
266         return false;
267     }
268 protected:
269 
270     CommandOptions m_options;
271 };
272 
273 OptionDefinition
274 CommandObjectFrameSelect::CommandOptions::g_option_table[] =
275 {
276 { LLDB_OPT_SET_1, false, "relative", 'r', required_argument, NULL, 0, eArgTypeOffset, "A relative frame index offset from the current frame index."},
277 { 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL }
278 };
279 
280 #pragma mark CommandObjectFrameVariable
281 //----------------------------------------------------------------------
282 // List images with associated information
283 //----------------------------------------------------------------------
284 class CommandObjectFrameVariable : public CommandObject
285 {
286 public:
287 
288     class CommandOptions : public Options
289     {
290     public:
291 
292         CommandOptions (CommandInterpreter &interpreter) :
293             Options(interpreter)
294         {
295             OptionParsingStarting ();
296         }
297 
298         virtual
299         ~CommandOptions ()
300         {
301         }
302 
303         virtual Error
304         SetOptionValue (uint32_t option_idx, const char *option_arg)
305         {
306             Error error;
307             bool success;
308             char short_option = (char) m_getopt_table[option_idx].val;
309             switch (short_option)
310             {
311             case 'o':   use_objc     = true;  break;
312             case 'd':
313                 {
314                     bool success;
315                     bool result;
316                     result = Args::StringToBoolean(option_arg, true, &success);
317                     if (!success)
318                         error.SetErrorStringWithFormat("Invalid dynamic value setting: \"%s\".\n", option_arg);
319                     else
320                     {
321                         if (result)
322                             use_dynamic  = eLazyBoolYes;
323                         else
324                             use_dynamic = eLazyBoolNo;
325                     }
326                 }
327                 break;
328             case 'r':   use_regex    = true;  break;
329             case 'a':   show_args    = false; break;
330             case 'l':   show_locals  = false; break;
331             case 'g':   show_globals = true;  break;
332             case 't':   show_types   = true;  break;
333             case 'y':   show_summary = false; break;
334             case 'L':   show_location= true;  break;
335             case 'c':   show_decl    = true;  break;
336             case 'D':   debug        = true;  break;
337             case 'f':   error = Args::StringToFormat(option_arg, format, NULL); break;
338             case 'F':   flat_output  = true;  break;
339             case 'A':
340                 max_depth = Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success);
341                 if (!success)
342                     error.SetErrorStringWithFormat("Invalid max depth '%s'.\n", option_arg);
343                 break;
344 
345             case 'p':
346                 ptr_depth = Args::StringToUInt32 (option_arg, 0, 0, &success);
347                 if (!success)
348                     error.SetErrorStringWithFormat("Invalid pointer depth '%s'.\n", option_arg);
349                 break;
350 
351             case 'G':
352                 globals.push_back(ConstString (option_arg));
353                 break;
354 
355             case 's':
356                 show_scope = true;
357                 break;
358 
359             default:
360                 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
361                 break;
362             }
363 
364             return error;
365         }
366 
367         void
368         OptionParsingStarting ()
369         {
370             use_objc      = false;
371             use_regex     = false;
372             show_args     = true;
373             show_locals   = true;
374             show_globals  = false;
375             show_types    = false;
376             show_scope    = false;
377             show_summary  = true;
378             show_location = false;
379             show_decl     = false;
380             debug         = false;
381             flat_output   = false;
382             use_dynamic   = eLazyBoolCalculate;
383             max_depth     = UINT32_MAX;
384             ptr_depth     = 0;
385             format        = eFormatDefault;
386             globals.clear();
387         }
388 
389         const OptionDefinition*
390         GetDefinitions ()
391         {
392             return g_option_table;
393         }
394 
395         // Options table: Required for subclasses of Options.
396 
397         static OptionDefinition g_option_table[];
398         bool use_objc:1,
399              use_regex:1,
400              show_args:1,
401              show_locals:1,
402              show_globals:1,
403              show_types:1,
404              show_scope:1,
405              show_summary:1,
406              show_location:1,
407              show_decl:1,
408              debug:1,
409              flat_output:1;
410         LazyBool     use_dynamic;
411         uint32_t max_depth; // The depth to print when dumping concrete (not pointers) aggreate values
412         uint32_t ptr_depth; // The default depth that is dumped when we find pointers
413         lldb::Format format; // The format to use when dumping variables or children of variables
414         std::vector<ConstString> globals;
415         // Instance variables to hold the values for command options.
416     };
417 
418     CommandObjectFrameVariable (CommandInterpreter &interpreter) :
419         CommandObject (interpreter,
420                        "frame variable",
421                        "Show frame variables. All argument and local variables "
422                        "that are in scope will be shown when no arguments are given. "
423                        "If any arguments are specified, they can be names of "
424                        "argument, local, file static and file global variables. "
425                        "Children of aggregate variables can be specified such as "
426                        "'var->child.x'.",
427                        NULL,
428                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
429         m_options (interpreter)
430     {
431         CommandArgumentEntry arg;
432         CommandArgumentData var_name_arg;
433 
434         // Define the first (and only) variant of this arg.
435         var_name_arg.arg_type = eArgTypeVarName;
436         var_name_arg.arg_repetition = eArgRepeatStar;
437 
438         // There is only one variant this argument could be; put it into the argument entry.
439         arg.push_back (var_name_arg);
440 
441         // Push the data for the first argument into the m_arguments vector.
442         m_arguments.push_back (arg);
443     }
444 
445     virtual
446     ~CommandObjectFrameVariable ()
447     {
448     }
449 
450     virtual
451     Options *
452     GetOptions ()
453     {
454         return &m_options;
455     }
456 
457 
458     virtual bool
459     Execute
460     (
461         Args& command,
462         CommandReturnObject &result
463     )
464     {
465         ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
466         if (exe_ctx.frame == NULL)
467         {
468             result.AppendError ("you must be stopped in a valid stack frame to view frame variables.");
469             result.SetStatus (eReturnStatusFailed);
470             return false;
471         }
472         else
473         {
474             Stream &s = result.GetOutputStream();
475 
476             bool get_file_globals = true;
477             VariableList *variable_list = exe_ctx.frame->GetVariableList (get_file_globals);
478 
479             VariableSP var_sp;
480             ValueObjectSP valobj_sp;
481 
482             bool use_dynamic;
483 
484             // If use dynamic is not set, get it from the target:
485             switch (m_options.use_dynamic)
486             {
487             case eLazyBoolCalculate:
488                 {
489                     if (exe_ctx.target->GetPreferDynamicValue())
490                         use_dynamic = true;
491                     else
492                         use_dynamic = false;
493                 }
494                 break;
495             case eLazyBoolYes:
496                 use_dynamic = true;
497                 break;
498             case eLazyBoolNo:
499                 use_dynamic = false;
500                 break;
501             }
502 
503             const char *name_cstr = NULL;
504             size_t idx;
505             if (!m_options.globals.empty())
506             {
507                 uint32_t fail_count = 0;
508                 if (exe_ctx.target)
509                 {
510                     const size_t num_globals = m_options.globals.size();
511                     for (idx = 0; idx < num_globals; ++idx)
512                     {
513                         VariableList global_var_list;
514                         const uint32_t num_matching_globals
515                                 = exe_ctx.target->GetImages().FindGlobalVariables (m_options.globals[idx],
516                                                                                    true,
517                                                                                    UINT32_MAX,
518                                                                                    global_var_list);
519 
520                         if (num_matching_globals == 0)
521                         {
522                             ++fail_count;
523                             result.GetErrorStream().Printf ("error: can't find global variable '%s'\n",
524                                                             m_options.globals[idx].AsCString());
525                         }
526                         else
527                         {
528                             for (uint32_t global_idx=0; global_idx<num_matching_globals; ++global_idx)
529                             {
530                                 var_sp = global_var_list.GetVariableAtIndex(global_idx);
531                                 if (var_sp)
532                                 {
533                                     valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp, use_dynamic);
534                                     if (!valobj_sp)
535                                         valobj_sp = exe_ctx.frame->TrackGlobalVariable (var_sp, use_dynamic);
536 
537                                     if (valobj_sp)
538                                     {
539                                         if (m_options.format != eFormatDefault)
540                                             valobj_sp->SetFormat (m_options.format);
541 
542                                         if (m_options.show_decl && var_sp->GetDeclaration ().GetFile())
543                                         {
544                                             var_sp->GetDeclaration ().DumpStopContext (&s, false);
545                                             s.PutCString (": ");
546                                         }
547 
548                                         ValueObject::DumpValueObject (result.GetOutputStream(),
549                                                                       valobj_sp.get(),
550                                                                       name_cstr,
551                                                                       m_options.ptr_depth,
552                                                                       0,
553                                                                       m_options.max_depth,
554                                                                       m_options.show_types,
555                                                                       m_options.show_location,
556                                                                       m_options.use_objc,
557                                                                       use_dynamic,
558                                                                       false,
559                                                                       m_options.flat_output);
560                                     }
561                                 }
562                             }
563                         }
564                     }
565                 }
566                 if (fail_count)
567                     result.SetStatus (eReturnStatusFailed);
568             }
569             else if (variable_list)
570             {
571                 if (command.GetArgumentCount() > 0)
572                 {
573                     VariableList regex_var_list;
574 
575                     // If we have any args to the variable command, we will make
576                     // variable objects from them...
577                     for (idx = 0; (name_cstr = command.GetArgumentAtIndex(idx)) != NULL; ++idx)
578                     {
579                         uint32_t ptr_depth = m_options.ptr_depth;
580 
581                         if (m_options.use_regex)
582                         {
583                             const uint32_t regex_start_index = regex_var_list.GetSize();
584                             RegularExpression regex (name_cstr);
585                             if (regex.Compile(name_cstr))
586                             {
587                                 size_t num_matches = 0;
588                                 const size_t num_new_regex_vars = variable_list->AppendVariablesIfUnique(regex,
589                                                                                                          regex_var_list,
590                                                                                                          num_matches);
591                                 if (num_new_regex_vars > 0)
592                                 {
593                                     for (uint32_t regex_idx = regex_start_index, end_index = regex_var_list.GetSize();
594                                          regex_idx < end_index;
595                                          ++regex_idx)
596                                     {
597                                         var_sp = regex_var_list.GetVariableAtIndex (regex_idx);
598                                         if (var_sp)
599                                         {
600                                             valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp, use_dynamic);
601                                             if (valobj_sp)
602                                             {
603                                                 if (m_options.format != eFormatDefault)
604                                                     valobj_sp->SetFormat (m_options.format);
605 
606                                                 if (m_options.show_decl && var_sp->GetDeclaration ().GetFile())
607                                                 {
608                                                     var_sp->GetDeclaration ().DumpStopContext (&s, false);
609                                                     s.PutCString (": ");
610                                                 }
611 
612                                                 ValueObject::DumpValueObject (result.GetOutputStream(),
613                                                                               valobj_sp.get(),
614                                                                               var_sp->GetName().AsCString(),
615                                                                               m_options.ptr_depth,
616                                                                               0,
617                                                                               m_options.max_depth,
618                                                                               m_options.show_types,
619                                                                               m_options.show_location,
620                                                                               m_options.use_objc,
621                                                                               use_dynamic,
622                                                                               false,
623                                                                               m_options.flat_output);
624                                             }
625                                         }
626                                     }
627                                 }
628                                 else if (num_matches == 0)
629                                 {
630                                     result.GetErrorStream().Printf ("error: no variables matched the regular expression '%s'.\n", name_cstr);
631                                 }
632                             }
633                             else
634                             {
635                                 char regex_error[1024];
636                                 if (regex.GetErrorAsCString(regex_error, sizeof(regex_error)))
637                                     result.GetErrorStream().Printf ("error: %s\n", regex_error);
638                                 else
639                                     result.GetErrorStream().Printf ("error: unkown regex error when compiling '%s'\n", name_cstr);
640                             }
641                         }
642                         else
643                         {
644                             Error error;
645                             uint32_t expr_path_options = StackFrame::eExpressionPathOptionCheckPtrVsMember;
646                             if (use_dynamic)
647                                 expr_path_options |= StackFrame::eExpressionPathOptionsDynamicValue;
648 
649                             valobj_sp = exe_ctx.frame->GetValueForVariableExpressionPath (name_cstr, expr_path_options, error);
650                             if (valobj_sp)
651                             {
652                                 if (m_options.format != eFormatDefault)
653                                     valobj_sp->SetFormat (m_options.format);
654 
655                                 if (m_options.show_decl && var_sp->GetDeclaration ().GetFile())
656                                 {
657                                     var_sp->GetDeclaration ().DumpStopContext (&s, false);
658                                     s.PutCString (": ");
659                                 }
660                                 ValueObject::DumpValueObject (result.GetOutputStream(),
661                                                               valobj_sp.get(),
662                                                               valobj_sp->GetParent() ? name_cstr : NULL,
663                                                               ptr_depth,
664                                                               0,
665                                                               m_options.max_depth,
666                                                               m_options.show_types,
667                                                               m_options.show_location,
668                                                               m_options.use_objc,
669                                                               use_dynamic,
670                                                               false,
671                                                               m_options.flat_output);
672                             }
673                             else
674                             {
675                                 const char *error_cstr = error.AsCString(NULL);
676                                 if (error_cstr)
677                                     result.GetErrorStream().Printf("error: %s\n", error_cstr);
678                                 else
679                                     result.GetErrorStream().Printf ("error: unable to find any variable expression path that matches '%s'\n", name_cstr);
680                             }
681                         }
682                     }
683                 }
684                 else
685                 {
686                     const uint32_t num_variables = variable_list->GetSize();
687 
688                     if (num_variables > 0)
689                     {
690                         for (uint32_t i=0; i<num_variables; i++)
691                         {
692                             var_sp = variable_list->GetVariableAtIndex(i);
693 
694                             bool dump_variable = true;
695 
696                             switch (var_sp->GetScope())
697                             {
698                             case eValueTypeVariableGlobal:
699                                 dump_variable = m_options.show_globals;
700                                 if (dump_variable && m_options.show_scope)
701                                     s.PutCString("GLOBAL: ");
702                                 break;
703 
704                             case eValueTypeVariableStatic:
705                                 dump_variable = m_options.show_globals;
706                                 if (dump_variable && m_options.show_scope)
707                                     s.PutCString("STATIC: ");
708                                 break;
709 
710                             case eValueTypeVariableArgument:
711                                 dump_variable = m_options.show_args;
712                                 if (dump_variable && m_options.show_scope)
713                                     s.PutCString("   ARG: ");
714                                 break;
715 
716                             case eValueTypeVariableLocal:
717                                 dump_variable = m_options.show_locals;
718                                 if (dump_variable && m_options.show_scope)
719                                     s.PutCString(" LOCAL: ");
720                                 break;
721 
722                             default:
723                                 break;
724                             }
725 
726                             if (dump_variable)
727                             {
728 
729                                 // Use the variable object code to make sure we are
730                                 // using the same APIs as the the public API will be
731                                 // using...
732                                 valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp, use_dynamic);
733                                 if (valobj_sp)
734                                 {
735                                     if (m_options.format != eFormatDefault)
736                                         valobj_sp->SetFormat (m_options.format);
737 
738                                     // When dumping all variables, don't print any variables
739                                     // that are not in scope to avoid extra unneeded output
740                                     if (valobj_sp->IsInScope ())
741                                     {
742                                         if (m_options.show_decl && var_sp->GetDeclaration ().GetFile())
743                                         {
744                                             var_sp->GetDeclaration ().DumpStopContext (&s, false);
745                                             s.PutCString (": ");
746                                         }
747                                         ValueObject::DumpValueObject (result.GetOutputStream(),
748                                                                       valobj_sp.get(),
749                                                                       name_cstr,
750                                                                       m_options.ptr_depth,
751                                                                       0,
752                                                                       m_options.max_depth,
753                                                                       m_options.show_types,
754                                                                       m_options.show_location,
755                                                                       m_options.use_objc,
756                                                                       use_dynamic,
757                                                                       false,
758                                                                       m_options.flat_output);
759                                     }
760                                 }
761                             }
762                         }
763                     }
764                 }
765                 result.SetStatus (eReturnStatusSuccessFinishResult);
766             }
767         }
768         return result.Succeeded();
769     }
770 protected:
771 
772     CommandOptions m_options;
773 };
774 
775 OptionDefinition
776 CommandObjectFrameVariable::CommandOptions::g_option_table[] =
777 {
778 { LLDB_OPT_SET_1, false, "aggregate-depth", 'A', required_argument, NULL, 0, eArgTypeCount,   "Set the max recurse depth when dumping aggregate types (default is infinity)."},
779 { LLDB_OPT_SET_1, false, "no-args",         'a', no_argument,       NULL, 0, eArgTypeNone,    "Omit function arguments."},
780 { LLDB_OPT_SET_1, false, "show-declaration",'c', no_argument,       NULL, 0, eArgTypeNone,    "Show variable declaration information (source file and line where the variable was declared)."},
781 { LLDB_OPT_SET_1, false, "debug",           'D', no_argument,       NULL, 0, eArgTypeNone,    "Enable verbose debug information."},
782 { LLDB_OPT_SET_1, false, "dynamic-type",    'd', required_argument, NULL, 0, eArgTypeBoolean, "Show the object as its full dynamic type, not its static type, if available."},
783 { LLDB_OPT_SET_1, false, "format",          'f', required_argument, NULL, 0, eArgTypeExprFormat,  "Specify the format that the variable output should use."},
784 { LLDB_OPT_SET_1, false, "flat",            'F', no_argument,       NULL, 0, eArgTypeNone,    "Display results in a flat format that uses expression paths for each variable or member."},
785 { LLDB_OPT_SET_1, false, "show-globals",    'g', no_argument,       NULL, 0, eArgTypeNone,    "Show the current frame source file global and static variables."},
786 { LLDB_OPT_SET_1, false, "find-global",     'G', required_argument, NULL, 0, eArgTypeVarName, "Find a global variable by name (which might not be in the current stack frame source file)."},
787 { LLDB_OPT_SET_1, false, "location",        'L', no_argument,       NULL, 0, eArgTypeNone,    "Show variable location information."},
788 { LLDB_OPT_SET_1, false, "no-locals",       'l', no_argument,       NULL, 0, eArgTypeNone,    "Omit local variables."},
789 { LLDB_OPT_SET_1, false, "objc",            'o', no_argument,       NULL, 0, eArgTypeNone,    "When looking up a variable by name, print as an Objective-C object."},
790 { LLDB_OPT_SET_1, false, "ptr-depth",       'p', required_argument, NULL, 0, eArgTypeCount,   "The number of pointers to be traversed when dumping values (default is zero)."},
791 { LLDB_OPT_SET_1, false, "regex",           'r', no_argument,       NULL, 0, eArgTypeRegularExpression,    "The <variable-name> argument for name lookups are regular expressions."},
792 { LLDB_OPT_SET_1, false, "scope",           's', no_argument,       NULL, 0, eArgTypeNone,    "Show variable scope (argument, local, global, static)."},
793 { LLDB_OPT_SET_1, false, "show-types",      't', no_argument,       NULL, 0, eArgTypeNone,    "Show variable types when dumping values."},
794 { LLDB_OPT_SET_1, false, "no-summary",      'y', no_argument,       NULL, 0, eArgTypeNone,    "Omit summary information."},
795 { 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL }
796 };
797 #pragma mark CommandObjectMultiwordFrame
798 
799 //-------------------------------------------------------------------------
800 // CommandObjectMultiwordFrame
801 //-------------------------------------------------------------------------
802 
803 CommandObjectMultiwordFrame::CommandObjectMultiwordFrame (CommandInterpreter &interpreter) :
804     CommandObjectMultiword (interpreter,
805                             "frame",
806                             "A set of commands for operating on the current thread's frames.",
807                             "frame <subcommand> [<subcommand-options>]")
808 {
809     LoadSubCommand ("info",   CommandObjectSP (new CommandObjectFrameInfo (interpreter)));
810     LoadSubCommand ("select", CommandObjectSP (new CommandObjectFrameSelect (interpreter)));
811     LoadSubCommand ("variable", CommandObjectSP (new CommandObjectFrameVariable (interpreter)));
812 }
813 
814 CommandObjectMultiwordFrame::~CommandObjectMultiwordFrame ()
815 {
816 }
817 
818