<rdar://problem/15180638>

Making GetNumberOfDirectBaseClasses() work for ObjC pointers, and for classes for which we don't have full debug info

llvm-svn: 192255
This commit is contained in:
Enrico Granata 2013-10-09 00:13:17 +00:00
parent 5f99ec0bf4
commit 99c8f7ae79
4 changed files with 113 additions and 18 deletions

View File

@ -2281,20 +2281,10 @@ ClangASTType::GetNumDirectBaseClasses () const
break;
case clang::Type::ObjCObjectPointer:
if (GetCompleteType())
{
const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
if (objc_class_type)
{
ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
if (class_interface_decl && class_interface_decl->getSuperClass())
count = 1;
}
}
count = GetPointeeType().GetNumDirectBaseClasses();
break;
case clang::Type::ObjCObject:
case clang::Type::ObjCInterface:
if (GetCompleteType())
{
const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
@ -2307,6 +2297,19 @@ ClangASTType::GetNumDirectBaseClasses () const
}
}
break;
case clang::Type::ObjCInterface:
if (GetCompleteType())
{
const ObjCInterfaceType *objc_interface_type = qual_type->getAs<ObjCInterfaceType>();
if (objc_interface_type)
{
ObjCInterfaceDecl *class_interface_decl = objc_interface_type->getInterface();
if (class_interface_decl && class_interface_decl->getSuperClass())
count = 1;
}
}
break;
case clang::Type::Typedef:
@ -2482,12 +2485,16 @@ ClangASTType::GetDirectBaseClassAtIndex (size_t idx, uint32_t *bit_offset_ptr) c
break;
case clang::Type::ObjCObjectPointer:
return GetPointeeType().GetDirectBaseClassAtIndex(idx,bit_offset_ptr);
case clang::Type::ObjCObject:
if (idx == 0 && GetCompleteType())
{
const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
if (objc_class_type)
{
ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
if (class_interface_decl)
{
ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
@ -2501,15 +2508,13 @@ ClangASTType::GetDirectBaseClassAtIndex (size_t idx, uint32_t *bit_offset_ptr) c
}
}
break;
case clang::Type::ObjCObject:
case clang::Type::ObjCInterface:
if (idx == 0 && GetCompleteType())
{
const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
if (objc_class_type)
const ObjCObjectType *objc_interface_type = qual_type->getAs<ObjCInterfaceType>();
if (objc_interface_type)
{
ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
ObjCInterfaceDecl *class_interface_decl = objc_interface_type->getInterface();
if (class_interface_decl)
{

View File

@ -0,0 +1,6 @@
LEVEL = ../../../make
OBJC_SOURCES := main.m
LDFLAGS = $(CFLAGS) -lobjc -framework AppKit
include $(LEVEL)/Makefile.rules

View File

@ -0,0 +1,75 @@
"""
Use lldb Python API to test base class resolution for ObjC classes
"""
import os, time
import re
import unittest2
import lldb, lldbutil
from lldbtest import *
class ObjCDynamicValueTestCase(TestBase):
mydir = os.path.join("lang", "objc", "objc-baseclass-sbtype")
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dsym_test
def test_get_baseclass_with_dsym(self):
"""Test fetching ObjC base class info."""
if self.getArchitecture() == 'i386':
# rdar://problem/9946499
self.skipTest("Dynamic types for ObjC V1 runtime not implemented")
self.buildDsym()
self.do_get_baseclass_info()
@unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
@python_api_test
@dwarf_test
def test_get_baseclass_with_dwarf(self):
"""Test fetching ObjC dynamic values."""
if self.getArchitecture() == 'i386':
# rdar://problem/9946499
self.skipTest("Dynamic types for ObjC V1 runtime not implemented")
self.buildDwarf()
self.do_get_baseclass_info()
def setUp(self):
# Call super's setUp().
TestBase.setUp(self)
self.line = line_number('main.m', '// Set breakpoint here.')
def do_get_baseclass_info(self):
"""Make sure we get dynamic values correctly both for compiled in classes and dynamic ones"""
exe = os.path.join(os.getcwd(), "a.out")
# Create a target from the debugger.
target = self.dbg.CreateTarget (exe)
self.assertTrue(target, VALID_TARGET)
# Set up our breakpoints:
target.BreakpointCreateByLocation('main.m', self.line)
process = target.LaunchSimple (None, None, os.getcwd())
self.assertTrue(process.GetState() == lldb.eStateStopped,
PROCESS_STOPPED)
button = self.frame().FindVariable("button")
button_ptr_type = button.GetType()
button_pte_type = button_ptr_type.GetPointeeType()
self.assertTrue(button_ptr_type.GetNumberOfDirectBaseClasses() == 1, "NSButton * has one base class")
self.assertTrue(button_pte_type.GetNumberOfDirectBaseClasses() == 1, "NSButton has one base class")
self.assertTrue(button_ptr_type.GetDirectBaseClassAtIndex(0).IsValid(), "NSButton * has a valid base class")
self.assertTrue(button_pte_type.GetDirectBaseClassAtIndex(0).IsValid(), "NSButton * has a valid base class")
self.assertTrue(button_ptr_type.GetDirectBaseClassAtIndex(0).GetName() == button_pte_type.GetDirectBaseClassAtIndex(0).GetName(), "NSButton and its pointer type don't agree on their base class")
if __name__ == '__main__':
import atexit
lldb.SBDebugger.Initialize()
atexit.register(lambda: lldb.SBDebugger.Terminate())
unittest2.main()

View File

@ -0,0 +1,9 @@
#import <AppKit/AppKit.h>
int main ()
{
NSButton *button = [NSButton new];
NSLog(@"a"); // Set breakpoint here.
return 0;
}