Skip to content

Commit 6f5944a

Browse files
committed
[ObjC] Check entire chain of superclasses to see if class has fixed offsets
As of now, we only check if a class directly inherits from NSObject to determine if said lass has fixed offsets and can therefore "opt-out" from the non-fragile ABI for ivars. However, if an NSObject subclass has fixed offsets, then so must the subclasses of that subclass, so this allows us to optimize instances of subclasses of subclasses that inherit from NSObject and so on.
1 parent 18987af commit 6f5944a

File tree

2 files changed

+18
-8
lines changed

2 files changed

+18
-8
lines changed

clang/lib/CodeGen/CGObjCMac.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1593,12 +1593,22 @@ class CGObjCNonFragileABIMac : public CGObjCCommonMac {
15931593
}
15941594

15951595
bool isClassLayoutKnownStatically(const ObjCInterfaceDecl *ID) {
1596-
// NSObject is a fixed size. If we can see the @implementation of a class
1597-
// which inherits from NSObject then we know that all it's offsets also must
1598-
// be fixed. FIXME: Can we do this if see a chain of super classes with
1599-
// implementations leading to NSObject?
1600-
return ID->getImplementation() && ID->getSuperClass() &&
1601-
ID->getSuperClass()->getName() == "NSObject";
1596+
// Test a class by checking its superclasses up to its base class if it has
1597+
// one
1598+
while (ID) {
1599+
// The base class NSObject is a fixed size
1600+
if (ID->getName() == "NSObject")
1601+
return true;
1602+
1603+
// If we cannot see the @implementation of a class, we cannot assume fixed
1604+
// offsets
1605+
if (!ID->getImplementation())
1606+
return false;
1607+
1608+
// Test superclass
1609+
ID = ID->getSuperClass();
1610+
}
1611+
return false;
16021612
}
16031613

16041614
public:

clang/test/CodeGenObjC/constant-non-fragile-ivar-offset.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// RUN: %clang_cc1 -triple x86_64-apple-macosx10.14.0 -emit-llvm %s -o - | FileCheck %s
22

33
// CHECK: @"OBJC_IVAR_$_StaticLayout.static_layout_ivar" = hidden constant i64 20
4-
// CHECK: @"OBJC_IVAR_$_StaticLayoutSubClass.static_layout_ivar2" = hidden global i64 24
4+
// CHECK: @"OBJC_IVAR_$_StaticLayoutSubClass.static_layout_ivar2" = hidden constant i64 24
55
// CHECK: @"OBJC_IVAR_$_NotStaticLayout.not_static_layout_ivar" = hidden global i64 12
66

77
@interface NSObject {
@@ -29,7 +29,7 @@ @implementation StaticLayoutSubClass {
2929
}
3030
-(void)meth2 {
3131
static_layout_ivar2 = 0;
32-
// CHECK: load i64, ptr @"OBJC_IVAR_$_StaticLayoutSubClass
32+
// CHECK-NOT: load i64, ptr @"OBJC_IVAR_$_StaticLayoutSubClass
3333
}
3434
@end
3535

0 commit comments

Comments
 (0)