本文整理汇总了C++中SILDeclRef类的典型用法代码示例。如果您正苦于以下问题:C++ SILDeclRef类的具体用法?C++ SILDeclRef怎么用?C++ SILDeclRef使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了SILDeclRef类的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: assert
/// Generate code to emit a thunk with native conventions that calls a
/// function with foreign conventions.
void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) {
assert(!thunk.isForeign && "foreign-to-native thunks only");
// Wrap the function in its original form.
auto fd = cast<AbstractFunctionDecl>(thunk.getDecl());
auto nativeCI = getConstantInfo(thunk);
auto nativeFormalResultTy = nativeCI.LoweredInterfaceType.getResult();
auto nativeFnTy = F.getLoweredFunctionType();
assert(nativeFnTy == nativeCI.SILFnType);
// Find the foreign error convention and 'self' parameter index.
Optional<ForeignErrorConvention> foreignError;
if (nativeFnTy->hasErrorResult()) {
foreignError = fd->getForeignErrorConvention();
assert(foreignError && "couldn't find foreign error convention!");
}
ImportAsMemberStatus memberStatus = fd->getImportAsMemberStatus();
// Forward the arguments.
auto forwardedParameters = fd->getParameterLists();
// For allocating constructors, 'self' is a metatype, not the 'self' value
// formally present in the constructor body.
Type allocatorSelfType;
if (thunk.kind == SILDeclRef::Kind::Allocator) {
allocatorSelfType = forwardedParameters[0]->getType(getASTContext())
->getLValueOrInOutObjectType();
forwardedParameters = forwardedParameters.slice(1);
}
SmallVector<SILValue, 8> params;
for (auto *paramList : reversed(forwardedParameters))
bindParametersForForwarding(paramList, params);
if (allocatorSelfType) {
auto selfMetatype =
CanMetatypeType::get(allocatorSelfType->getCanonicalType());
auto selfArg = new (F.getModule()) SILArgument(
F.begin(),
getLoweredLoadableType(selfMetatype),
fd->getImplicitSelfDecl());
params.push_back(selfArg);
}
// Set up the throw destination if necessary.
CleanupLocation cleanupLoc(fd);
if (foreignError) {
prepareRethrowEpilog(cleanupLoc);
}
SILValue result;
{
Scope scope(Cleanups, fd);
SILDeclRef foreignDeclRef = thunk.asForeign(true);
SILConstantInfo foreignCI = getConstantInfo(foreignDeclRef);
auto foreignFnTy = foreignCI.SILFnType;
// Bridge all the arguments.
SmallVector<ManagedValue, 8> args;
unsigned foreignArgIndex = 0;
// A helper function to add a function error argument in the
// appropriate position.
auto maybeAddForeignErrorArg = [&] {
if (foreignError &&
foreignArgIndex == foreignError->getErrorParameterIndex()) {
args.push_back(ManagedValue());
foreignArgIndex++;
}
};
for (unsigned nativeParamIndex : indices(params)) {
// Bring the parameter to +1.
auto paramValue = params[nativeParamIndex];
auto thunkParam = nativeFnTy->getParameters()[nativeParamIndex];
// TODO: Could avoid a retain if the bridged parameter is also +0 and
// doesn't require a bridging conversion.
ManagedValue param;
switch (thunkParam.getConvention()) {
case ParameterConvention::Direct_Owned:
param = emitManagedRValueWithCleanup(paramValue);
break;
case ParameterConvention::Direct_Guaranteed:
case ParameterConvention::Direct_Unowned:
param = emitManagedRetain(fd, paramValue);
break;
case ParameterConvention::Direct_Deallocating:
param = ManagedValue::forUnmanaged(paramValue);
break;
case ParameterConvention::Indirect_Inout:
case ParameterConvention::Indirect_InoutAliasable:
param = ManagedValue::forUnmanaged(paramValue);
break;
case ParameterConvention::Indirect_In:
case ParameterConvention::Indirect_In_Guaranteed:
llvm_unreachable("indirect args in foreign thunked method not implemented");
//.........这里部分代码省略.........
示例2: mangleConstant
static std::string mangleConstant(SILDeclRef c, StringRef prefix) {
using namespace Mangle;
Mangler mangler;
// Almost everything below gets one of the common prefixes:
// mangled-name ::= '_T' global // Native symbol
// mangled-name ::= '_TTo' global // ObjC interop thunk
// mangled-name ::= '_TTO' global // Foreign function thunk
// mangled-name ::= '_TTd' global // Direct
StringRef introducer = "_T";
if (!prefix.empty()) {
introducer = prefix;
} else if (c.isForeign) {
assert(prefix.empty() && "can't have custom prefix on thunk");
introducer = "_TTo";
} else if (c.isDirectReference) {
introducer = "_TTd";
} else if (c.isForeignToNativeThunk()) {
assert(prefix.empty() && "can't have custom prefix on thunk");
introducer = "_TTO";
}
// As a special case, Clang functions and globals don't get mangled at all.
if (c.hasDecl()) {
if (auto clangDecl = c.getDecl()->getClangDecl()) {
if (!c.isForeignToNativeThunk() && !c.isNativeToForeignThunk()
&& !c.isCurried) {
if (auto namedClangDecl = dyn_cast<clang::DeclaratorDecl>(clangDecl)) {
if (auto asmLabel = namedClangDecl->getAttr<clang::AsmLabelAttr>()) {
mangler.append('\01');
mangler.append(asmLabel->getLabel());
} else if (namedClangDecl->hasAttr<clang::OverloadableAttr>()) {
std::string storage;
llvm::raw_string_ostream SS(storage);
// FIXME: When we can import C++, use Clang's mangler all the time.
mangleClangDecl(SS, namedClangDecl,
c.getDecl()->getASTContext());
mangler.append(SS.str());
} else {
mangler.append(namedClangDecl->getName());
}
return mangler.finalize();
}
}
}
}
switch (c.kind) {
// entity ::= declaration // other declaration
case SILDeclRef::Kind::Func:
if (!c.hasDecl()) {
mangler.append(introducer);
mangler.mangleClosureEntity(c.getAbstractClosureExpr(),
c.uncurryLevel);
return mangler.finalize();
}
// As a special case, functions can have manually mangled names.
// Use the SILGen name only for the original non-thunked, non-curried entry
// point.
if (auto NameA = c.getDecl()->getAttrs().getAttribute<SILGenNameAttr>())
if (!c.isForeignToNativeThunk() && !c.isNativeToForeignThunk()
&& !c.isCurried) {
mangler.append(NameA->Name);
return mangler.finalize();
}
// Use a given cdecl name for native-to-foreign thunks.
if (auto CDeclA = c.getDecl()->getAttrs().getAttribute<CDeclAttr>())
if (c.isNativeToForeignThunk()) {
mangler.append(CDeclA->Name);
return mangler.finalize();
}
// Otherwise, fall through into the 'other decl' case.
SWIFT_FALLTHROUGH;
case SILDeclRef::Kind::EnumElement:
mangler.append(introducer);
mangler.mangleEntity(c.getDecl(), c.uncurryLevel);
return mangler.finalize();
// entity ::= context 'D' // deallocating destructor
case SILDeclRef::Kind::Deallocator:
mangler.append(introducer);
mangler.mangleDestructorEntity(cast<DestructorDecl>(c.getDecl()),
/*isDeallocating*/ true);
return mangler.finalize();
// entity ::= context 'd' // destroying destructor
case SILDeclRef::Kind::Destroyer:
mangler.append(introducer);
mangler.mangleDestructorEntity(cast<DestructorDecl>(c.getDecl()),
/*isDeallocating*/ false);
return mangler.finalize();
// entity ::= context 'C' type // allocating constructor
case SILDeclRef::Kind::Allocator:
mangler.append(introducer);
mangler.mangleConstructorEntity(cast<ConstructorDecl>(c.getDecl()),
//.........这里部分代码省略.........
示例3: emitOrigToSubstValue
ManagedValue
SILGenFunction::emitClosureValue(SILLocation loc, SILDeclRef constant,
CanType expectedType,
SubstitutionList subs) {
auto closure = *constant.getAnyFunctionRef();
auto captureInfo = closure.getCaptureInfo();
auto loweredCaptureInfo = SGM.Types.getLoweredLocalCaptures(closure);
auto hasCaptures = SGM.Types.hasLoweredLocalCaptures(closure);
auto constantInfo = getConstantInfo(constant);
SILValue functionRef = emitGlobalFunctionRef(loc, constant, constantInfo);
SILType functionTy = functionRef->getType();
// Apply substitutions.
auto pft = constantInfo.SILFnType;
auto *dc = closure.getAsDeclContext()->getParent();
if (dc->isLocalContext() && !loweredCaptureInfo.hasGenericParamCaptures()) {
// If the lowered function type is not polymorphic but we were given
// substitutions, we have a closure in a generic context which does not
// capture generic parameters. Just drop the substitutions.
subs = { };
} else if (closure.getAbstractClosureExpr()) {
// If we have a closure expression in generic context, Sema won't give
// us substitutions, so we just use the forwarding substitutions from
// context.
subs = getForwardingSubstitutions();
}
bool wasSpecialized = false;
if (!subs.empty()) {
auto specialized = pft->substGenericArgs(F.getModule(), subs);
functionTy = SILType::getPrimitiveObjectType(specialized);
wasSpecialized = true;
}
// If we're in top-level code, we don't need to physically capture script
// globals, but we still need to mark them as escaping so that DI can flag
// uninitialized uses.
if (this == SGM.TopLevelSGF) {
SGM.emitMarkFunctionEscapeForTopLevelCodeGlobals(
loc, captureInfo);
}
if (!hasCaptures && !wasSpecialized) {
auto result = ManagedValue::forUnmanaged(functionRef);
return emitOrigToSubstValue(loc, result,
AbstractionPattern(expectedType),
expectedType);
}
SmallVector<ManagedValue, 4> capturedArgs;
emitCaptures(loc, closure, CaptureEmission::PartialApplication,
capturedArgs);
// The partial application takes ownership of the context parameters.
SmallVector<SILValue, 4> forwardedArgs;
for (auto capture : capturedArgs)
forwardedArgs.push_back(capture.forward(*this));
auto calleeConvention = ParameterConvention::Direct_Guaranteed;
SILType closureTy = SILGenBuilder::getPartialApplyResultType(
functionRef->getType(), capturedArgs.size(), SGM.M, subs,
calleeConvention);
auto toClosure =
B.createPartialApply(loc, functionRef, functionTy,
subs, forwardedArgs, closureTy);
auto result = emitManagedRValueWithCleanup(toClosure);
// Get the lowered AST types:
// - the original type
auto origFormalType = AbstractionPattern(constantInfo.LoweredType);
// - the substituted type
auto substFormalType = expectedType;
// Generalize if necessary.
result = emitOrigToSubstValue(loc, result, origFormalType,
substFormalType);
return result;
}
示例4: DeclName
void SILGenFunction::emitObjCDestructor(SILDeclRef dtor) {
auto dd = cast<DestructorDecl>(dtor.getDecl());
auto cd = cast<ClassDecl>(dd->getDeclContext());
MagicFunctionName = DeclName(SGM.M.getASTContext().getIdentifier("deinit"));
RegularLocation loc(dd);
if (dd->isImplicit())
loc.markAutoGenerated();
SILValue selfValue = emitSelfDecl(dd->getImplicitSelfDecl());
// Create a basic block to jump to for the implicit destruction behavior
// of releasing the elements and calling the superclass destructor.
// We won't actually emit the block until we finish with the destructor body.
prepareEpilog(Type(), false, CleanupLocation::get(loc));
// Emit the destructor body.
emitStmt(dd->getBody());
Optional<SILValue> maybeReturnValue;
SILLocation returnLoc(loc);
std::tie(maybeReturnValue, returnLoc) = emitEpilogBB(loc);
if (!maybeReturnValue)
return;
auto cleanupLoc = CleanupLocation::get(loc);
// Note: the ivar destroyer is responsible for destroying the
// instance variables before the object is actually deallocated.
// Form a reference to the superclass -dealloc.
Type superclassTy = dd->mapTypeIntoContext(cd->getSuperclass());
assert(superclassTy && "Emitting Objective-C -dealloc without superclass?");
ClassDecl *superclass = superclassTy->getClassOrBoundGenericClass();
auto superclassDtorDecl = superclass->getDestructor();
SILDeclRef superclassDtor(superclassDtorDecl,
SILDeclRef::Kind::Deallocator,
SILDeclRef::ConstructAtBestResilienceExpansion,
SILDeclRef::ConstructAtNaturalUncurryLevel,
/*isForeign=*/true);
auto superclassDtorType = SGM.getConstantType(superclassDtor);
SILValue superclassDtorValue = B.createSuperMethod(
cleanupLoc, selfValue, superclassDtor,
superclassDtorType);
// Call the superclass's -dealloc.
SILType superclassSILTy = getLoweredLoadableType(superclassTy);
SILValue superSelf = B.createUpcast(cleanupLoc, selfValue, superclassSILTy);
ArrayRef<Substitution> subs
= superclassTy->gatherAllSubstitutions(SGM.M.getSwiftModule(), nullptr);
auto substDtorType = superclassDtorType.castTo<SILFunctionType>()
->substGenericArgs(SGM.M, subs);
B.createApply(cleanupLoc, superclassDtorValue,
SILType::getPrimitiveObjectType(substDtorType),
substDtorType->getSILResult(),
subs, superSelf);
// Return.
B.createReturn(returnLoc, emitEmptyTuple(cleanupLoc));
}
示例5: mangleConstant
static std::string mangleConstant(SILDeclRef c, SILDeclRef::ManglingKind Kind) {
using namespace NewMangling;
ASTMangler mangler;
// As a special case, Clang functions and globals don't get mangled at all.
if (c.hasDecl()) {
if (auto clangDecl = c.getDecl()->getClangDecl()) {
if (!c.isForeignToNativeThunk() && !c.isNativeToForeignThunk()
&& !c.isCurried) {
if (auto namedClangDecl = dyn_cast<clang::DeclaratorDecl>(clangDecl)) {
if (auto asmLabel = namedClangDecl->getAttr<clang::AsmLabelAttr>()) {
std::string s(1, '\01');
s += asmLabel->getLabel();
return s;
} else if (namedClangDecl->hasAttr<clang::OverloadableAttr>()) {
std::string storage;
llvm::raw_string_ostream SS(storage);
// FIXME: When we can import C++, use Clang's mangler all the time.
mangleClangDecl(SS, namedClangDecl,
c.getDecl()->getASTContext());
return SS.str();
}
return namedClangDecl->getName();
}
}
}
}
ASTMangler::SymbolKind SKind = ASTMangler::SymbolKind::Default;
switch (Kind) {
case SILDeclRef::ManglingKind::Default:
if (c.isForeign) {
SKind = ASTMangler::SymbolKind::SwiftAsObjCThunk;
} else if (c.isDirectReference) {
SKind = ASTMangler::SymbolKind::DirectMethodReferenceThunk;
} else if (c.isForeignToNativeThunk()) {
SKind = ASTMangler::SymbolKind::ObjCAsSwiftThunk;
}
break;
case SILDeclRef::ManglingKind::VTableMethod:
SKind = ASTMangler::SymbolKind::VTableMethod;
break;
case SILDeclRef::ManglingKind::DynamicThunk:
SKind = ASTMangler::SymbolKind::DynamicThunk;
break;
}
switch (c.kind) {
case SILDeclRef::Kind::Func:
if (!c.hasDecl())
return mangler.mangleClosureEntity(c.getAbstractClosureExpr(), SKind);
// As a special case, functions can have manually mangled names.
// Use the SILGen name only for the original non-thunked, non-curried entry
// point.
if (auto NameA = c.getDecl()->getAttrs().getAttribute<SILGenNameAttr>())
if (!c.isForeignToNativeThunk() && !c.isNativeToForeignThunk()
&& !c.isCurried) {
return NameA->Name;
}
// Use a given cdecl name for native-to-foreign thunks.
if (auto CDeclA = c.getDecl()->getAttrs().getAttribute<CDeclAttr>())
if (c.isNativeToForeignThunk()) {
return CDeclA->Name;
}
// Otherwise, fall through into the 'other decl' case.
SWIFT_FALLTHROUGH;
case SILDeclRef::Kind::EnumElement:
return mangler.mangleEntity(c.getDecl(), c.isCurried, SKind);
case SILDeclRef::Kind::Deallocator:
assert(!c.isCurried);
return mangler.mangleDestructorEntity(cast<DestructorDecl>(c.getDecl()),
/*isDeallocating*/ true,
SKind);
case SILDeclRef::Kind::Destroyer:
assert(!c.isCurried);
return mangler.mangleDestructorEntity(cast<DestructorDecl>(c.getDecl()),
/*isDeallocating*/ false,
SKind);
case SILDeclRef::Kind::Allocator:
return mangler.mangleConstructorEntity(cast<ConstructorDecl>(c.getDecl()),
/*allocating*/ true,
c.isCurried,
SKind);
case SILDeclRef::Kind::Initializer:
return mangler.mangleConstructorEntity(cast<ConstructorDecl>(c.getDecl()),
/*allocating*/ false,
c.isCurried,
SKind);
case SILDeclRef::Kind::IVarInitializer:
case SILDeclRef::Kind::IVarDestroyer:
assert(!c.isCurried);
//.........这里部分代码省略.........
示例6: DeclName
void SILGenFunction::emitObjCDestructor(SILDeclRef dtor) {
auto dd = cast<DestructorDecl>(dtor.getDecl());
auto cd = cast<ClassDecl>(dd->getDeclContext());
MagicFunctionName = DeclName(SGM.M.getASTContext().getIdentifier("deinit"));
RegularLocation loc(dd);
if (dd->isImplicit())
loc.markAutoGenerated();
SILValue selfValue = emitSelfDecl(dd->getImplicitSelfDecl());
// Create a basic block to jump to for the implicit destruction behavior
// of releasing the elements and calling the superclass destructor.
// We won't actually emit the block until we finish with the destructor body.
prepareEpilog(Type(), false, CleanupLocation::get(loc));
emitProfilerIncrement(dd->getBody());
// Emit the destructor body.
emitStmt(dd->getBody());
Optional<SILValue> maybeReturnValue;
SILLocation returnLoc(loc);
std::tie(maybeReturnValue, returnLoc) = emitEpilogBB(loc);
if (!maybeReturnValue)
return;
auto cleanupLoc = CleanupLocation::get(loc);
// Note: the ivar destroyer is responsible for destroying the
// instance variables before the object is actually deallocated.
// Form a reference to the superclass -dealloc.
Type superclassTy = dd->mapTypeIntoContext(cd->getSuperclass());
assert(superclassTy && "Emitting Objective-C -dealloc without superclass?");
ClassDecl *superclass = superclassTy->getClassOrBoundGenericClass();
auto superclassDtorDecl = superclass->getDestructor();
auto superclassDtor = SILDeclRef(superclassDtorDecl,
SILDeclRef::Kind::Deallocator)
.asForeign();
auto superclassDtorType = SGM.Types.getConstantType(superclassDtor);
SILValue superclassDtorValue = B.createObjCSuperMethod(
cleanupLoc, selfValue, superclassDtor,
superclassDtorType);
// Call the superclass's -dealloc.
SILType superclassSILTy = getLoweredLoadableType(superclassTy);
SILValue superSelf = B.createUpcast(cleanupLoc, selfValue, superclassSILTy);
assert(superSelf.getOwnershipKind() == ValueOwnershipKind::Owned);
auto subMap
= superclassTy->getContextSubstitutionMap(SGM.M.getSwiftModule(),
superclass);
auto substDtorType = superclassDtorType.substGenericArgs(SGM.M, subMap);
CanSILFunctionType substFnType = substDtorType.castTo<SILFunctionType>();
SILFunctionConventions dtorConv(substFnType, SGM.M);
assert(substFnType->getSelfParameter().getConvention() ==
ParameterConvention::Direct_Unowned &&
"Objective C deinitializing destructor takes self as unowned");
B.createApply(cleanupLoc, superclassDtorValue, substDtorType,
dtorConv.getSILResultType(), subMap, superSelf);
// We know that the givne value came in at +1, but we pass the relevant value
// as unowned to the destructor. Create a fake balance for the verifier to be
// happy.
B.createEndLifetime(cleanupLoc, superSelf);
// Return.
B.createReturn(returnLoc, emitEmptyTuple(cleanupLoc));
}
示例7: addMethod
void addMethod(SILDeclRef method) {
if (method.getDecl()->getDeclContext() == CD)
TBD.addDispatchThunk(method);
}
示例8: SpecializedEmitter
Optional<SpecializedEmitter>
SpecializedEmitter::forDecl(SILGenModule &SGM, SILDeclRef function) {
// Only consider standalone declarations in the Builtin module.
if (function.kind != SILDeclRef::Kind::Func)
return None;
if (!function.hasDecl())
return None;
ValueDecl *decl = function.getDecl();
if (!isa<BuiltinUnit>(decl->getDeclContext()))
return None;
auto name = decl->getBaseName().getIdentifier();
const BuiltinInfo &builtin = SGM.M.getBuiltinInfo(name);
switch (builtin.ID) {
// All the non-SIL, non-type-trait builtins should use the
// named-builtin logic, which just emits the builtin as a call to a
// builtin function. This includes builtins that aren't even declared
// in Builtins.def, i.e. all of the LLVM intrinsics.
//
// We do this in a separate pass over Builtins.def to avoid creating
// a bunch of identical cases.
#define BUILTIN(Id, Name, Attrs) \
case BuiltinValueKind::Id:
#define BUILTIN_SIL_OPERATION(Id, Name, Overload)
#define BUILTIN_SANITIZER_OPERATION(Id, Name, Attrs)
#define BUILTIN_TYPE_CHECKER_OPERATION(Id, Name)
#define BUILTIN_TYPE_TRAIT_OPERATION(Id, Name)
#include "swift/AST/Builtins.def"
case BuiltinValueKind::None:
return SpecializedEmitter(name);
// Do a second pass over Builtins.def, ignoring all the cases for
// which we emitted something above.
#define BUILTIN(Id, Name, Attrs)
// Use specialized emitters for SIL builtins.
#define BUILTIN_SIL_OPERATION(Id, Name, Overload) \
case BuiltinValueKind::Id: \
return SpecializedEmitter(&emitBuiltin##Id);
// Sanitizer builtins should never directly be called; they should only
// be inserted as instrumentation by SILGen.
#define BUILTIN_SANITIZER_OPERATION(Id, Name, Attrs) \
case BuiltinValueKind::Id: \
llvm_unreachable("Sanitizer builtin called directly?");
#define BUILTIN_TYPE_CHECKER_OPERATION(Id, Name) \
case BuiltinValueKind::Id: \
llvm_unreachable( \
"Compile-time type checker operation should not make it to SIL!");
// Lower away type trait builtins when they're trivially solvable.
#define BUILTIN_TYPE_TRAIT_OPERATION(Id, Name) \
case BuiltinValueKind::Id: \
return SpecializedEmitter(&emitBuiltinTypeTrait<&TypeBase::Name, \
BuiltinValueKind::Id>);
#include "swift/AST/Builtins.def"
}
llvm_unreachable("bad builtin kind");
}
示例9: assert
void SILGenFunction::emitCurryThunk(SILDeclRef thunk) {
assert(thunk.isCurried);
auto *vd = thunk.getDecl();
if (auto *fd = dyn_cast<AbstractFunctionDecl>(vd)) {
assert(!SGM.M.Types.hasLoweredLocalCaptures(fd) &&
"methods cannot have captures");
(void) fd;
}
SILLocation loc(vd);
Scope S(*this, vd);
auto thunkInfo = SGM.Types.getConstantInfo(thunk);
auto thunkFnTy = thunkInfo.SILFnType;
SILFunctionConventions fromConv(thunkFnTy, SGM.M);
auto selfTy = fromConv.getSILType(thunkFnTy->getSelfParameter());
selfTy = F.mapTypeIntoContext(selfTy);
ManagedValue selfArg = B.createInputFunctionArgument(selfTy, loc);
// Forward substitutions.
auto subs = F.getForwardingSubstitutionMap();
auto toFnAndRef = getNextUncurryLevelRef(*this, loc, thunk, selfArg, subs);
ManagedValue toFn = toFnAndRef.first;
SILDeclRef calleeRef = toFnAndRef.second;
SILType resultTy = fromConv.getSingleSILResultType();
resultTy = F.mapTypeIntoContext(resultTy);
// Partially apply the next uncurry level and return the result closure.
selfArg = selfArg.ensurePlusOne(*this, loc);
auto calleeConvention = ParameterConvention::Direct_Guaranteed;
ManagedValue toClosure =
B.createPartialApply(loc, toFn, subs, {selfArg},
calleeConvention);
if (resultTy != toClosure.getType()) {
CanSILFunctionType resultFnTy = resultTy.castTo<SILFunctionType>();
CanSILFunctionType closureFnTy = toClosure.getType().castTo<SILFunctionType>();
if (resultFnTy->isABICompatibleWith(closureFnTy).isCompatible()) {
toClosure = B.createConvertFunction(loc, toClosure, resultTy);
} else {
// Compute the partially-applied abstraction pattern for the callee:
// just grab the pattern for the curried fn ref and "call" it.
assert(!calleeRef.isCurried);
calleeRef.isCurried = true;
auto appliedFnPattern = SGM.Types.getConstantInfo(calleeRef).FormalPattern
.getFunctionResultType();
auto appliedThunkPattern =
thunkInfo.FormalPattern.getFunctionResultType();
// The formal type should be the same for the callee and the thunk.
auto formalType = thunkInfo.FormalType;
if (auto genericSubstType = dyn_cast<GenericFunctionType>(formalType)) {
formalType = genericSubstType.substGenericArgs(subs);
}
formalType = cast<AnyFunctionType>(formalType.getResult());
toClosure =
emitTransformedValue(loc, toClosure,
appliedFnPattern, formalType,
appliedThunkPattern, formalType);
}
}
toClosure = S.popPreservingValue(toClosure);
B.createReturn(ImplicitReturnLocation::getImplicitReturnLoc(loc), toClosure);
}