@@ -1205,11 +1205,33 @@ bool LinkEntity::isAvailableExternally(IRGenModule &IGM) const {
1205
1205
llvm_unreachable (" bad link entity kind" );
1206
1206
}
1207
1207
1208
+ bool LinkEntity::isFragile (IRGenModule &IGM) const {
1209
+ switch (getKind ()) {
1210
+ case Kind::SILFunction:
1211
+ return getSILFunction ()->isFragile ();
1212
+
1213
+ case Kind::SILGlobalVariable:
1214
+ return getSILGlobalVariable ()->isFragile ();
1215
+
1216
+ case Kind::DirectProtocolWitnessTable: {
1217
+ if (auto wt = IGM.SILMod ->lookUpWitnessTable (getProtocolConformance ())) {
1218
+ return wt->isFragile ();
1219
+ } else {
1220
+ return false ;
1221
+ }
1222
+ }
1223
+
1224
+ default :
1225
+ break ;
1226
+ }
1227
+ return false ;
1228
+ }
1229
+
1208
1230
1209
1231
static std::pair<llvm::GlobalValue::LinkageTypes,
1210
1232
llvm::GlobalValue::VisibilityTypes>
1211
1233
getIRLinkage (IRGenModule &IGM,
1212
- SILLinkage linkage, ForDefinition_t isDefinition,
1234
+ SILLinkage linkage, bool isFragile, ForDefinition_t isDefinition,
1213
1235
bool isWeakImported) {
1214
1236
1215
1237
#define RESULT (LINKAGE, VISIBILITY ) \
@@ -1231,25 +1253,39 @@ llvm::GlobalValue::VISIBILITY##Visibility }
1231
1253
break ;
1232
1254
}
1233
1255
1256
+ if (isFragile) {
1257
+ // Fragile functions/globals must be visible from outside, regardless of
1258
+ // their accessibility. If a caller is also fragile and inlined into another
1259
+ // module it must be able to access this (not-inlined) function/global.
1260
+ switch (linkage) {
1261
+ case SILLinkage::Hidden:
1262
+ case SILLinkage::Private:
1263
+ linkage = SILLinkage::Public;
1264
+ break ;
1265
+
1266
+ case SILLinkage::Public:
1267
+ case SILLinkage::Shared:
1268
+ case SILLinkage::HiddenExternal:
1269
+ case SILLinkage::PrivateExternal:
1270
+ case SILLinkage::PublicExternal:
1271
+ case SILLinkage::SharedExternal:
1272
+ break ;
1273
+ }
1274
+ }
1275
+
1234
1276
switch (linkage) {
1235
1277
case SILLinkage::Public:
1236
1278
return {llvm::GlobalValue::ExternalLinkage, PublicDefinitionVisibility};
1237
-
1238
1279
case SILLinkage::Shared:
1239
- case SILLinkage::SharedExternal:
1240
- return RESULT (LinkOnceODR, Hidden);
1241
-
1242
- case SILLinkage::Hidden:
1243
- return RESULT (External, Hidden);
1244
-
1280
+ case SILLinkage::SharedExternal: return RESULT (LinkOnceODR, Hidden);
1281
+ case SILLinkage::Hidden: return RESULT (External, Hidden);
1245
1282
case SILLinkage::Private:
1246
1283
if (IGM.dispatcher .hasMultipleIGMs ()) {
1247
1284
// In case of multiple llvm modules (in multi-threaded compilation) all
1248
1285
// private decls must be visible from other files.
1249
1286
return RESULT (External, Hidden);
1250
1287
}
1251
1288
return RESULT (Internal, Default);
1252
-
1253
1289
case SILLinkage::PublicExternal:
1254
1290
if (isDefinition) {
1255
1291
return RESULT (AvailableExternally, Default);
@@ -1258,12 +1294,15 @@ llvm::GlobalValue::VISIBILITY##Visibility }
1258
1294
if (isWeakImported)
1259
1295
return RESULT (ExternalWeak, Default);
1260
1296
return RESULT (External, Default);
1261
-
1262
1297
case SILLinkage::HiddenExternal:
1263
- case SILLinkage::PrivateExternal:
1264
- if (isDefinition)
1265
- return RESULT (AvailableExternally, Hidden);
1266
- return RESULT (External, Hidden);
1298
+ case SILLinkage::PrivateExternal: {
1299
+ auto visibility = isFragile ? llvm::GlobalValue::DefaultVisibility
1300
+ : llvm::GlobalValue::HiddenVisibility;
1301
+ if (isDefinition) {
1302
+ return {llvm::GlobalValue::AvailableExternallyLinkage, visibility};
1303
+ }
1304
+ return {llvm::GlobalValue::ExternalLinkage, visibility};
1305
+ }
1267
1306
}
1268
1307
llvm_unreachable (" bad SIL linkage" );
1269
1308
}
@@ -1278,6 +1317,7 @@ static void updateLinkageForDefinition(IRGenModule &IGM,
1278
1317
auto linkage = getIRLinkage (
1279
1318
IGM,
1280
1319
entity.getLinkage (IGM, ForDefinition),
1320
+ entity.isFragile (IGM),
1281
1321
ForDefinition,
1282
1322
entity.isWeakImported (IGM.SILMod ->getSwiftModule ()));
1283
1323
global->setLinkage (linkage.first );
@@ -1303,6 +1343,7 @@ LinkInfo LinkInfo::get(IRGenModule &IGM, const LinkEntity &entity,
1303
1343
1304
1344
std::tie (result.Linkage , result.Visibility ) =
1305
1345
getIRLinkage (IGM, entity.getLinkage (IGM, isDefinition),
1346
+ entity.isFragile (IGM),
1306
1347
isDefinition,
1307
1348
entity.isWeakImported (IGM.SILMod ->getSwiftModule ()));
1308
1349
0 commit comments