blob: 7a6592b9b84ce25e8f371f100d802d48053725ef [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- CommandObjectVariable.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 "CommandObjectVariable.h"
11
12// C Includes
13// C++ Includes
14// Other libraries and framework includes
15// Project includes
Jim Ingham84cdc152010-06-15 19:49:27 +000016#include "lldb/Interpreter/Options.h"
Chris Lattner24943d22010-06-08 16:52:24 +000017#include "lldb/Core/Module.h"
18#include "lldb/Core/StreamFile.h"
19#include "lldb/Core/Value.h"
20#include "lldb/Core/ValueObject.h"
21#include "lldb/Core/ValueObjectVariable.h"
22
23#include "lldb/Interpreter/CommandInterpreter.h"
24#include "lldb/Interpreter/CommandReturnObject.h"
25
Greg Clayton1674b122010-07-21 22:12:05 +000026#include "lldb/Symbol/ClangASTType.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "lldb/Symbol/ClangASTContext.h"
28#include "lldb/Symbol/ObjectFile.h"
29#include "lldb/Symbol/SymbolContext.h"
30#include "lldb/Symbol/Type.h"
31#include "lldb/Symbol/Variable.h"
32#include "lldb/Symbol/VariableList.h"
33
34#include "lldb/Target/Process.h"
35#include "lldb/Target/StackFrame.h"
36#include "lldb/Target/Target.h"
37
38using namespace lldb;
39using namespace lldb_private;
40
41//void
42//DumpValueObjectValues (Stream *sout, const char *root_valobj_name, ValueObjectSP& valobj_sp, bool follow_ptrs_and_refs, uint32_t curr_depth, uint32_t max_depth)
43//{
44// ValueObject *valobj = valobj_sp.get();
45// if (valobj)
46// {
47// const char *name_cstr = valobj->GetName().AsCString(NULL);
48// const char *val_cstr = valobj->GetValueAsCString();
49// const char *loc_cstr = valobj->GetLocationAsCString();
50// const char *type_cstr = valobj->GetTypeName().AsCString();
51// const char *sum_cstr = valobj->GetSummaryAsCString();
52// const char *err_cstr = valobj->GetError().AsCString();
53// // Indent
54// sout->Indent();
55// if (root_valobj_name)
56// {
57// sout->Printf ("%s = ", root_valobj_name);
58// }
59//
60// if (name_cstr)
61// sout->Printf ("%s => ", name_cstr);
62//
63// sout->Printf ("ValueObject{%u}", valobj->GetID());
64// const uint32_t num_children = valobj->GetNumChildren();
65//
66// if (type_cstr)
67// sout->Printf (", type = '%s'", type_cstr);
68//
69// if (loc_cstr)
70// sout->Printf (", location = %s", loc_cstr);
71//
72// sout->Printf (", num_children = %u", num_children);
73//
74// if (val_cstr)
75// sout->Printf (", value = %s", val_cstr);
76//
77// if (err_cstr)
78// sout->Printf (", error = %s", err_cstr);
79//
80// if (sum_cstr)
81// sout->Printf (", summary = %s", sum_cstr);
82//
83// sout->EOL();
84// bool is_ptr_or_ref = ClangASTContext::IsPointerOrReferenceType (valobj->GetOpaqueClangQualType());
85// if (!follow_ptrs_and_refs && is_ptr_or_ref)
86// return;
87//
88// if (curr_depth < max_depth)
89// {
90// for (uint32_t idx=0; idx<num_children; ++idx)
91// {
92// ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true));
93// if (child_sp.get())
94// {
95// sout->IndentMore();
96// DumpValueObjectValues (sout, NULL, child_sp, follow_ptrs_and_refs, curr_depth + 1, max_depth);
97// sout->IndentLess();
98// }
99// }
100// }
101// }
102//}
103
104//----------------------------------------------------------------------
105// List images with associated information
106//----------------------------------------------------------------------
107class CommandObjectVariableList : public CommandObject
108{
109public:
110
111 class CommandOptions : public Options
112 {
113 public:
114
115 CommandOptions () :
116 Options()
117 {
118 ResetOptionValues ();
119 }
120
121 virtual
122 ~CommandOptions ()
123 {
124 }
125
126 virtual Error
127 SetOptionValue (int option_idx, const char *option_arg)
128 {
129 Error error;
130 bool success;
131 char short_option = (char) m_getopt_table[option_idx].val;
132 switch (short_option)
133 {
134 case 'o': use_objc = true; break;
135 case 'n': name = option_arg; break;
136 case 'r': use_regex = true; break;
137 case 'a': show_args = false; break;
138 case 'l': show_locals = false; break;
139 case 'g': show_globals = false; break;
140 case 't': show_types = false; break;
141 case 'y': show_summary = false; break;
142 case 'L': show_location= true; break;
143 case 'D': debug = true; break;
144 case 'd':
145 max_depth = Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success);
146 if (!success)
147 error.SetErrorStringWithFormat("Invalid max depth '%s'.\n", option_arg);
148 break;
149
150 case 'p':
151 ptr_depth = Args::StringToUInt32 (option_arg, 0, 0, &success);
152 if (!success)
153 error.SetErrorStringWithFormat("Invalid pointer depth '%s'.\n", option_arg);
154 break;
155
156 case 'G':
157 {
158 ConstString const_string (option_arg);
159 globals.push_back(const_string);
160 }
161 break;
162
163 case 's':
164 show_scope = true;
165 break;
166
167 default:
168 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
169 break;
170 }
171
172 return error;
173 }
174
175 void
176 ResetOptionValues ()
177 {
178 Options::ResetOptionValues();
179
180 name.clear();
181 use_objc = false;
182 use_regex = false;
183 show_args = true;
184 show_locals = true;
185 show_globals = true;
186 show_types = true;
187 show_scope = false;
188 show_summary = true;
189 show_location = false;
190 debug = false;
191 max_depth = UINT32_MAX;
192 ptr_depth = 0;
193 globals.clear();
194 }
195
196 const lldb::OptionDefinition*
197 GetDefinitions ()
198 {
199 return g_option_table;
200 }
201
202 // Options table: Required for subclasses of Options.
203
204 static lldb::OptionDefinition g_option_table[];
205 std::string name;
206 bool use_objc;
207 bool use_regex;
208 bool show_args;
209 bool show_locals;
210 bool show_globals;
211 bool show_types;
212 bool show_scope; // local/arg/global/static
213 bool show_summary;
214 bool show_location;
215 bool debug;
216 uint32_t max_depth; // The depth to print when dumping concrete (not pointers) aggreate values
217 uint32_t ptr_depth; // The default depth that is dumped when we find pointers
218 std::vector<ConstString> globals;
219 // Instance variables to hold the values for command options.
220 };
221
222 CommandObjectVariableList () :
223 CommandObject (
224 "variable list",
225 "Show specified argument, local variable, static variable or global variable. If none specified, list them all.",
226 "variable list [<cmd-options>] [<var-name1> [<var-name2>...]]")
227 {
228 }
229
230 virtual
231 ~CommandObjectVariableList ()
232 {
233 }
234
235 virtual
236 Options *
237 GetOptions ()
238 {
239 return &m_options;
240 }
241
242 void
243 DumpVariable (CommandReturnObject &result, ExecutionContext *exe_ctx, Variable *variable)
244 {
245 if (variable)
246 {
247 Stream &s = result.GetOutputStream();
248 DWARFExpression &expr = variable->LocationExpression();
249 Value expr_result;
250 Error expr_error;
251 Type *variable_type = variable->GetType();
252 bool expr_success = expr.Evaluate(exe_ctx, NULL, NULL, expr_result, &expr_error);
253
254 if (m_options.debug)
255 s.Printf ("Variable{0x%8.8x}: ", variable->GetID());
256
257 if (!expr_success)
258 s.Printf ("%s = ERROR (%s)", variable->GetName().AsCString(NULL), expr_error.AsCString());
259 else
260 {
261 Value::ValueType expr_value_type = expr_result.GetValueType();
262 switch (expr_value_type)
263 {
264 case Value::eValueTypeScalar:
265 s.Printf ("%s = ", variable->GetName().AsCString(NULL));
266 if (variable_type)
267 {
268 DataExtractor data;
269 if (expr_result.ResolveValue (exe_ctx, NULL).GetData (data))
270 variable_type->DumpValue (exe_ctx, &s, data, 0, m_options.show_types, m_options.show_summary, m_options.debug);
271 }
272 break;
273
274 case Value::eValueTypeFileAddress:
275 case Value::eValueTypeLoadAddress:
276 case Value::eValueTypeHostAddress:
277 {
278 s.Printf ("%s = ", variable->GetName().AsCString(NULL));
279 lldb::addr_t addr = LLDB_INVALID_ADDRESS;
280 lldb::AddressType addr_type = eAddressTypeLoad;
281
282 if (expr_value_type == Value::eValueTypeFileAddress)
283 {
284 lldb::addr_t file_addr = expr_result.ResolveValue (exe_ctx, NULL).ULongLong(LLDB_INVALID_ADDRESS);
285 SymbolContext var_sc;
286 variable->CalculateSymbolContext(&var_sc);
287 if (var_sc.module_sp)
288 {
289 ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
290 if (objfile)
291 {
292 Address so_addr(file_addr, objfile->GetSectionList());
293 addr = so_addr.GetLoadAddress(exe_ctx->process);
294 }
295 if (addr == LLDB_INVALID_ADDRESS)
296 {
297 result.GetErrorStream().Printf ("error: %s is not loaded", var_sc.module_sp->GetFileSpec().GetFilename().AsCString());
298 }
299 }
300 else
301 {
302 result.GetErrorStream().Printf ("error: unable to resolve the variable address 0x%llx", file_addr);
303 }
304 }
305 else
306 {
307 if (expr_value_type == Value::eValueTypeHostAddress)
308 addr_type = eAddressTypeHost;
309 addr = expr_result.ResolveValue (exe_ctx, NULL).ULongLong(LLDB_INVALID_ADDRESS);
310 }
311
312 if (addr != LLDB_INVALID_ADDRESS)
313 {
314 if (m_options.debug)
315 s.Printf("@ 0x%8.8llx, value = ", addr);
316 variable_type->DumpValueInMemory (exe_ctx, &s, addr, addr_type, m_options.show_types, m_options.show_summary, m_options.debug);
317 }
318 }
319 break;
320 }
321 }
322 s.EOL();
323 }
324 }
325
326 void
327 DumpValueObject (CommandReturnObject &result,
328 ExecutionContextScope *exe_scope,
329 ValueObject *valobj,
330 const char *root_valobj_name,
331 uint32_t ptr_depth,
332 uint32_t curr_depth,
333 uint32_t max_depth,
334 bool use_objc)
335 {
336 if (valobj)
337 {
338 Stream &s = result.GetOutputStream();
339
340 //const char *loc_cstr = valobj->GetLocationAsCString();
341 if (m_options.show_location)
342 {
343 s.Printf("@ %s: ", valobj->GetLocationAsCString(exe_scope));
344 }
345 if (m_options.debug)
346 s.Printf ("%p ValueObject{%u} ", valobj, valobj->GetID());
347
348 s.Indent();
349
350 if (m_options.show_types)
351 s.Printf("(%s) ", valobj->GetTypeName().AsCString());
352
353 const char *name_cstr = root_valobj_name ? root_valobj_name : valobj->GetName().AsCString("");
354 s.Printf ("%s = ", name_cstr);
355
356 const char *val_cstr = valobj->GetValueAsCString(exe_scope);
357 const char *err_cstr = valobj->GetError().AsCString();
358
359 if (err_cstr)
360 {
361 s.Printf ("error: %s\n", err_cstr);
362 }
363 else
364 {
365 const char *sum_cstr = valobj->GetSummaryAsCString(exe_scope);
366
367 const bool is_aggregate = ClangASTContext::IsAggregateType (valobj->GetOpaqueClangQualType());
368
369 if (val_cstr)
370 s.PutCString(val_cstr);
371
372 if (sum_cstr)
373 s.Printf(" %s", sum_cstr);
374
375 if (use_objc)
376 {
377 if (!ClangASTContext::IsPointerType (valobj->GetOpaqueClangQualType()))
378 return;
379
380 if (!valobj->GetValueIsValid())
381 return;
382
383 Process *process = exe_scope->CalculateProcess();
384
385 if (!process)
386 return;
387
388 Scalar scalar;
389
Greg Clayton1674b122010-07-21 22:12:05 +0000390 if (!ClangASTType::GetValueAsScalar (valobj->GetClangAST(),
391 valobj->GetOpaqueClangQualType(),
392 valobj->GetDataExtractor(),
393 0,
394 valobj->GetByteSize(),
395 scalar))
Chris Lattner24943d22010-06-08 16:52:24 +0000396 return;
397
398 ConstString po_output;
399
400 ExecutionContext exe_ctx;
401 exe_scope->Calculate(exe_ctx);
402
403 Value val(scalar);
404 val.SetContext(Value::eContextTypeOpaqueClangQualType,
405 ClangASTContext::GetVoidPtrType(valobj->GetClangAST(), false));
406
407 if (!process->GetObjCObjectPrinter().PrintObject(po_output, val, exe_ctx))
408 return;
409
410 s.Printf("\n%s\n", po_output.GetCString());
411
412 return;
413 }
414
415
416 if (curr_depth < max_depth)
417 {
418 if (is_aggregate)
419 s.PutChar('{');
420
421 bool is_ptr_or_ref = ClangASTContext::IsPointerOrReferenceType (valobj->GetOpaqueClangQualType());
422
423 if (is_ptr_or_ref && ptr_depth == 0)
424 return;
425
426 const uint32_t num_children = valobj->GetNumChildren();
427 if (num_children)
428 {
429 s.IndentMore();
430 for (uint32_t idx=0; idx<num_children; ++idx)
431 {
432 ValueObjectSP child_sp(valobj->GetChildAtIndex(idx, true));
433 if (child_sp.get())
434 {
435 s.EOL();
436 DumpValueObject (result,
437 exe_scope,
438 child_sp.get(),
439 NULL,
440 is_ptr_or_ref ? ptr_depth - 1 : ptr_depth,
441 curr_depth + 1,
442 max_depth,
443 false);
444 if (idx + 1 < num_children)
445 s.PutChar(',');
446 }
447 }
448 s.IndentLess();
449 }
450 if (is_aggregate)
451 {
452 s.EOL();
453 s.Indent("}");
454 }
455 }
456 else
457 {
458 if (is_aggregate)
459 {
460 s.PutCString("{...}");
461 }
462 }
463
464 }
465 }
466 }
467
468 virtual bool
Greg Clayton63094e02010-06-23 01:19:29 +0000469 Execute
470 (
471 CommandInterpreter &interpreter,
472 Args& command,
473 CommandReturnObject &result
474 )
Chris Lattner24943d22010-06-08 16:52:24 +0000475 {
Greg Clayton63094e02010-06-23 01:19:29 +0000476 ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext());
Chris Lattner24943d22010-06-08 16:52:24 +0000477 if (exe_ctx.frame == NULL)
478 {
479 result.AppendError ("invalid frame");
480 result.SetStatus (eReturnStatusFailed);
481 return false;
482 }
483 else
484 {
485 VariableList variable_list;
486
487 SymbolContext frame_sc = exe_ctx.frame->GetSymbolContext (eSymbolContextEverything);
488 if (exe_ctx.frame && frame_sc.block)
489 frame_sc.block->AppendVariables(true, true, &variable_list);
490 VariableSP var_sp;
491 ValueObjectSP valobj_sp;
492 //ValueObjectList &valobj_list = exe_ctx.frame->GetValueObjectList();
493 const char *name_cstr = NULL;
494 size_t idx;
495 if (!m_options.globals.empty())
496 {
497 uint32_t fail_count = 0;
Greg Clayton63094e02010-06-23 01:19:29 +0000498 if (exe_ctx.target)
Chris Lattner24943d22010-06-08 16:52:24 +0000499 {
500 const size_t num_globals = m_options.globals.size();
501 for (idx = 0; idx < num_globals; ++idx)
502 {
503 VariableList global_var_list;
Greg Clayton63094e02010-06-23 01:19:29 +0000504 const uint32_t num_matching_globals = exe_ctx.target->GetImages().FindGlobalVariables (m_options.globals[idx], true, UINT32_MAX, global_var_list);
Chris Lattner24943d22010-06-08 16:52:24 +0000505
506 if (num_matching_globals == 0)
507 {
508 ++fail_count;
509 result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", m_options.globals[idx].AsCString());
510 }
511 else
512 {
513 for (uint32_t global_idx=0; global_idx<num_matching_globals; ++global_idx)
514 {
515 var_sp = global_var_list.GetVariableAtIndex(global_idx);
516 if (var_sp)
517 {
518 valobj_sp = exe_ctx.frame->GetValueObjectList().FindValueObjectByValueName (m_options.globals[idx].AsCString());
519 if (!valobj_sp)
520 valobj_sp.reset (new ValueObjectVariable (var_sp));
521
522 if (valobj_sp)
523 {
524 exe_ctx.frame->GetValueObjectList().Append (valobj_sp);
525 DumpValueObject (result, exe_ctx.frame, valobj_sp.get(), name_cstr, m_options.ptr_depth, 0, m_options.max_depth, false);
526 result.GetOutputStream().EOL();
527 }
528 }
529 }
530 }
531 }
532 }
533 if (fail_count)
534 {
535 result.SetStatus (eReturnStatusFailed);
536 }
537 }
538
539 if (command.GetArgumentCount() > 0)
540 {
541 // If we have any args to the variable command, we will make
542 // variable objects from them...
543 for (idx = 0; (name_cstr = command.GetArgumentAtIndex(idx)) != NULL; ++idx)
544 {
545 uint32_t ptr_depth = m_options.ptr_depth;
546 // If first character is a '*', then show pointer contents
547 if (name_cstr[0] == '*')
548 {
549 ++ptr_depth;
550 name_cstr++; // Skip the '*'
551 }
552
553 std::string var_path (name_cstr);
554 size_t separator_idx = var_path.find_first_of(".-[");
555
556 ConstString name_const_string;
557 if (separator_idx == std::string::npos)
558 name_const_string.SetCString (var_path.c_str());
559 else
560 name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
561
562 var_sp = variable_list.FindVariable(name_const_string);
563 if (var_sp)
564 {
565 //DumpVariable (result, &exe_ctx, var_sp.get());
566 // TODO: redo history variables using a different map
567// if (var_path[0] == '$')
568// valobj_sp = valobj_list.FindValueObjectByValueObjectName (name_const_string.GetCString());
569// else
570 valobj_sp = exe_ctx.frame->GetValueObjectList().FindValueObjectByValueName (name_const_string.GetCString());
571
572 if (!valobj_sp)
573 {
574 valobj_sp.reset (new ValueObjectVariable (var_sp));
575 exe_ctx.frame->GetValueObjectList().Append (valobj_sp);
576 }
577
578 var_path.erase (0, name_const_string.GetLength ());
579 // We are dumping at least one child
580 while (separator_idx != std::string::npos)
581 {
582 // Calculate the next separator index ahead of time
583 ValueObjectSP child_valobj_sp;
584 const char separator_type = var_path[0];
585 switch (separator_type)
586 {
587
588 case '-':
589 if (var_path.size() >= 2 && var_path[1] != '>')
590 {
591 result.GetErrorStream().Printf ("error: invalid character in variable path starting at '%s'\n",
592 var_path.c_str());
593 var_path.clear();
594 valobj_sp.reset();
595 break;
596 }
597 var_path.erase (0, 1); // Remove the '-'
598 // Fall through
599 case '.':
600 {
601 var_path.erase (0, 1); // Remove the '.' or '>'
602 separator_idx = var_path.find_first_of(".-[");
603 ConstString child_name;
604 if (separator_idx == std::string::npos)
605 child_name.SetCString (var_path.c_str());
606 else
607 child_name.SetCStringWithLength(var_path.c_str(), separator_idx);
608
609 child_valobj_sp = valobj_sp->GetChildMemberWithName (child_name, true);
610 if (!child_valobj_sp)
611 {
612 result.GetErrorStream().Printf ("error: can't find child of '%s' named '%s'\n",
613 valobj_sp->GetName().AsCString(),
614 child_name.GetCString());
615 var_path.clear();
616 valobj_sp.reset();
617 break;
618 }
619 // Remove the child name from the path
620 var_path.erase(0, child_name.GetLength());
621 }
622 break;
623
624 case '[':
625 // Array member access, or treating pointer as an array
626 if (var_path.size() > 2) // Need at least two brackets and a number
627 {
628 char *end = NULL;
629 int32_t child_index = ::strtol (&var_path[1], &end, 0);
630 if (end && *end == ']')
631 {
632
633 if (valobj_sp->IsPointerType ())
634 {
635 child_valobj_sp = valobj_sp->GetSyntheticArrayMemberFromPointer (child_index, true);
636 }
637 else
638 {
639 child_valobj_sp = valobj_sp->GetChildAtIndex (child_index, true);
640 }
641
642 if (!child_valobj_sp)
643 {
644 result.GetErrorStream().Printf ("error: invalid array index %u in '%s'\n",
645 child_index,
646 valobj_sp->GetName().AsCString());
647 var_path.clear();
648 valobj_sp.reset();
649 break;
650 }
651
652 // Erase the array member specification '[%i]' where %i is the array index
653 var_path.erase(0, (end - var_path.c_str()) + 1);
654 separator_idx = var_path.find_first_of(".-[");
655
656 // Break out early from the switch since we were able to find the child member
657 break;
658 }
659 }
660 result.GetErrorStream().Printf ("error: invalid array member specification for '%s' starting at '%s'\n",
661 valobj_sp->GetName().AsCString(),
662 var_path.c_str());
663 var_path.clear();
664 valobj_sp.reset();
665 break;
666
667 break;
668
669 default:
670 result.GetErrorStream().Printf ("error: invalid character in variable path starting at '%s'\n",
671 var_path.c_str());
672 var_path.clear();
673 valobj_sp.reset();
674 separator_idx = std::string::npos;
675 break;
676 }
677
678 if (child_valobj_sp)
679 valobj_sp = child_valobj_sp;
680
681 if (var_path.empty())
682 break;
683
684 }
685
686 if (valobj_sp)
687 {
688 DumpValueObject (result, exe_ctx.frame, valobj_sp.get(), name_cstr, ptr_depth, 0, m_options.max_depth, m_options.use_objc);
689 result.GetOutputStream().EOL();
690 }
691 }
692 else
693 {
694 result.GetErrorStream().Printf ("error: unable to find any variables named '%s'\n", name_cstr);
695 var_path.clear();
696 }
697 }
698 }
699 else
700 {
701
702 if (m_options.show_globals)
703 {
704 if (frame_sc.comp_unit)
705 {
706 variable_list.AddVariables (frame_sc.comp_unit->GetVariableList(true).get());
707 }
708 }
709
710 const uint32_t num_variables = variable_list.GetSize();
711
712 if (num_variables > 0)
713 {
714 for (uint32_t i=0; i<num_variables; i++)
715 {
716 Variable *variable = variable_list.GetVariableAtIndex(i).get();
717 bool dump_variable = true;
718
719 switch (variable->GetScope())
720 {
721 case eValueTypeVariableGlobal:
722 dump_variable = m_options.show_globals;
723 if (dump_variable && m_options.show_scope)
724 result.GetOutputStream().PutCString("GLOBAL: ");
725 break;
726
727 case eValueTypeVariableStatic:
728 dump_variable = m_options.show_globals;
729 if (dump_variable && m_options.show_scope)
730 result.GetOutputStream().PutCString("STATIC: ");
731 break;
732
733 case eValueTypeVariableArgument:
734 dump_variable = m_options.show_args;
735 if (dump_variable && m_options.show_scope)
736 result.GetOutputStream().PutCString(" ARG: ");
737 break;
738
739 case eValueTypeVariableLocal:
740 dump_variable = m_options.show_locals;
741 if (dump_variable && m_options.show_scope)
742 result.GetOutputStream().PutCString(" LOCAL: ");
743 break;
744
745 default:
746 break;
747 }
748
749 if (dump_variable)
750 DumpVariable (result, &exe_ctx, variable);
751 }
752 }
753 }
754 result.SetStatus (eReturnStatusSuccessFinishResult);
755 }
756 return result.Succeeded();
757 }
758protected:
759
760 CommandOptions m_options;
761};
762
763lldb::OptionDefinition
764CommandObjectVariableList::CommandOptions::g_option_table[] =
765{
Jim Ingham34e9a982010-06-15 18:47:14 +0000766{ LLDB_OPT_SET_1, false, "debug", 'D', no_argument, NULL, 0, NULL, "Show verbose debug information."},
767{ LLDB_OPT_SET_1, false, "depth", 'd', required_argument, NULL, 0, "<count>", "Set the max recurse depth when dumping aggregate types (default is infinity)."},
768{ LLDB_OPT_SET_1, false, "globals", 'g', no_argument, NULL, 0, NULL, "List global and static variables for the current stack frame source file."},
769{ LLDB_OPT_SET_1, false, "global", 'G', required_argument, NULL, 0, NULL, "Find a global variable by name (which might not be in the current stack frame source file)."},
770{ LLDB_OPT_SET_1, false, "location", 'L', no_argument, NULL, 0, NULL, "Show variable location information."},
771{ LLDB_OPT_SET_1, false, "name", 'n', required_argument, NULL, 0, "<name>", "Lookup a variable by name or regex (--regex) for the current execution context."},
772{ LLDB_OPT_SET_1, false, "no-args", 'a', no_argument, NULL, 0, NULL, "Omit function arguments."},
773{ LLDB_OPT_SET_1, false, "no-locals", 'l', no_argument, NULL, 0, NULL, "Omit local variables."},
774{ LLDB_OPT_SET_1, false, "no-types", 't', no_argument, NULL, 0, NULL, "Omit variable type names."},
775{ LLDB_OPT_SET_1, false, "no-summary", 'y', no_argument, NULL, 0, NULL, "Omit summary information."},
776{ LLDB_OPT_SET_1, false, "scope", 's', no_argument, NULL, 0, NULL, "Show variable scope (argument, local, global, static)."},
777{ LLDB_OPT_SET_1, false, "objc", 'o', no_argument, NULL, 0, NULL, "When looking up a variable by name (--name), print as an Objective-C object."},
778{ LLDB_OPT_SET_1, false, "ptr-depth", 'p', required_argument, NULL, 0, "<count>", "The number of pointers to be traversed when dumping values (default is zero)."},
779{ LLDB_OPT_SET_1, false, "regex", 'r', no_argument, NULL, 0, NULL, "The <name> argument for name lookups are regular expressions."},
Chris Lattner24943d22010-06-08 16:52:24 +0000780{ 0, false, NULL, 0, 0, NULL, NULL, NULL, NULL }
781};
782
783//----------------------------------------------------------------------
784// CommandObjectVariable constructor
785//----------------------------------------------------------------------
Greg Clayton63094e02010-06-23 01:19:29 +0000786CommandObjectVariable::CommandObjectVariable(CommandInterpreter &interpreter) :
Chris Lattner24943d22010-06-08 16:52:24 +0000787 CommandObjectMultiword ("variable",
Greg Clayton63094e02010-06-23 01:19:29 +0000788 "Access program arguments, locals, static and global variables.",
789 "variable [list] ...")
Chris Lattner24943d22010-06-08 16:52:24 +0000790{
Greg Clayton63094e02010-06-23 01:19:29 +0000791 LoadSubCommand (interpreter, "list", CommandObjectSP (new CommandObjectVariableList ()));
Chris Lattner24943d22010-06-08 16:52:24 +0000792}
793
794//----------------------------------------------------------------------
795// Destructor
796//----------------------------------------------------------------------
797CommandObjectVariable::~CommandObjectVariable()
798{
799}
800
801
802
803