FixedTypeMetadataBuilder(IRGenModule &IGM, CanType builtinType) : ReflectionMetadataBuilder(IGM) { module = builtinType->getASTContext().TheBuiltinModule; type = builtinType; ti = &cast<FixedTypeInfo>(IGM.getTypeInfoForUnlowered(builtinType)); }
void addBuiltinType(CanType builtinType) { addTypeRef(builtinType->getASTContext().TheBuiltinModule, builtinType); auto &ti = cast<FixedTypeInfo>(IGM.getTypeInfoForUnlowered(builtinType)); addConstantInt32(ti.getFixedSize().getValue()); addConstantInt32(ti.getFixedAlignment().getValue()); addConstantInt32(ti.getFixedStride().getValue()); addConstantInt32(ti.getFixedExtraInhabitantCount(IGM)); }
CanType TypeConverter::getBridgedInputType(SILFunctionTypeRepresentation rep, AbstractionPattern pattern, CanType input) { if (auto tuple = dyn_cast<TupleType>(input)) { SmallVector<TupleTypeElt, 4> bridgedFields; bool changed = false; for (unsigned i : indices(tuple->getElements())) { auto &elt = tuple->getElement(i); Type bridged = getLoweredBridgedType(pattern.getTupleElementType(i), elt.getType(), rep, TypeConverter::ForArgument); if (!bridged) { Context.Diags.diagnose(SourceLoc(), diag::could_not_find_bridge_type, elt.getType()); llvm::report_fatal_error("unable to set up the ObjC bridge!"); } CanType canBridged = bridged->getCanonicalType(); if (canBridged != CanType(elt.getType())) { changed = true; bridgedFields.push_back(elt.getWithType(canBridged)); } else { bridgedFields.push_back(elt); } } if (!changed) return input; return CanType(TupleType::get(bridgedFields, input->getASTContext())); } auto loweredBridgedType = getLoweredBridgedType(pattern, input, rep, TypeConverter::ForArgument); if (!loweredBridgedType) { Context.Diags.diagnose(SourceLoc(), diag::could_not_find_bridge_type, input); llvm::report_fatal_error("unable to set up the ObjC bridge!"); } return loweredBridgedType->getCanonicalType(); }
static CanType dropLastElement(CanType type) { auto elts = cast<TupleType>(type)->getElements().drop_back(); return TupleType::get(elts, type->getASTContext())->getCanonicalType(); }
Optional<ProtocolConformanceRef> SubstitutionMap::lookupConformance(CanType type, ProtocolDecl *proto) const { if (empty()) return None; // If we have an archetype, map out of the context so we can compute a // conformance access path. if (auto archetype = dyn_cast<ArchetypeType>(type)) { type = archetype->getInterfaceType()->getCanonicalType(); } // Error path: if we don't have a type parameter, there is no conformance. // FIXME: Query concrete conformances in the generic signature? if (!type->isTypeParameter()) return None; auto genericSig = getGenericSignature(); // Fast path unsigned index = 0; for (auto reqt : genericSig->getRequirements()) { if (reqt.getKind() == RequirementKind::Conformance) { if (reqt.getFirstType()->isEqual(type) && reqt.getSecondType()->isEqual(proto->getDeclaredType())) return getConformances()[index]; index++; } } // Retrieve the starting conformance from the conformance map. auto getInitialConformance = [&](Type type, ProtocolDecl *proto) -> Optional<ProtocolConformanceRef> { unsigned conformanceIndex = 0; for (const auto &req : getGenericSignature()->getRequirements()) { if (req.getKind() != RequirementKind::Conformance) continue; // Is this the conformance we're looking for? if (req.getFirstType()->isEqual(type) && req.getSecondType()->castTo<ProtocolType>()->getDecl() == proto) { return getConformances()[conformanceIndex]; } ++conformanceIndex; } return None; }; // Check whether the superclass conforms. if (auto superclass = genericSig->getSuperclassBound(type)) { LookUpConformanceInSignature lookup(*getGenericSignature()); if (auto conformance = lookup(type->getCanonicalType(), superclass, proto)) return conformance; } // If the type doesn't conform to this protocol, the result isn't formed // from these requirements. if (!genericSig->conformsToProtocol(type, proto)) return None; auto accessPath = genericSig->getConformanceAccessPath(type, proto); // Fall through because we cannot yet evaluate an access path. Optional<ProtocolConformanceRef> conformance; for (const auto &step : accessPath) { // For the first step, grab the initial conformance. if (!conformance) { conformance = getInitialConformance(step.first, step.second); if (!conformance) return None; continue; } if (conformance->isInvalid()) return conformance; // If we've hit an abstract conformance, everything from here on out is // abstract. // FIXME: This may not always be true, but it holds for now. if (conformance->isAbstract()) { // FIXME: Rip this out once we can get a concrete conformance from // an archetype. auto *M = proto->getParentModule(); auto substType = type.subst(*this); if (substType && (!substType->is<ArchetypeType>() || substType->castTo<ArchetypeType>()->getSuperclass()) && !substType->isTypeParameter() && !substType->isExistentialType()) { return M->lookupConformance(substType, proto); } return ProtocolConformanceRef(proto); } // For the second step, we're looking into the requirement signature for // this protocol. auto concrete = conformance->getConcrete(); auto normal = concrete->getRootNormalConformance(); // If we haven't set the signature conformances yet, force the issue now. if (normal->getSignatureConformances().empty()) { // If we're in the process of checking the type witnesses, fail // gracefully. // FIXME: Seems like we should be able to get at the intermediate state // to use that. if (normal->getState() == ProtocolConformanceState::CheckingTypeWitnesses) return None; auto lazyResolver = type->getASTContext().getLazyResolver(); if (lazyResolver == nullptr) return None; lazyResolver->resolveTypeWitness(normal, nullptr); // Error case: the conformance is broken, so we cannot handle this // substitution. if (normal->getSignatureConformances().empty()) return None; } // Get the associated conformance. conformance = concrete->getAssociatedConformance(step.first, step.second); } return conformance; }