@@ -1617,16 +1617,34 @@ class SILGenConformance : public SILGenWitnessTable<SILGenConformance> {
1617
1617
NormalProtocolConformance *Conformance;
1618
1618
std::vector<SILWitnessTable::Entry> Entries;
1619
1619
SILLinkage Linkage;
1620
+ IsFragile_t isFragile;
1620
1621
1621
1622
SILGenConformance (SILGenModule &SGM, NormalProtocolConformance *C)
1622
1623
// We only need to emit witness tables for base NormalProtocolConformances.
1623
1624
: SGM(SGM), Conformance(C->getRootNormalConformance ()),
1624
1625
Linkage(getLinkageForProtocolConformance(Conformance,
1625
1626
ForDefinition))
1626
1627
{
1627
- // Not all protocols use witness tables.
1628
- if (!Lowering::TypeConverter::protocolRequiresWitnessTable (
1629
- Conformance->getProtocol ()))
1628
+ auto *proto = Conformance->getProtocol ();
1629
+
1630
+ isFragile = IsNotFragile;
1631
+
1632
+ // Serialize the witness table if we're serializing everything with
1633
+ // -sil-serialize-all.
1634
+ if (SGM.makeModuleFragile )
1635
+ isFragile = IsFragile;
1636
+
1637
+ // Serialize the witness table if type has a fixed layout in all
1638
+ // resilience domains, and the conformance is externally visible.
1639
+ auto nominal = Conformance->getInterfaceType ()->getAnyNominal ();
1640
+ if (nominal->hasFixedLayout () &&
1641
+ proto->getEffectiveAccess () >= Accessibility::Public &&
1642
+ nominal->getEffectiveAccess () >= Accessibility::Public)
1643
+ isFragile = IsFragile;
1644
+
1645
+ // Not all protocols use witness tables; in this case we just skip
1646
+ // all of emit() below completely.
1647
+ if (!Lowering::TypeConverter::protocolRequiresWitnessTable (proto))
1630
1648
Conformance = nullptr ;
1631
1649
}
1632
1650
@@ -1638,19 +1656,6 @@ class SILGenConformance : public SILGenWitnessTable<SILGenConformance> {
1638
1656
auto *proto = Conformance->getProtocol ();
1639
1657
visitProtocolDecl (proto);
1640
1658
1641
- // Serialize the witness table in two cases:
1642
- // 1) We're serializing everything
1643
- // 2) The type has a fixed layout in all resilience domains, and the
1644
- // conformance is externally visible
1645
- IsFragile_t isFragile = IsNotFragile;
1646
- if (SGM.makeModuleFragile )
1647
- isFragile = IsFragile;
1648
- if (auto nominal = Conformance->getInterfaceType ()->getAnyNominal ())
1649
- if (nominal->hasFixedLayout () &&
1650
- proto->getEffectiveAccess () >= Accessibility::Public &&
1651
- nominal->getEffectiveAccess () >= Accessibility::Public)
1652
- isFragile = IsFragile;
1653
-
1654
1659
// Check if we already have a declaration or definition for this witness
1655
1660
// table.
1656
1661
if (auto *wt = SGM.M .lookUpWitnessTable (Conformance, false )) {
@@ -1733,7 +1738,8 @@ class SILGenConformance : public SILGenWitnessTable<SILGenConformance> {
1733
1738
}
1734
1739
1735
1740
SILFunction *witnessFn =
1736
- SGM.emitProtocolWitness (Conformance, Linkage, requirementRef, witnessRef,
1741
+ SGM.emitProtocolWitness (Conformance, isFragile,
1742
+ requirementRef, witnessRef,
1737
1743
isFree, witness);
1738
1744
Entries.push_back (
1739
1745
SILWitnessTable::MethodWitness{requirementRef, witnessFn});
@@ -1844,7 +1850,7 @@ static bool maybeOpenCodeProtocolWitness(SILGenFunction &gen,
1844
1850
1845
1851
SILFunction *
1846
1852
SILGenModule::emitProtocolWitness (ProtocolConformance *conformance,
1847
- SILLinkage linkage ,
1853
+ IsFragile_t isFragile ,
1848
1854
SILDeclRef requirement,
1849
1855
SILDeclRef witnessRef,
1850
1856
IsFreeFunctionWitness_t isFree,
@@ -1942,11 +1948,11 @@ SILGenModule::emitProtocolWitness(ProtocolConformance *conformance,
1942
1948
if (witnessRef.isAlwaysInline ())
1943
1949
InlineStrategy = AlwaysInline;
1944
1950
1945
- IsFragile_t isFragile = IsNotFragile ;
1946
- if (makeModuleFragile)
1947
- isFragile = IsFragile;
1948
- if (witnessRef. isFragile ())
1949
- isFragile = IsFragile ;
1951
+ // Witness thunks for fragile conformances have shared linkage ;
1952
+ // otherwise the thunk can just be private.
1953
+ SILLinkage linkage = (isFragile
1954
+ ? SILLinkage::Shared
1955
+ : SILLinkage::Private) ;
1950
1956
1951
1957
auto *f = M.createFunction (
1952
1958
linkage, nameBuffer, witnessSILFnType,
@@ -2045,7 +2051,7 @@ class SILGenDefaultWitnessTable
2045
2051
SILDeclRef witnessRef,
2046
2052
IsFreeFunctionWitness_t isFree,
2047
2053
Witness witness) {
2048
- SILFunction *witnessFn = SGM.emitProtocolWitness (nullptr , Linkage ,
2054
+ SILFunction *witnessFn = SGM.emitProtocolWitness (nullptr , IsNotFragile ,
2049
2055
requirementRef, witnessRef,
2050
2056
isFree, witness);
2051
2057
auto entry = SILDefaultWitnessTable::Entry (requirementRef, witnessFn);
0 commit comments