Skip to content

Commit d9ce520

Browse files
authored
Merge pull request #13225 from compnerd/objc-irgen
2 parents a14664a + d8552ce commit d9ce520

File tree

10 files changed

+159
-28
lines changed

10 files changed

+159
-28
lines changed

lib/IRGen/GenClass.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,10 +2108,14 @@ namespace {
21082108
IGM.getPointerAlignment(),
21092109
/*constant*/ true,
21102110
llvm::GlobalVariable::PrivateLinkage);
2111+
21112112
switch (IGM.TargetInfo.OutputObjectFormat) {
21122113
case llvm::Triple::MachO:
21132114
var->setSection("__DATA, __objc_const");
21142115
break;
2116+
case llvm::Triple::COFF:
2117+
var->setSection(".data");
2118+
break;
21152119
case llvm::Triple::ELF:
21162120
var->setSection(".data");
21172121
break;

lib/IRGen/GenDecl.cpp

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -770,31 +770,82 @@ void IRGenModule::addLazyConformances(NominalTypeDecl *Nominal) {
770770
}
771771
}
772772

773+
std::string IRGenModule::GetObjCSectionName(StringRef Section,
774+
StringRef MachOAttributes) {
775+
assert(Section.substr(0, 2) == "__" && "expected the name to begin with __");
776+
777+
switch (TargetInfo.OutputObjectFormat) {
778+
case llvm::Triple::UnknownObjectFormat:
779+
llvm_unreachable("must know the object file format");
780+
case llvm::Triple::MachO:
781+
return MachOAttributes.empty()
782+
? ("__DATA," + Section).str()
783+
: ("__DATA," + Section + "," + MachOAttributes).str();
784+
case llvm::Triple::ELF:
785+
return Section.substr(2).str();
786+
case llvm::Triple::COFF:
787+
return ("." + Section.substr(2) + "$B").str();
788+
case llvm::Triple::Wasm:
789+
error(SourceLoc(), "wasm is not a supported object file format");
790+
}
791+
792+
llvm_unreachable("unexpected object file format");
793+
}
794+
795+
void IRGenModule::SetCStringLiteralSection(llvm::GlobalVariable *GV,
796+
ObjCLabelType Type) {
797+
switch (TargetInfo.OutputObjectFormat) {
798+
case llvm::Triple::UnknownObjectFormat:
799+
llvm_unreachable("must know the object file format");
800+
case llvm::Triple::MachO:
801+
switch (Type) {
802+
case ObjCLabelType::ClassName:
803+
GV->setSection("__TEXT,__objc_classname,cstring_literals");
804+
return;
805+
case ObjCLabelType::MethodVarName:
806+
GV->setSection("__TEXT,__objc_methname,cstring_literals");
807+
return;
808+
case ObjCLabelType::MethodVarType:
809+
GV->setSection("__TEXT,__objc_methtype,cstring_literals");
810+
return;
811+
case ObjCLabelType::PropertyName:
812+
GV->setSection("__TEXT,__cstring,cstring_literals");
813+
return;
814+
}
815+
case llvm::Triple::ELF:
816+
return;
817+
case llvm::Triple::COFF:
818+
return;
819+
case llvm::Triple::Wasm:
820+
error(SourceLoc(), "wasm is not a supported object file format");
821+
return;
822+
}
823+
824+
llvm_unreachable("unexpected object file format");
825+
}
826+
773827
void IRGenModule::emitGlobalLists() {
774828
if (ObjCInterop) {
775-
assert(TargetInfo.OutputObjectFormat == llvm::Triple::MachO);
776829
// Objective-C class references go in a variable with a meaningless
777830
// name but a magic section.
778831
emitGlobalList(*this, ObjCClasses, "objc_classes",
779-
"__DATA, __objc_classlist, regular, no_dead_strip",
780-
llvm::GlobalValue::InternalLinkage,
781-
Int8PtrTy,
782-
false);
832+
GetObjCSectionName("__objc_classlist",
833+
"regular,no_dead_strip"),
834+
llvm::GlobalValue::InternalLinkage, Int8PtrTy, false);
835+
783836
// So do categories.
784837
emitGlobalList(*this, ObjCCategories, "objc_categories",
785-
"__DATA, __objc_catlist, regular, no_dead_strip",
786-
llvm::GlobalValue::InternalLinkage,
787-
Int8PtrTy,
788-
false);
838+
GetObjCSectionName("__objc_catlist",
839+
"regular,no_dead_strip"),
840+
llvm::GlobalValue::InternalLinkage, Int8PtrTy, false);
789841

790842
// Emit nonlazily realized class references in a second magic section to make
791843
// sure they are realized by the Objective-C runtime before any instances
792844
// are allocated.
793845
emitGlobalList(*this, ObjCNonLazyClasses, "objc_non_lazy_classes",
794-
"__DATA, __objc_nlclslist, regular, no_dead_strip",
795-
llvm::GlobalValue::InternalLinkage,
796-
Int8PtrTy,
797-
false);
846+
GetObjCSectionName("__objc_nlclslist",
847+
"regular,no_dead_strip"),
848+
llvm::GlobalValue::InternalLinkage, Int8PtrTy, false);
798849
}
799850

800851
// @llvm.used
@@ -2422,7 +2473,8 @@ Address IRGenModule::getAddrOfObjCClassRef(ClassDecl *theClass) {
24222473
// Define it lazily.
24232474
if (auto global = dyn_cast<llvm::GlobalVariable>(addr)) {
24242475
if (global->isDeclaration()) {
2425-
global->setSection("__DATA,__objc_classrefs,regular,no_dead_strip");
2476+
global->setSection(GetObjCSectionName("__objc_classrefs",
2477+
"regular,no_dead_strip"));
24262478
global->setLinkage(llvm::GlobalVariable::PrivateLinkage);
24272479
global->setExternallyInitialized(true);
24282480
global->setInitializer(getAddrOfObjCClass(theClass, NotForDefinition));

lib/IRGen/GenMeta.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3939,7 +3939,8 @@ void irgen::emitClassMetadata(IRGenModule &IGM, ClassDecl *classDecl,
39393939
bool isIndirect = false;
39403940

39413941
StringRef section{};
3942-
if (classDecl->isObjC())
3942+
if (classDecl->isObjC() &&
3943+
IGM.TargetInfo.OutputObjectFormat == llvm::Triple::MachO)
39433944
section = "__DATA,__objc_data, regular";
39443945

39453946
auto var = IGM.defineTypeMetadata(declaredType, isIndirect, isPattern,

lib/IRGen/GenObjC.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ llvm::Constant *IRGenModule::getAddrOfObjCMethodName(StringRef selector) {
329329
llvm::GlobalValue::PrivateLinkage,
330330
init,
331331
llvm::Twine("\01L_selector_data(") + selector + ")");
332-
global->setSection("__TEXT,__objc_methname,cstring_literals");
332+
SetCStringLiteralSection(global, ObjCLabelType::MethodVarName);
333333
global->setAlignment(1);
334334
addCompilerUsedGlobal(global);
335335

@@ -364,7 +364,8 @@ llvm::Constant *IRGenModule::getAddrOfObjCSelectorRef(StringRef selector) {
364364
global->setAlignment(getPointerAlignment().getValue());
365365

366366
// This section name is magical for the Darwin static and dynamic linkers.
367-
global->setSection("__DATA,__objc_selrefs,literal_pointers,no_dead_strip");
367+
global->setSection(GetObjCSectionName("__objc_selrefs",
368+
"literal_pointers,no_dead_strip"));
368369

369370
// Make sure that this reference does not get optimized away.
370371
addCompilerUsedGlobal(global);
@@ -426,19 +427,19 @@ IRGenModule::getObjCProtocolGlobalVars(ProtocolDecl *proto) {
426427
+ protocolName);
427428
protocolLabel->setAlignment(getPointerAlignment().getValue());
428429
protocolLabel->setVisibility(llvm::GlobalValue::HiddenVisibility);
429-
protocolLabel->setSection("__DATA,__objc_protolist,coalesced,no_dead_strip");
430-
430+
protocolLabel->setSection(GetObjCSectionName("__objc_protolist",
431+
"coalesced,no_dead_strip"));
432+
431433
// Introduce a variable to reference the protocol.
432-
auto *protocolRef
433-
= new llvm::GlobalVariable(Module, Int8PtrTy,
434-
/*constant*/ false,
434+
auto *protocolRef =
435+
new llvm::GlobalVariable(Module, Int8PtrTy, /*constant*/ false,
435436
llvm::GlobalValue::WeakAnyLinkage,
436437
protocolRecord,
437-
llvm::Twine("\01l_OBJC_PROTOCOL_REFERENCE_$_")
438-
+ protocolName);
438+
llvm::Twine("\01l_OBJC_PROTOCOL_REFERENCE_$_") + protocolName);
439439
protocolRef->setAlignment(getPointerAlignment().getValue());
440440
protocolRef->setVisibility(llvm::GlobalValue::HiddenVisibility);
441-
protocolRef->setSection("__DATA,__objc_protorefs,coalesced,no_dead_strip");
441+
protocolRef->setSection(GetObjCSectionName("__objc_protorefs",
442+
"coalesced,no_dead_strip"));
442443

443444
ObjCProtocolPair pair{protocolRecord, protocolRef};
444445
ObjCProtocols.insert({proto, pair});

lib/IRGen/IRGenModule.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,16 @@ class IRGenModule {
587587
Size getAtomicBoolSize() const { return AtomicBoolSize; }
588588
Alignment getAtomicBoolAlignment() const { return AtomicBoolAlign; }
589589

590+
enum class ObjCLabelType {
591+
ClassName,
592+
MethodVarName,
593+
MethodVarType,
594+
PropertyName,
595+
};
596+
597+
std::string GetObjCSectionName(StringRef Section, StringRef MachOAttributes);
598+
void SetCStringLiteralSection(llvm::GlobalVariable *GV, ObjCLabelType Type);
599+
590600
private:
591601
Size PtrSize;
592602
Size AtomicBoolSize;
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
@protocol P
3+
@optional
4+
- (void)method;
5+
@end
6+
7+
@interface I
8+
- (instancetype _Nonnull)init;
9+
@end
10+
11+
I * _Nonnull f(I * _Nonnull);
12+

test/IRGen/Inputs/usr/include/module.map

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@ module Foundation {
2222
module CoreFoundation {
2323
header "BridgeTestCoreFoundation.h"
2424
}
25+
26+
module ObjCInterop {
27+
header "ObjCInterop.h"
28+
}

test/IRGen/objc-sections.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// RUN: %swift -target x86_64-unknown-windows-msvc -parse-stdlib -enable-objc-interop -disable-objc-attr-requires-foundation-module -I %S/Inputs/usr/include -emit-ir %s -o - | %FileCheck %s -check-prefix CHECK-COFF
2+
// RUN: %swift -target x86_64-unknown-linux-gnu -parse-stdlib -enable-objc-interop -disable-objc-attr-requires-foundation-module -I %S/Inputs/usr/include -Xcc --sysroot=/var/empty -emit-ir %s -o - | %FileCheck %s -check-prefix CHECK-ELF
3+
// RUN: %swift -target x86_64-apple-ios -parse-stdlib -enable-objc-interop -disable-objc-attr-requires-foundation-module -I %S/Inputs/usr/include -emit-ir %s -o - | %FileCheck %s -check-prefix CHECK-MACHO
4+
5+
import ObjCInterop
6+
7+
@objc
8+
class C {
9+
}
10+
11+
extension C : P {
12+
public func method() {
13+
f(I())
14+
}
15+
}
16+
17+
@objc_non_lazy_realization
18+
class D {
19+
}
20+
21+
// CHECK-COFF-NOT: @_T04main1CCMf = {{.*}}, section "__DATA,__objc_data, regular"
22+
// CHECK-COFF: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, section ".objc_protolist$B"
23+
// CHECK-COFF: @"\01l_OBJC_PROTOCOL_REFERENCE_$_P" = {{.*}}, section ".objc_protorefs$B"
24+
// CHECK-COFF: @"OBJC_CLASS_REF_$_I" = {{.*}}, section ".objc_classrefs$B"
25+
// CHECK-COFF: @"\01L_selector(init)" = {{.*}}, section ".objc_selrefs$B"
26+
// CHECK-COFF: @objc_classes = {{.*}}, section ".objc_classlist$B"
27+
// CHECK-COFF: @objc_categories = {{.*}}, section ".objc_catlist$B"
28+
// CHECK-COFF: @objc_non_lazy_classes = {{.*}}, section ".objc_nlclslist$B"
29+
30+
// CHECK-ELF-NOT: @_T04main1CCMf = {{.*}}, section "__DATA,__objc_data, regular"
31+
// CHECK-ELF: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, section "objc_protolist"
32+
// CHECK-ELF: @"\01l_OBJC_PROTOCOL_REFERENCE_$_P" = {{.*}}, section "objc_protorefs", align 8
33+
// CHECK-ELF: @"OBJC_CLASS_REF_$_I" = {{.*}}, section "objc_classrefs", align 8
34+
// CHECK-ELF: @"\01L_selector(init)" = {{.*}}, section "objc_selrefs"
35+
// CHECK-ELF: @objc_classes = {{.*}}, section "objc_classlist"
36+
// CHECK-ELF: @objc_categories = {{.*}}, section "objc_catlist"
37+
// CHECK-ELF: @objc_non_lazy_classes = {{.*}}, section "objc_nlclslist", align 8
38+
39+
// CHECK-MACHO: @_T04main1CCMf = {{.*}}, section "__DATA,__objc_data, regular"
40+
// CHECK-MACHO: @"\01l_OBJC_LABEL_PROTOCOL_$_P" = {{.*}}, section "__DATA,__objc_protolist,coalesced,no_dead_strip"
41+
// CHECK-MACHO: @"\01l_OBJC_PROTOCOL_REFERENCE_$_P" = {{.*}}, section "__DATA,__objc_protorefs,coalesced,no_dead_strip"
42+
// CHECK-MACHO: @"OBJC_CLASS_REF_$_I" = {{.*}}, section "__DATA,__objc_classrefs,regular,no_dead_strip"
43+
// CHECK-MACHO: @"\01L_selector(init)" = {{.*}}, section "__DATA,__objc_selrefs,literal_pointers,no_dead_strip"
44+
// CHECK-MACHO: @objc_classes = {{.*}}, section "__DATA,__objc_classlist,regular,no_dead_strip"
45+
// CHECK-MACHO: @objc_categories = {{.*}}, section "__DATA,__objc_catlist,regular,no_dead_strip"
46+
// CHECK-MACHO: @objc_non_lazy_classes = {{.*}}, section "__DATA,__objc_nlclslist,regular,no_dead_strip"
47+

test/IRGen/objc_subclass.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -271,9 +271,9 @@
271271
// CHECK-64: ] }
272272

273273

274-
// CHECK: @objc_classes = internal global [2 x i8*] [i8* bitcast (%swift.type* @_T013objc_subclass10SwiftGizmoCN to i8*), i8* bitcast (%swift.type* @_T013objc_subclass11SwiftGizmo2CN to i8*)], section "__DATA, __objc_classlist, regular, no_dead_strip", align [[WORD_SIZE_IN_BYTES]]
274+
// CHECK: @objc_classes = internal global [2 x i8*] [i8* bitcast (%swift.type* @_T013objc_subclass10SwiftGizmoCN to i8*), i8* bitcast (%swift.type* @_T013objc_subclass11SwiftGizmo2CN to i8*)], section "__DATA,__objc_classlist,regular,no_dead_strip", align [[WORD_SIZE_IN_BYTES]]
275275

276-
// CHECK: @objc_non_lazy_classes = internal global [1 x i8*] [i8* bitcast (%swift.type* @_T013objc_subclass11SwiftGizmo2CN to i8*)], section "__DATA, __objc_nlclslist, regular, no_dead_strip", align [[WORD_SIZE_IN_BYTES]]
276+
// CHECK: @objc_non_lazy_classes = internal global [1 x i8*] [i8* bitcast (%swift.type* @_T013objc_subclass11SwiftGizmo2CN to i8*)], section "__DATA,__objc_nlclslist,regular,no_dead_strip", align [[WORD_SIZE_IN_BYTES]]
277277

278278
import Foundation
279279
import gizmo

test/IRGen/subclass.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
// CHECK: i64 ([[B]]*)* @_T08subclass1BC1fSiyF,
3636
// CHECK: [[A]]* ([[TYPE]]*)* @_T08subclass1AC1gACyFZ
3737
// CHECK: }>
38-
// CHECK: @objc_classes = internal global [2 x i8*] [i8* {{.*}} @_T08subclass1ACN {{.*}}, i8* {{.*}} @_T08subclass1BCN {{.*}}], section "__DATA, __objc_classlist, regular, no_dead_strip", align 8
38+
// CHECK: @objc_classes = internal global [2 x i8*] [i8* {{.*}} @_T08subclass1ACN {{.*}}, i8* {{.*}} @_T08subclass1BCN {{.*}}], section "__DATA,__objc_classlist,regular,no_dead_strip", align 8
3939

4040
class A {
4141
var x = 0

0 commit comments

Comments
 (0)