3333using namespace swift ;
3434using namespace irgen ;
3535
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+
3678static void accumulateSum (IRGenFunction &IGF, llvm::Value *&result,
3779 llvm::Value *value) {
3880 if (result == nullptr ) {
@@ -324,33 +366,6 @@ irgen::emitTypeMetadataPack(IRGenFunction &IGF,
324366 return pack;
325367}
326368
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-
354369MetadataResponse
355370irgen::emitTypeMetadataPackRef (IRGenFunction &IGF, CanPackType packType,
356371 DynamicMetadataRequest request) {
@@ -456,8 +471,6 @@ static llvm::Value *emitPackExpansionElementWitnessTable(
456471 ->mapPackTypeIntoElementContext (patternTy->mapTypeOutOfContext ())
457472 ->getCanonicalType ();
458473
459- // FIXME: Handle witness table packs for associatedtype's conformances.
460-
461474 // Emit the element witness table.
462475 auto *wtable = emitWitnessTableRef (IGF, instantiatedPatternTy,
463476 /* srcMetadataCache=*/ nullptr , conformance);
@@ -574,11 +587,16 @@ llvm::Value *irgen::emitWitnessTablePackRef(IRGenFunction &IGF,
574587 conformance->getProtocol ()) &&
575588 " looking up witness table for protocol that doesn't have one" );
576589
590+ if (auto *wtable = tryGetLocalPackTypeData (
591+ IGF, packType,
592+ LocalTypeDataKind::forAbstractProtocolWitnessTable (
593+ conformance->getProtocol ())))
594+ return wtable;
595+
577596 auto localDataKind =
578597 LocalTypeDataKind::forProtocolWitnessTablePack (conformance);
579598
580- auto wtable = IGF.tryGetLocalTypeData (packType, localDataKind);
581- if (wtable)
599+ if (auto *wtable = tryGetLocalPackTypeData (IGF, packType, localDataKind))
582600 return wtable;
583601
584602 auto pack = emitWitnessTablePack (IGF, packType, conformance);
@@ -600,20 +618,26 @@ llvm::Value *irgen::emitTypeMetadataPackElementRef(
600618 tryGetLocalPackTypeMetadata (IGF, packType, request);
601619 llvm::SmallVector<llvm::Value *> materializedWtablePacks;
602620 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);
606625 }
607626 if (materializedMetadataPack &&
608627 llvm::all_of (materializedWtablePacks,
609- [](auto *wtable ) { return wtable ; })) {
628+ [](auto *wtablePack ) { return wtablePack ; })) {
610629 auto *gep = IGF.Builder .CreateInBoundsGEP (
611630 IGF.IGM .TypeMetadataPtrTy , materializedMetadataPack.getMetadata (),
612631 index);
613632 auto addr =
614633 Address (gep, IGF.IGM .TypeMetadataPtrTy , IGF.IGM .getPointerAlignment ());
615634 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);
617641 wtables.push_back (wtable);
618642 }
619643 return metadata;
0 commit comments