MetadataResponse irgen::emitArchetypeTypeMetadataRef(IRGenFunction &IGF, CanArchetypeType archetype, DynamicMetadataRequest request) { // Check for an existing cache entry. if (auto response = IGF.tryGetLocalTypeMetadata(archetype, request)) return response; // If that's not present, this must be an associated type. assert(!archetype->isPrimary() && "type metadata for primary archetype was not bound in context"); CanArchetypeType parent(archetype->getParent()); AssociatedType association(archetype->getAssocType()); MetadataResponse response = emitAssociatedTypeMetadataRef(IGF, parent, association, request); setTypeMetadataName(IGF.IGM, response.getMetadata(), archetype); IGF.setScopedLocalTypeMetadata(archetype, response); return response; }
static IRGenFunction::ArchetypeAccessPath findAccessPathDeclaringConformance(IRGenFunction &IGF, CanArchetypeType archetype, ProtocolDecl *protocol) { // Consider all the associated type relationships we know about. // Use the archetype's parent relationship first if possible. if (!archetype->isPrimary()) { auto parent = archetype.getParent(); auto association = findConformanceDeclaration(parent->getConformsTo(), archetype->getAssocType(), protocol); if (association) return { parent, association }; } for (auto accessPath : IGF.getArchetypeAccessPaths(archetype)) { auto association = findConformanceDeclaration(accessPath.BaseType->getConformsTo(), accessPath.Association, protocol); if (association) return { accessPath.BaseType, association }; } llvm_unreachable("no relation found that declares conformance to target"); }