Skip to content

Commit 8631376

Browse files
Merge pull request #40486 from aschwaighofer/make_objc_protocol_metadata_weak_hidden
Make Objective-C protocol metadata weak hidden
2 parents 4fc9d01 + 0d3af14 commit 8631376

File tree

8 files changed

+100
-83
lines changed

8 files changed

+100
-83
lines changed

lib/IRGen/GenClass.cpp

Lines changed: 87 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,22 +1319,25 @@ namespace {
13191319
assert(TheExtension && "can't emit category data for a class");
13201320
ConstantInitBuilder builder(IGM);
13211321
auto fields = builder.beginStruct();
1322+
auto internalLinkage = llvm::GlobalVariable::InternalLinkage;
13221323

13231324
// struct category_t {
13241325
// char const *name;
13251326
fields.add(IGM.getAddrOfGlobalString(CategoryName));
13261327
// const class_t *theClass;
13271328
fields.add(getClassMetadataRef());
13281329
// const method_list_t *instanceMethods;
1329-
emitAndAddMethodList(fields, MethodListKind::InstanceMethods);
1330+
emitAndAddMethodList(fields, MethodListKind::InstanceMethods,
1331+
internalLinkage);
13301332
// const method_list_t *classMethods;
1331-
emitAndAddMethodList(fields, MethodListKind::ClassMethods);
1333+
emitAndAddMethodList(fields, MethodListKind::ClassMethods,
1334+
internalLinkage);
13321335
// const protocol_list_t *baseProtocols;
1333-
fields.add(buildProtocolList());
1336+
fields.add(buildProtocolList(internalLinkage));
13341337
// const property_list_t *properties;
1335-
fields.add(buildPropertyList(ForClass));
1338+
fields.add(buildPropertyList(ForClass, internalLinkage));
13361339
// const property_list_t *classProperties;
1337-
fields.add(buildPropertyList(ForMetaClass));
1340+
fields.add(buildPropertyList(ForMetaClass, internalLinkage));
13381341
// uint32_t size;
13391342
// FIXME: Clang does this by using non-ad-hoc types for ObjC runtime
13401343
// structures.
@@ -1343,13 +1346,15 @@ namespace {
13431346
// };
13441347

13451348
assert(fields.getNextOffsetFromGlobal() == size);
1346-
return buildGlobalVariable(fields, "_CATEGORY_", /*const*/ true);
1349+
return buildGlobalVariable(fields, "_CATEGORY_", /*const*/ true,
1350+
internalLinkage);
13471351
}
13481352

13491353
llvm::Constant *emitProtocol() {
13501354
ConstantInitBuilder builder(IGM);
13511355
auto fields = builder.beginStruct();
13521356
llvm::SmallString<64> nameBuffer;
1357+
auto weakLinkage = llvm::GlobalVariable::WeakAnyLinkage;
13531358

13541359
assert(isBuildingProtocol() && "not emitting a protocol");
13551360

@@ -1359,17 +1364,20 @@ namespace {
13591364
// char const *name;
13601365
fields.add(IGM.getAddrOfGlobalString(getEntityName(nameBuffer)));
13611366
// const protocol_list_t *baseProtocols;
1362-
fields.add(buildProtocolList());
1367+
fields.add(buildProtocolList(weakLinkage));
13631368
// const method_list_t *requiredInstanceMethods;
1364-
emitAndAddMethodList(fields, MethodListKind::InstanceMethods);
1369+
emitAndAddMethodList(fields, MethodListKind::InstanceMethods,
1370+
weakLinkage);
13651371
// const method_list_t *requiredClassMethods;
1366-
emitAndAddMethodList(fields, MethodListKind::ClassMethods);
1372+
emitAndAddMethodList(fields, MethodListKind::ClassMethods, weakLinkage);
13671373
// const method_list_t *optionalInstanceMethods;
1368-
emitAndAddMethodList(fields, MethodListKind::OptionalInstanceMethods);
1374+
emitAndAddMethodList(fields, MethodListKind::OptionalInstanceMethods,
1375+
weakLinkage);
13691376
// const method_list_t *optionalClassMethods;
1370-
emitAndAddMethodList(fields, MethodListKind::OptionalClassMethods);
1377+
emitAndAddMethodList(fields, MethodListKind::OptionalClassMethods,
1378+
weakLinkage);
13711379
// const property_list_t *properties;
1372-
fields.add(buildPropertyList(ForClass));
1380+
fields.add(buildPropertyList(ForClass, weakLinkage));
13731381

13741382
// uint32_t size;
13751383
// FIXME: Clang does this by using non-ad-hoc types for ObjC runtime
@@ -1391,11 +1399,12 @@ namespace {
13911399
// const char *demangledName;
13921400
fields.addNullPointer(IGM.Int8PtrTy);
13931401
// const property_list_t *classProperties;
1394-
fields.add(buildPropertyList(ForMetaClass));
1402+
fields.add(buildPropertyList(ForMetaClass, weakLinkage));
13951403
// };
13961404

13971405
assert(fields.getNextOffsetFromGlobal() == size);
1398-
return buildGlobalVariable(fields, "_PROTOCOL_", /*const*/ true);
1406+
return buildGlobalVariable(fields, "_PROTOCOL_", /*const*/ true,
1407+
weakLinkage);
13991408
}
14001409

14011410
void emitRODataFields(ConstantStructBuilder &b,
@@ -1456,12 +1465,14 @@ namespace {
14561465
b.add(buildName());
14571466

14581467
// const method_list_t *baseMethods;
1459-
emitAndAddMethodList(b, forMeta ? MethodListKind::ClassMethods
1460-
: MethodListKind::InstanceMethods);
1468+
emitAndAddMethodList(b,
1469+
forMeta ? MethodListKind::ClassMethods
1470+
: MethodListKind::InstanceMethods,
1471+
llvm::GlobalVariable::InternalLinkage);
14611472

14621473
// const protocol_list_t *baseProtocols;
14631474
// Apparently, this list is the same in the class and the metaclass.
1464-
b.add(buildProtocolList());
1475+
b.add(buildProtocolList(llvm::GlobalVariable::InternalLinkage));
14651476

14661477
// const ivar_list_t *ivars;
14671478
if (forMeta) {
@@ -1475,7 +1486,7 @@ namespace {
14751486
b.addNullPointer(IGM.Int8PtrTy);
14761487

14771488
// const property_list_t *baseProperties;
1478-
b.add(buildPropertyList(forMeta));
1489+
b.add(buildPropertyList(forMeta, llvm::GlobalVariable::InternalLinkage));
14791490

14801491
// If hasUpdater is true, the metadata update callback goes here.
14811492
if (hasUpdater) {
@@ -1503,7 +1514,8 @@ namespace {
15031514
// statically. Otherwise, the ObjC runtime may slide the InstanceSize
15041515
// based on changing base class layout.
15051516
return buildGlobalVariable(fields, dataSuffix,
1506-
/*const*/ forMeta || FieldLayout->isFixedSize());
1517+
/*const*/ forMeta || FieldLayout->isFixedSize(),
1518+
llvm::GlobalVariable::InternalLinkage);
15071519
}
15081520

15091521
private:
@@ -1723,7 +1735,8 @@ namespace {
17231735

17241736
/// Emit the method list and add the pointer to the `builder`.
17251737
void emitAndAddMethodList(ConstantInitBuilder::StructBuilder &builder,
1726-
MethodListKind kind) {
1738+
MethodListKind kind,
1739+
llvm::GlobalValue::LinkageTypes linkage) {
17271740
ArrayRef<MethodDescriptor> methods;
17281741
StringRef namePrefix;
17291742
switch (kind) {
@@ -1748,7 +1761,8 @@ namespace {
17481761
namePrefix = "_PROTOCOL_INSTANCE_METHODS_OPT_";
17491762
break;
17501763
}
1751-
llvm::Constant *methodListPtr = buildMethodList(methods, namePrefix);
1764+
llvm::Constant *methodListPtr =
1765+
buildMethodList(methods, namePrefix, linkage);
17521766
builder.add(methodListPtr);
17531767
}
17541768

@@ -1768,12 +1782,9 @@ namespace {
17681782
return null();
17691783
}
17701784

1771-
auto *gv_as_const = buildGlobalVariable(array, "_PROTOCOL_METHOD_TYPES_",
1772-
/*const*/ true,
1773-
/*likage*/ llvm::GlobalVariable::WeakAnyLinkage);
1774-
llvm::GlobalValue *gv = (llvm::GlobalValue *)gv_as_const;
1775-
gv->setVisibility(llvm::GlobalValue::HiddenVisibility);
1776-
return gv;
1785+
return buildGlobalVariable(array, "_PROTOCOL_METHOD_TYPES_",
1786+
/*const*/ true,
1787+
llvm::GlobalVariable::WeakAnyLinkage);
17771788
}
17781789

17791790
void buildExtMethodTypes(ConstantArrayBuilder &array,
@@ -1796,13 +1807,14 @@ namespace {
17961807
///
17971808
/// This method does not return a value of a predictable type.
17981809
llvm::Constant *buildMethodList(ArrayRef<MethodDescriptor> methods,
1799-
StringRef name) {
1800-
return buildOptionalList(methods, 3 * IGM.getPointerSize(), name,
1801-
/*isConst*/ false,
1802-
[&](ConstantArrayBuilder &descriptors,
1803-
MethodDescriptor descriptor) {
1804-
buildMethod(descriptors, descriptor);
1805-
});
1810+
StringRef name,
1811+
llvm::GlobalValue::LinkageTypes linkage) {
1812+
return buildOptionalList(
1813+
methods, 3 * IGM.getPointerSize(), name,
1814+
/*isConst*/ false, linkage,
1815+
[&](ConstantArrayBuilder &descriptors, MethodDescriptor descriptor) {
1816+
buildMethod(descriptors, descriptor);
1817+
});
18061818
}
18071819

18081820
/*** Protocols *********************************************************/
@@ -1819,16 +1831,15 @@ namespace {
18191831
/// };
18201832
///
18211833
/// This method does not return a value of a predictable type.
1822-
llvm::Constant *buildProtocolList() {
1823-
return buildOptionalList(Protocols, Size(0),
1824-
chooseNamePrefix("_PROTOCOLS_",
1825-
"_CATEGORY_PROTOCOLS_",
1826-
"_PROTOCOL_PROTOCOLS_"),
1827-
/*isConst*/ true,
1828-
[&](ConstantArrayBuilder &descriptors,
1829-
ProtocolDecl *protocol) {
1830-
buildProtocol(descriptors, protocol);
1831-
});
1834+
llvm::Constant *buildProtocolList(llvm::GlobalValue::LinkageTypes linkage) {
1835+
return buildOptionalList(
1836+
Protocols, Size(0),
1837+
chooseNamePrefix("_PROTOCOLS_", "_CATEGORY_PROTOCOLS_",
1838+
"_PROTOCOL_PROTOCOLS_"),
1839+
/*isConst*/ true, linkage,
1840+
[&](ConstantArrayBuilder &descriptors, ProtocolDecl *protocol) {
1841+
buildProtocol(descriptors, protocol);
1842+
});
18321843
}
18331844

18341845
void buildProtocol(ConstantArrayBuilder &array, ProtocolDecl *protocol) {
@@ -1949,12 +1960,12 @@ namespace {
19491960
/// This method does not return a value of a predictable type.
19501961
llvm::Constant *buildIvarList() {
19511962
Size eltSize = 3 * IGM.getPointerSize() + Size(8);
1952-
return buildOptionalList(Ivars, eltSize, "_IVARS_",
1953-
/*constant*/ true,
1954-
[&](ConstantArrayBuilder &descriptors,
1955-
Field field) {
1956-
buildIvar(descriptors, field);
1957-
});
1963+
return buildOptionalList(
1964+
Ivars, eltSize, "_IVARS_",
1965+
/*constant*/ true, llvm::GlobalVariable::InternalLinkage,
1966+
[&](ConstantArrayBuilder &descriptors, Field field) {
1967+
buildIvar(descriptors, field);
1968+
});
19581969
}
19591970

19601971
/*** Properties ********************************************************/
@@ -2062,12 +2073,14 @@ namespace {
20622073
/// };
20632074
///
20642075
/// This method does not return a value of a predictable type.
2065-
llvm::Constant *buildPropertyList(ForMetaClass_t classOrMeta) {
2076+
llvm::Constant *buildPropertyList(ForMetaClass_t classOrMeta,
2077+
llvm::GlobalValue::LinkageTypes linkage) {
20662078
if (classOrMeta == ForClass) {
20672079
return buildPropertyList(InstanceProperties,
20682080
chooseNamePrefix("_PROPERTIES_",
20692081
"_CATEGORY_PROPERTIES_",
2070-
"_PROTOCOL_PROPERTIES_"));
2082+
"_PROTOCOL_PROPERTIES_"),
2083+
linkage);
20712084
}
20722085

20732086
// Older OSs' libobjcs can't handle class property data.
@@ -2079,18 +2092,20 @@ namespace {
20792092
return buildPropertyList(ClassProperties,
20802093
chooseNamePrefix("_CLASS_PROPERTIES_",
20812094
"_CATEGORY_CLASS_PROPERTIES_",
2082-
"_PROTOCOL_CLASS_PROPERTIES_"));
2095+
"_PROTOCOL_CLASS_PROPERTIES_"),
2096+
linkage);
20832097
}
20842098

2085-
llvm::Constant *buildPropertyList(ArrayRef<VarDecl*> properties,
2086-
StringRef namePrefix) {
2099+
llvm::Constant *buildPropertyList(ArrayRef<VarDecl *> properties,
2100+
StringRef namePrefix,
2101+
llvm::GlobalValue::LinkageTypes linkage) {
20872102
Size eltSize = 2 * IGM.getPointerSize();
2088-
return buildOptionalList(properties, eltSize, namePrefix,
2089-
/*constant*/ true,
2090-
[&](ConstantArrayBuilder &descriptors,
2091-
VarDecl *property) {
2092-
buildProperty(descriptors, property);
2093-
});
2103+
return buildOptionalList(
2104+
properties, eltSize, namePrefix,
2105+
/*constant*/ true, linkage,
2106+
[&](ConstantArrayBuilder &descriptors, VarDecl *property) {
2107+
buildProperty(descriptors, property);
2108+
});
20942109
}
20952110

20962111
/*** General ***********************************************************/
@@ -2102,10 +2117,9 @@ namespace {
21022117
/// \param optionalEltSize - if non-zero, a size which needs
21032118
/// to be placed in the list header
21042119
template <class C, class Fn>
2105-
llvm::Constant *buildOptionalList(const C &objects,
2106-
Size optionalEltSize,
2107-
StringRef nameBase,
2108-
bool isConst,
2120+
llvm::Constant *buildOptionalList(const C &objects, Size optionalEltSize,
2121+
StringRef nameBase, bool isConst,
2122+
llvm::GlobalValue::LinkageTypes linkage,
21092123
Fn &&buildElement) {
21102124
if (objects.empty())
21112125
return null();
@@ -2144,9 +2158,9 @@ namespace {
21442158

21452159
fields.fillPlaceholderWithInt(countPosition, countType, count);
21462160

2147-
return buildGlobalVariable(fields, nameBase, isConst);
2161+
return buildGlobalVariable(fields, nameBase, isConst, linkage);
21482162
}
2149-
2163+
21502164
/// Get the name of the class or protocol to mangle into the ObjC symbol
21512165
/// name.
21522166
StringRef getEntityName(llvm::SmallVectorImpl<char> &buffer) const {
@@ -2173,9 +2187,9 @@ namespace {
21732187
/// Build a private global variable as a structure containing the
21742188
/// given fields.
21752189
template <class B>
2176-
llvm::Constant *buildGlobalVariable(B &fields, StringRef nameBase, bool isConst,
2177-
llvm::GlobalValue::LinkageTypes linkage =
2178-
llvm::GlobalVariable::InternalLinkage) {
2190+
llvm::Constant *
2191+
buildGlobalVariable(B &fields, StringRef nameBase, bool isConst,
2192+
llvm::GlobalValue::LinkageTypes linkage) {
21792193
llvm::SmallString<64> nameBuffer;
21802194
auto var =
21812195
fields.finishAndCreateGlobal(Twine(nameBase)
@@ -2186,6 +2200,9 @@ namespace {
21862200
IGM.getPointerAlignment(),
21872201
/*constant*/ true,
21882202
linkage);
2203+
if (linkage == llvm::GlobalVariable::WeakAnyLinkage) {
2204+
var->setVisibility(llvm::GlobalValue::HiddenVisibility);
2205+
}
21892206

21902207
switch (IGM.TargetInfo.OutputObjectFormat) {
21912208
case llvm::Triple::MachO:

test/Concurrency/objc_async_protocol_irgen.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ let anyObject: AnyObject = (MyAsyncProtocol.self as AnyObject) // or something l
99
// Make sure we don't emit 2 copies of methods, due to a completion-handler
1010
// version and another due to an async based version.
1111

12-
// CHECK-LABEL: @_PROTOCOL_INSTANCE_METHODS_MyAsyncProtocol = internal constant
12+
// CHECK-LABEL: @_PROTOCOL_INSTANCE_METHODS_MyAsyncProtocol = weak hidden constant
1313
// CHECK-SAME: selector_data(myAsyncMethod:)
1414
// CHECK-NOT: selector_data(myAsyncMethod:)
1515
// CHECK-SAME: align [[ALIGNMENT]]

test/IRGen/generic_casts.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ import Foundation
88
import gizmo
99

1010
// -- Protocol records for cast-to ObjC protocols
11-
// CHECK: @_PROTOCOL__TtP13generic_casts10ObjCProto1_ = internal constant
11+
// CHECK: @_PROTOCOL__TtP13generic_casts10ObjCProto1_ = weak hidden constant
1212
// CHECK: @"\01l_OBJC_LABEL_PROTOCOL_$__TtP13generic_casts10ObjCProto1_" = weak hidden global i8* bitcast ({{.*}} @_PROTOCOL__TtP13generic_casts10ObjCProto1_ to i8*), section {{"__DATA,__objc_protolist,coalesced,no_dead_strip"|"objc_protolist"|".objc_protolist\$B"}}
1313
// CHECK: @"\01l_OBJC_PROTOCOL_REFERENCE_$__TtP13generic_casts10ObjCProto1_" = weak hidden global i8* bitcast ({{.*}} @_PROTOCOL__TtP13generic_casts10ObjCProto1_ to i8*), section {{"__DATA,__objc_protorefs,coalesced,no_dead_strip"|"objc_protorefs"|".objc_protorefs\$B"}}
1414

15-
// CHECK: @_PROTOCOL_NSRuncing = internal constant
15+
// CHECK: @_PROTOCOL_NSRuncing = weak hidden constant
1616
// CHECK: @"\01l_OBJC_LABEL_PROTOCOL_$_NSRuncing" = weak hidden global i8* bitcast ({{.*}} @_PROTOCOL_NSRuncing to i8*), section {{"__DATA,__objc_protolist,coalesced,no_dead_strip"|"objc_protolist"|".objc_protolist\$B"}}
1717
// CHECK: @"\01l_OBJC_PROTOCOL_REFERENCE_$_NSRuncing" = weak hidden global i8* bitcast ({{.*}} @_PROTOCOL_NSRuncing to i8*), section {{"__DATA,__objc_protorefs,coalesced,no_dead_strip"|"objc_protorefs"|".objc_protorefs\$B"}}
1818

@@ -23,7 +23,7 @@ import gizmo
2323

2424
// CHECK: @_DATA__TtC13generic_casts10ObjCClass2 = internal constant {{.*}} @_PROTOCOLS__TtC13generic_casts10ObjCClass2
2525

26-
// CHECK: @_PROTOCOL_PROTOCOLS__TtP13generic_casts10ObjCProto2_ = internal constant { i64, [1 x i8*] } {
26+
// CHECK: @_PROTOCOL_PROTOCOLS__TtP13generic_casts10ObjCProto2_ = weak hidden constant { i64, [1 x i8*] } {
2727
// CHECK: i64 1,
2828
// CHECK: @_PROTOCOL__TtP13generic_casts10ObjCProto1_
2929
// CHECK: }

test/IRGen/objc_async_metadata.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class MyClass: NSObject {
2323
}
2424

2525
// CHECK: [[ENCODE_ASYNC_STRING_PROTO:@.*]] = private unnamed_addr constant [15 x i8] c"v32@0:8@16@?24\00"
26-
// CHECK-LABEL: @_PROTOCOL_INSTANCE_METHODS__TtP19objc_async_metadata7MyProto_ = internal constant
26+
// CHECK-LABEL: @_PROTOCOL_INSTANCE_METHODS__TtP19objc_async_metadata7MyProto_ = weak hidden constant
2727
// CHECK-SAME: _selector_data(myProtoRequirement:completionHandler:)
2828
// CHECK-SAME: [15 x i8]* [[ENCODE_ASYNC_STRING_PROTO]]
2929

test/IRGen/objc_properties.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ class SomeWrapperTests {
269269
// CHECK: i8* getelementptr inbounds ([11 x i8], [11 x i8]* [[SETTER_SIGNATURE]], i64 0, i64 0),
270270
// CHECK: @"$s15objc_properties4TreeC6parentACSgvsTo{{(.ptrauth)?}}"
271271

272-
// CHECK: @_PROTOCOL__TtP15objc_properties5Proto_ = internal constant { {{.+}} } {
272+
// CHECK: @_PROTOCOL__TtP15objc_properties5Proto_ = weak hidden constant { {{.+}} } {
273273
// CHECK: i8* null,
274274
// CHECK: i8* getelementptr inbounds ([{{.+}} x i8], [{{.+}} x i8]* {{@.+}}, i64 0, i64 0),
275275
// CHECK: i8* null,
@@ -289,7 +289,7 @@ class SomeWrapperTests {
289289
// CHECK: [[PROTOCOLPROPERTY_NAME:@.+]] = private unnamed_addr constant [6 x i8] c"value\00"
290290
// CHECK: [[PROTOCOLPROPERTY_ATTRS:@.+]] = private unnamed_addr constant [7 x i8] c"Tq,N,R\00"
291291

292-
// CHECK: @_PROTOCOL_PROPERTIES__TtP15objc_properties5Proto_ = internal constant { {{.*}}] } {
292+
// CHECK: @_PROTOCOL_PROPERTIES__TtP15objc_properties5Proto_ = weak hidden constant { {{.*}}] } {
293293
// CHECK: i32 16,
294294
// CHECK: i32 1,
295295
// CHECK: [1 x { i8*, i8* }] [{
@@ -301,7 +301,7 @@ class SomeWrapperTests {
301301
// CHECK-NEW: [[PROTOCOLCLASSPROPERTY_NAME:@.+]] = private unnamed_addr constant [15 x i8] c"sharedInstance\00"
302302
// CHECK-NEW: [[PROTOCOLCLASSPROPERTY_ATTRS:@.+]] = private unnamed_addr constant [7 x i8] c"T@,N,&\00"
303303

304-
// CHECK-NEW: @_PROTOCOL_CLASS_PROPERTIES__TtP15objc_properties5Proto_ = internal constant { {{.*}}] } {
304+
// CHECK-NEW: @_PROTOCOL_CLASS_PROPERTIES__TtP15objc_properties5Proto_ = weak hidden constant { {{.*}}] } {
305305
// CHECK-NEW: i32 16,
306306
// CHECK-NEW: i32 1,
307307
// CHECK-NEW: [1 x { i8*, i8* }] [{

0 commit comments

Comments
 (0)