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