ValueObject and SBValue's GetChildMemberWithName should look through anonymous structs

and unions the same way that C would.

<rdar://problem/11987906>

llvm-svn: 193016
This commit is contained in:
Jim Ingham 2013-10-18 23:53:55 +00:00
parent 768b917dc8
commit be40554915
2 changed files with 54 additions and 1 deletions

View File

@ -3522,7 +3522,17 @@ ClangASTType::GetIndexOfChildMemberWithName (const char *name,
field != field_end;
++field, ++child_idx)
{
if (field->getName().equals (name_sref))
llvm::StringRef field_name = field->getName();
if (field_name.empty())
{
ClangASTType field_type(m_ast,field->getType());
child_indexes.push_back(child_idx);
if (field_type.GetIndexOfChildMemberWithName(name, omit_empty_base_classes, child_indexes))
return child_indexes.size();
child_indexes.pop_back();
}
else if (field_name.equals (name_sref))
{
// We have to add on the number of base classes to this index!
child_indexes.push_back (child_idx + ClangASTContext::GetNumBaseClasses (cxx_record_decl, omit_empty_base_classes));

View File

@ -36,6 +36,11 @@ class AnonymousTestCase(TestBase):
self.buildDsym()
self.expr_null()
@dsym_test
def test_child_by_name(self):
self.buildDsym()
self.child_by_name()
@skipIfGcc # llvm.org/pr15036: LLDB generates an incorrect AST layout for an anonymous struct when DWARF is generated by GCC
@skipIfIcc # llvm.org/pr15036: LLDB generates an incorrect AST layout for an anonymous struct when DWARF is generated by ICC
@dwarf_test
@ -67,6 +72,11 @@ class AnonymousTestCase(TestBase):
self.buildDwarf()
self.expr_null()
@dwarf_test
def test_child_by_name_with_dwarf(self):
self.buildDsym()
self.child_by_name()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
@ -144,6 +154,39 @@ class AnonymousTestCase(TestBase):
self.expect("expression *(type_z *)pz",
substrs = ["Cannot access memory at address 0x0"], error = True)
def child_by_name(self):
exe = os.path.join (os.getcwd(), "a.out")
target = self.dbg.CreateTarget(exe)
self.assertTrue(target, VALID_TARGET)
break_in_main = target.BreakpointCreateBySourceRegex ('// Set breakpoint 2 here.', lldb.SBFileSpec("main.c"))
self.assertTrue(break_in_main, VALID_BREAKPOINT)
process = target.LaunchSimple (None, None, os.getcwd())
self.assertTrue (process, PROCESS_IS_VALID)
threads = lldbutil.get_threads_stopped_at_breakpoint (process, break_in_main)
if len(threads) != 1:
self.fail ("Failed to stop at breakpoint in main.")
thread = threads[0]
frame = thread.frames[0]
if not frame.IsValid():
self.fail ("Failed to get frame 0.")
var_n = frame.FindVariable("n")
if not var_n.IsValid():
self.fail ("Failed to get the variable 'n'")
elem_a = var_n.GetChildMemberWithName("a")
if not elem_a.IsValid():
self.fail ("Failed to get the element a in n")
error = lldb.SBError()
value = elem_a.GetValueAsSigned(error, 1000)
if not error.Success() or value != 0:
self.fail ("failed to get the correct value for element a in n")
if __name__ == '__main__':
import atexit