Added a work in the DWARF parser when we parse an array that ends up having

no elements so that they at least have 1 element. 

Added the ability to show the declaration location of variables to the 
"frame variables" with the "--show-declaration" option ("-c" for short).

Changed the "frame variables" command over to use the value object code
so that we use the same code path as the public API does when accessing and
displaying variable values.

llvm-svn: 113733
This commit is contained in:
Greg Clayton 2010-09-13 02:37:44 +00:00
parent 0c5550a998
commit a134cc1bf8
3 changed files with 126 additions and 50 deletions

View File

@ -205,10 +205,11 @@ public:
case 'r': use_regex = true; break;
case 'a': show_args = false; break;
case 'l': show_locals = false; break;
case 'g': show_globals = false; break;
case 'g': show_globals = true; break;
case 't': show_types = false; break;
case 'y': show_summary = false; break;
case 'L': show_location= true; break;
case 'c': show_decl = true; break;
case 'D': debug = true; break;
case 'd':
max_depth = Args::StringToUInt32 (option_arg, UINT32_MAX, 0, &success);
@ -223,10 +224,7 @@ public:
break;
case 'G':
{
ConstString const_string (option_arg);
globals.push_back(const_string);
}
globals.push_back(ConstString (option_arg));
break;
case 's':
@ -251,11 +249,12 @@ public:
use_regex = false;
show_args = true;
show_locals = true;
show_globals = true;
show_globals = false;
show_types = true;
show_scope = false;
show_summary = true;
show_location = false;
show_decl = false;
debug = false;
max_depth = UINT32_MAX;
ptr_depth = 0;
@ -272,16 +271,17 @@ public:
static lldb::OptionDefinition g_option_table[];
std::string name;
bool use_objc;
bool use_regex;
bool show_args;
bool show_locals;
bool show_globals;
bool show_types;
bool show_scope; // local/arg/global/static
bool show_summary;
bool show_location;
bool debug;
bool use_objc:1,
use_regex:1,
show_args:1,
show_locals:1,
show_globals:1,
show_types:1,
show_scope:1,
show_summary:1,
show_location:1,
show_decl:1,
debug:1;
uint32_t max_depth; // The depth to print when dumping concrete (not pointers) aggreate values
uint32_t ptr_depth; // The default depth that is dumped when we find pointers
std::vector<ConstString> globals;
@ -522,16 +522,16 @@ public:
}
else
{
VariableList variable_list;
Stream &s = result.GetOutputStream();
bool get_file_globals = true;
VariableList *variable_list = exe_ctx.frame->GetVariableList (get_file_globals);
bool show_inlined = true; // TODO: Get this from the process
SymbolContext frame_sc = exe_ctx.frame->GetSymbolContext (eSymbolContextEverything);
if (exe_ctx.frame && frame_sc.block)
frame_sc.block->AppendVariables(true, true, show_inlined, &variable_list);
VariableSP var_sp;
ValueObjectSP valobj_sp;
//ValueObjectList &valobj_list = exe_ctx.frame->GetValueObjectList();
const char *name_cstr = NULL;
bool show_fullpaths = true;
size_t idx;
if (!m_options.globals.empty())
{
@ -563,7 +563,13 @@ public:
if (valobj_sp)
{
DumpValueObject (result, exe_ctx.frame, valobj_sp.get(), name_cstr, m_options.ptr_depth, 0, m_options.max_depth, false);
result.GetOutputStream().EOL();
if (m_options.show_decl && var_sp->GetDeclaration ().GetFile())
{
var_sp->GetDeclaration ().Dump (&s);
}
s.EOL();
}
}
}
@ -571,12 +577,9 @@ public:
}
}
if (fail_count)
{
result.SetStatus (eReturnStatusFailed);
}
}
if (command.GetArgumentCount() > 0)
else if (command.GetArgumentCount() > 0)
{
// If we have any args to the variable command, we will make
// variable objects from them...
@ -599,7 +602,7 @@ public:
else
name_const_string.SetCStringWithLength (var_path.c_str(), separator_idx);
var_sp = variable_list.FindVariable(name_const_string);
var_sp = variable_list->FindVariable(name_const_string);
if (var_sp)
{
valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp);
@ -714,8 +717,22 @@ public:
if (valobj_sp)
{
DumpValueObject (result, exe_ctx.frame, valobj_sp.get(), name_cstr, ptr_depth, 0, m_options.max_depth, m_options.use_objc);
result.GetOutputStream().EOL();
if (m_options.show_decl && var_sp->GetDeclaration ().GetFile())
{
var_sp->GetDeclaration ().DumpStopContext (&s, false);
s.PutCString (": ");
}
DumpValueObject (result,
exe_ctx.frame,
valobj_sp.get(),
name_cstr,
ptr_depth,
0,
m_options.max_depth,
m_options.use_objc);
s.EOL();
}
}
else
@ -727,48 +744,39 @@ public:
}
else
{
if (m_options.show_globals)
{
if (frame_sc.comp_unit)
{
variable_list.AddVariables (frame_sc.comp_unit->GetVariableList(true).get());
}
}
const uint32_t num_variables = variable_list.GetSize();
const uint32_t num_variables = variable_list->GetSize();
if (num_variables > 0)
{
for (uint32_t i=0; i<num_variables; i++)
{
Variable *variable = variable_list.GetVariableAtIndex(i).get();
VariableSP var_sp (variable_list->GetVariableAtIndex(i));
bool dump_variable = true;
switch (variable->GetScope())
switch (var_sp->GetScope())
{
case eValueTypeVariableGlobal:
dump_variable = m_options.show_globals;
if (dump_variable && m_options.show_scope)
result.GetOutputStream().PutCString("GLOBAL: ");
s.PutCString("GLOBAL: ");
break;
case eValueTypeVariableStatic:
dump_variable = m_options.show_globals;
if (dump_variable && m_options.show_scope)
result.GetOutputStream().PutCString("STATIC: ");
s.PutCString("STATIC: ");
break;
case eValueTypeVariableArgument:
dump_variable = m_options.show_args;
if (dump_variable && m_options.show_scope)
result.GetOutputStream().PutCString(" ARG: ");
s.PutCString(" ARG: ");
break;
case eValueTypeVariableLocal:
dump_variable = m_options.show_locals;
if (dump_variable && m_options.show_scope)
result.GetOutputStream().PutCString(" LOCAL: ");
s.PutCString(" LOCAL: ");
break;
default:
@ -776,7 +784,33 @@ public:
}
if (dump_variable)
DumpVariable (result, &exe_ctx, variable);
{
//DumpVariable (result, &exe_ctx, var_sp.get());
// Use the variable object code to make sure we are
// using the same APIs as the the public API will be
// using...
valobj_sp = exe_ctx.frame->GetValueObjectForFrameVariable (var_sp);
if (valobj_sp)
{
if (m_options.show_decl && var_sp->GetDeclaration ().GetFile())
{
var_sp->GetDeclaration ().DumpStopContext (&s, false);
s.PutCString (": ");
}
DumpValueObject (result,
exe_ctx.frame,
valobj_sp.get(),
name_cstr,
m_options.ptr_depth,
0,
m_options.max_depth,
m_options.use_objc);
s.EOL();
}
}
}
}
}
@ -792,11 +826,12 @@ protected:
lldb::OptionDefinition
CommandObjectFrameVariable::CommandOptions::g_option_table[] =
{
{ LLDB_OPT_SET_1, false, "debug", 'D', no_argument, NULL, 0, NULL, "Show verbose debug information."},
{ LLDB_OPT_SET_1, false, "debug", 'D', no_argument, NULL, 0, NULL, "Enable verbose debug information."},
{ LLDB_OPT_SET_1, false, "depth", 'd', required_argument, NULL, 0, "<count>", "Set the max recurse depth when dumping aggregate types (default is infinity)."},
{ LLDB_OPT_SET_1, false, "globals", 'g', no_argument, NULL, 0, NULL, "List global and static variables for the current stack frame source file."},
{ 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)."},
{ LLDB_OPT_SET_1, false, "show-globals",'g', no_argument, NULL, 0, NULL, "Show the current frame source file global and static variables."},
{ LLDB_OPT_SET_1, false, "find-global",'G', required_argument, NULL, 0, NULL, "Find a global variable by name (which might not be in the current stack frame source file)."},
{ LLDB_OPT_SET_1, false, "location", 'L', no_argument, NULL, 0, NULL, "Show variable location information."},
{ LLDB_OPT_SET_1, false, "show-declaration", 'c', no_argument, NULL, 0, NULL, "Show variable declaration information (source file and line where the variable was declared)."},
{ 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."},
{ LLDB_OPT_SET_1, false, "no-args", 'a', no_argument, NULL, 0, NULL, "Omit function arguments."},
{ LLDB_OPT_SET_1, false, "no-locals", 'l', no_argument, NULL, 0, NULL, "Omit local variables."},

View File

@ -133,6 +133,32 @@ ValueObjectVariable::UpdateValue (ExecutionContextScope *exe_scope)
// their own values as needed. If this variable is a simple
// type, we read all data for it into m_data.
// Make sure this type has a value before we try and read it
// If we have a file address, convert it to a load address if we can.
if (value_type == Value::eValueTypeFileAddress && exe_ctx.process)
{
lldb::addr_t file_addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
if (file_addr != LLDB_INVALID_ADDRESS)
{
SymbolContext var_sc;
variable->CalculateSymbolContext(&var_sc);
if (var_sc.module_sp)
{
ObjectFile *objfile = var_sc.module_sp->GetObjectFile();
if (objfile)
{
Address so_addr(file_addr, objfile->GetSectionList());
lldb::addr_t load_addr = so_addr.GetLoadAddress (exe_ctx.process);
if (load_addr != LLDB_INVALID_ADDRESS)
{
m_value.SetValueType(Value::eValueTypeLoadAddress);
m_value.GetScalar() = load_addr;
}
}
}
}
}
if (ClangASTContext::IsAggregateType (GetOpaqueClangQualType()))
{
// this value object represents an aggregate type whose

View File

@ -3064,6 +3064,9 @@ SymbolFileDWARF::ParseType(const SymbolContext& sc, const DWARFCompileUnit* dwar
{
std::vector<uint64_t> element_orders;
ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
// We have an array that claims to have no members, lets give it at least one member...
if (element_orders.empty())
element_orders.push_back (1);
if (byte_stride == 0 && bit_stride == 0)
byte_stride = element_type->GetByteSize();
void *array_element_type = element_type->GetOpaqueClangQualType();
@ -3357,6 +3360,7 @@ SymbolFileDWARF::ParseVariableDIE
if (num_attributes > 0)
{
const char *name = NULL;
const char *mangled = NULL;
Declaration decl;
uint32_t i;
TypeSP type_sp;
@ -3378,6 +3382,7 @@ SymbolFileDWARF::ParseVariableDIE
case DW_AT_decl_line: decl.SetLine(form_value.Unsigned()); break;
case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
case DW_AT_name: name = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
case DW_AT_type: var_type = GetUniquedTypeForDIEOffset(form_value.Reference(dwarf_cu), type_sp, 0, 0, false); break;
case DW_AT_external: is_external = form_value.Unsigned() != 0; break;
case DW_AT_location:
@ -3427,7 +3432,17 @@ SymbolFileDWARF::ParseVariableDIE
{
assert(var_type != DIE_IS_BEING_PARSED);
ConstString var_name(name);
ConstString var_name;
if (mangled)
{
Mangled mangled_var_name (mangled, true);
var_name = mangled_var_name.GetDemangledName();
}
if (!var_name && name)
{
var_name.SetCString(name);
}
ValueType scope = eValueTypeInvalid;