forked from OSchip/llvm-project
[lldb-mi] Fix expansion of anonymous structures and unions
A variable of type: struct S { union { int i1; unsigned u1; }; union { int i2; unsigned u2; }; }; had been impossible to evaluate in lldb-mi, because MI assigns '??' as the variable name to each of the unnamed unions after "-var-list-children" command. Also '??' incorrectly goes to 'exp' field which is treated by IDE as a structure field name and is displayed in watch window. The patch fixes this returning empty string as type name for unnamed union and assigning $N to variable name, where N is the field number in the parent entity. Patch from evgeny.leviant@gmail.com Reviewed by: clayborg, abidh Subscribers: lldb-commits Differential Revision: http://reviews.llvm.org/D13947 llvm-svn: 251176
This commit is contained in:
parent
c27d2f266e
commit
b5d425ecfb
|
@ -356,3 +356,45 @@ class MiVarTestCase(lldbmi_testcase.MiTestCaseBase):
|
|||
# Test for std::string
|
||||
self.runCmd("-var-create - * std_string")
|
||||
self.expect('\^done,name="var\d+",numchild="[0-9]+",value="\\\\"hello\\\\"",type="std::[\S]*?string",thread-id="1",has_more="0"')
|
||||
|
||||
@lldbmi_test
|
||||
@skipIfWindows #llvm.org/pr24452: Get lldb-mi working on Windows
|
||||
@skipIfFreeBSD # llvm.org/pr22411: Failure presumably due to known thread races
|
||||
@skipIfLinux # llvm.org/pr22841: lldb-mi tests fail on all Linux buildbots
|
||||
def test_lldbmi_var_create_for_unnamed_objects(self):
|
||||
"""Test that 'lldb-mi --interpreter' can expand unnamed structures and unions."""
|
||||
|
||||
self.spawnLldbMi(args = None)
|
||||
|
||||
# Load executable
|
||||
self.runCmd("-file-exec-and-symbols %s" % self.myexe)
|
||||
self.expect("\^done")
|
||||
|
||||
# Run to breakpoint
|
||||
line = line_number('main.cpp', '// BP_unnamed_objects_test')
|
||||
self.runCmd("-break-insert main.cpp:%d" % line)
|
||||
self.expect("\^done,bkpt={number=\"1\"")
|
||||
self.runCmd("-exec-run")
|
||||
self.expect("\^running")
|
||||
self.expect("\*stopped,reason=\"breakpoint-hit\"")
|
||||
|
||||
# Evaluate struct_with_unions type and its children
|
||||
self.runCmd("-var-create v0 * swu")
|
||||
self.expect('\^done,name="v0",numchild="2",value="\{\.\.\.\}",type="struct_with_unions",thread-id="1",has_more="0"')
|
||||
|
||||
self.runCmd("-var-list-children v0")
|
||||
|
||||
# inspect the first unnamed union
|
||||
self.runCmd("-var-list-children v0.$0")
|
||||
self.runCmd("-var-evaluate-expression v0.$0.u_i")
|
||||
self.expect('\^done,value="1"')
|
||||
|
||||
# inspect the second unnamed union
|
||||
self.runCmd("-var-list-children v0.$1")
|
||||
self.runCmd("-var-evaluate-expression v0.$1.u1")
|
||||
self.expect('\^done,value="-1"')
|
||||
# inspect unnamed structure
|
||||
self.runCmd("-var-list-children v0.$1.$1")
|
||||
self.runCmd("-var-evaluate-expression v0.$1.$1.s1")
|
||||
self.expect('\^done,value="-1"')
|
||||
|
||||
|
|
|
@ -27,6 +27,25 @@ struct pcomplex_type : complex_type
|
|||
|
||||
int pcomplex_type::si;
|
||||
|
||||
struct struct_with_unions
|
||||
{
|
||||
struct_with_unions(): u_i(1), u1(-1) {}
|
||||
union
|
||||
{
|
||||
int u_i;
|
||||
int u_j;
|
||||
};
|
||||
union
|
||||
{
|
||||
int u1;
|
||||
struct
|
||||
{
|
||||
short s1;
|
||||
short s2;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
void
|
||||
var_update_test(void)
|
||||
{
|
||||
|
@ -80,6 +99,13 @@ cpp_stl_types_test(void)
|
|||
// BP_cpp_stl_types_test
|
||||
}
|
||||
|
||||
void
|
||||
unnamed_objects_test(void)
|
||||
{
|
||||
struct_with_unions swu;
|
||||
// BP_unnamed_objects_test
|
||||
}
|
||||
|
||||
struct not_str
|
||||
{
|
||||
not_str(char _c, int _f)
|
||||
|
@ -119,6 +145,7 @@ main(int argc, char const *argv[])
|
|||
var_list_children_test();
|
||||
gdb_set_show_print_char_array_as_string_test();
|
||||
cpp_stl_types_test();
|
||||
unnamed_objects_test();
|
||||
gdb_set_show_print_expand_aggregates();
|
||||
gdb_set_show_print_aggregate_field_names();
|
||||
return 0; // BP_return
|
||||
|
|
|
@ -1015,7 +1015,9 @@ CMICmdCmdVarListChildren::Execute()
|
|||
lldb::SBValue member = rValue.GetChildAtIndex(i);
|
||||
const CMICmnLLDBUtilSBValue utilValue(member);
|
||||
const CMIUtilString strExp = utilValue.GetName();
|
||||
const CMIUtilString name(CMIUtilString::Format("%s.%s", rVarObjName.c_str(), strExp.c_str()));
|
||||
const CMIUtilString name(strExp.empty() ?
|
||||
CMIUtilString::Format("%s.$%u", rVarObjName.c_str(), i) :
|
||||
CMIUtilString::Format("%s.%s", rVarObjName.c_str(), strExp.c_str()));
|
||||
const MIuint nChildren = member.GetNumChildren();
|
||||
const CMIUtilString strThreadId(CMIUtilString::Format("%u", member.GetThread().GetIndexID()));
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ CMIUtilString
|
|||
CMICmnLLDBUtilSBValue::GetName() const
|
||||
{
|
||||
const char *pName = m_bValidSBValue ? m_rValue.GetName() : nullptr;
|
||||
const CMIUtilString text((pName != nullptr) ? pName : m_pUnkwn);
|
||||
const CMIUtilString text((pName != nullptr) ? pName : CMIUtilString());
|
||||
|
||||
return text;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue