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