本文整理汇总了C++中ProtocolConformanceRef::getConcrete方法的典型用法代码示例。如果您正苦于以下问题:C++ ProtocolConformanceRef::getConcrete方法的具体用法?C++ ProtocolConformanceRef::getConcrete怎么用?C++ ProtocolConformanceRef::getConcrete使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类ProtocolConformanceRef
的用法示例。
在下文中一共展示了ProtocolConformanceRef::getConcrete方法的10个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: SubstitutionMap
/// Compute substitutions for making a direct call to a SIL function with
/// @convention(witness_method) convention.
///
/// Such functions have a substituted generic signature where the
/// abstract `Self` parameter from the original type of the protocol
/// requirement is replaced by a concrete type.
///
/// Thus, the original substitutions of the apply instruction that
/// are written in terms of the requirement's generic signature need
/// to be remapped to substitutions suitable for the witness signature.
///
/// Supported remappings are:
///
/// - (Concrete witness thunk) Original substitutions:
/// [Self := ConcreteType, R0 := X0, R1 := X1, ...]
/// - Requirement generic signature:
/// <Self : P, R0, R1, ...>
/// - Witness thunk generic signature:
/// <W0, W1, ...>
/// - Remapped substitutions:
/// [W0 := X0, W1 := X1, ...]
///
/// - (Class witness thunk) Original substitutions:
/// [Self := C<A0, A1>, T0 := X0, T1 := X1, ...]
/// - Requirement generic signature:
/// <Self : P, R0, R1, ...>
/// - Witness thunk generic signature:
/// <Self : C<B0, B1>, B0, B1, W0, W1, ...>
/// - Remapped substitutions:
/// [Self := C<B0, B1>, B0 := A0, B1 := A1, W0 := X0, W1 := X1]
///
/// - (Default witness thunk) Original substitutions:
/// [Self := ConcreteType, R0 := X0, R1 := X1, ...]
/// - Requirement generic signature:
/// <Self : P, R0, R1, ...>
/// - Witness thunk generic signature:
/// <Self : P, W0, W1, ...>
/// - Remapped substitutions:
/// [Self := ConcreteType, W0 := X0, W1 := X1, ...]
///
/// \param conformanceRef The (possibly-specialized) conformance
/// \param requirementSig The generic signature of the requirement
/// \param witnessThunkSig The generic signature of the witness method
/// \param origSubMap The substitutions from the call instruction
/// \param isDefaultWitness True if this is a default witness method
/// \param classWitness The ClassDecl if this is a class witness method
static SubstitutionMap
getWitnessMethodSubstitutions(
ModuleDecl *mod,
ProtocolConformanceRef conformanceRef,
GenericSignature *requirementSig,
GenericSignature *witnessThunkSig,
SubstitutionMap origSubMap,
bool isDefaultWitness,
ClassDecl *classWitness) {
if (witnessThunkSig == nullptr)
return SubstitutionMap();
if (isDefaultWitness)
return origSubMap;
assert(!conformanceRef.isAbstract());
auto conformance = conformanceRef.getConcrete();
// If `Self` maps to a bound generic type, this gives us the
// substitutions for the concrete type's generic parameters.
auto baseSubMap = conformance->getSubstitutions(mod);
unsigned baseDepth = 0;
auto *rootConformance = conformance->getRootNormalConformance();
if (auto *witnessSig = rootConformance->getGenericSignature())
baseDepth = witnessSig->getGenericParams().back()->getDepth() + 1;
// If the witness has a class-constrained 'Self' generic parameter,
// we have to build a new substitution map that shifts all generic
// parameters down by one.
if (classWitness != nullptr) {
auto *proto = conformance->getProtocol();
auto selfType = proto->getSelfInterfaceType();
auto selfSubMap = SubstitutionMap::getProtocolSubstitutions(
proto, selfType.subst(origSubMap), conformanceRef);
if (baseSubMap.empty()) {
assert(baseDepth == 0);
baseSubMap = selfSubMap;
} else {
baseSubMap = SubstitutionMap::combineSubstitutionMaps(
selfSubMap,
baseSubMap,
CombineSubstitutionMaps::AtDepth,
/*firstDepth=*/1,
/*secondDepth=*/0,
witnessThunkSig);
}
baseDepth += 1;
}
return SubstitutionMap::combineSubstitutionMaps(
baseSubMap,
//.........这里部分代码省略.........
示例2: get
Type
ProtocolConformanceRef::getTypeWitnessByName(Type type,
ProtocolConformanceRef conformance,
Identifier name,
LazyResolver *resolver) {
// For an archetype, retrieve the nested type with the appropriate
// name. There are no conformance tables.
if (auto archetype = type->getAs<ArchetypeType>()) {
return archetype->getNestedType(name);
}
// Find the named requirement.
AssociatedTypeDecl *assocType = nullptr;
auto members = conformance.getRequirement()->lookupDirect(name);
for (auto member : members) {
assocType = dyn_cast<AssociatedTypeDecl>(member);
if (assocType)
break;
}
// FIXME: Shouldn't this be a hard error?
if (!assocType)
return nullptr;
if (conformance.isAbstract())
return DependentMemberType::get(type, assocType);
auto concrete = conformance.getConcrete();
if (!concrete->hasTypeWitness(assocType, resolver)) {
return nullptr;
}
return concrete->getTypeWitness(assocType, resolver);
}
示例3: mustDeserializeProtocolConformance
// Eagerly visiting all used conformances leads to a large blowup
// in the amount of SIL we read in. For optimization purposes we can defer
// reading in most conformances until we need them for devirtualization.
// However, we *must* pull in shared clang-importer-derived conformances
// we potentially use, since we may not otherwise have a local definition.
static bool mustDeserializeProtocolConformance(SILModule &M,
ProtocolConformanceRef c) {
if (!c.isConcrete())
return false;
auto conformance = c.getConcrete()->getRootNormalConformance();
return M.Types.protocolRequiresWitnessTable(conformance->getProtocol())
&& isa<ClangModuleUnit>(conformance->getDeclContext()
->getModuleScopeContext());
}
示例4: lookUpWitnessTable
std::pair<SILWitnessTable *, ArrayRef<Substitution>>
SILModule::
lookUpWitnessTable(ProtocolConformanceRef C, bool deserializeLazily) {
// If we have an abstract conformance passed in (a legal value), just return
// nullptr.
if (!C.isConcrete())
return {nullptr, {}};
return lookUpWitnessTable(C.getConcrete());
}
示例5: getWitnessType
Type TypeChecker::getWitnessType(Type type, ProtocolDecl *protocol,
ProtocolConformanceRef conformance,
Identifier name,
Diag<> brokenProtocolDiag) {
Type ty = ProtocolConformance::getTypeWitnessByName(type, conformance,
name, this);
if (!ty &&
!(conformance.isConcrete() && conformance.getConcrete()->isInvalid()))
diagnose(protocol->getLoc(), brokenProtocolDiag);
return ty;
}
示例6: visitProtocolConformance
bool SILLinkerVisitor::visitProtocolConformance(
ProtocolConformanceRef ref, const Optional<SILDeclRef> &Member) {
// If an abstract protocol conformance was passed in, just return false.
if (ref.isAbstract())
return false;
// Otherwise try and lookup a witness table for C.
auto C = ref.getConcrete();
SILWitnessTable *WT = Mod.lookUpWitnessTable(C).first;
// If we don't find any witness table for the conformance, bail and return
// false.
if (!WT) {
Mod.createWitnessTableDeclaration(
C, TypeConverter::getLinkageForProtocolConformance(
C->getRootNormalConformance(), NotForDefinition));
return false;
}
// If the looked up witness table is a declaration, there is nothing we can
// do here. Just bail and return false.
if (WT->isDeclaration())
return false;
bool performFuncDeserialization = false;
// For each entry in the witness table...
for (auto &E : WT->getEntries()) {
// If the entry is a witness method...
if (E.getKind() == SILWitnessTable::WitnessKind::Method) {
// And we are only interested in deserializing a specific requirement
// and don't have that requirement, don't deserialize this method.
if (Member.hasValue() && E.getMethodWitness().Requirement != *Member)
continue;
// The witness could be removed by dead function elimination.
if (!E.getMethodWitness().Witness)
continue;
// Otherwise if it is the requirement we are looking for or we just want
// to deserialize everything, add the function to the list of functions
// to deserialize.
performFuncDeserialization = true;
addFunctionToWorklist(E.getMethodWitness().Witness);
}
}
return performFuncDeserialization;
}
示例7: getWitnessMethodSubstitutions
/// Compute substitutions for making a direct call to a SIL function with
/// @convention(witness_method) convention.
///
/// Such functions have a substituted generic signature where the
/// abstract `Self` parameter from the original type of the protocol
/// requirement is replaced by a concrete type.
///
/// Thus, the original substitutions of the apply instruction that
/// are written in terms of the requirement's generic signature need
/// to be remapped to substitutions suitable for the witness signature.
///
/// \param conformanceRef The (possibly-specialized) conformance
/// \param requirementSig The generic signature of the requirement
/// \param witnessThunkSig The generic signature of the witness method
/// \param origSubs The substitutions from the call instruction
/// \param newSubs New substitutions are stored here
static void getWitnessMethodSubstitutions(
SILModule &M,
ProtocolConformanceRef conformanceRef,
GenericSignature *requirementSig,
GenericSignature *witnessThunkSig,
SubstitutionList origSubs,
bool isDefaultWitness,
SmallVectorImpl<Substitution> &newSubs) {
if (witnessThunkSig == nullptr)
return;
if (isDefaultWitness) {
newSubs.append(origSubs.begin(), origSubs.end());
return;
}
assert(!conformanceRef.isAbstract());
auto conformance = conformanceRef.getConcrete();
// If `Self` maps to a bound generic type, this gives us the
// substitutions for the concrete type's generic parameters.
auto baseSubMap = getSubstitutionsForProtocolConformance(conformanceRef);
unsigned baseDepth = 0;
auto *rootConformance = conformance->getRootNormalConformance();
if (auto *witnessSig = rootConformance->getGenericSignature())
baseDepth = witnessSig->getGenericParams().back()->getDepth() + 1;
auto origDepth = 1;
auto origSubMap = requirementSig->getSubstitutionMap(origSubs);
auto subMap =
SubstitutionMap::combineSubstitutionMaps(baseSubMap,
origSubMap,
CombineSubstitutionMaps::AtDepth,
baseDepth,
origDepth,
witnessThunkSig);
witnessThunkSig->getSubstitutions(subMap, newSubs);
}
示例8: while
static ArrayRef<Substitution>
getSubstitutionsForProtocolConformance(ProtocolConformanceRef CRef) {
if (CRef.isAbstract())
return {};
auto C = CRef.getConcrete();
// Walk down to the base NormalProtocolConformance.
ArrayRef<Substitution> Subs;
const ProtocolConformance *ParentC = C;
while (!isa<NormalProtocolConformance>(ParentC)) {
switch (ParentC->getKind()) {
case ProtocolConformanceKind::Normal:
llvm_unreachable("should have exited the loop?!");
case ProtocolConformanceKind::Inherited:
ParentC = cast<InheritedProtocolConformance>(ParentC)
->getInheritedConformance();
break;
case ProtocolConformanceKind::Specialized: {
auto SC = cast<SpecializedProtocolConformance>(ParentC);
ParentC = SC->getGenericConformance();
assert(Subs.empty() && "multiple conformance specializations?!");
Subs = SC->getGenericSubstitutions();
break;
}
}
}
const NormalProtocolConformance *NormalC
= cast<NormalProtocolConformance>(ParentC);
// If the normal conformance is for a generic type, and we didn't hit a
// specialized conformance, collect the substitutions from the generic type.
// FIXME: The AST should do this for us.
if (NormalC->getType()->isSpecialized() && Subs.empty()) {
Subs = NormalC->getType()
->gatherAllSubstitutions(NormalC->getDeclContext()->getParentModule(),
nullptr);
}
return Subs;
}
示例9: visitProtocolConformance
void SILLinkerVisitor::visitProtocolConformance(
ProtocolConformanceRef ref, const Optional<SILDeclRef> &Member) {
// If an abstract protocol conformance was passed in, do nothing.
if (ref.isAbstract())
return;
bool mustDeserialize = mustDeserializeProtocolConformance(Mod, ref);
// Otherwise try and lookup a witness table for C.
auto C = ref.getConcrete();
if (!VisitedConformances.insert(C).second)
return;
auto *WT = Mod.lookUpWitnessTable(C, mustDeserialize);
// If the looked up witness table is a declaration, there is nothing we can
// do here.
if (WT == nullptr || WT->isDeclaration()) {
assert(!mustDeserialize &&
"unable to deserialize witness table when we must?!");
return;
}
auto maybeVisitRelatedConformance = [&](ProtocolConformanceRef c) {
// Formally all conformances referenced by a used conformance are used.
// However, eagerly visiting them all at this point leads to a large blowup
// in the amount of SIL we read in. For optimization purposes we can defer
// reading in most conformances until we need them for devirtualization.
// However, we *must* pull in shared clang-importer-derived conformances
// we potentially use, since we may not otherwise have a local definition.
if (mustDeserializeProtocolConformance(Mod, c))
visitProtocolConformance(c, None);
};
// For each entry in the witness table...
for (auto &E : WT->getEntries()) {
switch (E.getKind()) {
// If the entry is a witness method...
case SILWitnessTable::WitnessKind::Method: {
// And we are only interested in deserializing a specific requirement
// and don't have that requirement, don't deserialize this method.
if (Member.hasValue() && E.getMethodWitness().Requirement != *Member)
continue;
// The witness could be removed by dead function elimination.
if (!E.getMethodWitness().Witness)
continue;
// Otherwise, deserialize the witness if it has shared linkage, or if
// we were asked to deserialize everything.
maybeAddFunctionToWorklist(E.getMethodWitness().Witness);
break;
}
// If the entry is a related witness table, see whether we need to
// eagerly deserialize it.
case SILWitnessTable::WitnessKind::BaseProtocol: {
auto baseConformance = E.getBaseProtocolWitness().Witness;
maybeVisitRelatedConformance(ProtocolConformanceRef(baseConformance));
break;
}
case SILWitnessTable::WitnessKind::AssociatedTypeProtocol: {
auto assocConformance = E.getAssociatedTypeProtocolWitness().Witness;
maybeVisitRelatedConformance(assocConformance);
break;
}
case SILWitnessTable::WitnessKind::AssociatedType:
case SILWitnessTable::WitnessKind::Invalid:
break;
}
}
}
示例10: getWitnessMethodSubstitutions
/// Compute substitutions for making a direct call to a SIL function with
/// @convention(witness_method) convention.
///
/// Such functions have a substituted generic signature where the
/// abstract `Self` parameter from the original type of the protocol
/// requirement is replaced by a concrete type.
///
/// Thus, the original substitutions of the apply instruction that
/// are written in terms of the requirement's generic signature need
/// to be remapped to substitutions suitable for the witness signature.
///
/// \param conformanceRef The (possibly-specialized) conformance
/// \param requirementSig The generic signature of the requirement
/// \param witnessThunkSig The generic signature of the witness method
/// \param origSubs The substitutions from the call instruction
/// \param newSubs New substitutions are stored here
static void getWitnessMethodSubstitutions(
SILModule &M,
ProtocolConformanceRef conformanceRef,
GenericSignature *requirementSig,
GenericSignature *witnessThunkSig,
ArrayRef<Substitution> origSubs,
bool isDefaultWitness,
SmallVectorImpl<Substitution> &newSubs) {
if (witnessThunkSig == nullptr)
return;
assert(!conformanceRef.isAbstract());
auto conformance = conformanceRef.getConcrete();
// Otherwise, we need to build new caller-side substitutions
// written in terms of the witness thunk's generic signature,
// mapping to the archetypes of the caller.
SubstitutionMap subMap;
// Take apart substitutions from the conforming type.
ArrayRef<Substitution> witnessSubs;
auto *rootConformance = conformance->getRootNormalConformance();
auto *witnessSig = rootConformance->getGenericSignature();
unsigned depth = 0;
if (isDefaultWitness) {
// For default witnesses, we substitute all of Self.
auto gp = witnessThunkSig->getGenericParams().front()->getCanonicalType();
subMap.addSubstitution(gp, origSubs.front().getReplacement());
subMap.addConformances(gp, origSubs.front().getConformances());
// For default witnesses, innermost generic parameters are always at
// depth 1.
depth = 1;
} else {
// If `Self` maps to a bound generic type, this gives us the
// substitutions for the concrete type's generic parameters.
witnessSubs = getSubstitutionsForProtocolConformance(conformanceRef);
if (!witnessSubs.empty()) {
witnessSig->getSubstitutionMap(witnessSubs, subMap);
depth = witnessSig->getGenericParams().back()->getDepth() + 1;
}
}
// Next, take apart caller-side substitutions.
//
// Note that the Self-derived dependent types appearing on the left
// hand side of the map are dropped.
// FIXME: This won't be correct if the requirement itself adds 'Self'
// requirements. We should be working from the substitutions in the witness.
//
// Also note that we rebuild the generic parameters in the requirement
// to provide them with the required depth for the thunk itself.
if (requirementSig->getGenericParams().back()->getDepth() > 0) {
// Local function to replace generic parameters within the requirement
// signature with the generic parameter we want to use in the substitution
// map:
// - If the generic parameter is 'Self', return a null type so we don't
// add any substitution.
// - Otherwise, reset the generic parameter's depth one level deeper than
// the deepest generic parameter in the conformance.
//
// This local function is meant to be used with Type::transform();
auto replaceGenericParameter = [&](Type type) -> Type {
if (auto gp = type->getAs<GenericTypeParamType>()) {
if (gp->getDepth() == 0) return Type();
return GenericTypeParamType::get(depth, gp->getIndex(),
M.getASTContext());
}
return type;
};
// Walk through the substitutions and dependent types.
ArrayRef<Substitution> subs = origSubs;
for (auto origDepTy : requirementSig->getAllDependentTypes()) {
// Grab the next substitution.
auto sub = subs.front();
subs = subs.slice(1);
// Map the generic parameters in the dependent type into the witness
// thunk's depth.
//.........这里部分代码省略.........