forked from OSchip/llvm-project
<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:
parent
5f99ec0bf4
commit
99c8f7ae79
|
@ -2281,20 +2281,10 @@ ClangASTType::GetNumDirectBaseClasses () const
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case clang::Type::ObjCObjectPointer:
|
case clang::Type::ObjCObjectPointer:
|
||||||
if (GetCompleteType())
|
count = GetPointeeType().GetNumDirectBaseClasses();
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case clang::Type::ObjCObject:
|
case clang::Type::ObjCObject:
|
||||||
case clang::Type::ObjCInterface:
|
|
||||||
if (GetCompleteType())
|
if (GetCompleteType())
|
||||||
{
|
{
|
||||||
const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
|
const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
|
||||||
|
@ -2307,6 +2297,19 @@ ClangASTType::GetNumDirectBaseClasses () const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case clang::Type::Typedef:
|
||||||
|
@ -2482,12 +2485,16 @@ ClangASTType::GetDirectBaseClassAtIndex (size_t idx, uint32_t *bit_offset_ptr) c
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case clang::Type::ObjCObjectPointer:
|
case clang::Type::ObjCObjectPointer:
|
||||||
|
return GetPointeeType().GetDirectBaseClassAtIndex(idx,bit_offset_ptr);
|
||||||
|
|
||||||
|
case clang::Type::ObjCObject:
|
||||||
if (idx == 0 && GetCompleteType())
|
if (idx == 0 && GetCompleteType())
|
||||||
{
|
{
|
||||||
const ObjCObjectPointerType *objc_class_type = qual_type->getAsObjCInterfacePointerType();
|
const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
|
||||||
if (objc_class_type)
|
if (objc_class_type)
|
||||||
{
|
{
|
||||||
ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterfaceDecl();
|
ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
|
||||||
|
|
||||||
if (class_interface_decl)
|
if (class_interface_decl)
|
||||||
{
|
{
|
||||||
ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
|
ObjCInterfaceDecl *superclass_interface_decl = class_interface_decl->getSuperClass();
|
||||||
|
@ -2501,15 +2508,13 @@ ClangASTType::GetDirectBaseClassAtIndex (size_t idx, uint32_t *bit_offset_ptr) c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case clang::Type::ObjCObject:
|
|
||||||
case clang::Type::ObjCInterface:
|
case clang::Type::ObjCInterface:
|
||||||
if (idx == 0 && GetCompleteType())
|
if (idx == 0 && GetCompleteType())
|
||||||
{
|
{
|
||||||
const ObjCObjectType *objc_class_type = qual_type->getAsObjCQualifiedInterfaceType();
|
const ObjCObjectType *objc_interface_type = qual_type->getAs<ObjCInterfaceType>();
|
||||||
if (objc_class_type)
|
if (objc_interface_type)
|
||||||
{
|
{
|
||||||
ObjCInterfaceDecl *class_interface_decl = objc_class_type->getInterface();
|
ObjCInterfaceDecl *class_interface_decl = objc_interface_type->getInterface();
|
||||||
|
|
||||||
if (class_interface_decl)
|
if (class_interface_decl)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
LEVEL = ../../../make
|
||||||
|
|
||||||
|
OBJC_SOURCES := main.m
|
||||||
|
LDFLAGS = $(CFLAGS) -lobjc -framework AppKit
|
||||||
|
|
||||||
|
include $(LEVEL)/Makefile.rules
|
|
@ -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()
|
|
@ -0,0 +1,9 @@
|
||||||
|
#import <AppKit/AppKit.h>
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
NSButton *button = [NSButton new];
|
||||||
|
NSLog(@"a"); // Set breakpoint here.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue