@@ -746,6 +746,8 @@ namespace {
746
746
SmallVector<WitnessTableEntry, 16 > Entries;
747
747
748
748
public:
749
+ void addProtocolConformanceDescriptor () { }
750
+
749
751
// / The next witness is an out-of-line base protocol.
750
752
void addOutOfLineBaseProtocol (ProtocolDecl *baseProto) {
751
753
Entries.push_back (WitnessTableEntry::forOutOfLineBase (baseProto));
@@ -822,7 +824,7 @@ namespace {
822
824
llvm::Value *apply (IRGenFunction &IGF, llvm::Value *wtable) const {
823
825
for (unsigned i = ReversePath.size (); i != 0 ; --i) {
824
826
wtable = emitInvariantLoadOfOpaqueWitness (IGF, wtable,
825
- ReversePath[i-1 ]);
827
+ ReversePath[i-1 ]. forProtocolWitnessTable () );
826
828
wtable = IGF.Builder .CreateBitCast (wtable, IGF.IGM .WitnessTablePtrTy );
827
829
}
828
830
return wtable;
@@ -1224,6 +1226,18 @@ class AccessorConformanceInfo : public ConformanceInfo {
1224
1226
// / Create the access function.
1225
1227
void buildAccessFunction (llvm::Constant *wtable);
1226
1228
1229
+ // / Add reference to the protocol conformance descriptor that generated
1230
+ // / this table.
1231
+ void addProtocolConformanceDescriptor () {
1232
+ if (Conformance.isBehaviorConformance ()) {
1233
+ Table.addNullPointer (IGM.Int8PtrTy );
1234
+ } else {
1235
+ auto descriptor =
1236
+ IGM.getAddrOfProtocolConformanceDescriptor (&Conformance);
1237
+ Table.addBitCast (descriptor, IGM.Int8PtrTy );
1238
+ }
1239
+ }
1240
+
1227
1241
// / A base protocol is witnessed by a pointer to the conformance
1228
1242
// / of this type to that protocol.
1229
1243
void addOutOfLineBaseProtocol (ProtocolDecl *baseProto) {
@@ -1234,7 +1248,8 @@ class AccessorConformanceInfo : public ConformanceInfo {
1234
1248
assert (entry.getBaseProtocolWitness ().Requirement == baseProto
1235
1249
&& " sil witness table does not match protocol" );
1236
1250
auto piIndex = PI.getBaseIndex (baseProto);
1237
- assert ((size_t )piIndex.getValue () == Table.size () &&
1251
+ assert ((size_t )piIndex.getValue () ==
1252
+ Table.size () - WitnessTableFirstRequirementOffset &&
1238
1253
" offset doesn't match ProtocolInfo layout" );
1239
1254
#endif
1240
1255
@@ -1279,7 +1294,8 @@ class AccessorConformanceInfo : public ConformanceInfo {
1279
1294
&& " sil witness table does not match protocol" );
1280
1295
auto piIndex =
1281
1296
PI.getFunctionIndex (cast<AbstractFunctionDecl>(requirement.getDecl ()));
1282
- assert ((size_t )piIndex.getValue () == Table.size () &&
1297
+ assert ((size_t )piIndex.getValue () ==
1298
+ Table.size () - WitnessTableFirstRequirementOffset &&
1283
1299
" offset doesn't match ProtocolInfo layout" );
1284
1300
#endif
1285
1301
@@ -1310,7 +1326,8 @@ class AccessorConformanceInfo : public ConformanceInfo {
1310
1326
== requirement.getAssociation ()
1311
1327
&& " sil witness table does not match protocol" );
1312
1328
auto piIndex = PI.getAssociatedTypeIndex (requirement);
1313
- assert ((size_t )piIndex.getValue () == Table.size () &&
1329
+ assert ((size_t )piIndex.getValue () ==
1330
+ Table.size () - WitnessTableFirstRequirementOffset &&
1314
1331
" offset doesn't match ProtocolInfo layout" );
1315
1332
#endif
1316
1333
@@ -1358,7 +1375,8 @@ class AccessorConformanceInfo : public ConformanceInfo {
1358
1375
requirement.getAssociatedRequirement ()
1359
1376
&& " sil witness table does not match protocol" );
1360
1377
auto piIndex = PI.getAssociatedConformanceIndex (requirement);
1361
- assert ((size_t )piIndex.getValue () == Table.size () &&
1378
+ assert ((size_t )piIndex.getValue () ==
1379
+ Table.size () - WitnessTableFirstRequirementOffset &&
1362
1380
" offset doesn't match ProtocolInfo layout" );
1363
1381
#endif
1364
1382
@@ -2057,16 +2075,17 @@ void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) {
2057
2075
2058
2076
// Build the witnesses.
2059
2077
ConstantInitBuilder builder (*this );
2060
- auto witnesses = builder.beginArray (Int8PtrTy);
2061
- WitnessTableBuilder wtableBuilder (*this , witnesses , wt);
2078
+ auto wtableContents = builder.beginArray (Int8PtrTy);
2079
+ WitnessTableBuilder wtableBuilder (*this , wtableContents , wt);
2062
2080
wtableBuilder.build ();
2063
2081
2064
- assert (getProtocolInfo (wt->getConformance ()->getProtocol ())
2065
- .getNumWitnesses () == witnesses.size ()
2082
+ assert ((getProtocolInfo (wt->getConformance ()->getProtocol ())
2083
+ .getNumWitnesses () + WitnessTableFirstRequirementOffset)
2084
+ == wtableContents.size ()
2066
2085
&& " witness table size doesn't match ProtocolInfo" );
2067
2086
2068
2087
// Produce the initializer value.
2069
- auto initializer = witnesses .finishAndCreateFuture ();
2088
+ auto initializer = wtableContents .finishAndCreateFuture ();
2070
2089
2071
2090
auto global = cast<llvm::GlobalVariable>(
2072
2091
getAddrOfWitnessTable (wt->getConformance (), initializer));
@@ -2264,7 +2283,8 @@ emitAssociatedTypeWitnessTableRef(IRGenFunction &IGF,
2264
2283
llvm::Value *wtable,
2265
2284
WitnessIndex index,
2266
2285
llvm::Value *associatedTypeMetadata) {
2267
- llvm::Value *witness = emitInvariantLoadOfOpaqueWitness (IGF, wtable, index );
2286
+ llvm::Value *witness = emitInvariantLoadOfOpaqueWitness (IGF, wtable,
2287
+ index .forProtocolWitnessTable ());
2268
2288
2269
2289
// Cast the witness to the appropriate function type.
2270
2290
auto sig = IGF.IGM .getAssociatedTypeWitnessTableAccessFunctionSignature ();
@@ -2360,7 +2380,8 @@ llvm::Value *MetadataPath::followComponent(IRGenFunction &IGF,
2360
2380
2361
2381
if (source) {
2362
2382
WitnessIndex index (component.getPrimaryIndex (), /* prefix*/ false );
2363
- source = emitInvariantLoadOfOpaqueWitness (IGF, source, index );
2383
+ source = emitInvariantLoadOfOpaqueWitness (IGF, source,
2384
+ index .forProtocolWitnessTable ());
2364
2385
source = IGF.Builder .CreateBitCast (source, IGF.IGM .WitnessTablePtrTy );
2365
2386
setProtocolWitnessTableName (IGF.IGM , source, sourceKey.Type ,
2366
2387
inheritedProtocol);
@@ -3090,7 +3111,8 @@ irgen::emitWitnessMethodValue(IRGenFunction &IGF,
3090
3111
auto &fnProtoInfo = IGF.IGM .getProtocolInfo (proto);
3091
3112
auto index = fnProtoInfo.getFunctionIndex (fn);
3092
3113
llvm::Value *witnessFnPtr =
3093
- emitInvariantLoadOfOpaqueWitness (IGF, wtable, index );
3114
+ emitInvariantLoadOfOpaqueWitness (IGF, wtable,
3115
+ index .forProtocolWitnessTable ());
3094
3116
3095
3117
auto fnType = IGF.IGM .getSILTypes ().getConstantFunctionType (member);
3096
3118
Signature signature = IGF.IGM .getSignature (fnType);
@@ -3134,7 +3156,8 @@ llvm::Value *irgen::emitAssociatedTypeMetadataRef(IRGenFunction &IGF,
3134
3156
AssociatedType associatedType) {
3135
3157
auto &pi = IGF.IGM .getProtocolInfo (associatedType.getSourceProtocol ());
3136
3158
auto index = pi .getAssociatedTypeIndex (associatedType);
3137
- llvm::Value *witness = emitInvariantLoadOfOpaqueWitness (IGF, wtable, index );
3159
+ llvm::Value *witness = emitInvariantLoadOfOpaqueWitness (IGF, wtable,
3160
+ index .forProtocolWitnessTable ());
3138
3161
3139
3162
// Cast the witness to the appropriate function type.
3140
3163
auto sig = IGF.IGM .getAssociatedTypeMetadataAccessFunctionSignature ();
0 commit comments