CommandObjectFrame.cpp revision b227e142b5eb7d1825e85f0d797f12e817bf89c7
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                ("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 'd':
322                max_depth = Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success);
323                if (!success)
324                    error.SetErrorStringWithFormat("Invalid max depth '%s'.\n", option_arg);
325                break;
326
327            case 'p':
328                ptr_depth = Args::StringToUInt32 (option_arg, 0, 0, &success);
329                if (!success)
330                    error.SetErrorStringWithFormat("Invalid pointer depth '%s'.\n", option_arg);
331                break;
332
333            case 'G':
334                globals.push_back(ConstString (option_arg));
335                break;
336
337            case 's':
338                show_scope = true;
339                break;
340
341            default:
342                error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
343                break;
344            }
345
346            return error;
347        }
348
349        void
350        ResetOptionValues ()
351        {
352            Options::ResetOptionValues();
353
354            use_objc      = false;
355            use_regex     = false;
356            show_args     = true;
357            show_locals   = true;
358            show_globals  = false;
359            show_types    = false;
360            show_scope    = false;
361            show_summary  = true;
362            show_location = false;
363            show_decl     = false;
364            debug         = false;
365            max_depth     = UINT32_MAX;
366            ptr_depth     = 0;
367            globals.clear();
368        }
369
370        const lldb::OptionDefinition*
371        GetDefinitions ()
372        {
373            return g_option_table;
374        }
375
376        // Options table: Required for subclasses of Options.
377
378        static lldb::OptionDefinition g_option_table[];
379        bool use_objc:1,
380             use_regex:1,
381             show_args:1,
382             show_locals:1,
383             show_globals:1,
384             show_types:1,
385             show_scope:1,
386             show_summary:1,
387             show_location:1,
388             show_decl:1,
389             debug:1;
390        uint32_t max_depth; // The depth to print when dumping concrete (not pointers) aggreate values
391        uint32_t ptr_depth; // The default depth that is dumped when we find pointers
392        std::vector<ConstString> globals;
393        // Instance variables to hold the values for command options.
394    };
395
396    CommandObjectFrameVariable (CommandInterpreter &interpreter) :
397        CommandObject (interpreter,
398                       "frame variable",
399                       "Show frame variables. All argument and local variables "
400                       "that are in scope will be shown when no arguments are given. "
401                       "If any arguments are specified, they can be names of "
402                       "argument, local, file static and file global variables."
403                       "Children of aggregate variables can be specified such as "
404                       "'var->child.x'.",
405                       NULL)
406    {
407        CommandArgumentEntry arg;
408        CommandArgumentData var_name_arg;
409
410        // Define the first (and only) variant of this arg.
411        var_name_arg.arg_type = eArgTypeVarName;
412        var_name_arg.arg_repetition = eArgRepeatStar;
413
414        // There is only one variant this argument could be; put it into the argument entry.
415        arg.push_back (var_name_arg);
416
417        // Push the data for the first argument into the m_arguments vector.
418        m_arguments.push_back (arg);
419    }
420
421    virtual
422    ~CommandObjectFrameVariable ()
423    {
424    }
425
426    virtual
427    Options *
428    GetOptions ()
429    {
430        return &m_options;
431    }
432
433
434    virtual bool
435    Execute
436    (
437        Args& command,
438        CommandReturnObject &result
439    )
440    {
441        ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
442        if (exe_ctx.frame == NULL)
443        {
444            result.AppendError ("you must be stopped in a valid stack frame to view frame variables.");
445            result.SetStatus (eReturnStatusFailed);
446            return false;
447        }
448        else
449        {
450            Stream &s = result.GetOutputStream();
451
452            bool get_file_globals = true;
453            VariableList *variable_list = exe_ctx.frame->GetVariableList (get_file_globals);
454
455            VariableSP var_sp;
456            ValueObjectSP valobj_sp;
457            //ValueObjectList &valobj_list = exe_ctx.frame->GetValueObjectList();
458            const char *name_cstr = NULL;
459            size_t idx;
460            if (!m_options.globals.empty())
461            {
462                uint32_t fail_count = 0;
463                if (exe_ctx.target)
464                {
465                    const size_t num_globals = m_options.globals.size();
466                    for (idx = 0; idx < num_globals; ++idx)
467                    {
468                        VariableList global_var_list;
469                        const uint32_t num_matching_globals = exe_ctx.target->GetImages().FindGlobalVariables (m_options.globals[idx], true, UINT32_MAX, global_var_list);
470
471                        if (num_matching_globals == 0)
472                        {
473                            ++fail_count;
474                            result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", m_options.globals[idx].AsCString());
475                        }
476                        else
477                        {
478                            for (uint32_t global_idx=0; global_idx<num_matching_globals; ++global_idx)
479                            {
480                                var_sp = global_var_list.GetVariableAtIndex(global_idx);
481                                if (var_sp)
482                                {
483                                    valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp);
484                                    if (!valobj_sp)
485                                        valobj_sp = exe_ctx.frame->TrackGlobalVariable (var_sp);
486
487                                    if (valobj_sp)
488                                    {
489                                        if (m_options.show_decl && var_sp->GetDeclaration ().GetFile())
490                                        {
491                                            var_sp->GetDeclaration ().DumpStopContext (&s, false);
492                                            s.PutCString (": ");
493                                        }
494
495                                        ValueObject::DumpValueObject (result.GetOutputStream(),
496                                                                      exe_ctx.frame,
497                                                                      valobj_sp.get(),
498                                                                      name_cstr,
499                                                                      m_options.ptr_depth,
500                                                                      0,
501                                                                      m_options.max_depth,
502                                                                      m_options.show_types,
503                                                                      m_options.show_location,
504                                                                      m_options.use_objc,
505                                                                      false);
506                                        s.EOL();
507                                    }
508                                }
509                            }
510                        }
511                    }
512                }
513                if (fail_count)
514                    result.SetStatus (eReturnStatusFailed);
515            }
516            else if (variable_list)
517            {
518                if (command.GetArgumentCount() > 0)
519                {
520                    VariableList regex_var_list;
521
522                    // If we have any args to the variable command, we will make
523                    // variable objects from them...
524                    for (idx = 0; (name_cstr = command.GetArgumentAtIndex(idx)) != NULL; ++idx)
525                    {
526                        uint32_t ptr_depth = m_options.ptr_depth;
527
528                        if (m_options.use_regex)
529                        {
530                            const uint32_t regex_start_index = regex_var_list.GetSize();
531                            RegularExpression regex (name_cstr);
532                            if (regex.Compile(name_cstr))
533                            {
534                                size_t num_matches = 0;
535                                const size_t num_new_regex_vars = variable_list->AppendVariablesIfUnique(regex, regex_var_list, num_matches);
536                                if (num_new_regex_vars > 0)
537                                {
538                                    for (uint32_t regex_idx = regex_start_index, end_index = regex_var_list.GetSize();
539                                         regex_idx < end_index;
540                                         ++regex_idx)
541                                    {
542                                        var_sp = regex_var_list.GetVariableAtIndex (regex_idx);
543                                        if (var_sp)
544                                        {
545                                            valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp);
546                                            if (valobj_sp)
547                                            {
548                                                if (m_options.show_decl && var_sp->GetDeclaration ().GetFile())
549                                                {
550                                                    var_sp->GetDeclaration ().DumpStopContext (&s, false);
551                                                    s.PutCString (": ");
552                                                }
553
554                                                ValueObject::DumpValueObject (result.GetOutputStream(),
555                                                                              exe_ctx.frame,
556                                                                              valobj_sp.get(),
557                                                                              var_sp->GetName().AsCString(),
558                                                                              m_options.ptr_depth,
559                                                                              0,
560                                                                              m_options.max_depth,
561                                                                              m_options.show_types,
562                                                                              m_options.show_location,
563                                                                              m_options.use_objc,
564                                                                              false);
565                                                s.EOL();
566                                            }
567                                        }
568                                    }
569                                }
570                                else if (num_matches == 0)
571                                {
572                                    result.GetErrorStream().Printf ("error: no variables matched the regular expression '%s'.\n", name_cstr);
573                                }
574                            }
575                            else
576                            {
577                                char regex_error[1024];
578                                if (regex.GetErrorAsCString(regex_error, sizeof(regex_error)))
579                                    result.GetErrorStream().Printf ("error: %s\n", regex_error);
580                                else
581                                    result.GetErrorStream().Printf ("error: unkown regex error when compiling '%s'\n", name_cstr);
582                            }
583                        }
584                        else
585                        {
586                            // If first character is a '*', then show pointer contents
587                            if (name_cstr[0] == '*')
588                            {
589                                ++ptr_depth;
590                                name_cstr++; // Skip the '*'
591                            }
592
593                            std::string var_path (name_cstr);
594                            size_t separator_idx = var_path.find_first_of(".-[");
595
596                            ConstString name_const_string;
597                            if (separator_idx == std::string::npos)
598                                name_const_string.SetCString (var_path.c_str());
599                            else
600                                name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
601
602                            var_sp = variable_list->FindVariable(name_const_string);
603                            if (var_sp)
604                            {
605                                valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp);
606
607                                var_path.erase (0, name_const_string.GetLength ());
608                                // We are dumping at least one child
609                                while (separator_idx != std::string::npos)
610                                {
611                                    // Calculate the next separator index ahead of time
612                                    ValueObjectSP child_valobj_sp;
613                                    const char separator_type = var_path[0];
614                                    switch (separator_type)
615                                    {
616
617                                    case '-':
618                                        if (var_path.size() >= 2 && var_path[1] != '>')
619                                        {
620                                            result.GetErrorStream().Printf ("error: invalid character in variable path starting at '%s'\n",
621                                                                            var_path.c_str());
622                                            var_path.clear();
623                                            valobj_sp.reset();
624                                            break;
625                                        }
626                                        var_path.erase (0, 1); // Remove the '-'
627                                        // Fall through
628                                    case '.':
629                                        {
630                                            var_path.erase (0, 1); // Remove the '.' or '>'
631                                            separator_idx = var_path.find_first_of(".-[");
632                                            ConstString child_name;
633                                            if (separator_idx == std::string::npos)
634                                                child_name.SetCString (var_path.c_str());
635                                            else
636                                                child_name.SetCStringWithLength(var_path.c_str(), separator_idx);
637
638                                            child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true);
639                                            if (!child_valobj_sp)
640                                            {
641                                                result.GetErrorStream().Printf ("error: can't find child of '%s' named '%s'\n",
642                                                                                valobj_sp->GetName().AsCString(),
643                                                                                child_name.GetCString());
644                                                var_path.clear();
645                                                valobj_sp.reset();
646                                                break;
647                                            }
648                                            // Remove the child name from the path
649                                            var_path.erase(0, child_name.GetLength());
650                                        }
651                                        break;
652
653                                    case '[':
654                                        // Array member access, or treating pointer as an array
655                                        if (var_path.size() > 2) // Need at least two brackets and a number
656                                        {
657                                            char *end = NULL;
658                                            int32_t child_index = ::strtol (&var_path[1], &end, 0);
659                                            if (end && *end == ']')
660                                            {
661
662                                                if (valobj_sp->IsPointerType ())
663                                                {
664                                                    child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true);
665                                                }
666                                                else
667                                                {
668                                                    child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
669                                                }
670
671                                                if (!child_valobj_sp)
672                                                {
673                                                    result.GetErrorStream().Printf ("error: invalid array index %u in '%s'\n",
674                                                                                    child_index,
675                                                                                    valobj_sp->GetName().AsCString());
676                                                    var_path.clear();
677                                                    valobj_sp.reset();
678                                                    break;
679                                                }
680
681                                                // Erase the array member specification '[%i]' where %i is the array index
682                                                var_path.erase(0, (end - var_path.c_str()) + 1);
683                                                separator_idx = var_path.find_first_of(".-[");
684
685                                                // Break out early from the switch since we were able to find the child member
686                                                break;
687                                            }
688                                        }
689                                        result.GetErrorStream().Printf ("error: invalid array member specification for '%s' starting at '%s'\n",
690                                                                        valobj_sp->GetName().AsCString(),
691                                                                        var_path.c_str());
692                                        var_path.clear();
693                                        valobj_sp.reset();
694                                        break;
695
696                                        break;
697
698                                    default:
699                                        result.GetErrorStream().Printf ("error: invalid character in variable path starting at '%s'\n",
700                                                                            var_path.c_str());
701                                        var_path.clear();
702                                        valobj_sp.reset();
703                                        separator_idx = std::string::npos;
704                                        break;
705                                    }
706
707                                    if (child_valobj_sp)
708                                        valobj_sp = child_valobj_sp;
709
710                                    if (var_path.empty())
711                                        break;
712
713                                }
714
715                                if (valobj_sp)
716                                {
717                                    if (m_options.show_decl && var_sp->GetDeclaration ().GetFile())
718                                    {
719                                        var_sp->GetDeclaration ().DumpStopContext (&s, false);
720                                        s.PutCString (": ");
721                                    }
722
723
724                                    ValueObject::DumpValueObject (result.GetOutputStream(),
725                                                                  exe_ctx.frame,
726                                                                  valobj_sp.get(),
727                                                                  name_cstr,
728                                                                  ptr_depth,
729                                                                  0,
730                                                                  m_options.max_depth,
731                                                                  m_options.show_types,
732                                                                  m_options.show_location,
733                                                                  m_options.use_objc,
734                                                                  false);
735
736                                    s.EOL();
737                                }
738                            }
739                            else
740                            {
741                                result.GetErrorStream().Printf ("error: unable to find any variables named '%s'\n", name_cstr);
742                                var_path.clear();
743                            }
744                        }
745                    }
746                }
747                else
748                {
749                    const uint32_t num_variables = variable_list->GetSize();
750
751                    if (num_variables > 0)
752                    {
753                        for (uint32_t i=0; i<num_variables; i++)
754                        {
755                            VariableSP var_sp (variable_list->GetVariableAtIndex(i));
756                            bool dump_variable = true;
757
758                            switch (var_sp->GetScope())
759                            {
760                            case eValueTypeVariableGlobal:
761                                dump_variable = m_options.show_globals;
762                                if (dump_variable && m_options.show_scope)
763                                    s.PutCString("GLOBAL: ");
764                                break;
765
766                            case eValueTypeVariableStatic:
767                                dump_variable = m_options.show_globals;
768                                if (dump_variable && m_options.show_scope)
769                                    s.PutCString("STATIC: ");
770                                break;
771
772                            case eValueTypeVariableArgument:
773                                dump_variable = m_options.show_args;
774                                if (dump_variable && m_options.show_scope)
775                                    s.PutCString("   ARG: ");
776                                break;
777
778                            case eValueTypeVariableLocal:
779                                dump_variable = m_options.show_locals;
780                                if (dump_variable && m_options.show_scope)
781                                    s.PutCString(" LOCAL: ");
782                                break;
783
784                            default:
785                                break;
786                            }
787
788                            if (dump_variable)
789                            {
790
791                                // Use the variable object code to make sure we are
792                                // using the same APIs as the the public API will be
793                                // using...
794                                valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp);
795                                if (valobj_sp)
796                                {
797                                    // When dumping all variables, don't print any variables
798                                    // that are not in scope to avoid extra unneeded output
799                                    if (valobj_sp->IsInScope (exe_ctx.frame))
800                                    {
801                                        if (m_options.show_decl && var_sp->GetDeclaration ().GetFile())
802                                        {
803                                            var_sp->GetDeclaration ().DumpStopContext (&s, false);
804                                            s.PutCString (": ");
805                                        }
806                                        ValueObject::DumpValueObject (result.GetOutputStream(),
807                                                                      exe_ctx.frame,
808                                                                      valobj_sp.get(),
809                                                                      name_cstr,
810                                                                      m_options.ptr_depth,
811                                                                      0,
812                                                                      m_options.max_depth,
813                                                                      m_options.show_types,
814                                                                      m_options.show_location,
815                                                                      m_options.use_objc,
816                                                                      false);
817
818                                        s.EOL();
819                                    }
820                                }
821                            }
822                        }
823                    }
824                }
825                result.SetStatus (eReturnStatusSuccessFinishResult);
826            }
827        }
828        return result.Succeeded();
829    }
830protected:
831
832    CommandOptions m_options;
833};
834
835lldb::OptionDefinition
836CommandObjectFrameVariable::CommandOptions::g_option_table[] =
837{
838{ LLDB_OPT_SET_1, false, "debug",      'D', no_argument,       NULL, 0, eArgTypeNone,    "Enable verbose debug information."},
839{ LLDB_OPT_SET_1, false, "depth",      'd', required_argument, NULL, 0, eArgTypeCount,   "Set the max recurse depth when dumping aggregate types (default is infinity)."},
840{ LLDB_OPT_SET_1, false, "show-globals",'g', no_argument,      NULL, 0, eArgTypeNone,    "Show the current frame source file global and static variables."},
841{ 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)."},
842{ LLDB_OPT_SET_1, false, "location",   'L', no_argument,       NULL, 0, eArgTypeNone,    "Show variable location information."},
843{ 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)."},
844{ LLDB_OPT_SET_1, false, "no-args",    'a', no_argument,       NULL, 0, eArgTypeNone,    "Omit function arguments."},
845{ LLDB_OPT_SET_1, false, "no-locals",  'l', no_argument,       NULL, 0, eArgTypeNone,    "Omit local variables."},
846{ LLDB_OPT_SET_1, false, "show-types", 't', no_argument,       NULL, 0, eArgTypeNone,    "Show variable types when dumping values."},
847{ LLDB_OPT_SET_1, false, "no-summary", 'y', no_argument,       NULL, 0, eArgTypeNone,    "Omit summary information."},
848{ LLDB_OPT_SET_1, false, "scope",      's', no_argument,       NULL, 0, eArgTypeNone,    "Show variable scope (argument, local, global, static)."},
849{ LLDB_OPT_SET_1, false, "objc",       'o', no_argument,       NULL, 0, eArgTypeNone,    "When looking up a variable by name (--name), print as an Objective-C object."},
850{ 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)."},
851{ LLDB_OPT_SET_1, false, "regex",      'r', no_argument,       NULL, 0, eArgTypeRegularExpression,    "The <variable-name> argument for name lookups are regular expressions."},
852{ 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL }
853};
854#pragma mark CommandObjectMultiwordFrame
855
856//-------------------------------------------------------------------------
857// CommandObjectMultiwordFrame
858//-------------------------------------------------------------------------
859
860CommandObjectMultiwordFrame::CommandObjectMultiwordFrame (CommandInterpreter &interpreter) :
861    CommandObjectMultiword (interpreter,
862                            "frame",
863                            "A set of commands for operating on the current thread's frames.",
864                            "frame <subcommand> [<subcommand-options>]")
865{
866    LoadSubCommand ("info",   CommandObjectSP (new CommandObjectFrameInfo (interpreter)));
867    LoadSubCommand ("select", CommandObjectSP (new CommandObjectFrameSelect (interpreter)));
868    LoadSubCommand ("variable", CommandObjectSP (new CommandObjectFrameVariable (interpreter)));
869}
870
871CommandObjectMultiwordFrame::~CommandObjectMultiwordFrame ()
872{
873}
874
875