33
33
using namespace swift ;
34
34
using namespace irgen ;
35
35
36
+ static CanPackArchetypeType
37
+ getForwardedPackArchetypeType (CanPackType packType) {
38
+ if (packType->getNumElements () != 1 )
39
+ return CanPackArchetypeType ();
40
+ auto uncastElement = packType.getElementType (0 );
41
+ auto element = dyn_cast<PackExpansionType>(uncastElement);
42
+ if (!element)
43
+ return CanPackArchetypeType ();
44
+ auto patternType = element.getPatternType ();
45
+ auto packArchetype = dyn_cast<PackArchetypeType>(patternType);
46
+ return packArchetype;
47
+ }
48
+
49
+ static MetadataResponse
50
+ tryGetLocalPackTypeMetadata (IRGenFunction &IGF, CanPackType packType,
51
+ DynamicMetadataRequest request) {
52
+ if (auto result = IGF.tryGetLocalTypeMetadata (packType, request))
53
+ return result;
54
+
55
+ if (auto packArchetypeType = getForwardedPackArchetypeType (packType)) {
56
+ if (auto result = IGF.tryGetLocalTypeMetadata (packArchetypeType, request))
57
+ return result;
58
+ }
59
+
60
+ return MetadataResponse ();
61
+ }
62
+
63
+ static llvm::Value *tryGetLocalPackTypeData (IRGenFunction &IGF,
64
+ CanPackType packType,
65
+ LocalTypeDataKind localDataKind) {
66
+ if (auto *wtable = IGF.tryGetLocalTypeData (packType, localDataKind))
67
+ return wtable;
68
+
69
+ if (auto packArchetypeType = getForwardedPackArchetypeType (packType)) {
70
+ if (auto *wtable =
71
+ IGF.tryGetLocalTypeData (packArchetypeType, localDataKind))
72
+ return wtable;
73
+ }
74
+
75
+ return nullptr ;
76
+ }
77
+
36
78
static void accumulateSum (IRGenFunction &IGF, llvm::Value *&result,
37
79
llvm::Value *value) {
38
80
if (result == nullptr ) {
@@ -324,33 +366,6 @@ irgen::emitTypeMetadataPack(IRGenFunction &IGF,
324
366
return pack;
325
367
}
326
368
327
- static CanPackArchetypeType
328
- getForwardedPackArchetypeType (CanPackType packType) {
329
- if (packType->getNumElements () != 1 )
330
- return CanPackArchetypeType ();
331
- auto uncastElement = packType.getElementType (0 );
332
- auto element = dyn_cast<PackExpansionType>(uncastElement);
333
- if (!element)
334
- return CanPackArchetypeType ();
335
- auto patternType = element.getPatternType ();
336
- auto packArchetype = dyn_cast<PackArchetypeType>(patternType);
337
- return packArchetype;
338
- }
339
-
340
- static MetadataResponse
341
- tryGetLocalPackTypeMetadata (IRGenFunction &IGF, CanPackType packType,
342
- DynamicMetadataRequest request) {
343
- if (auto result = IGF.tryGetLocalTypeMetadata (packType, request))
344
- return result;
345
-
346
- if (auto packArchetypeType = getForwardedPackArchetypeType (packType)) {
347
- if (auto result = IGF.tryGetLocalTypeMetadata (packArchetypeType, request))
348
- return result;
349
- }
350
-
351
- return MetadataResponse ();
352
- }
353
-
354
369
MetadataResponse
355
370
irgen::emitTypeMetadataPackRef (IRGenFunction &IGF, CanPackType packType,
356
371
DynamicMetadataRequest request) {
@@ -456,8 +471,6 @@ static llvm::Value *emitPackExpansionElementWitnessTable(
456
471
->mapPackTypeIntoElementContext (patternTy->mapTypeOutOfContext ())
457
472
->getCanonicalType ();
458
473
459
- // FIXME: Handle witness table packs for associatedtype's conformances.
460
-
461
474
// Emit the element witness table.
462
475
auto *wtable = emitWitnessTableRef (IGF, instantiatedPatternTy,
463
476
/* srcMetadataCache=*/ nullptr , conformance);
@@ -574,11 +587,16 @@ llvm::Value *irgen::emitWitnessTablePackRef(IRGenFunction &IGF,
574
587
conformance->getProtocol ()) &&
575
588
" looking up witness table for protocol that doesn't have one" );
576
589
590
+ if (auto *wtable = tryGetLocalPackTypeData (
591
+ IGF, packType,
592
+ LocalTypeDataKind::forAbstractProtocolWitnessTable (
593
+ conformance->getProtocol ())))
594
+ return wtable;
595
+
577
596
auto localDataKind =
578
597
LocalTypeDataKind::forProtocolWitnessTablePack (conformance);
579
598
580
- auto wtable = IGF.tryGetLocalTypeData (packType, localDataKind);
581
- if (wtable)
599
+ if (auto *wtable = tryGetLocalPackTypeData (IGF, packType, localDataKind))
582
600
return wtable;
583
601
584
602
auto pack = emitWitnessTablePack (IGF, packType, conformance);
@@ -600,20 +618,26 @@ llvm::Value *irgen::emitTypeMetadataPackElementRef(
600
618
tryGetLocalPackTypeMetadata (IGF, packType, request);
601
619
llvm::SmallVector<llvm::Value *> materializedWtablePacks;
602
620
for (auto protocol : protocols) {
603
- auto wtable = IGF.tryGetLocalTypeData (
604
- packType, LocalTypeDataKind::forAbstractProtocolWitnessTable (protocol));
605
- materializedWtablePacks.push_back (wtable);
621
+ auto *wtablePack = tryGetLocalPackTypeData (
622
+ IGF, packType,
623
+ LocalTypeDataKind::forAbstractProtocolWitnessTable (protocol));
624
+ materializedWtablePacks.push_back (wtablePack);
606
625
}
607
626
if (materializedMetadataPack &&
608
627
llvm::all_of (materializedWtablePacks,
609
- [](auto *wtable ) { return wtable ; })) {
628
+ [](auto *wtablePack ) { return wtablePack ; })) {
610
629
auto *gep = IGF.Builder .CreateInBoundsGEP (
611
630
IGF.IGM .TypeMetadataPtrTy , materializedMetadataPack.getMetadata (),
612
631
index);
613
632
auto addr =
614
633
Address (gep, IGF.IGM .TypeMetadataPtrTy , IGF.IGM .getPointerAlignment ());
615
634
auto *metadata = IGF.Builder .CreateLoad (addr);
616
- for (auto *wtable : materializedWtablePacks) {
635
+ for (auto *wtablePack : materializedWtablePacks) {
636
+ auto *gep = IGF.Builder .CreateInBoundsGEP (IGF.IGM .WitnessTablePtrTy ,
637
+ wtablePack, index);
638
+ auto addr = Address (gep, IGF.IGM .WitnessTablePtrTy ,
639
+ IGF.IGM .getPointerAlignment ());
640
+ auto *wtable = IGF.Builder .CreateLoad (addr);
617
641
wtables.push_back (wtable);
618
642
}
619
643
return metadata;
0 commit comments