void layout() override { // If the conforming type is generic, we just want to emit the // unbound generic type here. auto *Nominal = Conformance->getType()->getAnyNominal(); assert(Nominal && "Structural conformance?"); PrettyStackTraceDecl DebugStack("emitting associated type metadata", Nominal); auto *M = IGM.getSILModule().getSwiftModule(); addTypeRef(M, Nominal->getDeclaredType()->getCanonicalType()); auto ProtoTy = Conformance->getProtocol()->getDeclaredType(); addTypeRef(M, ProtoTy->getCanonicalType()); B.addInt32(AssociatedTypes.size()); B.addInt32(AssociatedTypeRecordSize); for (auto AssocTy : AssociatedTypes) { auto NameGlobal = IGM.getAddrOfStringForTypeRef(AssocTy.first); B.addRelativeAddress(NameGlobal); addBuiltinTypeRefs(AssocTy.second); addTypeRef(M, AssocTy.second); } }
ProtocolConformance * ProtocolConformance::getInheritedConformance(ProtocolDecl *protocol) const { // Preserve specialization through this operation by peeling off the // substitutions from a specialized conformance so we can apply them later. const ProtocolConformance *unspecialized; SubstitutionIterator subs; switch (getKind()) { case ProtocolConformanceKind::Specialized: { auto spec = cast<SpecializedProtocolConformance>(this); unspecialized = spec->getGenericConformance(); subs = spec->getGenericSubstitutionIterator(); break; } case ProtocolConformanceKind::Normal: case ProtocolConformanceKind::Inherited: unspecialized = this; break; } ProtocolConformance *foundInherited; // Search for the inherited conformance among our immediate parents. auto &inherited = unspecialized->getInheritedConformances(); auto known = inherited.find(protocol); if (known != inherited.end()) { foundInherited = known->second; goto found_inherited; } // If not there, the inherited conformance must be available through one of // our parents. for (auto &inheritedMapping : inherited) if (inheritedMapping.first->inheritsFrom(protocol)) { foundInherited = inheritedMapping.second-> getInheritedConformance(protocol); goto found_inherited; } llvm_unreachable("Can't find the inherited conformance."); found_inherited: // Specialize the inherited conformance, if necessary. if (!subs.empty()) { TypeSubstitutionMap subMap; ArchetypeConformanceMap conformanceMap; // Fill in the substitution and conformance maps. for (auto archAndSub : subs) { auto arch = archAndSub.first; auto sub = archAndSub.second; conformanceMap[arch] = sub.getConformances(); if (arch->isPrimary()) subMap[arch] = sub.getReplacement(); } return foundInherited->subst(getDeclContext()->getParentModule(), getType(), subs.getSubstitutions(), subMap, conformanceMap); } assert((getType()->isEqual(foundInherited->getType()) || foundInherited->getType()->isSuperclassOf(getType(), nullptr)) && "inherited conformance does not match type"); return foundInherited; }