Skip to content

Commit d8552ce

Browse files
committed
IRGen: ensure that ObjC sections match on all targets
Adjust the IRGen for ObjC interop to ensure that the section that metadata is emitted into the correct section for non-MachO targets. This also adds a more comprehensive test for ensuring that the IRGen can now be tested on all targets. Since the ObjC interop is now controllable via the driver, this test does not require that the objc_interop feature is present as it is a IRGen test. This is the first step to remove the `REQUIRES: objc_interop` from the IRGen tests.
1 parent a14664a commit d8552ce

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)