Example #1
0
  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);
    }
  }
Example #2
0
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;
}