[ObjC] Expand isClassLayoutKnownStatically to base classes as long as the implementation of it is known (#85465)
Only NSObject we can trust the layout of won't change even though we cannot directly see its @implementation
This commit is contained in:
parent
aeca2aa193
commit
6720465c47
@ -1545,7 +1545,8 @@ private:
|
||||
bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
|
||||
// Test a class by checking its superclasses up to
|
||||
// its base class if it has one.
|
||||
for (; ID; ID = ID->getSuperClass()) {
|
||||
assert(ID != nullptr && "Passed a null class to check layout");
|
||||
for (; ID != nullptr; ID = ID->getSuperClass()) {
|
||||
// The layout of base class NSObject
|
||||
// is guaranteed to be statically known
|
||||
if (ID->getIdentifier()->getName() == "NSObject")
|
||||
@ -1556,7 +1557,9 @@ private:
|
||||
if (!ID->getImplementation())
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
// We know the layout of all the intermediate classes and superclasses.
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -422,16 +422,16 @@ void test11b(void) {
|
||||
@implementation Test12
|
||||
@synthesize ablock, nblock;
|
||||
// CHECK: define internal ptr @"\01-[Test12 ablock]"(
|
||||
// CHECK: call ptr @objc_getProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef {{%.*}}, i1 noundef zeroext true)
|
||||
// CHECK: call ptr @objc_getProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef 0, i1 noundef zeroext true)
|
||||
|
||||
// CHECK: define internal void @"\01-[Test12 setAblock:]"(
|
||||
// CHECK: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef {{%.*}}, ptr noundef {{%.*}}, i1 noundef zeroext true, i1 noundef zeroext true)
|
||||
// CHECK: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef 0, ptr noundef {{%.*}}, i1 noundef zeroext true, i1 noundef zeroext true)
|
||||
|
||||
// CHECK: define internal ptr @"\01-[Test12 nblock]"(
|
||||
// CHECK: %add.ptr = getelementptr inbounds i8, ptr %0, i64 %ivar
|
||||
// CHECK: %add.ptr = getelementptr inbounds i8, ptr %0, i64 8
|
||||
|
||||
// CHECK: define internal void @"\01-[Test12 setNblock:]"(
|
||||
// CHECK: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef {{%.*}}, ptr noundef {{%.*}}, i1 noundef zeroext false, i1 noundef zeroext true)
|
||||
// CHECK: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef 8, ptr noundef {{%.*}}, i1 noundef zeroext false, i1 noundef zeroext true)
|
||||
@end
|
||||
|
||||
void test13(id x) {
|
||||
|
@ -22,16 +22,14 @@ struct S1 { Class isa; };
|
||||
@end
|
||||
// The getter should be a simple load.
|
||||
// CHECK: define internal ptr @"\01-[Test1 pointer]"(
|
||||
// CHECK: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test1.pointer"
|
||||
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i64 [[OFFSET]]
|
||||
// CHECK: [[T1:%.*]] = getelementptr inbounds i8, ptr {{%.*}}, i64 0
|
||||
// CHECK-NEXT: [[T3:%.*]] = load ptr, ptr [[T1]], align 8
|
||||
// CHECK-NEXT: ret ptr [[T3]]
|
||||
|
||||
// The setter should be using objc_setProperty.
|
||||
// CHECK: define internal void @"\01-[Test1 setPointer:]"(
|
||||
// CHECK: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test1.pointer"
|
||||
// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr {{%.*}}
|
||||
// CHECK-NEXT: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef [[OFFSET]], ptr noundef [[T1]], i1 noundef zeroext false, i1 noundef zeroext false)
|
||||
// CHECK: [[T1:%.*]] = load ptr, ptr {{%.*}}
|
||||
// CHECK: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef 0, ptr noundef {{%.*}}, i1 noundef zeroext false, i1 noundef zeroext false)
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
|
||||
@ -52,26 +50,22 @@ static Class theGlobalClass;
|
||||
// CHECK: define internal void @"\01-[Test2 test]"(
|
||||
// CHECK: [[T0:%.*]] = load ptr, ptr @theGlobalClass, align 8
|
||||
// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr
|
||||
// CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test2._theClass"
|
||||
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T1]], i64 [[OFFSET]]
|
||||
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T1]], i64 0
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T3]], ptr [[T0]]) [[NUW:#[0-9]+]]
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
// CHECK: define internal ptr @"\01-[Test2 theClass]"(
|
||||
// CHECK: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test2._theClass"
|
||||
// CHECK-NEXT: [[T0:%.*]] = tail call ptr @objc_getProperty(ptr noundef {{.*}}, ptr noundef {{.*}}, i64 noundef [[OFFSET]], i1 noundef zeroext true)
|
||||
// CHECK: [[T0:%.*]] = tail call ptr @objc_getProperty(ptr noundef {{.*}}, ptr noundef {{.*}}, i64 noundef 0, i1 noundef zeroext true)
|
||||
// CHECK-NEXT: ret ptr [[T0]]
|
||||
|
||||
// CHECK: define internal void @"\01-[Test2 setTheClass:]"(
|
||||
// CHECK: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test2._theClass"
|
||||
// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr {{%.*}}
|
||||
// CHECK-NEXT: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef [[OFFSET]], ptr noundef [[T1]], i1 noundef zeroext true, i1 noundef zeroext true)
|
||||
// CHECK: [[T1:%.*]] = load ptr, ptr {{%.*}}
|
||||
// CHECK: call void @objc_setProperty(ptr noundef {{%.*}}, ptr noundef {{%.*}}, i64 noundef 0, ptr noundef {{%.*}}, i1 noundef zeroext true, i1 noundef zeroext true)
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
// CHECK: define internal void @"\01-[Test2 .cxx_destruct]"(
|
||||
// CHECK: [[T0:%.*]] = load ptr, ptr
|
||||
// CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test2._theClass"
|
||||
// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 [[OFFSET]]
|
||||
// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 0
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T2]], ptr null) [[NUW]]
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fobjc-runtime-has-weak -fblocks -fobjc-arc -o - %s | FileCheck %s
|
||||
|
||||
@interface WeakPropertyTest {
|
||||
@interface SuperClass
|
||||
@end
|
||||
|
||||
@interface WeakPropertyTest : SuperClass {
|
||||
__weak id PROP;
|
||||
}
|
||||
@property () __weak id PROP;
|
||||
|
@ -577,8 +577,7 @@ void test21(unsigned n) {
|
||||
@implementation Test26 @end
|
||||
// CHECK: define internal void @"\01-[Test26 .cxx_destruct]"(
|
||||
// CHECK: [[SELF:%.*]] = load ptr, ptr
|
||||
// CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test26.x"
|
||||
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i64 [[OFFSET]]
|
||||
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i64 0
|
||||
// CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [4 x ptr], ptr [[T1]], i32 0, i32 0
|
||||
// CHECK-NEXT: [[END:%.*]] = getelementptr inbounds ptr, ptr [[BEGIN]], i64 4
|
||||
// CHECK-NEXT: br label
|
||||
@ -616,8 +615,7 @@ void test21(unsigned n) {
|
||||
@end
|
||||
// CHECK: define internal void @"\01-[Test28 .cxx_destruct]"
|
||||
// CHECK: [[SELF:%.*]] = load ptr, ptr
|
||||
// CHECK-NEXT: [[OFFSET:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test28.prop"
|
||||
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i64 [[OFFSET]]
|
||||
// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, ptr [[SELF]], i64 0
|
||||
// CHECK-NEXT: call void @llvm.objc.storeStrong(ptr [[T1]], ptr null)
|
||||
// CHECK-NEXT: ret void
|
||||
|
||||
@ -738,8 +736,7 @@ char *helper;
|
||||
|
||||
// Assignment.
|
||||
// CHECK-NEXT: [[T1:%.*]] = load ptr, ptr [[SELF]]
|
||||
// CHECK-NEXT: [[IVAR:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test30.helper"
|
||||
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T1]], i64 [[IVAR]]
|
||||
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T1]], i64 0
|
||||
// CHECK-NEXT#: [[T5:%.*]] = load ptr, ptr [[T3]]
|
||||
// CHECK-NEXT#: [[T6:%.*]] = call ptr @llvm.objc.retain(ptr [[CALL]])
|
||||
// CHECK-NEXT#: call void @llvm.objc.release(ptr [[T5]])
|
||||
@ -1137,23 +1134,20 @@ void test56_test(void) {
|
||||
@end
|
||||
// CHECK: define internal ptr @"\01-[Test57 strong]"(
|
||||
// CHECK: [[T0:%.*]] = load ptr, ptr {{%.*}}
|
||||
// CHECK-NEXT: [[T1:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test57.strong"
|
||||
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 [[T1]]
|
||||
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 0
|
||||
// CHECK-NEXT: [[T5:%.*]] = load ptr, ptr [[T3]]
|
||||
// CHECK-NEXT: ret ptr [[T5]]
|
||||
|
||||
// CHECK: define internal ptr @"\01-[Test57 weak]"(
|
||||
// CHECK: [[T0:%.*]] = load ptr, ptr {{%.*}}
|
||||
// CHECK-NEXT: [[T1:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test57.weak"
|
||||
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 [[T1]]
|
||||
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 8
|
||||
// CHECK-NEXT: [[T5:%.*]] = call ptr @llvm.objc.loadWeakRetained(ptr [[T3]])
|
||||
// CHECK-NEXT: [[T6:%.*]] = tail call ptr @llvm.objc.autoreleaseReturnValue(ptr [[T5]])
|
||||
// CHECK-NEXT: ret ptr [[T6]]
|
||||
|
||||
// CHECK: define internal ptr @"\01-[Test57 unsafe]"(
|
||||
// CHECK: [[T0:%.*]] = load ptr, ptr {{%.*}}
|
||||
// CHECK-NEXT: [[T1:%.*]] = load i64, ptr @"OBJC_IVAR_$_Test57.unsafe"
|
||||
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 [[T1]]
|
||||
// CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, ptr [[T0]], i64 16
|
||||
// CHECK-NEXT: [[T5:%.*]] = load ptr, ptr [[T3]]
|
||||
// CHECK-NEXT: ret ptr [[T5]]
|
||||
|
||||
|
@ -2,7 +2,10 @@
|
||||
|
||||
// CHECK: @"OBJC_IVAR_$_I.IVAR2" = global i32 8
|
||||
// CHECK: @"OBJC_IVAR_$_I.IVAR1" = global i32 0
|
||||
@interface I
|
||||
@interface SuperClass
|
||||
@end
|
||||
|
||||
@interface I : SuperClass
|
||||
{
|
||||
id IVAR1;
|
||||
id IVAR2;
|
||||
|
@ -8,7 +8,10 @@
|
||||
// RUN: grep -F '@"OBJC_IVAR_$_I0._b4" = global i64 7, section "__DATA, __objc_ivar", align 8' %t
|
||||
// RUN: not grep -F '@"OBJC_IVAR_$_I0." = global' %t
|
||||
|
||||
@interface I0 {
|
||||
@interface SuperClass
|
||||
@end
|
||||
|
||||
@interface I0 : SuperClass {
|
||||
unsigned _b0:4;
|
||||
unsigned _b1:5;
|
||||
unsigned _b2:5;
|
||||
|
@ -8,6 +8,12 @@
|
||||
// CHECK: @"OBJC_IVAR_$_IntermediateClass._intermediateProperty" = hidden constant i64 48
|
||||
// CHECK: @"OBJC_IVAR_$_SubClass.subClassIvar" = constant i64 56
|
||||
// CHECK: @"OBJC_IVAR_$_SubClass._subClassProperty" = hidden constant i64 64
|
||||
|
||||
// CHECK: @"OBJC_IVAR_$_RootClass.these" = constant i64 0
|
||||
// CHECK: @"OBJC_IVAR_$_RootClass.never" = constant i64 4
|
||||
// CHECK: @"OBJC_IVAR_$_RootClass.change" = constant i64 8
|
||||
// CHECK: @"OBJC_IVAR_$_StillStaticLayout.static_layout_ivar" = hidden constant i64 12
|
||||
|
||||
// CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden global i64 12
|
||||
// CHECK: @"OBJC_IVAR_$_SuperClass2._superClassProperty2" = hidden constant i64 20
|
||||
// CHECK: @"OBJC_IVAR_$_IntermediateClass2._IntermediateClass2Property" = hidden constant i64 24
|
||||
@ -123,12 +129,34 @@
|
||||
// CHECK: getelementptr inbounds i8, ptr %1, i64 64
|
||||
@end
|
||||
|
||||
@interface NotNSObject {
|
||||
int these, might, change;
|
||||
__attribute((objc_root_class)) @interface RootClass {
|
||||
int these, never, change;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface NotStaticLayout : NotNSObject
|
||||
@implementation RootClass
|
||||
@end
|
||||
|
||||
@interface StillStaticLayout : RootClass
|
||||
@end
|
||||
|
||||
@implementation StillStaticLayout {
|
||||
int static_layout_ivar;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define internal void @"\01-[StillStaticLayout meth]"
|
||||
-(void)meth {
|
||||
static_layout_ivar = 0;
|
||||
// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$StillStaticLayout.static_layout_ivar
|
||||
}
|
||||
@end
|
||||
|
||||
@interface NotNSObject
|
||||
@end
|
||||
|
||||
@interface NotStaticLayout : NotNSObject {
|
||||
int these, might, change;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NotStaticLayout {
|
||||
|
@ -167,8 +167,7 @@ __attribute__((objc_root_class))
|
||||
// CHECK-LABEL: define hidden ptr @"\01-[Root objectProperty]"(
|
||||
// CHECK-LABEL: objc_direct_method.cont:
|
||||
// CHECK-NEXT: [[SELFVAL:%.*]] = load {{.*}} %self.addr,
|
||||
// CHECK-NEXT: [[IVAR:%.*]] = load {{.*}} @"OBJC_IVAR_$_Root._objectProperty",
|
||||
// CHECK-NEXT: call ptr @objc_getProperty(ptr noundef [[SELFVAL]], ptr noundef poison, i64 noundef [[IVAR]], {{.*}})
|
||||
// CHECK-NEXT: call ptr @objc_getProperty(ptr noundef [[SELFVAL]], ptr noundef poison, i64 noundef 8, {{.*}})
|
||||
|
||||
@interface Foo : Root {
|
||||
id __strong _cause_cxx_destruct;
|
||||
|
@ -1,7 +1,7 @@
|
||||
// RUN: %clang_cc1 -triple i386-apple-macosx -fvisibility=hidden -emit-llvm -o - %s | FileCheck %s
|
||||
// CHECK: @"OBJC_IVAR_$_I.P" = hidden
|
||||
// CHECK: @"OBJC_CLASS_$_I" = hidden
|
||||
// CHECK: @"OBJC_METACLASS_$_I" = hidden
|
||||
// CHECK: @"OBJC_IVAR_$_I.P" = hidden
|
||||
// CHECK: @"_OBJC_PROTOCOL_$_Prot0" = weak hidden
|
||||
|
||||
@interface I {
|
||||
|
@ -10,11 +10,11 @@
|
||||
// CHECK: @"OBJC_IVAR_$_I5._iv5" = global i64 14, section "__DATA, __objc_ivar", align 8
|
||||
// CHECK: _OBJC_CLASS_RO_$_I5" = internal global {{.*}} { i32 0, i32 14, i32 24, {{.*}}
|
||||
// CHECK: @"OBJC_IVAR_$_I6.iv0" = global i64 0, section "__DATA, __objc_ivar", align 8
|
||||
// CHECK: _OBJC_CLASS_RO_$_I6" = internal global {{.*}} { i32 2, i32 0, i32 1, {{.*}}
|
||||
// CHECK: _OBJC_CLASS_RO_$_I6" = internal global {{.*}} { i32 0, i32 0, i32 1, {{.*}}
|
||||
// CHECK: @"OBJC_IVAR_$_I8.b" = global i64 8, section "__DATA, __objc_ivar", align 8
|
||||
// CHECK: _OBJC_CLASS_RO_$_I8" = internal global {{.*}} { i32 0, i32 8, i32 16, {{.*}}
|
||||
// CHECK: @"OBJC_IVAR_$_I9.iv0" = global i64 0, section "__DATA, __objc_ivar", align 8
|
||||
// CHECK: _OBJC_CLASS_RO_$_I9" = internal global {{.*}} { i32 2, i32 0, i32 4, {{.*}}
|
||||
// CHECK: _OBJC_CLASS_RO_$_I9" = internal global {{.*}} { i32 0, i32 0, i32 4, {{.*}}
|
||||
// CHECK: @"OBJC_IVAR_$_I10.iv1" = global i64 4, section "__DATA, __objc_ivar", align 8
|
||||
// CHECK: _OBJC_CLASS_RO_$_I10" = internal global {{.*}} { i32 0, i32 4, i32 5, {{.*}}
|
||||
// CHECK: _OBJC_CLASS_RO_$_I11" = internal global {{.*}} { i32 0, i32 5, i32 5, {{.*}}
|
||||
@ -28,11 +28,15 @@
|
||||
gcc -m64 -S -o - interface-layout-64.m | grep '^l{{.*}}_CLASS_RO_$_I[0-9]*' -A 3
|
||||
*/
|
||||
|
||||
@interface SuperClass
|
||||
@end
|
||||
|
||||
struct s0 {
|
||||
double x;
|
||||
};
|
||||
|
||||
@interface I2 {
|
||||
|
||||
@interface I2 : SuperClass {
|
||||
struct s0 _iv1;
|
||||
}
|
||||
@end
|
||||
@ -74,7 +78,7 @@ struct s0 {
|
||||
@end
|
||||
|
||||
// The size rounds up to the next available byte.
|
||||
@interface I6 {
|
||||
@interface I6 : SuperClass {
|
||||
unsigned iv0 : 2;
|
||||
}
|
||||
@end
|
||||
@ -82,7 +86,7 @@ struct s0 {
|
||||
@end
|
||||
|
||||
// The start of the subclass includes padding for its own alignment.
|
||||
@interface I7 {
|
||||
@interface I7 : SuperClass {
|
||||
char a;
|
||||
}
|
||||
@end
|
||||
@ -94,7 +98,7 @@ struct s0 {
|
||||
@end
|
||||
|
||||
// Padding bit-fields
|
||||
@interface I9 {
|
||||
@interface I9 : SuperClass {
|
||||
unsigned iv0 : 2;
|
||||
unsigned : 0;
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin -x objective-c %s -o - | FileCheck %s
|
||||
|
||||
@interface A {
|
||||
@interface SuperClass
|
||||
@end
|
||||
|
||||
@interface A : SuperClass {
|
||||
struct {
|
||||
unsigned char a : 1;
|
||||
unsigned char b : 1;
|
||||
|
@ -1,9 +1,8 @@
|
||||
// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fobjc-dispatch-method=mixed -emit-llvm -o - %s | FileCheck %s
|
||||
|
||||
// CHECK: @"OBJC_IVAR_$_A._ivar" ={{.*}} global {{.*}} section "__DATA, __objc_ivar", align 8
|
||||
// CHECK: @_objc_empty_cache = external global
|
||||
// CHECK: @_objc_empty_vtable = external global
|
||||
// CHECK: @"OBJC_CLASS_$_A" ={{.*}} global
|
||||
// CHECK: @"OBJC_CLASS_$_A" = global
|
||||
// CHECK: @"OBJC_METACLASS_$_A" ={{.*}} global {{.*}} section "__DATA, __objc_data", align 8
|
||||
// CHECK: @OBJC_CLASS_NAME_{{[0-9]*}} = private unnamed_addr constant {{.*}} section "__TEXT,__objc_classname,cstring_literals", align 1
|
||||
// CHECK: @OBJC_METH_VAR_NAME_{{[0-9]*}} = private unnamed_addr constant {{.*}} section "__TEXT,__objc_methname,cstring_literals", align 1
|
||||
@ -16,6 +15,7 @@
|
||||
// CHECK: @"_OBJC_CLASS_PROTOCOLS_$_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
|
||||
// CHECK: @"_OBJC_METACLASS_RO_$_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
|
||||
// CHECK: @"_OBJC_$_INSTANCE_METHODS_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
|
||||
// CHECK: @"OBJC_IVAR_$_A._ivar" ={{.*}} constant {{.*}} section "__DATA, __objc_ivar", align
|
||||
// CHECK: @"_OBJC_$_INSTANCE_VARIABLES_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
|
||||
// CHECK: @OBJC_PROP_NAME_ATTR_{{[0-9]*}} = private unnamed_addr constant {{.*}} section "__TEXT,__objc_methname,cstring_literals", align 1
|
||||
// CHECK: @"_OBJC_$_PROP_LIST_A" = internal global {{.*}} section "__DATA, __objc_const", align 8
|
||||
|
@ -1,10 +1,12 @@
|
||||
// RUN: %clang_cc1 -triple arm64-apple-ios11 -fobjc-arc -emit-llvm -o - %s | FileCheck %s
|
||||
@interface SuperClass
|
||||
@end
|
||||
|
||||
typedef struct {
|
||||
id x;
|
||||
} S0;
|
||||
|
||||
@interface C {
|
||||
@interface C : SuperClass {
|
||||
S0 _p1;
|
||||
}
|
||||
@property(nonatomic) S0 nonatomic;
|
||||
|
@ -57,7 +57,6 @@ id Test16877359(void) {
|
||||
return [SLREarth alloc];
|
||||
}
|
||||
|
||||
// CHECK: @"OBJC_IVAR_$_MySecretNamespace.Message.MyIVAR" ={{.*}} global i64 0
|
||||
// CHECK: @"OBJC_CLASS_$_MySecretNamespace.Message" ={{.*}} global %struct._class_t
|
||||
// CHECK: @"OBJC_METACLASS_$_MySecretNamespace.Message" ={{.*}} global %struct._class_t
|
||||
|
||||
@ -65,10 +64,12 @@ id Test16877359(void) {
|
||||
// CHECK-NEXT: @OBJC_PROP_NAME_ATTR_.11 = private unnamed_addr constant [7 x i8] c"T@,?,&\00"
|
||||
// CHECK: @"_OBJC_$_PROP_LIST_MySecretNamespace.Protocol2" ={{.*}} [%struct._prop_t { ptr @OBJC_PROP_NAME_ATTR_, ptr @OBJC_PROP_NAME_ATTR_.11 }]
|
||||
|
||||
// CHECK: @"OBJC_IVAR_$_MySecretNamespace.Message.MyIVAR" ={{.*}} constant i64 0
|
||||
|
||||
// CHECK: private unnamed_addr constant [42 x i8] c"T@\22MySecretNamespace.Message\22,&,V_msgProp\00"
|
||||
// CHECK: private unnamed_addr constant [76 x i8] c"T@\22MySecretNamespace.Message<MySecretNamespace.Protocol3>\22,&,V_msgProtoProp\00"
|
||||
// CHECK: private unnamed_addr constant [50 x i8] c"T@\22<MySecretNamespace.Protocol3>\22,&,V_idProtoProp\00"
|
||||
|
||||
// CHECK: @"OBJC_CLASS_$_foo" = external global %struct._class_t
|
||||
// CHECK: define internal ptr @"\01-[Message MyMethod]"
|
||||
// CHECK: [[IVAR:%.*]] = load i64, ptr @"OBJC_IVAR_$_MySecretNamespace.Message.MyIVAR"
|
||||
// CHECK: [[IVAR:%.*]] = load ptr, ptr {{.*}}
|
||||
|
@ -31,7 +31,10 @@ BOOL f2(struct S1 *s) {
|
||||
}
|
||||
|
||||
#ifdef __OBJC__
|
||||
@interface I1 {
|
||||
@interface SuperClass
|
||||
@end
|
||||
|
||||
@interface I1 : SuperClass {
|
||||
@public
|
||||
BOOL b1 : 1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user