Skip to content

Commit adf4efe

Browse files
authored
Merge pull request #21107 from DougGregor/relative-objc-class-by-name
[IRGen] Don't emit relative references to Objective-C class references.
2 parents b773515 + fbaacf9 commit adf4efe

13 files changed

+35
-42
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2565,28 +2565,12 @@ getProtocolDescriptorEntityReference(IRGenModule &IGM, ProtocolDecl *protocol) {
25652565
}
25662566

25672567
static TypeEntityReference
2568-
getObjCClassRefEntityReference(IRGenModule &IGM, ClassDecl *cls) {
2569-
// A reference to an Objective-C class object.
2570-
assert(cls->isObjC() && "Must have an Objective-C class here");
2571-
2572-
auto kind = TypeReferenceKind::IndirectObjCClass;
2573-
auto entity = LinkEntity::forObjCClassRef(cls);
2574-
2575-
auto ref = IGM.getAddrOfLLVMVariableOrGOTEquivalent(entity);
2576-
assert(!ref.isIndirect());
2577-
2578-
return TypeEntityReference(kind, ref.getValue());
2579-
}
2580-
2581-
static TypeEntityReference
2582-
getRuntimeOnlyClassEntityReference(IRGenModule &IGM, ClassDecl *cls) {
2583-
assert(cls->getForeignClassKind() == ClassDecl::ForeignKind::RuntimeOnly);
2584-
2585-
auto namedClangDecl = Mangle::ASTMangler::getClangDeclForMangling(cls);
2586-
assert(namedClangDecl);
2587-
2568+
getObjCClassByNameReference(IRGenModule &IGM, ClassDecl *cls) {
25882569
auto kind = TypeReferenceKind::DirectObjCClassName;
2589-
auto ref = IGM.getAddrOfGlobalString(namedClangDecl->getName());
2570+
SmallString<64> objcRuntimeNameBuffer;
2571+
auto ref = IGM.getAddrOfGlobalString(
2572+
cls->getObjCRuntimeName(objcRuntimeNameBuffer),
2573+
/*willByRelativelyAddressed=*/true);
25902574

25912575
return TypeEntityReference(kind, ref);
25922576
}
@@ -2605,17 +2589,22 @@ IRGenModule::getTypeEntityReference(NominalTypeDecl *decl) {
26052589

26062590
switch (clas->getForeignClassKind()) {
26072591
case ClassDecl::ForeignKind::RuntimeOnly:
2608-
return getRuntimeOnlyClassEntityReference(*this, clas);
2592+
return getObjCClassByNameReference(*this, clas);
26092593

26102594
case ClassDecl::ForeignKind::CFType:
26112595
return getTypeContextDescriptorEntityReference(*this, clas);
26122596

26132597
case ClassDecl::ForeignKind::Normal:
26142598
if (hasKnownSwiftMetadata(*this, clas)) {
26152599
return getTypeContextDescriptorEntityReference(*this, clas);
2616-
} else {
2617-
return getObjCClassRefEntityReference(*this, clas);
26182600
}
2601+
2602+
// Note: we would like to use an Objective-C class reference, but the
2603+
// Darwin linker currently has a bug where it will coalesce these symbols
2604+
// *after* computing a relative offset, causing incorrect relative
2605+
// offsets in the metadata. Therefore, reference Objective-C classes by
2606+
// their runtime names.
2607+
return getObjCClassByNameReference(*this, clas);
26192608
}
26202609
llvm_unreachable("bad foreign type kind");
26212610
}

lib/IRGen/Linking.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ std::string LinkEntity::mangleAsString() const {
265265
case Kind::ObjCClassRef: {
266266
llvm::SmallString<64> tempBuffer;
267267
StringRef name = cast<ClassDecl>(getDecl())->getObjCRuntimeName(tempBuffer);
268-
std::string Result("\01l_OBJC_CLASS_REF_$_");
268+
std::string Result("OBJC_CLASS_REF_$_");
269269
Result.append(name.data(), name.size());
270270
return Result;
271271
}

test/ClangImporter/attr-swift_private.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public func testTopLevel() {
9292
}
9393

9494
// CHECK-LABEL: define linkonce_odr hidden swiftcc %swift.metadata_response @"$sSo10PrivFooSubCMa{{.*}} {
95-
// CHECK: %objc_class** @"\01l_OBJC_CLASS_REF_$_PrivFooSub"
95+
// CHECK: %objc_class** @"OBJC_CLASS_REF_$_PrivFooSub"
9696
// CHECK: }
9797

9898
// CHECK-LABEL: define linkonce_odr hidden {{.+}} @"$sSo3BarC8__noArgsABSgyt_tcfcTO"

test/ClangImporter/objc_ir.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,15 @@ func propertyAccess(b b: B) {
7474
// CHECK: load i8*, i8** @"\01L_selector(setCounter:)"
7575
b.counter = b.counter + 1
7676

77-
// CHECK: load %objc_class*, %objc_class** @"\01l_OBJC_CLASS_REF_$_B"
77+
// CHECK: load %objc_class*, %objc_class** @"OBJC_CLASS_REF_$_B"
7878
// CHECK: load i8*, i8** @"\01L_selector(sharedCounter)"
7979
// CHECK: load i8*, i8** @"\01L_selector(setSharedCounter:)"
8080
B.sharedCounter = B.sharedCounter + 1
8181
}
8282

8383
// CHECK-LABEL: define hidden swiftcc %TSo1BC* @"$s7objc_ir8downcast1aSo1BCSo1AC_tF"(
8484
func downcast(a a: A) -> B {
85-
// CHECK: [[CLASS:%.*]] = load %objc_class*, %objc_class** @"\01l_OBJC_CLASS_REF_$_B"
85+
// CHECK: [[CLASS:%.*]] = load %objc_class*, %objc_class** @"OBJC_CLASS_REF_$_B"
8686
// CHECK: [[T0:%.*]] = call %objc_class* @swift_getInitializedObjCClass(%objc_class* [[CLASS]])
8787
// CHECK: [[T1:%.*]] = bitcast %objc_class* [[T0]] to i8*
8888
// CHECK: call i8* @swift_dynamicCastObjCClassUnconditional(i8* [[A:%.*]], i8* [[T1]]) [[NOUNWIND:#[0-9]+]]

test/IRGen/COFF-objc-sections.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class D {
2121
// CHECK-COFF-NOT: @"$s4main1CCMf" = {{.*}}, section "__DATA,__objc_data, regular"
2222
// CHECK-COFF: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, section ".objc_protolist$B"
2323
// CHECK-COFF: @"\01l_OBJC_PROTOCOL_REFERENCE_$_P" = {{.*}}, section ".objc_protorefs$B"
24-
// CHECK-COFF: @"\01l_OBJC_CLASS_REF_$_I" = {{.*}}, section ".objc_classrefs$B"
24+
// CHECK-COFF: @"OBJC_CLASS_REF_$_I" = {{.*}}, section ".objc_classrefs$B"
2525
// CHECK-COFF: @"\01L_selector(init)" = {{.*}}, section ".objc_selrefs$B"
2626
// CHECK-COFF: @objc_classes = {{.*}}, section ".objc_classlist$B"
2727
// CHECK-COFF: @objc_categories = {{.*}}, section ".objc_catlist$B"

test/IRGen/ELF-objc-sections.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class D {
2121
// CHECK-ELF-NOT: @"$s4main1CCMf" = {{.*}}, section "__DATA,__objc_data, regular"
2222
// CHECK-ELF: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, section "objc_protolist"
2323
// CHECK-ELF: @"\01l_OBJC_PROTOCOL_REFERENCE_$_P" = {{.*}}, section "objc_protorefs", align 8
24-
// CHECK-ELF: @"\01l_OBJC_CLASS_REF_$_I" = {{.*}}, section "objc_classrefs", align 8
24+
// CHECK-ELF: @"OBJC_CLASS_REF_$_I" = {{.*}}, section "objc_classrefs", align 8
2525
// CHECK-ELF: @"\01L_selector(init)" = {{.*}}, section "objc_selrefs"
2626
// CHECK-ELF: @objc_classes = {{.*}}, section "objc_classlist"
2727
// CHECK-ELF: @objc_categories = {{.*}}, section "objc_catlist"

test/IRGen/MachO-objc-sections.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class D {
2121
// CHECK-MACHO: @"$s4main1CCMf" = {{.*}}, section "__DATA,__objc_data, regular"
2222
// CHECK-MACHO: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, section "__DATA,__objc_protolist,coalesced,no_dead_strip"
2323
// CHECK-MACHO: @"\01l_OBJC_PROTOCOL_REFERENCE_$_P" = {{.*}}, section "__DATA,__objc_protorefs,coalesced,no_dead_strip"
24-
// CHECK-MACHO: @"\01l_OBJC_CLASS_REF_$_I" = {{.*}}, section "__DATA,__objc_classrefs,regular,no_dead_strip"
24+
// CHECK-MACHO: @"OBJC_CLASS_REF_$_I" = {{.*}}, section "__DATA,__objc_classrefs,regular,no_dead_strip"
2525
// CHECK-MACHO: @"\01L_selector(init)" = {{.*}}, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip"
2626
// CHECK-MACHO: @objc_classes = {{.*}}, section "__DATA,__objc_classlist,regular,no_dead_strip"
2727
// CHECK-MACHO: @objc_categories = {{.*}}, section "__DATA,__objc_catlist,regular,no_dead_strip"

test/IRGen/objc_bridged_generic_conformance.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
// CHECK-NOT: _TMnCSo
44

5-
// CHECK: @"$sSo6ThingyCyxG32objc_bridged_generic_conformance1PADMc" = hidden constant %swift.protocol_conformance_descriptor {{.*}} @"\01l_OBJC_CLASS_REF_$_Thingy"
5+
// CHECK: @"$sSo6ThingyCyxG32objc_bridged_generic_conformance1PADMc" = hidden constant %swift.protocol_conformance_descriptor {{.*}} @[[THINGY_NAME:[0-9]]]
6+
7+
// CHECK: @[[THINGY_NAME]] = private constant [7 x i8] c"Thingy\00"
68

79
// CHECK-NOT: _TMnCSo
810

test/IRGen/objc_casts.sil

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ bb0(%unused : $@thick T.Type, %obj : $NSObject):
3333
// CHECK: [[T0:%.*]] = call %objc_object* @swift_dynamicCastMetatypeToObjectUnconditional(%swift.type* %0)
3434
// TODO: is this really necessary? also, this really shouldn't use a direct reference
3535
// CHECK-NEXT: [[T1:%.*]] = bitcast %objc_object* [[T0]] to i8*
36-
// CHECK-NEXT: [[T2a:%.*]] = load %objc_class*, %objc_class** @"\01l_OBJC_CLASS_REF_$_Foo"
36+
// CHECK-NEXT: [[T2a:%.*]] = load %objc_class*, %objc_class** @"OBJC_CLASS_REF_$_Foo"
3737
// CHECK-NEXT: [[T2:%.*]] = call %objc_class* @swift_getInitializedObjCClass(%objc_class* [[T2a]])
3838
// CHECK-NEXT: [[T3:%.*]] = bitcast %objc_class* [[T2]] to i8*
3939
// CHECK-NEXT: call i8* @swift_dynamicCastObjCClassUnconditional(i8* [[T1]], i8* [[T3]])
@@ -49,7 +49,7 @@ bb0(%metatype : $@thick T.Type):
4949
// CHECK: [[T0:%.*]] = call %objc_object* @swift_dynamicCastMetatypeToObjectUnconditional(%swift.type* [[ARG]])
5050
// TODO: is this really necessary? also, this really shouldn't use a direct reference
5151
// CHECK-NEXT: [[T1:%.*]] = bitcast %objc_object* [[T0]] to i8*
52-
// CHECK-NEXT: [[T2a:%.*]] = load %objc_class*, %objc_class** @"\01l_OBJC_CLASS_REF_$_Foo"
52+
// CHECK-NEXT: [[T2a:%.*]] = load %objc_class*, %objc_class** @"OBJC_CLASS_REF_$_Foo"
5353
// CHECK-NEXT: [[T2:%.*]] = call %objc_class* @swift_getInitializedObjCClass(%objc_class* [[T2a]])
5454
// CHECK-NEXT: [[T3:%.*]] = bitcast %objc_class* [[T2]] to i8*
5555
// CHECK-NEXT: call i8* @swift_dynamicCastObjCClassUnconditional(i8* [[T1]], i8* [[T3]])

test/IRGen/objc_generic_class_metadata.sil

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ entry:
3939
%b = metatype $@thick GenericClass<NSObject>.Type
4040
apply %z<GenericClass<NSObject>>(%b) : $@convention(thin) <T> (@thick T.Type) -> ()
4141

42-
// CHECK: [[T0:%.*]] = load %objc_class*, %objc_class** @"\01l_OBJC_CLASS_REF_$_GenericClass",
42+
// CHECK: [[T0:%.*]] = load %objc_class*, %objc_class** @"OBJC_CLASS_REF_$_GenericClass",
4343
// CHECK: [[OBJC_CLASS:%.*]] = call %objc_class* @swift_getInitializedObjCClass(%objc_class* [[T0]])
4444
// CHECK: call swiftcc void @objc_class_sink(%objc_class* [[OBJC_CLASS]], %swift.type* [[METADATA]])
4545
%c = metatype $@objc_metatype GenericClass<NSString>.Type
@@ -79,7 +79,7 @@ entry(%0: @owned $Subclass, %1: @owned $NSDictionary):
7979
}
8080

8181
// CHECK-LABEL: define linkonce_odr hidden swiftcc %swift.metadata_response @"$sSo12GenericClassCMa"(
82-
// CHECK: [[T0:%.*]] = load %objc_class*, %objc_class** @"\01l_OBJC_CLASS_REF_$_GenericClass",
82+
// CHECK: [[T0:%.*]] = load %objc_class*, %objc_class** @"OBJC_CLASS_REF_$_GenericClass",
8383
// CHECK: call %objc_class* @swift_getInitializedObjCClass(%objc_class* [[T0]])
8484

8585
// CHECK-LABEL: define linkonce_odr hidden swiftcc %swift.metadata_response @"$sSaySo12GenericClassC_SitGMa"

test/IRGen/objc_properties_jit.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ extension NSString {
1414
}
1515

1616
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} private void @runtime_registration
17-
// CHECK: [[NSOBJECT_UNINIT:%.*]] = load %objc_class*, %objc_class** @"\01l_OBJC_CLASS_REF_$_NSString"
17+
// CHECK: [[NSOBJECT_UNINIT:%.*]] = load %objc_class*, %objc_class** @"OBJC_CLASS_REF_$_NSString"
1818
// CHECK: [[NSOBJECT:%.*]] = call %objc_class* @swift_getInitializedObjCClass(%objc_class* [[NSOBJECT_UNINIT]])
1919
// CHECK: [[GET_CLASS_PROP:%.*]] = call i8* @sel_registerName({{.*}}(classProp)
2020
// CHECK: call i8* @class_replaceMethod(%objc_class* @"OBJC_METACLASS_$_NSString", i8* [[GET_CLASS_PROP]]

test/IRGen/objc_runtime_visible_conformance.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ extension A : YourProtocol {}
1010

1111
// CHECK-LABEL: @"$sSo1AC32objc_runtime_visible_conformance10MyProtocolACMc"
1212
// CHECK-SAME: @"$s32objc_runtime_visible_conformance10MyProtocolMp"
13-
// CHECK-SAME: [2 x i8]* [[STRING_A:@[0-9]+]]
13+
// CHECK-SAME: [[STRING_A:@[0-9]+]]
1414
// CHECK-SAME: @"$sSo1AC32objc_runtime_visible_conformance10MyProtocolACWP"
1515
// DirectObjCClassName
1616
// CHECK-SAME: i32 16
17-
// CHECK: [[STRING_A]] = private unnamed_addr constant [2 x i8] c"A\00"
17+
// CHECK: [[STRING_A]] = private constant [22 x i8] c"MyRuntimeVisibleClass\00"

test/IRGen/protocol_conformance_records_objc.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,19 @@ extension NSRect: Runcible {
2929
// CHECK-LABEL: @"$sSo5GizmoC33protocol_conformance_records_objc8RuncibleACMc" = constant %swift.protocol_conformance_descriptor {
3030
// -- protocol descriptor
3131
// CHECK-SAME: [[RUNCIBLE]]
32-
// -- class object reference
33-
// CHECK-SAME: @"\01l_OBJC_CLASS_REF_$_Gizmo"
32+
// -- class name reference
33+
// CHECK-SAME: @[[GIZMO_NAME:[0-9]+]]
3434
// -- witness table
3535
// CHECK-SAME: @"$sSo5GizmoC33protocol_conformance_records_objc8RuncibleACWP"
3636
// -- flags
37-
// CHECK-SAME: i32 24
37+
// CHECK-SAME: i32 16
3838
// CHECK-SAME: }
3939
extension Gizmo: Runcible {
4040
public func runce() {}
4141
}
4242

43+
// CHECK: @[[GIZMO_NAME]] = private constant [6 x i8] c"Gizmo\00"
44+
4345
// CHECK-LABEL: @"\01l_protocol_conformances" = private constant [
4446
// CHECK-SAME: @"$sSo6NSRectV33protocol_conformance_records_objc8RuncibleACMc"
4547
// CHECK-SAME: @"$sSo5GizmoC33protocol_conformance_records_objc8RuncibleACMc"

0 commit comments

Comments
 (0)