Skip to content

Commit 9e414da

Browse files
[IRGen] Use llvm.used for __objc_protorefs and __objc_protolist and add test to verify.
1 parent 3e48f71 commit 9e414da

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

lib/IRGen/GenObjC.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,11 @@ IRGenModule::getObjCProtocolGlobalVars(ProtocolDecl *proto) {
363363
protocolLabel->setSection(GetObjCSectionName("__objc_protolist",
364364
"coalesced,no_dead_strip"));
365365

366+
// Mark used to prevent DCE of public unreferenced protocols to ensure
367+
// that they are available for external use when a used module is used
368+
// as a library.
369+
addUsedGlobal(protocolLabel);
370+
366371
// Introduce a variable to reference the protocol.
367372
auto *protocolRef =
368373
new llvm::GlobalVariable(Module, Int8PtrTy, /*constant*/ false,
@@ -374,6 +379,11 @@ IRGenModule::getObjCProtocolGlobalVars(ProtocolDecl *proto) {
374379
protocolRef->setSection(GetObjCSectionName("__objc_protorefs",
375380
"coalesced,no_dead_strip"));
376381

382+
// Mark used to prevent DCE of public unreferenced protocols to ensure
383+
// that they are available for external use when a used module is used
384+
// as a library.
385+
addUsedGlobal(protocolRef);
386+
377387
ObjCProtocolPair pair{protocolRecord, protocolRef};
378388
ObjCProtocols.insert({proto, pair});
379389

test/IRGen/objc_protocol_vars.sil

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-objc-interop -parse-as-library -emit-ir %s | %FileCheck %s
2+
3+
// It tests whether the vars @"\01l_OBJC_LABEL_PROTOCOL_$__TtP18objc_protocol_vars1T_"
4+
// and @"\01l_OBJC_PROTOCOL_REFERENCE_$__TtP18objc_protocol_vars1T_" are in llvm.used.
5+
//
6+
// import Foundation
7+
// @objc
8+
// public protocol T: AnyObject {
9+
//
10+
// var current: Int32 { get }
11+
//
12+
// func clone() -> T
13+
//
14+
//}
15+
sil_stage canonical
16+
17+
import Builtin
18+
import Swift
19+
import SwiftShims
20+
21+
import Foundation
22+
23+
@objc public protocol T : AnyObject {
24+
@objc var current: Int32 { get }
25+
@objc func clone() -> T
26+
}
27+
28+
// CHECK: @llvm.used = appending global [{{.*}}] [{{.*}}, i8* bitcast (i8** @"\01l_OBJC_LABEL_PROTOCOL_$__TtP18objc_protocol_vars1T_" to i8*), i8* bitcast (i8** @"\01l_OBJC_PROTOCOL_REFERENCE_$__TtP18objc_protocol_vars1T_" to i8*), {{.*}}], {{.*}}
29+

0 commit comments

Comments
 (0)