本文整理汇总了C++中mangle::ASTMangler::mangleWitnessThunk方法的典型用法代码示例。如果您正苦于以下问题:C++ ASTMangler::mangleWitnessThunk方法的具体用法?C++ ASTMangler::mangleWitnessThunk怎么用?C++ ASTMangler::mangleWitnessThunk使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类mangle::ASTMangler
的用法示例。
在下文中一共展示了ASTMangler::mangleWitnessThunk方法的4个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: addConformances
void TBDGenVisitor::addConformances(DeclContext *DC) {
for (auto conformance : DC->getLocalConformances()) {
auto protocol = conformance->getProtocol();
auto needsWTable =
Lowering::TypeConverter::protocolRequiresWitnessTable(protocol);
if (!needsWTable)
continue;
// Only root conformances get symbols; the others get any public symbols
// from their parent conformances.
auto rootConformance = dyn_cast<RootProtocolConformance>(conformance);
if (!rootConformance) {
continue;
}
addSymbol(LinkEntity::forProtocolWitnessTable(rootConformance));
addSymbol(LinkEntity::forProtocolConformanceDescriptor(rootConformance));
// FIXME: the logic around visibility in extensions is confusing, and
// sometimes witness thunks need to be manually made public.
auto conformanceIsFixed = SILWitnessTable::conformanceIsSerialized(
rootConformance);
auto addSymbolIfNecessary = [&](ValueDecl *requirementDecl,
ValueDecl *witnessDecl) {
auto witnessLinkage = SILDeclRef(witnessDecl).getLinkage(ForDefinition);
if (conformanceIsFixed &&
(isa<SelfProtocolConformance>(rootConformance) ||
fixmeWitnessHasLinkageThatNeedsToBePublic(witnessLinkage))) {
Mangle::ASTMangler Mangler;
addSymbol(
Mangler.mangleWitnessThunk(rootConformance, requirementDecl));
}
};
rootConformance->forEachValueWitness(
nullptr, [&](ValueDecl *valueReq, Witness witness) {
auto witnessDecl = witness.getDecl();
if (isa<AbstractFunctionDecl>(valueReq)) {
addSymbolIfNecessary(valueReq, witnessDecl);
} else if (auto *storage = dyn_cast<AbstractStorageDecl>(valueReq)) {
auto witnessStorage = cast<AbstractStorageDecl>(witnessDecl);
storage->visitOpaqueAccessors([&](AccessorDecl *reqtAccessor) {
auto witnessAccessor =
witnessStorage->getAccessor(reqtAccessor->getAccessorKind());
assert(witnessAccessor && "no corresponding witness accessor?");
addSymbolIfNecessary(reqtAccessor, witnessAccessor);
});
}
});
}
}
示例2: builder
SILFunction *SILGenModule::emitProtocolWitness(
ProtocolConformanceRef conformance, SILLinkage linkage,
IsSerialized_t isSerialized, SILDeclRef requirement, SILDeclRef witnessRef,
IsFreeFunctionWitness_t isFree, Witness witness) {
auto requirementInfo = Types.getConstantInfo(requirement);
// Work out the lowered function type of the SIL witness thunk.
auto reqtOrigTy = cast<GenericFunctionType>(requirementInfo.LoweredType);
// Mapping from the requirement's generic signature to the witness
// thunk's generic signature.
auto reqtSubMap = witness.getRequirementToSyntheticSubs();
// The generic environment for the witness thunk.
auto *genericEnv = witness.getSyntheticEnvironment();
// The type of the witness thunk.
auto substReqtTy =
cast<AnyFunctionType>(reqtOrigTy.subst(reqtSubMap)->getCanonicalType());
// If there's something to map to for the witness thunk, the conformance
// should be phrased in the same terms. This particularly applies to classes
// where a thunk for a method in a conformance like `extension Class: P where
// T: Q` will go from its native signature of `<τ_0_0 where τ_0_0: Q>` (with T
// canonicalised to τ_0_0), to `<τ_0_0, τ_1_0 where τ_0_0: Class<τ_1_0>,
// τ_1_0: Q>` (with T now represented by τ_1_0). Find the right conformance by
// looking for the conformance of 'Self'.
if (reqtSubMap) {
auto requirement = conformance.getRequirement();
auto self = requirement->getProtocolSelfType()->getCanonicalType();
conformance = *reqtSubMap.lookupConformance(self, requirement);
}
CanAnyFunctionType reqtSubstTy;
if (genericEnv) {
auto *genericSig = genericEnv->getGenericSignature();
reqtSubstTy = CanGenericFunctionType::get(
genericSig->getCanonicalSignature(),
substReqtTy->getParams(), substReqtTy.getResult(),
reqtOrigTy->getExtInfo());
} else {
reqtSubstTy = CanFunctionType::get(substReqtTy->getParams(),
substReqtTy.getResult(),
reqtOrigTy->getExtInfo());
}
// Coroutine lowering requires us to provide these substitutions
// in order to recreate the appropriate yield types for the accessor
// because they aren't reflected in the accessor's AST type.
// But this is expensive, so we only do it for coroutine lowering.
// When they're part of the AST function type, we can remove this
// parameter completely.
Optional<SubstitutionMap> witnessSubsForTypeLowering;
if (auto accessor = dyn_cast<AccessorDecl>(requirement.getDecl())) {
if (accessor->isCoroutine()) {
witnessSubsForTypeLowering =
witness.getSubstitutions().mapReplacementTypesOutOfContext();
}
}
// FIXME: this needs to pull out the conformances/witness-tables for any
// conditional requirements from the witness table and pass them to the
// underlying function in the thunk.
// Lower the witness thunk type with the requirement's abstraction level.
auto witnessSILFnType = getNativeSILFunctionType(
M, AbstractionPattern(reqtOrigTy), reqtSubstTy,
requirement, witnessRef, witnessSubsForTypeLowering, conformance);
// Mangle the name of the witness thunk.
Mangle::ASTMangler NewMangler;
auto manglingConformance =
conformance.isConcrete() ? conformance.getConcrete() : nullptr;
std::string nameBuffer =
NewMangler.mangleWitnessThunk(manglingConformance, requirement.getDecl());
// If the thunked-to function is set to be always inlined, do the
// same with the witness, on the theory that the user wants all
// calls removed if possible, e.g. when we're able to devirtualize
// the witness method call. Otherwise, use the default inlining
// setting on the theory that forcing inlining off should only
// effect the user's function, not otherwise invisible thunks.
Inline_t InlineStrategy = InlineDefault;
if (witnessRef.isAlwaysInline())
InlineStrategy = AlwaysInline;
SILGenFunctionBuilder builder(*this);
auto *f = builder.createFunction(
linkage, nameBuffer, witnessSILFnType, genericEnv,
SILLocation(witnessRef.getDecl()), IsNotBare, IsTransparent, isSerialized,
ProfileCounter(), IsThunk, SubclassScope::NotApplicable, InlineStrategy);
f->setDebugScope(new (M)
SILDebugScope(RegularLocation(witnessRef.getDecl()), f));
PrettyStackTraceSILFunction trace("generating protocol witness thunk", f);
// Create the witness.
SILGenFunction SGF(*this, *f, SwiftModule);
//.........这里部分代码省略.........
示例3: trace
SILFunction *SILGenModule::emitProtocolWitness(
ProtocolConformanceRef conformance, SILLinkage linkage,
IsSerialized_t isSerialized, SILDeclRef requirement, SILDeclRef witnessRef,
IsFreeFunctionWitness_t isFree, Witness witness) {
auto requirementInfo = Types.getConstantInfo(requirement);
// Work out the lowered function type of the SIL witness thunk.
auto reqtOrigTy = cast<GenericFunctionType>(requirementInfo.LoweredType);
// Mapping from the requirement's generic signature to the witness
// thunk's generic signature.
auto reqtSubMap = witness.getRequirementToSyntheticSubs();
// The generic environment for the witness thunk.
auto *genericEnv = witness.getSyntheticEnvironment();
// The type of the witness thunk.
auto input = reqtOrigTy->getInput().subst(reqtSubMap)->getCanonicalType();
auto result = reqtOrigTy->getResult().subst(reqtSubMap)->getCanonicalType();
// If there's something to map to for the witness thunk, the conformance
// should be phrased in the same terms. This particularly applies to classes
// where a thunk for a method in a conformance like `extension Class: P where
// T: Q` will go from its native signature of `<τ_0_0 where τ_0_0: Q>` (with T
// canonicalised to τ_0_0), to `<τ_0_0, τ_1_0 where τ_0_0: Class<τ_1_0>,
// τ_1_0: Q>` (with T now represented by τ_1_0). Find the right conformance by
// looking for the conformance of 'Self'.
if (reqtSubMap) {
auto requirement = conformance.getRequirement();
auto self = requirement->getProtocolSelfType()->getCanonicalType();
conformance = *reqtSubMap.lookupConformance(self, requirement);
}
CanAnyFunctionType reqtSubstTy;
if (genericEnv) {
auto *genericSig = genericEnv->getGenericSignature();
reqtSubstTy = CanGenericFunctionType::get(
genericSig->getCanonicalSignature(),
input, result, reqtOrigTy->getExtInfo());
} else {
reqtSubstTy = CanFunctionType::get(
input, result, reqtOrigTy->getExtInfo());
}
// FIXME: this needs to pull out the conformances/witness-tables for any
// conditional requirements from the witness table and pass them to the
// underlying function in the thunk.
// Lower the witness thunk type with the requirement's abstraction level.
auto witnessSILFnType = getNativeSILFunctionType(
M, AbstractionPattern(reqtOrigTy), reqtSubstTy, witnessRef, conformance);
// Mangle the name of the witness thunk.
Mangle::ASTMangler NewMangler;
auto manglingConformance =
conformance.isConcrete() ? conformance.getConcrete() : nullptr;
std::string nameBuffer =
NewMangler.mangleWitnessThunk(manglingConformance, requirement.getDecl());
// If the thunked-to function is set to be always inlined, do the
// same with the witness, on the theory that the user wants all
// calls removed if possible, e.g. when we're able to devirtualize
// the witness method call. Otherwise, use the default inlining
// setting on the theory that forcing inlining off should only
// effect the user's function, not otherwise invisible thunks.
Inline_t InlineStrategy = InlineDefault;
if (witnessRef.isAlwaysInline())
InlineStrategy = AlwaysInline;
auto *f = M.createFunction(
linkage, nameBuffer, witnessSILFnType, genericEnv,
SILLocation(witnessRef.getDecl()), IsNotBare, IsTransparent, isSerialized,
ProfileCounter(), IsThunk, SubclassScope::NotApplicable, InlineStrategy);
f->setDebugScope(new (M)
SILDebugScope(RegularLocation(witnessRef.getDecl()), f));
PrettyStackTraceSILFunction trace("generating protocol witness thunk", f);
// Create the witness.
SILGenFunction SGF(*this, *f);
// Substitutions mapping the generic parameters of the witness to
// archetypes of the witness thunk generic environment.
auto witnessSubs = witness.getSubstitutions();
// Open-code protocol witness thunks for materializeForSet.
if (auto witnessFn = dyn_cast<AccessorDecl>(witnessRef.getDecl())) {
if (witnessFn->isMaterializeForSet()) {
assert(!isFree);
auto *proto = cast<ProtocolDecl>(requirement.getDecl()->getDeclContext());
auto selfInterfaceType = proto->getSelfInterfaceType().subst(reqtSubMap);
auto selfType = GenericEnvironment::mapTypeIntoContext(
genericEnv, selfInterfaceType);
auto reqFn = cast<AccessorDecl>(requirement.getDecl());
assert(reqFn->isMaterializeForSet());
//.........这里部分代码省略.........
示例4: addConformances
void TBDGenVisitor::addConformances(DeclContext *DC) {
for (auto conformance : DC->getLocalConformances()) {
auto protocol = conformance->getProtocol();
auto needsWTable =
Lowering::TypeConverter::protocolRequiresWitnessTable(protocol);
if (!needsWTable)
continue;
// Only normal conformances get symbols; the others get any public symbols
// from their parent normal conformance.
auto normalConformance = dyn_cast<NormalProtocolConformance>(conformance);
if (!normalConformance)
continue;
addSymbol(LinkEntity::forDirectProtocolWitnessTable(normalConformance));
addSymbol(
LinkEntity::forProtocolWitnessTableAccessFunction(normalConformance));
// FIXME: the logic around visibility in extensions is confusing, and
// sometimes witness thunks need to be manually made public.
auto conformanceIsFixed = SILWitnessTable::conformanceIsSerialized(
normalConformance, SwiftModule->getResilienceStrategy(),
SILSerializeWitnessTables);
auto addSymbolIfNecessary = [&](ValueDecl *valueReq,
SILLinkage witnessLinkage) {
if (conformanceIsFixed &&
fixmeWitnessHasLinkageThatNeedsToBePublic(witnessLinkage)) {
Mangle::ASTMangler Mangler;
addSymbol(Mangler.mangleWitnessThunk(normalConformance, valueReq));
}
};
normalConformance->forEachValueWitness(nullptr, [&](ValueDecl *valueReq,
Witness witness) {
if (isa<AbstractFunctionDecl>(valueReq)) {
auto witnessLinkage =
SILDeclRef(witness.getDecl()).getLinkage(ForDefinition);
addSymbolIfNecessary(valueReq, witnessLinkage);
} else if (auto VD = dyn_cast<AbstractStorageDecl>(valueReq)) {
// A var or subscript decl needs extra special handling: the things that
// end up in the witness table are the accessors, but the compiler only
// talks about the actual storage decl in the conformance, so we have to
// manually walk over the members, having pulled out something that will
// have the right linkage.
auto witnessVD = cast<AbstractStorageDecl>(witness.getDecl());
SmallVector<Decl *, 4> members;
VD->getAllAccessorFunctions(members);
// Grab one of the accessors, and then use that to pull out which of the
// getter or setter will have the appropriate linkage.
FuncDecl *witnessWithRelevantLinkage;
switch (cast<FuncDecl>(members[0])->getAccessorKind()) {
case AccessorKind::NotAccessor:
llvm_unreachable("must be an accessor");
case AccessorKind::IsGetter:
case AccessorKind::IsAddressor:
witnessWithRelevantLinkage = witnessVD->getGetter();
break;
case AccessorKind::IsSetter:
case AccessorKind::IsWillSet:
case AccessorKind::IsDidSet:
case AccessorKind::IsMaterializeForSet:
case AccessorKind::IsMutableAddressor:
witnessWithRelevantLinkage = witnessVD->getSetter();
break;
}
auto witnessLinkage =
SILDeclRef(witnessWithRelevantLinkage).getLinkage(ForDefinition);
for (auto member : members) {
addSymbolIfNecessary(cast<ValueDecl>(member), witnessLinkage);
}
}
});
}
}