blob: b90997cb0c69cff60cad77753eb760d807176c72 [file] [log] [blame] [edit]
//===--- SILGenExpr.cpp - Implements Lowering of ASTs -> SIL for Exprs ----===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
#include "ArgumentScope.h"
#include "ArgumentSource.h"
#include "Callee.h"
#include "Condition.h"
#include "Conversion.h"
#include "ExitableFullExpr.h"
#include "Initialization.h"
#include "LValue.h"
#include "RValue.h"
#include "ResultPlan.h"
#include "SILGen.h"
#include "SILGenDynamicCast.h"
#include "SILGenFunctionBuilder.h"
#include "Scope.h"
#include "SwitchEnumBuilder.h"
#include "Varargs.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTMangler.h"
#include "swift/AST/CanTypeVisitor.h"
#include "swift/AST/Decl.h"
#include "swift/AST/DiagnosticsCommon.h"
#include "swift/AST/Expr.h"
#include "swift/AST/ForeignErrorConvention.h"
#include "swift/AST/GenericEnvironment.h"
#include "swift/AST/ParameterList.h"
#include "swift/AST/ProtocolConformance.h"
#include "swift/AST/SubstitutionMap.h"
#include "swift/AST/Types.h"
#include "swift/Basic/SourceManager.h"
#include "swift/Basic/type_traits.h"
#include "swift/SIL/DynamicCasts.h"
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/SILUndef.h"
#include "swift/SIL/TypeLowering.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h"
#include "swift/AST/DiagnosticsSIL.h"
using namespace swift;
using namespace Lowering;
ManagedValue SILGenFunction::emitManagedRetain(SILLocation loc,
SILValue v) {
auto &lowering = getTypeLowering(v->getType());
return emitManagedRetain(loc, v, lowering);
}
ManagedValue SILGenFunction::emitManagedRetain(SILLocation loc,
SILValue v,
const TypeLowering &lowering) {
assert(lowering.getLoweredType() == v->getType());
if (lowering.isTrivial())
return ManagedValue::forUnmanaged(v);
if (v->getType().isObject() && v.getOwnershipKind() == OwnershipKind::None)
return ManagedValue::forUnmanaged(v);
assert((!lowering.isAddressOnly() || !silConv.useLoweredAddresses()) &&
"cannot retain an unloadable type");
v = lowering.emitCopyValue(B, loc, v);
return emitManagedRValueWithCleanup(v, lowering);
}
ManagedValue SILGenFunction::emitManagedLoadCopy(SILLocation loc, SILValue v) {
auto &lowering = getTypeLowering(v->getType());
return emitManagedLoadCopy(loc, v, lowering);
}
ManagedValue SILGenFunction::emitManagedLoadCopy(SILLocation loc, SILValue v,
const TypeLowering &lowering) {
assert(lowering.getLoweredType().getAddressType() == v->getType());
v = lowering.emitLoadOfCopy(B, loc, v, IsNotTake);
if (lowering.isTrivial())
return ManagedValue::forUnmanaged(v);
if (v.getOwnershipKind() == OwnershipKind::None)
return ManagedValue::forUnmanaged(v);
assert((!lowering.isAddressOnly() || !silConv.useLoweredAddresses()) &&
"cannot retain an unloadable type");
return emitManagedRValueWithCleanup(v, lowering);
}
ManagedValue SILGenFunction::emitManagedLoadBorrow(SILLocation loc,
SILValue v) {
auto &lowering = getTypeLowering(v->getType());
return emitManagedLoadBorrow(loc, v, lowering);
}
ManagedValue
SILGenFunction::emitManagedLoadBorrow(SILLocation loc, SILValue v,
const TypeLowering &lowering) {
assert(lowering.getLoweredType().getAddressType() == v->getType());
if (lowering.isTrivial()) {
v = lowering.emitLoadOfCopy(B, loc, v, IsNotTake);
return ManagedValue::forUnmanaged(v);
}
assert((!lowering.isAddressOnly() || !silConv.useLoweredAddresses()) &&
"cannot retain an unloadable type");
auto *lbi = B.createLoadBorrow(loc, v);
return emitManagedBorrowedRValueWithCleanup(v, lbi, lowering);
}
ManagedValue SILGenFunction::emitManagedStoreBorrow(SILLocation loc, SILValue v,
SILValue addr) {
auto &lowering = getTypeLowering(v->getType());
return emitManagedStoreBorrow(loc, v, addr, lowering);
}
ManagedValue SILGenFunction::emitManagedStoreBorrow(
SILLocation loc, SILValue v, SILValue addr, const TypeLowering &lowering) {
assert(lowering.getLoweredType().getObjectType() == v->getType());
if (lowering.isTrivial() || v.getOwnershipKind() == OwnershipKind::None) {
lowering.emitStore(B, loc, v, addr, StoreOwnershipQualifier::Trivial);
return ManagedValue::forUnmanaged(v);
}
assert((!lowering.isAddressOnly() || !silConv.useLoweredAddresses()) &&
"cannot retain an unloadable type");
auto *sbi = B.createStoreBorrow(loc, v, addr);
return emitManagedBorrowedRValueWithCleanup(sbi->getSrc(), sbi, lowering);
}
ManagedValue SILGenFunction::emitManagedBeginBorrow(SILLocation loc,
SILValue v) {
auto &lowering = getTypeLowering(v->getType());
return emitManagedBeginBorrow(loc, v, lowering);
}
ManagedValue
SILGenFunction::emitManagedBeginBorrow(SILLocation loc, SILValue v,
const TypeLowering &lowering) {
assert(lowering.getLoweredType().getObjectType() ==
v->getType().getObjectType());
if (lowering.isTrivial())
return ManagedValue::forUnmanaged(v);
if (v.getOwnershipKind() == OwnershipKind::None)
return ManagedValue::forUnmanaged(v);
if (v.getOwnershipKind() == OwnershipKind::Guaranteed)
return ManagedValue::forUnmanaged(v);
auto *bbi = B.createBeginBorrow(loc, v);
return emitManagedBorrowedRValueWithCleanup(v, bbi, lowering);
}
namespace {
struct EndBorrowCleanup : Cleanup {
SILValue borrowedValue;
EndBorrowCleanup(SILValue borrowedValue) : borrowedValue(borrowedValue) {
if (auto *arg = dyn_cast<SILPhiArgument>(borrowedValue)) {
if (auto *ti = arg->getSingleTerminator()) {
assert(!ti->isTransformationTerminator() &&
"Transforming terminators do not have end_borrow");
}
}
}
void emit(SILGenFunction &SGF, CleanupLocation l,
ForUnwind_t forUnwind) override {
SGF.B.createEndBorrow(l, borrowedValue);
}
void dump(SILGenFunction &) const override {
#ifndef NDEBUG
llvm::errs() << "EndBorrowCleanup "
<< "State:" << getState() << "\n"
<< "borrowed:" << borrowedValue
<< "\n";
#endif
}
};
struct FormalEvaluationEndBorrowCleanup : Cleanup {
FormalEvaluationContext::stable_iterator Depth;
FormalEvaluationEndBorrowCleanup() : Depth() {}
void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
getEvaluation(SGF).finish(SGF);
}
void dump(SILGenFunction &SGF) const override {
#ifndef NDEBUG
llvm::errs() << "FormalEvaluationEndBorrowCleanup "
<< "State:" << getState() << "\n"
<< "original:" << getOriginalValue(SGF) << "\n"
<< "borrowed:" << getBorrowedValue(SGF) << "\n";
#endif
}
SharedBorrowFormalAccess &getEvaluation(SILGenFunction &SGF) const {
auto &evaluation = *SGF.FormalEvalContext.find(Depth);
assert(evaluation.getKind() == FormalAccess::Shared);
return static_cast<SharedBorrowFormalAccess &>(evaluation);
}
SILValue getOriginalValue(SILGenFunction &SGF) const {
return getEvaluation(SGF).getOriginalValue();
}
SILValue getBorrowedValue(SILGenFunction &SGF) const {
return getEvaluation(SGF).getBorrowedValue();
}
};
} // end anonymous namespace
ManagedValue
SILGenFunction::emitFormalEvaluationManagedBeginBorrow(SILLocation loc,
SILValue v) {
if (v.getOwnershipKind() == OwnershipKind::Guaranteed)
return ManagedValue::forUnmanaged(v);
auto &lowering = getTypeLowering(v->getType());
return emitFormalEvaluationManagedBeginBorrow(loc, v, lowering);
}
ManagedValue SILGenFunction::emitFormalEvaluationManagedBeginBorrow(
SILLocation loc, SILValue v, const TypeLowering &lowering) {
assert(lowering.getLoweredType().getObjectType() ==
v->getType().getObjectType());
if (lowering.isTrivial())
return ManagedValue::forUnmanaged(v);
if (v.getOwnershipKind() == OwnershipKind::Guaranteed)
return ManagedValue::forUnmanaged(v);
auto *bbi = B.createBeginBorrow(loc, v);
return emitFormalEvaluationManagedBorrowedRValueWithCleanup(loc, v, bbi,
lowering);
}
ManagedValue
SILGenFunction::emitFormalEvaluationManagedBorrowedRValueWithCleanup(
SILLocation loc, SILValue original, SILValue borrowed) {
auto &lowering = getTypeLowering(original->getType());
return emitFormalEvaluationManagedBorrowedRValueWithCleanup(
loc, original, borrowed, lowering);
}
ManagedValue
SILGenFunction::emitFormalEvaluationManagedBorrowedRValueWithCleanup(
SILLocation loc, SILValue original, SILValue borrowed,
const TypeLowering &lowering) {
assert(lowering.getLoweredType().getObjectType() ==
original->getType().getObjectType());
if (lowering.isTrivial())
return ManagedValue::forUnmanaged(borrowed);
if (!borrowed->getType().isObject()) {
return ManagedValue(borrowed, CleanupHandle::invalid());
}
assert(isInFormalEvaluationScope() && "Must be in formal evaluation scope");
auto &cleanup = Cleanups.pushCleanup<FormalEvaluationEndBorrowCleanup>();
CleanupHandle handle = Cleanups.getTopCleanup();
FormalEvalContext.push<SharedBorrowFormalAccess>(loc, handle, original,
borrowed);
cleanup.Depth = FormalEvalContext.stable_begin();
return ManagedValue(borrowed, CleanupHandle::invalid());
}
ManagedValue
SILGenFunction::emitManagedBorrowedArgumentWithCleanup(SILPhiArgument *arg) {
if (arg->getOwnershipKind() == OwnershipKind::None ||
arg->getType().isTrivial(F)) {
return ManagedValue::forUnmanaged(arg);
}
assert(arg->getOwnershipKind() == OwnershipKind::Guaranteed);
Cleanups.pushCleanup<EndBorrowCleanup>(arg);
return ManagedValue(arg, CleanupHandle::invalid());
}
ManagedValue
SILGenFunction::emitManagedBorrowedRValueWithCleanup(SILValue original,
SILValue borrowed) {
assert(original->getType().getObjectType() ==
borrowed->getType().getObjectType());
auto &lowering = getTypeLowering(original->getType());
return emitManagedBorrowedRValueWithCleanup(original, borrowed, lowering);
}
ManagedValue
SILGenFunction::emitManagedBorrowedRValueWithCleanup(SILValue borrowed) {
auto &lowering = getTypeLowering(borrowed->getType());
return emitManagedBorrowedRValueWithCleanup(borrowed, lowering);
}
ManagedValue SILGenFunction::emitManagedBorrowedRValueWithCleanup(
SILValue borrowed, const TypeLowering &lowering) {
assert(lowering.getLoweredType().getObjectType() ==
borrowed->getType().getObjectType());
if (lowering.isTrivial())
return ManagedValue::forUnmanaged(borrowed);
if (borrowed->getType().isObject() &&
borrowed.getOwnershipKind() == OwnershipKind::None)
return ManagedValue::forUnmanaged(borrowed);
if (borrowed->getType().isObject()) {
Cleanups.pushCleanup<EndBorrowCleanup>(borrowed);
}
return ManagedValue(borrowed, CleanupHandle::invalid());
}
ManagedValue SILGenFunction::emitManagedBorrowedRValueWithCleanup(
SILValue original, SILValue borrowed, const TypeLowering &lowering) {
assert(lowering.getLoweredType().getObjectType() ==
original->getType().getObjectType());
if (lowering.isTrivial())
return ManagedValue::forUnmanaged(borrowed);
if (original->getType().isObject() &&
original.getOwnershipKind() == OwnershipKind::None)
return ManagedValue::forUnmanaged(borrowed);
if (borrowed->getType().isObject()) {
Cleanups.pushCleanup<EndBorrowCleanup>(borrowed);
}
return ManagedValue(borrowed, CleanupHandle::invalid());
}
ManagedValue SILGenFunction::emitManagedRValueWithCleanup(SILValue v) {
auto &lowering = getTypeLowering(v->getType());
return emitManagedRValueWithCleanup(v, lowering);
}
ManagedValue SILGenFunction::emitManagedRValueWithCleanup(SILValue v,
const TypeLowering &lowering) {
assert(lowering.getLoweredType().getObjectType() ==
v->getType().getObjectType());
if (lowering.isTrivial())
return ManagedValue::forUnmanaged(v);
if (v->getType().isObject() && v.getOwnershipKind() == OwnershipKind::None) {
return ManagedValue::forUnmanaged(v);
}
return ManagedValue(v, enterDestroyCleanup(v));
}
ManagedValue SILGenFunction::emitManagedBufferWithCleanup(SILValue v) {
auto &lowering = getTypeLowering(v->getType());
return emitManagedBufferWithCleanup(v, lowering);
}
ManagedValue SILGenFunction::emitManagedBufferWithCleanup(SILValue v,
const TypeLowering &lowering) {
assert(lowering.getLoweredType().getAddressType() == v->getType() ||
!silConv.useLoweredAddresses());
if (lowering.isTrivial())
return ManagedValue::forUnmanaged(v);
return ManagedValue(v, enterDestroyCleanup(v));
}
void SILGenFunction::emitExprInto(Expr *E, Initialization *I,
Optional<SILLocation> L) {
// Handle the special case of copying an lvalue.
if (auto load = dyn_cast<LoadExpr>(E)) {
FormalEvaluationScope writeback(*this);
auto lv = emitLValue(load->getSubExpr(),
SGFAccessKind::BorrowedAddressRead);
emitCopyLValueInto(E, std::move(lv), I);
return;
}
RValue result = emitRValue(E, SGFContext(I));
if (result.isInContext())
return;
std::move(result).ensurePlusOne(*this, E).forwardInto(*this, L ? *L : E, I);
}
namespace {
class RValueEmitter
: public Lowering::ExprVisitor<RValueEmitter, RValue, SGFContext>
{
typedef Lowering::ExprVisitor<RValueEmitter,RValue,SGFContext> super;
public:
SILGenFunction &SGF;
RValueEmitter(SILGenFunction &SGF) : SGF(SGF) {}
using super::visit;
RValue visit(Expr *E) {
assert(!E->getType()->is<LValueType>() &&
!E->getType()->is<InOutType>() &&
"RValueEmitter shouldn't be called on lvalues");
return visit(E, SGFContext());
}
// These always produce lvalues.
RValue visitInOutExpr(InOutExpr *E, SGFContext C) {
LValue lv = SGF.emitLValue(E->getSubExpr(), SGFAccessKind::ReadWrite);
return RValue(SGF, E, SGF.emitAddressOfLValue(E->getSubExpr(),
std::move(lv)));
}
RValue visitApplyExpr(ApplyExpr *E, SGFContext C);
RValue visitDiscardAssignmentExpr(DiscardAssignmentExpr *E, SGFContext C) {
llvm_unreachable("cannot appear in rvalue");
}
RValue visitDeclRefExpr(DeclRefExpr *E, SGFContext C);
RValue visitTypeExpr(TypeExpr *E, SGFContext C);
RValue visitSuperRefExpr(SuperRefExpr *E, SGFContext C);
RValue visitOtherConstructorDeclRefExpr(OtherConstructorDeclRefExpr *E,
SGFContext C);
RValue visitForceTryExpr(ForceTryExpr *E, SGFContext C);
RValue visitOptionalTryExpr(OptionalTryExpr *E, SGFContext C);
RValue visitNilLiteralExpr(NilLiteralExpr *E, SGFContext C);
RValue visitIntegerLiteralExpr(IntegerLiteralExpr *E, SGFContext C);
RValue visitFloatLiteralExpr(FloatLiteralExpr *E, SGFContext C);
RValue visitBooleanLiteralExpr(BooleanLiteralExpr *E, SGFContext C);
RValue emitStringLiteral(Expr *E, StringRef Str, SGFContext C,
StringLiteralExpr::Encoding encoding);
RValue visitStringLiteralExpr(StringLiteralExpr *E, SGFContext C);
RValue visitLoadExpr(LoadExpr *E, SGFContext C);
RValue visitDerivedToBaseExpr(DerivedToBaseExpr *E, SGFContext C);
RValue visitMetatypeConversionExpr(MetatypeConversionExpr *E,
SGFContext C);
RValue visitCollectionUpcastConversionExpr(
CollectionUpcastConversionExpr *E,
SGFContext C);
RValue visitBridgeToObjCExpr(BridgeToObjCExpr *E, SGFContext C);
RValue visitBridgeFromObjCExpr(BridgeFromObjCExpr *E, SGFContext C);
RValue visitConditionalBridgeFromObjCExpr(ConditionalBridgeFromObjCExpr *E,
SGFContext C);
RValue visitArchetypeToSuperExpr(ArchetypeToSuperExpr *E, SGFContext C);
RValue visitUnresolvedTypeConversionExpr(UnresolvedTypeConversionExpr *E,
SGFContext C);
RValue visitFunctionConversionExpr(FunctionConversionExpr *E,
SGFContext C);
RValue visitCovariantFunctionConversionExpr(
CovariantFunctionConversionExpr *E,
SGFContext C);
RValue visitCovariantReturnConversionExpr(
CovariantReturnConversionExpr *E,
SGFContext C);
RValue visitImplicitlyUnwrappedFunctionConversionExpr(
ImplicitlyUnwrappedFunctionConversionExpr *E, SGFContext C);
RValue visitErasureExpr(ErasureExpr *E, SGFContext C);
RValue visitAnyHashableErasureExpr(AnyHashableErasureExpr *E, SGFContext C);
RValue visitForcedCheckedCastExpr(ForcedCheckedCastExpr *E,
SGFContext C);
RValue visitConditionalCheckedCastExpr(ConditionalCheckedCastExpr *E,
SGFContext C);
RValue visitIsExpr(IsExpr *E, SGFContext C);
RValue visitCoerceExpr(CoerceExpr *E, SGFContext C);
RValue visitUnderlyingToOpaqueExpr(UnderlyingToOpaqueExpr *E, SGFContext C);
RValue visitTupleExpr(TupleExpr *E, SGFContext C);
RValue visitMemberRefExpr(MemberRefExpr *E, SGFContext C);
RValue visitDynamicMemberRefExpr(DynamicMemberRefExpr *E, SGFContext C);
RValue visitDotSyntaxBaseIgnoredExpr(DotSyntaxBaseIgnoredExpr *E,
SGFContext C);
RValue visitTupleElementExpr(TupleElementExpr *E, SGFContext C);
RValue visitSubscriptExpr(SubscriptExpr *E, SGFContext C);
RValue visitKeyPathApplicationExpr(KeyPathApplicationExpr *E, SGFContext C);
RValue visitDynamicSubscriptExpr(DynamicSubscriptExpr *E,
SGFContext C);
RValue visitDestructureTupleExpr(DestructureTupleExpr *E, SGFContext C);
RValue visitDynamicTypeExpr(DynamicTypeExpr *E, SGFContext C);
RValue visitCaptureListExpr(CaptureListExpr *E, SGFContext C);
RValue visitAbstractClosureExpr(AbstractClosureExpr *E, SGFContext C);
RValue visitInterpolatedStringLiteralExpr(InterpolatedStringLiteralExpr *E,
SGFContext C);
RValue visitObjectLiteralExpr(ObjectLiteralExpr *E, SGFContext C);
RValue visitEditorPlaceholderExpr(EditorPlaceholderExpr *E, SGFContext C);
RValue visitObjCSelectorExpr(ObjCSelectorExpr *E, SGFContext C);
RValue visitKeyPathExpr(KeyPathExpr *E, SGFContext C);
RValue visitMagicIdentifierLiteralExpr(MagicIdentifierLiteralExpr *E,
SGFContext C);
RValue visitCollectionExpr(CollectionExpr *E, SGFContext C);
RValue visitRebindSelfInConstructorExpr(RebindSelfInConstructorExpr *E,
SGFContext C);
RValue visitInjectIntoOptionalExpr(InjectIntoOptionalExpr *E, SGFContext C);
RValue visitClassMetatypeToObjectExpr(ClassMetatypeToObjectExpr *E,
SGFContext C);
RValue visitExistentialMetatypeToObjectExpr(ExistentialMetatypeToObjectExpr *E,
SGFContext C);
RValue visitProtocolMetatypeToObjectExpr(ProtocolMetatypeToObjectExpr *E,
SGFContext C);
RValue visitIfExpr(IfExpr *E, SGFContext C);
RValue visitAssignExpr(AssignExpr *E, SGFContext C);
RValue visitEnumIsCaseExpr(EnumIsCaseExpr *E, SGFContext C);
RValue visitBindOptionalExpr(BindOptionalExpr *E, SGFContext C);
RValue visitOptionalEvaluationExpr(OptionalEvaluationExpr *E,
SGFContext C);
RValue visitForceValueExpr(ForceValueExpr *E, SGFContext C);
RValue emitForceValue(ForceValueExpr *loc, Expr *E,
unsigned numOptionalEvaluations,
SGFContext C);
RValue visitOpenExistentialExpr(OpenExistentialExpr *E, SGFContext C);
RValue visitMakeTemporarilyEscapableExpr(
MakeTemporarilyEscapableExpr *E, SGFContext C);
RValue visitOpaqueValueExpr(OpaqueValueExpr *E, SGFContext C);
RValue visitPropertyWrapperValuePlaceholderExpr(
PropertyWrapperValuePlaceholderExpr *E, SGFContext C);
RValue visitInOutToPointerExpr(InOutToPointerExpr *E, SGFContext C);
RValue visitArrayToPointerExpr(ArrayToPointerExpr *E, SGFContext C);
RValue visitStringToPointerExpr(StringToPointerExpr *E, SGFContext C);
RValue visitPointerToPointerExpr(PointerToPointerExpr *E, SGFContext C);
RValue visitForeignObjectConversionExpr(ForeignObjectConversionExpr *E,
SGFContext C);
RValue visitUnevaluatedInstanceExpr(UnevaluatedInstanceExpr *E,
SGFContext C);
RValue visitTapExpr(TapExpr *E, SGFContext C);
RValue visitDefaultArgumentExpr(DefaultArgumentExpr *E, SGFContext C);
RValue visitErrorExpr(ErrorExpr *E, SGFContext C);
RValue visitDifferentiableFunctionExpr(DifferentiableFunctionExpr *E,
SGFContext C);
RValue visitLinearFunctionExpr(LinearFunctionExpr *E, SGFContext C);
RValue visitDifferentiableFunctionExtractOriginalExpr(
DifferentiableFunctionExtractOriginalExpr *E, SGFContext C);
RValue visitLinearFunctionExtractOriginalExpr(
LinearFunctionExtractOriginalExpr *E, SGFContext C);
RValue visitLinearToDifferentiableFunctionExpr(
LinearToDifferentiableFunctionExpr *E, SGFContext C);
};
} // end anonymous namespace
namespace {
struct BridgingConversion {
Expr *SubExpr;
Optional<Conversion::KindTy> Kind;
unsigned MaxOptionalDepth;
BridgingConversion() : SubExpr(nullptr) {}
BridgingConversion(Expr *sub, Optional<Conversion::KindTy> kind,
unsigned depth)
: SubExpr(sub), Kind(kind), MaxOptionalDepth(depth) {
assert(!kind || Conversion::isBridgingKind(*kind));
}
explicit operator bool() const { return SubExpr != nullptr; }
};
}
static BridgingConversion getBridgingConversion(Expr *E) {
E = E->getSemanticsProvidingExpr();
// Detect bridging conversions.
if (auto bridge = dyn_cast<BridgeToObjCExpr>(E)) {
return { bridge->getSubExpr(), Conversion::BridgeToObjC, 0 };
}
if (auto bridge = dyn_cast<BridgeFromObjCExpr>(E)) {
return { bridge->getSubExpr(), Conversion::BridgeFromObjC, 0 };
}
// We can handle optional injections.
if (auto inject = dyn_cast<InjectIntoOptionalExpr>(E)) {
return getBridgingConversion(inject->getSubExpr());
}
// Look through optional-to-optional conversions.
if (auto optEval = dyn_cast<OptionalEvaluationExpr>(E)) {
auto sub = optEval->getSubExpr()->getSemanticsProvidingExpr();
if (auto subResult = getBridgingConversion(sub)) {
sub = subResult.SubExpr->getSemanticsProvidingExpr();
if (auto bind = dyn_cast<BindOptionalExpr>(sub)) {
if (bind->getDepth() == subResult.MaxOptionalDepth) {
return { bind->getSubExpr(),
subResult.Kind,
subResult.MaxOptionalDepth + 1 };
}
}
}
}
// Open-existentials can be part of bridging conversions in very
// specific patterns.
auto open = dyn_cast<OpenExistentialExpr>(E);
if (open) E = open->getSubExpr();
// Existential erasure.
if (auto erasure = dyn_cast<ErasureExpr>(E)) {
Conversion::KindTy kind;
// Converting to Any is sometimes part of bridging and definitely
// needs special peepholing behavior.
if (erasure->getType()->isAny()) {
kind = Conversion::AnyErasure;
// Otherwise, nope.
} else {
return {};
}
// Tentatively look through the erasure.
E = erasure->getSubExpr();
// If we have an opening, we can only peephole if the value being
// used is exactly the original value.
if (open) {
if (E == open->getOpaqueValue()) {
return { open->getExistentialValue(), kind, 0 };
}
return {};
}
// Otherwise we can always peephole.
return { E, kind, 0 };
}
// If we peeked through an opening, and we didn't recognize a specific
// pattern above involving the opaque value, make sure we use the opening
// as the final expression instead of accidentally look through it.
if (open) return { open, None, 0 };
return { E, None, 0 };
}
/// If the given expression represents a bridging conversion, emit it with
/// the special reabstracting context.
static Optional<ManagedValue>
tryEmitAsBridgingConversion(SILGenFunction &SGF, Expr *E, bool isExplicit,
SGFContext C) {
// Try to pattern-match a conversion. This can find bridging
// conversions, but it can also find simple optional conversions:
// injections and opt-to-opt conversions.
auto result = getBridgingConversion(E);
// If we didn't find a conversion at all, there's nothing special to do.
if (!result ||
result.SubExpr == E ||
result.SubExpr->getType()->isEqual(E->getType()))
return None;
// Even if the conversion doesn't involve bridging, we might still
// expose more peephole opportunities by combining it with a contextual
// conversion.
if (!result.Kind) {
// Only do this if the conversion is implicit.
if (isExplicit)
return None;
// Look for a contextual conversion.
auto conversion = C.getAsConversion();
if (!conversion)
return None;
// Adjust the contextual conversion.
auto sub = result.SubExpr;
auto sourceType = sub->getType()->getCanonicalType();
if (auto adjusted = conversion->getConversion()
.adjustForInitialOptionalConversions(sourceType)) {
// Emit into the applied conversion.
return conversion->emitWithAdjustedConversion(SGF, E, *adjusted,
[sub](SILGenFunction &SGF, SILLocation loc, SGFContext C) {
return SGF.emitRValueAsSingleValue(sub, C);
});
}
// If that didn't work, there's nothing special to do.
return None;
}
auto kind = *result.Kind;
auto subExpr = result.SubExpr;
CanType resultType = E->getType()->getCanonicalType();
Conversion conversion =
Conversion::getBridging(kind, subExpr->getType()->getCanonicalType(),
resultType, SGF.getLoweredType(resultType),
isExplicit);
// Only use this special pattern for AnyErasure conversions when we're
// emitting into a peephole.
if (kind == Conversion::AnyErasure) {
auto outerConversion = C.getAsConversion();
if (!outerConversion ||
!canPeepholeConversions(SGF, outerConversion->getConversion(),
conversion)) {
return None;
}
}
return SGF.emitConvertedRValue(subExpr, conversion, C);
}
RValue RValueEmitter::visitApplyExpr(ApplyExpr *E, SGFContext C) {
return SGF.emitApplyExpr(E, C);
}
SILValue SILGenFunction::emitEmptyTuple(SILLocation loc) {
return B.createTuple(
loc, getLoweredType(TupleType::getEmpty(SGM.M.getASTContext())),
ArrayRef<SILValue>());
}
namespace {
/// This is a simple cleanup class that at the end of a lexical scope consumes
/// an owned value by writing it back to memory. The user can forward this
/// cleanup to take ownership of the value and thus prevent it form being
/// written back.
struct OwnedValueWritebackCleanup final : Cleanup {
using Flags = Cleanup::Flags;
/// We store our own loc so that we can ensure that DI ignores our writeback.
SILLocation loc;
SILValue lvalueAddress;
SILValue value;
OwnedValueWritebackCleanup(SILLocation loc, SILValue lvalueAddress,
SILValue value)
: loc(loc), lvalueAddress(lvalueAddress), value(value) {}
bool getWritebackBuffer(function_ref<void(SILValue)> func) override {
func(lvalueAddress);
return true;
}
void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
SILValue valueToStore = value;
SILType lvalueObjTy = lvalueAddress->getType().getObjectType();
// If we calling a super.init and thus upcasted self, when we store self
// back into the self slot, we need to perform a downcast from the upcasted
// store value to the derived type of our lvalueAddress.
if (valueToStore->getType() != lvalueObjTy) {
if (!valueToStore->getType().isExactSuperclassOf(lvalueObjTy)) {
llvm_unreachable("Invalid usage of delegate init self writeback");
}
valueToStore = SGF.B.createUncheckedRefCast(loc, valueToStore,
lvalueObjTy);
}
SGF.B.emitStoreValueOperation(loc, valueToStore, lvalueAddress,
StoreOwnershipQualifier::Init);
}
void dump(SILGenFunction &) const override {
#ifndef NDEBUG
llvm::errs() << "OwnedValueWritebackCleanup "
<< "State:" << getState() << "\n"
<< "lvalueAddress:" << lvalueAddress << "value:" << value
<< "\n";
#endif
}
};
} // end anonymous namespace
CleanupHandle SILGenFunction::enterOwnedValueWritebackCleanup(
SILLocation loc, SILValue address, SILValue newValue) {
Cleanups.pushCleanup<OwnedValueWritebackCleanup>(loc, address, newValue);
return Cleanups.getTopCleanup();
}
RValue SILGenFunction::emitRValueForSelfInDelegationInit(SILLocation loc,
CanType refType,
SILValue addr,
SGFContext C) {
assert(SelfInitDelegationState != SILGenFunction::NormalSelf &&
"This should never be called unless we are in a delegation sequence");
assert(getTypeLowering(addr->getType()).isLoadable() &&
"Make sure that we are not dealing with semantic rvalues");
// If we are currently in the WillSharedBorrowSelf state, then we know that
// old self is not the self to our delegating initializer. Self in this case
// to the delegating initializer is a metatype. Thus, we perform a
// load_borrow. And move from WillSharedBorrowSelf -> DidSharedBorrowSelf.
if (SelfInitDelegationState == SILGenFunction::WillSharedBorrowSelf) {
assert(C.isGuaranteedPlusZeroOk() &&
"This should only be called if guaranteed plus zero is ok");
SelfInitDelegationState = SILGenFunction::DidSharedBorrowSelf;
ManagedValue result =
B.createLoadBorrow(loc, ManagedValue::forUnmanaged(addr));
return RValue(*this, loc, refType, result);
}
// If we are already in the did shared borrow self state, just return the
// shared borrow value.
if (SelfInitDelegationState == SILGenFunction::DidSharedBorrowSelf) {
assert(C.isGuaranteedPlusZeroOk() &&
"This should only be called if guaranteed plus zero is ok");
ManagedValue result =
B.createLoadBorrow(loc, ManagedValue::forUnmanaged(addr));
return RValue(*this, loc, refType, result);
}
// If we are in WillExclusiveBorrowSelf, then we need to perform an exclusive
// borrow (i.e. a load take) and then move to DidExclusiveBorrowSelf.
if (SelfInitDelegationState == SILGenFunction::WillExclusiveBorrowSelf) {
const auto &typeLowering = getTypeLowering(addr->getType());
SelfInitDelegationState = SILGenFunction::DidExclusiveBorrowSelf;
SILValue self =
emitLoad(loc, addr, typeLowering, C, IsTake, false).forward(*this);
// Forward our initial value for init delegation self and create a new
// cleanup that performs a writeback at the end of lexical scope if our
// value is not consumed.
InitDelegationSelf = ManagedValue::forExclusivelyBorrowedOwnedObjectRValue(
self, enterOwnedValueWritebackCleanup(*InitDelegationLoc, addr, self));
InitDelegationSelfBox = addr;
return RValue(*this, loc, refType, InitDelegationSelf);
}
// If we hit this point, we must have DidExclusiveBorrowSelf. We should have
// gone through the formal evaluation variant but did not. The only way that
// this can happen is if during argument evaluation, we are accessing self in
// a way that is illegal before we call super. Return a copy of self in this
// case so that DI will flag on this issue. We do not care where the destroy
// occurs, so we can use a normal scoped copy.
ManagedValue Result;
if (!SuperInitDelegationSelf) {
Result = InitDelegationSelf.copy(*this, loc);
} else {
Result =
B.createUncheckedRefCast(loc, SuperInitDelegationSelf.copy(*this, loc),
InitDelegationSelf.getType());
}
return RValue(*this, loc, refType, Result);
}
RValue SILGenFunction::emitFormalEvaluationRValueForSelfInDelegationInit(
SILLocation loc, CanType refType, SILValue addr, SGFContext C) {
assert(SelfInitDelegationState != SILGenFunction::NormalSelf &&
"This should never be called unless we are in a delegation sequence");
assert(getTypeLowering(addr->getType()).isLoadable() &&
"Make sure that we are not dealing with semantic rvalues");
// If we are currently in the WillSharedBorrowSelf state, then we know that
// old self is not the self to our delegating initializer. Self in this case
// to the delegating initializer is a metatype. Thus, we perform a
// load_borrow. And move from WillSharedBorrowSelf -> DidSharedBorrowSelf.
if (SelfInitDelegationState == SILGenFunction::WillSharedBorrowSelf) {
assert(C.isGuaranteedPlusZeroOk() &&
"This should only be called if guaranteed plus zero is ok");
SelfInitDelegationState = SILGenFunction::DidSharedBorrowSelf;
ManagedValue result =
B.createFormalAccessLoadBorrow(loc, ManagedValue::forUnmanaged(addr));
return RValue(*this, loc, refType, result);
}
// If we are already in the did shared borrow self state, just return the
// shared borrow value.
if (SelfInitDelegationState == SILGenFunction::DidSharedBorrowSelf) {
assert(C.isGuaranteedPlusZeroOk() &&
"This should only be called if guaranteed plus zero is ok");
ManagedValue result =
B.createFormalAccessLoadBorrow(loc, ManagedValue::forUnmanaged(addr));
return RValue(*this, loc, refType, result);
}
// If we hit this point, we must have DidExclusiveBorrowSelf. Thus borrow
// self.
//
// *NOTE* This routine should /never/ begin an exclusive borrow of self. It is
// only called when emitting self as a base in lvalue emission.
assert(SelfInitDelegationState == SILGenFunction::DidExclusiveBorrowSelf);
// If we do not have a super init delegation self, just perform a formal
// access borrow and return. This occurs with delegating initializers.
if (!SuperInitDelegationSelf) {
return RValue(*this, loc, refType,
InitDelegationSelf.formalAccessBorrow(*this, loc));
}
// Otherwise, we had an upcast of some sort due to a chaining
// initializer. This means that we need to perform a borrow from
// SuperInitDelegationSelf and then downcast that borrow.
ManagedValue borrowedUpcast =
SuperInitDelegationSelf.formalAccessBorrow(*this, loc);
ManagedValue castedBorrowedType = B.createUncheckedRefCast(
loc, borrowedUpcast, InitDelegationSelf.getType());
return RValue(*this, loc, refType, castedBorrowedType);
}
RValue SILGenFunction::
emitRValueForDecl(SILLocation loc, ConcreteDeclRef declRef, Type ncRefType,
AccessSemantics semantics, SGFContext C) {
assert(!ncRefType->is<LValueType>() &&
"RValueEmitter shouldn't be called on lvalues");
// If this is a decl that we have an lvalue for, produce and return it.
ValueDecl *decl = declRef.getDecl();
CanType refType = ncRefType->getCanonicalType();
// If this is a reference to a module, produce an undef value. The
// module value should never actually be used.
if (isa<ModuleDecl>(decl)) {
return emitUndefRValue(loc, refType);
}
// If this is a reference to a var, emit it as an l-value and then load.
if (auto *var = dyn_cast<VarDecl>(decl))
return emitRValueForNonMemberVarDecl(loc, declRef, refType, semantics, C);
assert(!isa<TypeDecl>(decl));
// If the referenced decl isn't a VarDecl, it should be a constant of some
// sort.
SILDeclRef silDeclRef(decl);
assert(silDeclRef.getParameterListCount() == 1);
ManagedValue result = emitClosureValue(loc, silDeclRef, refType,
declRef.getSubstitutions());
return RValue(*this, loc, refType, result);
}
RValue RValueEmitter::visitDeclRefExpr(DeclRefExpr *E, SGFContext C) {
return SGF.emitRValueForDecl(E, E->getDeclRef(), E->getType(),
E->getAccessSemantics(), C);
}
RValue RValueEmitter::visitTypeExpr(TypeExpr *E, SGFContext C) {
assert(E->getType()->is<AnyMetatypeType>() &&
"TypeExpr must have metatype type");
auto Val = SGF.B.createMetatype(E, SGF.getLoweredType(E->getType()));
return RValue(SGF, E, ManagedValue::forUnmanaged(Val));
}
RValue RValueEmitter::visitSuperRefExpr(SuperRefExpr *E, SGFContext C) {
assert(!E->getType()->is<LValueType>() &&
"RValueEmitter shouldn't be called on lvalues");
// If we have a normal self call, then use the emitRValueForDecl call. This
// will emit self at +0 since it is guaranteed.
ManagedValue Self =
SGF.emitRValueForDecl(E, E->getSelf(), E->getSelf()->getType(),
AccessSemantics::Ordinary)
.getScalarValue();
// Perform an upcast to convert self to the indicated super type.
auto result = SGF.B.createUpcast(E, Self, SGF.getLoweredType(E->getType()));
return RValue(SGF, E, result);
}
RValue RValueEmitter::
visitUnresolvedTypeConversionExpr(UnresolvedTypeConversionExpr *E,
SGFContext C) {
llvm_unreachable("invalid code made its way into SILGen");
}
RValue RValueEmitter::visitOtherConstructorDeclRefExpr(
OtherConstructorDeclRefExpr *E, SGFContext C) {
// This should always be a child of an ApplyExpr and so will be emitted by
// SILGenApply.
llvm_unreachable("unapplied reference to constructor?!");
}
RValue RValueEmitter::visitNilLiteralExpr(NilLiteralExpr *E, SGFContext C) {
// Peephole away the call to Optional<T>(nilLiteral: ()).
if (E->getType()->getOptionalObjectType()) {
auto *noneDecl = SGF.getASTContext().getOptionalNoneDecl();
auto enumTy = SGF.getLoweredType(E->getType());
ManagedValue noneValue;
if (enumTy.isLoadable(SGF.F) || !SGF.silConv.useLoweredAddresses()) {
noneValue = ManagedValue::forUnmanaged(
SGF.B.createEnum(E, SILValue(), noneDecl, enumTy));
} else {
noneValue =
SGF.B.bufferForExpr(E, enumTy, SGF.getTypeLowering(enumTy), C,
[&](SILValue newAddr) {
SGF.B.createInjectEnumAddr(E, newAddr, noneDecl);
});
}
return RValue(SGF, E, noneValue);
}
return SGF.emitLiteral(E, C);
}
RValue RValueEmitter::visitIntegerLiteralExpr(IntegerLiteralExpr *E,
SGFContext C) {
if (E->getType()->is<AnyBuiltinIntegerType>())
return RValue(SGF, E,
ManagedValue::forUnmanaged(SGF.B.createIntegerLiteral(E)));
return SGF.emitLiteral(E, C);
}
RValue RValueEmitter::visitFloatLiteralExpr(FloatLiteralExpr *E,
SGFContext C) {
if (E->getType()->is<BuiltinFloatType>())
return RValue(SGF, E,
ManagedValue::forUnmanaged(SGF.B.createFloatLiteral(E)));
return SGF.emitLiteral(E, C);
}
RValue RValueEmitter::visitBooleanLiteralExpr(BooleanLiteralExpr *E,
SGFContext C) {
return SGF.emitLiteral(E, C);
}
RValue RValueEmitter::visitStringLiteralExpr(StringLiteralExpr *E,
SGFContext C) {
return SGF.emitLiteral(E, C);
}
RValue RValueEmitter::visitLoadExpr(LoadExpr *E, SGFContext C) {
// Any writebacks here are tightly scoped.
FormalEvaluationScope writeback(SGF);
LValue lv = SGF.emitLValue(E->getSubExpr(), SGFAccessKind::OwnedObjectRead);
// We can't load at immediate +0 from the lvalue without deeper analysis,
// since the access will be immediately ended and might invalidate the value
// we loaded.
return SGF.emitLoadOfLValue(E, std::move(lv), C.withFollowingSideEffects());
}
SILValue SILGenFunction::emitTemporaryAllocation(SILLocation loc,
SILType ty) {
ty = ty.getObjectType();
Optional<SILDebugVariable> DbgVar;
if (auto *VD = loc.getAsASTNode<VarDecl>())
DbgVar = SILDebugVariable(VD->isLet(), 0);
auto alloc = B.createAllocStack(loc, ty, DbgVar);
enterDeallocStackCleanup(alloc);
return alloc;
}
SILValue SILGenFunction::
getBufferForExprResult(SILLocation loc, SILType ty, SGFContext C) {
// If you change this, change manageBufferForExprResult below as well.
// If we have a single-buffer "emit into" initialization, use that for the
// result.
if (SILValue address = C.getAddressForInPlaceInitialization(*this, loc))
return address;
// If we couldn't emit into the Initialization, emit into a temporary
// allocation.
return emitTemporaryAllocation(loc, ty.getObjectType());
}
ManagedValue SILGenFunction::
manageBufferForExprResult(SILValue buffer, const TypeLowering &bufferTL,
SGFContext C) {
// If we have a single-buffer "emit into" initialization, use that for the
// result.
if (C.finishInPlaceInitialization(*this))
return ManagedValue::forInContext();
// Add a cleanup for the temporary we allocated.
if (bufferTL.isTrivial())
return ManagedValue::forUnmanaged(buffer);
return ManagedValue(buffer, enterDestroyCleanup(buffer));
}
SILGenFunction::ForceTryEmission::ForceTryEmission(SILGenFunction &SGF,
ForceTryExpr *loc)
: SGF(SGF), Loc(loc), OldThrowDest(SGF.ThrowDest) {
assert(loc && "cannot pass a null location");
// Set up a "catch" block for when an error occurs.
SILBasicBlock *catchBB = SGF.createBasicBlock(FunctionSection::Postmatter);
SGF.ThrowDest = JumpDest(catchBB, SGF.Cleanups.getCleanupsDepth(),
CleanupLocation::get(loc));
}
void SILGenFunction::ForceTryEmission::finish() {
assert(Loc && "emission already finished");
auto catchBB = SGF.ThrowDest.getBlock();
SGF.ThrowDest = OldThrowDest;
// If there are no uses of the catch block, just drop it.
if (catchBB->pred_empty()) {
SGF.eraseBasicBlock(catchBB);
} else {
// Otherwise, we need to emit it.
SILGenSavedInsertionPoint scope(SGF, catchBB, FunctionSection::Postmatter);
if (auto diagnoseError = SGF.getASTContext().getDiagnoseUnexpectedError()) {
ASTContext &ctx = SGF.getASTContext();
auto error = SGF.B.createOwnedPhiArgument(SILType::getExceptionType(ctx));
auto args = SGF.emitSourceLocationArgs(Loc->getExclaimLoc(), Loc);
SGF.emitApplyOfLibraryIntrinsic(
Loc,
diagnoseError,
SubstitutionMap(),
{
error,
args.filenameStartPointer,
args.filenameLength,
args.filenameIsAscii,
args.line
},
SGFContext());
}
SGF.B.createUnreachable(Loc);
}
// Prevent double-finishing and make the destructor a no-op.
Loc = nullptr;
}
RValue RValueEmitter::visitForceTryExpr(ForceTryExpr *E, SGFContext C) {
SILGenFunction::ForceTryEmission emission(SGF, E);
// Visit the sub-expression.
return visit(E->getSubExpr(), C);
}
RValue RValueEmitter::visitOptionalTryExpr(OptionalTryExpr *E, SGFContext C) {
// FIXME: Much of this was copied from visitOptionalEvaluationExpr.
// Prior to Swift 5, an optional try's subexpression is always wrapped in an additional optional
bool shouldWrapInOptional = !(SGF.getASTContext().LangOpts.isSwiftVersionAtLeast(5));
auto &optTL = SGF.getTypeLowering(E->getType());
Initialization *optInit = C.getEmitInto();
bool usingProvidedContext =
optInit && optInit->canPerformInPlaceInitialization();
// Form the optional using address operations if the type is address-only or
// if we already have an address to use.
bool isByAddress = usingProvidedContext || optTL.isAddressOnly();
std::unique_ptr<TemporaryInitialization> optTemp;
if (!usingProvidedContext && isByAddress) {
// Allocate the temporary for the Optional<T> if we didn't get one from the
// context.
optTemp = SGF.emitTemporary(E, optTL);
optInit = optTemp.get();
} else if (!usingProvidedContext) {
// If the caller produced a context for us, but we can't use it, then don't.
optInit = nullptr;
}
FullExpr localCleanups(SGF.Cleanups, E);
// Set up a "catch" block for when an error occurs.
SILBasicBlock *catchBB = SGF.createBasicBlock(FunctionSection::Postmatter);
llvm::SaveAndRestore<JumpDest> throwDest{
SGF.ThrowDest,
JumpDest(catchBB, SGF.Cleanups.getCleanupsDepth(), E)};
SILValue branchArg;
if (shouldWrapInOptional) {
if (isByAddress) {
assert(optInit);
SILValue optAddr = optInit->getAddressForInPlaceInitialization(SGF, E);
SGF.emitInjectOptionalValueInto(E, E->getSubExpr(), optAddr, optTL);
} else {
ManagedValue subExprValue = SGF.emitRValueAsSingleValue(E->getSubExpr());
ManagedValue wrapped = SGF.getOptionalSomeValue(E, subExprValue, optTL);
branchArg = wrapped.forward(SGF);
}
}
else {
if (isByAddress) {
assert(optInit);
SGF.emitExprInto(E->getSubExpr(), optInit);
} else {
ManagedValue subExprValue = SGF.emitRValueAsSingleValue(E->getSubExpr());
branchArg = subExprValue.forward(SGF);
}
}
localCleanups.pop();
// If it turns out there are no uses of the catch block, just drop it.
if (catchBB->pred_empty()) {
// Remove the dead failureBB.
SGF.eraseBasicBlock(catchBB);
// The value we provide is the one we've already got.
if (!isByAddress)
return RValue(SGF, E,
SGF.emitManagedRValueWithCleanup(branchArg, optTL));
if (shouldWrapInOptional) {
optInit->finishInitialization(SGF);
}
// If we emitted into the provided context, we're done.
if (usingProvidedContext)
return RValue::forInContext();
return RValue(SGF, E, optTemp->getManagedAddress());
}
SILBasicBlock *contBB = SGF.createBasicBlock();
// Branch to the continuation block.
if (isByAddress)
SGF.B.createBranch(E, contBB);
else
SGF.B.createBranch(E, contBB, branchArg);
// If control branched to the failure block, inject .None into the
// result type.
SGF.B.emitBlock(catchBB);
FullExpr catchCleanups(SGF.Cleanups, E);
auto *errorArg = catchBB->createPhiArgument(
SILType::getExceptionType(SGF.getASTContext()), OwnershipKind::Owned);
(void) SGF.emitManagedRValueWithCleanup(errorArg);
catchCleanups.pop();
if (isByAddress) {
SGF.emitInjectOptionalNothingInto(E,
optInit->getAddressForInPlaceInitialization(SGF, E), optTL);
SGF.B.createBranch(E, contBB);
} else {
auto branchArg = SGF.getOptionalNoneValue(E, optTL);
SGF.B.createBranch(E, contBB, branchArg);
}
// Emit the continuation block.
SGF.B.emitBlock(contBB);
// If this was done in SSA registers, then the value is provided as an
// argument to the block.
if (!isByAddress) {
auto arg =
contBB->createPhiArgument(optTL.getLoweredType(), OwnershipKind::Owned);
return RValue(SGF, E, SGF.emitManagedRValueWithCleanup(arg, optTL));
}
if (shouldWrapInOptional) {
optInit->finishInitialization(SGF);
}
// If we emitted into the provided context, we're done.
if (usingProvidedContext)
return RValue::forInContext();
assert(optTemp);
return RValue(SGF, E, optTemp->getManagedAddress());
}
static bool inExclusiveBorrowSelfSection(
SILGenFunction::SelfInitDelegationStates delegationState) {
return delegationState == SILGenFunction::WillExclusiveBorrowSelf ||
delegationState == SILGenFunction::DidExclusiveBorrowSelf;
}
static RValue visitDerivedToBaseExprOfSelf(SILGenFunction &SGF,
DeclRefExpr *dre,
DerivedToBaseExpr *E, SGFContext C) {
SGFContext ctx;
auto *vd = cast<ParamDecl>(dre->getDecl());
SILType derivedType = SGF.getLoweredType(E->getType());
ManagedValue selfValue;
// If we have not exclusively borrowed self, we need to do so now.
if (SGF.SelfInitDelegationState == SILGenFunction::WillExclusiveBorrowSelf) {
// We need to use a full scope here to ensure that any underlying
// "normal cleanup" borrows are cleaned up.
Scope S(SGF, E);
selfValue = S.popPreservingValue(SGF.emitRValueAsSingleValue(dre));
} else {
// If we already exclusively borrowed self, then we need to emit self
// using formal evaluation primitives.
assert(SGF.SelfInitDelegationState ==
SILGenFunction::DidExclusiveBorrowSelf);
// This needs to be inlined since there is a Formal Evaluation Scope
// in emitRValueForDecl that causing any borrow for this LValue to be
// popped too soon.
selfValue =
SGF.emitAddressOfLocalVarDecl(dre, vd, dre->getType()->getCanonicalType(),
SGFAccessKind::OwnedObjectRead);
selfValue = SGF.emitFormalEvaluationRValueForSelfInDelegationInit(
E, dre->getType()->getCanonicalType(),
selfValue.getLValueAddress(), ctx)
.getAsSingleValue(SGF, E);
}
assert(selfValue);
// Check if we need to perform a conversion here.
if (derivedType && selfValue.getType() != derivedType)
selfValue = SGF.B.createUpcast(E, selfValue, derivedType);
return RValue(SGF, dre, selfValue);
}
RValue RValueEmitter::visitDerivedToBaseExpr(DerivedToBaseExpr *E,
SGFContext C) {
// If we are going through a decl ref expr and have self and we are in the
// exclusive borrow section of delegating init emission, use a special case.
if (inExclusiveBorrowSelfSection(SGF.SelfInitDelegationState)) {
if (auto *dre = dyn_cast<DeclRefExpr>(E->getSubExpr())) {
if (isa<ParamDecl>(dre->getDecl()) &&
dre->getDecl()->getName() == SGF.getASTContext().Id_self &&
dre->getDecl()->isImplicit()) {
return visitDerivedToBaseExprOfSelf(SGF, dre, E, C);
}
}
}
// We can pass down the SGFContext as a following projection. We have never
// actually implemented emit into here, so we are not changing behavior.
ManagedValue original =
SGF.emitRValueAsSingleValue(E->getSubExpr(), C.withFollowingProjection());
// Derived-to-base casts in the AST might not be reflected as such
// in the SIL type system, for example, a cast from DynamicSelf
// directly to its own Self type.
auto loweredResultTy = SGF.getLoweredType(E->getType());
if (original.getType() == loweredResultTy)
return RValue(SGF, E, original);
ManagedValue converted = SGF.B.createUpcast(E, original, loweredResultTy);
return RValue(SGF, E, converted);
}
RValue RValueEmitter::visitMetatypeConversionExpr(MetatypeConversionExpr *E,
SGFContext C) {
SILValue metaBase =
SGF.emitRValueAsSingleValue(E->getSubExpr()).getUnmanagedValue();
// Metatype conversion casts in the AST might not be reflected as
// such in the SIL type system, for example, a cast from DynamicSelf.Type
// directly to its own Self.Type.
auto loweredResultTy = SGF.getLoweredLoadableType(E->getType());
if (metaBase->getType() == loweredResultTy)
return RValue(SGF, E, ManagedValue::forUnmanaged(metaBase));
auto upcast = SGF.B.createUpcast(E, metaBase, loweredResultTy);
return RValue(SGF, E, ManagedValue::forUnmanaged(upcast));
}
RValue SILGenFunction::emitCollectionConversion(SILLocation loc,
FuncDecl *fn,
CanType fromCollection,
CanType toCollection,
ManagedValue mv,
SGFContext C) {
auto *fromDecl = fromCollection->getAnyNominal();
auto *toDecl = toCollection->getAnyNominal();
auto fromSubMap = fromCollection->getContextSubstitutionMap(
SGM.SwiftModule, fromDecl);
auto toSubMap = toCollection->getContextSubstitutionMap(
SGM.SwiftModule, toDecl);
// Form type parameter substitutions.
auto genericSig = fn->getGenericSignature();
unsigned fromParamCount = fromDecl->getGenericSignature()
->getGenericParams().size();
auto subMap =
SubstitutionMap::combineSubstitutionMaps(fromSubMap,
toSubMap,
CombineSubstitutionMaps::AtIndex,
fromParamCount,
0,
genericSig);
return emitApplyOfLibraryIntrinsic(loc, fn, subMap, {mv}, C);
}
RValue RValueEmitter::
visitCollectionUpcastConversionExpr(CollectionUpcastConversionExpr *E,
SGFContext C) {
SILLocation loc = RegularLocation(E);
// Get the sub expression argument as a managed value
auto mv = SGF.emitRValueAsSingleValue(E->getSubExpr());
// Compute substitutions for the intrinsic call.
auto fromCollection = E->getSubExpr()->getType()->getCanonicalType();
auto toCollection = E->getType()->getCanonicalType();
// Get the intrinsic function.
auto &ctx = SGF.getASTContext();
FuncDecl *fn = nullptr;
if (fromCollection->getAnyNominal() == ctx.getArrayDecl()) {
fn = SGF.SGM.getArrayForceCast(loc);
} else if (fromCollection->getAnyNominal() == ctx.getDictionaryDecl()) {
fn = SGF.SGM.getDictionaryUpCast(loc);
} else if (fromCollection->getAnyNominal() == ctx.getSetDecl()) {
fn = SGF.SGM.getSetUpCast(loc);
} else {
llvm_unreachable("unsupported collection upcast kind");
}
return SGF.emitCollectionConversion(loc, fn, fromCollection, toCollection,
mv, C);
}
RValue
RValueEmitter::visitConditionalBridgeFromObjCExpr(
ConditionalBridgeFromObjCExpr *E, SGFContext C) {
// Get the sub expression argument as a managed value
auto mv = SGF.emitRValueAsSingleValue(E->getSubExpr());
auto conversionRef = E->getConversion();
auto conversion = cast<FuncDecl>(conversionRef.getDecl());
auto subs = conversionRef.getSubstitutions();
auto nativeType =
Type(GenericTypeParamType::get(0, 0, SGF.getASTContext())).subst(subs);
auto metatypeType = SGF.getLoweredType(MetatypeType::get(nativeType));
auto metatype =
ManagedValue::forUnmanaged(SGF.B.createMetatype(E, metatypeType));
return SGF.emitApplyOfLibraryIntrinsic(E, conversion, subs,
{ mv, metatype }, C);
}
/// Given an implicit bridging conversion, check whether the context
/// can be peepholed.
static bool
tryPeepholeBridgingConversion(SILGenFunction &SGF, Conversion::KindTy kind,
ImplicitConversionExpr *E, SGFContext C) {
assert(isa<BridgeFromObjCExpr>(E) || isa<BridgeToObjCExpr>(E));
if (auto outerConversion = C.getAsConversion()) {
auto subExpr = E->getSubExpr();
CanType sourceType = subExpr->getType()->getCanonicalType();
CanType resultType = E->getType()->getCanonicalType();
SILType loweredResultTy = SGF.getLoweredType(resultType);
auto conversion = Conversion::getBridging(kind, sourceType, resultType,
loweredResultTy);
if (outerConversion->tryPeephole(SGF, E->getSubExpr(), conversion)) {
outerConversion->finishInitialization(SGF);
return true;
}
}
return false;
}
RValue
RValueEmitter::visitBridgeFromObjCExpr(BridgeFromObjCExpr *E, SGFContext C) {
if (tryPeepholeBridgingConversion(SGF, Conversion::BridgeFromObjC, E, C))
return RValue::forInContext();
// Emit the sub-expression.
auto mv = SGF.emitRValueAsSingleValue(E->getSubExpr());
CanType origType = E->getSubExpr()->getType()->getCanonicalType();
CanType resultType = E->getType()->getCanonicalType();
SILType loweredResultTy = SGF.getLoweredType(resultType);
auto result = SGF.emitBridgedToNativeValue(E, mv, origType, resultType,
loweredResultTy, C);
return RValue(SGF, E, result);
}
RValue
RValueEmitter::visitBridgeToObjCExpr(BridgeToObjCExpr *E, SGFContext C) {
if (tryPeepholeBridgingConversion(SGF, Conversion::BridgeToObjC, E, C))
return RValue::forInContext();
// Emit the sub-expression.
auto mv = SGF.emitRValueAsSingleValue(E->getSubExpr());
CanType origType = E->getSubExpr()->getType()->getCanonicalType();
CanType resultType = E->getType()->getCanonicalType();
SILType loweredResultTy = SGF.getLoweredType(resultType);
auto result = SGF.emitNativeToBridgedValue(E, mv, origType, resultType,
loweredResultTy, C);
return RValue(SGF, E, result);
}
RValue RValueEmitter::visitArchetypeToSuperExpr(ArchetypeToSuperExpr *E,
SGFContext C) {
ManagedValue archetype = SGF.emitRValueAsSingleValue(E->getSubExpr());
auto loweredTy = SGF.getLoweredLoadableType(E->getType());
if (loweredTy == archetype.getType())
return RValue(SGF, E, archetype);
// Replace the cleanup with a new one on the superclass value so we always use
// concrete retain/release operations.
auto base = SGF.B.createUpcast(E, archetype, loweredTy);
return RValue(SGF, E, base);
}
static ManagedValue convertCFunctionSignature(SILGenFunction &SGF,
FunctionConversionExpr *e,
SILType loweredResultTy,
llvm::function_ref<ManagedValue ()> fnEmitter) {
SILType loweredDestTy = SGF.getLoweredType(e->getType());
ManagedValue result;
// We're converting between C function pointer types. They better be
// ABI-compatible, since we can't emit a thunk.
switch (SGF.SGM.Types.checkForABIDifferences(SGF.SGM.M,
loweredResultTy, loweredDestTy)){
case TypeConverter::ABIDifference::CompatibleRepresentation:
case TypeConverter::ABIDifference::CompatibleCallingConvention:
result = fnEmitter();
assert(result.getType() == loweredResultTy);
if (loweredResultTy != loweredDestTy) {
assert(!result.hasCleanup());
result = SGF.B.createConvertFunction(e, result, loweredDestTy);
}
break;
case TypeConverter::ABIDifference::NeedsThunk:
// Note: in this case, we don't call the emitter at all -- doing so
// just runs the risk of tripping up asserts in SILGenBridging.cpp
SGF.SGM.diagnose(e, diag::unsupported_c_function_pointer_conversion,
e->getSubExpr()->getType(), e->getType());
result = SGF.emitUndef(loweredDestTy);
break;
case TypeConverter::ABIDifference::CompatibleCallingConvention_ThinToThick:
case TypeConverter::ABIDifference::CompatibleRepresentation_ThinToThick:
llvm_unreachable("Cannot have thin to thick conversion here");
}
return result;
}
static
ManagedValue emitCFunctionPointer(SILGenFunction &SGF,
FunctionConversionExpr *conversionExpr) {
auto expr = conversionExpr->getSubExpr();
// Look through base-ignored exprs to get to the function ref.
auto semanticExpr = expr->getSemanticsProvidingExpr();
while (auto ignoredBase = dyn_cast<DotSyntaxBaseIgnoredExpr>(semanticExpr)){
SGF.emitIgnoredExpr(ignoredBase->getLHS());
semanticExpr = ignoredBase->getRHS()->getSemanticsProvidingExpr();
}
// Recover the decl reference.
SILDeclRef::Loc loc;
auto setLocFromConcreteDeclRef = [&](ConcreteDeclRef declRef) {
// TODO: Handle generic instantiations, where we need to eagerly specialize
// on the given generic parameters, and static methods, where we need to drop
// in the metatype.
assert(!declRef.getDecl()->getDeclContext()->isTypeContext()
&& "c pointers to static methods not implemented");
loc = declRef.getDecl();
};
if (auto declRef = dyn_cast<DeclRefExpr>(semanticExpr)) {
setLocFromConcreteDeclRef(declRef->getDeclRef());
} else if (auto memberRef = dyn_cast<MemberRefExpr>(semanticExpr)) {
setLocFromConcreteDeclRef(memberRef->getMember());
} else if (auto closure = dyn_cast<AbstractClosureExpr>(semanticExpr)) {
// Emit the closure body.
SGF.SGM.emitClosure(closure);
loc = closure;
} else if (auto captureList = dyn_cast<CaptureListExpr>(semanticExpr)) {
// Ensure that weak captures are in a separate scope.
DebugScope scope(SGF, CleanupLocation(captureList));
// CaptureListExprs evaluate their bound variables.
for (auto capture : captureList->getCaptureList()) {
SGF.visit(capture.Var);
SGF.visit(capture.Init);
}
// Emit the closure body.
auto *closure = captureList->getClosureBody();
SGF.SGM.emitClosure(closure);
loc = closure;
} else {
llvm_unreachable("c function pointer converted from a non-concrete decl ref");
}
// Produce a reference to the C-compatible entry point for the function.
SILDeclRef constant(loc, /*foreign*/ true);
SILConstantInfo constantInfo =
SGF.getConstantInfo(SGF.getTypeExpansionContext(), constant);
// C function pointers cannot capture anything from their context.
auto captures = SGF.SGM.Types.getLoweredLocalCaptures(constant);
if (!captures.getCaptures().empty() ||
captures.hasGenericParamCaptures() ||
captures.hasDynamicSelfCapture() ||
captures.hasOpaqueValueCapture()) {
unsigned kind = 0;
if (captures.hasGenericParamCaptures())
kind = 1;
else if (captures.hasDynamicSelfCapture())
kind = 2;
SGF.SGM.diagnose(expr->getLoc(),
diag::c_function_pointer_from_function_with_context,
/*closure*/ constant.hasClosureExpr(),
kind);
auto loweredTy = SGF.getLoweredType(conversionExpr->getType());
return SGF.emitUndef(loweredTy);
}
return convertCFunctionSignature(
SGF, conversionExpr,
constantInfo.getSILType(),
[&]() -> ManagedValue {
SILValue cRef = SGF.emitGlobalFunctionRef(expr, constant);
return ManagedValue::forUnmanaged(cRef);
});
}
// Change the representation without changing the signature or
// abstraction level.
static ManagedValue convertFunctionRepresentation(SILGenFunction &SGF,
SILLocation loc,
ManagedValue source,
CanAnyFunctionType sourceFormalTy,
CanAnyFunctionType resultFormalTy) {
auto sourceTy = source.getType().castTo<SILFunctionType>();
CanSILFunctionType resultTy =
SGF.getLoweredType(resultFormalTy).castTo<SILFunctionType>();
// Note that conversions to and from block require a thunk
switch (resultFormalTy->getRepresentation()) {
// Convert thin, c, block => thick
case AnyFunctionType::Representation::Swift: {
switch (sourceTy->getRepresentation()) {
case SILFunctionType::Representation::Thin: {
auto v = SGF.B.createThinToThickFunction(
loc, source.getValue(),
SILType::getPrimitiveObjectType(
sourceTy->getWithRepresentation(
SILFunctionTypeRepresentation::Thick)));
// FIXME: what if other reabstraction is required?
return ManagedValue(v, source.getCleanup());
}
case SILFunctionType::Representation::Thick:
llvm_unreachable("should not try thick-to-thick repr change");
case SILFunctionType::Representation::CFunctionPointer:
case SILFunctionType::Representation::Block:
return SGF.emitBlockToFunc(loc, source, sourceFormalTy, resultFormalTy,
resultTy);
case SILFunctionType::Representation::Method:
case SILFunctionType::Representation::Closure:
case SILFunctionType::Representation::ObjCMethod:
case SILFunctionType::Representation::WitnessMethod:
llvm_unreachable("should not do function conversion from method rep");
}
llvm_unreachable("bad representation");
}
// Convert thin, thick, c => block
case AnyFunctionType::Representation::Block:
switch (sourceTy->getRepresentation()) {
case SILFunctionType::Representation::Thin: {
// Make thick first.
auto v = SGF.B.createThinToThickFunction(
loc, source.getValue(),
SILType::getPrimitiveObjectType(
sourceTy->getWithRepresentation(
SILFunctionTypeRepresentation::Thick)));
source = ManagedValue(v, source.getCleanup());
LLVM_FALLTHROUGH;
}
case SILFunctionType::Representation::Thick:
case SILFunctionType::Representation::CFunctionPointer:
// Convert to a block.
return SGF.emitFuncToBlock(loc, source, sourceFormalTy, resultFormalTy,
resultTy);
case SILFunctionType::Representation::Block:
llvm_unreachable("should not try block-to-block repr change");
case SILFunctionType::Representation::Method:
case SILFunctionType::Representation::Closure:
case SILFunctionType::Representation::ObjCMethod:
case SILFunctionType::Representation::WitnessMethod:
llvm_unreachable("should not do function conversion from method rep");
}
llvm_unreachable("bad representation");
// Unsupported
case AnyFunctionType::Representation::Thin:
llvm_unreachable("should not do function conversion to thin");
case AnyFunctionType::Representation::CFunctionPointer:
llvm_unreachable("should not do C function pointer conversion here");
}
llvm_unreachable("bad representation");
}
RValue RValueEmitter::visitFunctionConversionExpr(FunctionConversionExpr *e,
SGFContext C)
{
CanAnyFunctionType srcRepTy =
cast<FunctionType>(e->getSubExpr()->getType()->getCanonicalType());
CanAnyFunctionType destRepTy =
cast<FunctionType>(e->getType()->getCanonicalType());
if (destRepTy->getRepresentation() ==
FunctionTypeRepresentation::CFunctionPointer) {
ManagedValue result;
if (srcRepTy->getRepresentation() !=
FunctionTypeRepresentation::CFunctionPointer) {
// A "conversion" of a DeclRef a C function pointer is done by referencing
// the thunk (or original C function) with the C calling convention.
result = emitCFunctionPointer(SGF, e);
} else {
// Ok, we're converting a C function pointer value to another C function
// pointer.
// Emit the C function pointer
result = SGF.emitRValueAsSingleValue(e->getSubExpr());
// Possibly bitcast the C function pointer to account for ABI-compatible
// parameter and result type conversions
result = convertCFunctionSignature(SGF, e, result.getType(),
[&]() -> ManagedValue {
return result;
});
}
return RValue(SGF, e, result);
}
// Handle a reference to a "thin" native Swift function that only changes
// representation and refers to an inherently thin function reference.
if (destRepTy->getRepresentation() == FunctionTypeRepresentation::Thin) {
if (srcRepTy->getRepresentation() == FunctionTypeRepresentation::Swift
&& srcRepTy->withExtInfo(destRepTy->getExtInfo())->isEqual(destRepTy)) {
auto value = SGF.emitRValueAsSingleValue(e->getSubExpr());
auto expectedTy = SGF.getLoweredType(e->getType());
if (auto thinToThick =
dyn_cast<ThinToThickFunctionInst>(value.getValue())) {
value = ManagedValue::forUnmanaged(thinToThick->getOperand());
} else {
SGF.SGM.diagnose(e->getLoc(), diag::not_implemented,
"nontrivial thin function reference");
value = SGF.emitUndef(expectedTy);
}
if (value.getType() != expectedTy) {
SGF.SGM.diagnose(e->getLoc(), diag::not_implemented,
"nontrivial thin function reference");
value = SGF.emitUndef(expectedTy);
}
return RValue(SGF, e, value);
}
}
// Break the conversion into three stages:
// 1) changing the representation from foreign to native
// 2) changing the signature within the representation
// 3) changing the representation from native to foreign
//
// We only do one of 1) or 3), but we have to do them in the right order
// with respect to 2).
CanAnyFunctionType srcTy = srcRepTy;
CanAnyFunctionType destTy = destRepTy;
switch(srcRepTy->getRepresentation()) {
case AnyFunctionType::Representation::Swift:
case AnyFunctionType::Representation::Thin:
// Source is native, so we can convert signature first.
destTy = adjustFunctionType(destRepTy, srcTy->getRepresentation(),
srcTy->getClangTypeInfo());
break;
case AnyFunctionType::Representation::Block:
case AnyFunctionType::Representation::CFunctionPointer:
// Source is foreign, so do the representation change first.
srcTy = adjustFunctionType(srcRepTy, destRepTy->getRepresentation(),
destRepTy->getClangTypeInfo());
}
auto result = SGF.emitRValueAsSingleValue(e->getSubExpr());
if (srcRepTy != srcTy)
result = convertFunctionRepresentation(SGF, e, result, srcRepTy, srcTy);
if (srcTy != destTy) {
result = SGF.emitTransformedValue(e, result, srcTy, destTy, SGFContext());
}
if (destTy != destRepTy)
result = convertFunctionRepresentation(SGF, e, result, destTy, destRepTy);
return RValue(SGF, e, result);
}
RValue RValueEmitter::visitCovariantFunctionConversionExpr(
CovariantFunctionConversionExpr *e,
SGFContext C) {
ManagedValue original = SGF.emitRValueAsSingleValue(e->getSubExpr());
CanAnyFunctionType destTy
= cast<AnyFunctionType>(e->getType()->getCanonicalType());
SILType resultType = SGF.getLoweredType(destTy);
SILValue result =
SGF.B.createConvertFunction(e, original.forward(SGF), resultType,
/*Withoutactuallyescaping=*/false);
return RValue(SGF, e, SGF.emitManagedRValueWithCleanup(result));
}
RValue RValueEmitter::visitCovariantReturnConversionExpr(
CovariantReturnConversionExpr *e,
SGFContext C) {
ManagedValue original = SGF.emitRValueAsSingleValue(e->getSubExpr());
SILType resultType = SGF.getLoweredType(e->getType());
// DynamicSelfType lowers as its self type, so no SIL-level conversion
// is required in this case.
if (resultType == original.getType())
return RValue(SGF, e, original);
ManagedValue result = SGF.B.createUncheckedRefCast(e, original, resultType);
return RValue(SGF, e, result);
}
RValue RValueEmitter::visitImplicitlyUnwrappedFunctionConversionExpr(
ImplicitlyUnwrappedFunctionConversionExpr *e, SGFContext C) {
// These are generated for short term use in the type checker.
llvm_unreachable(
"We should not see ImplicitlyUnwrappedFunctionConversionExpr here");
}
RValue RValueEmitter::visitErasureExpr(ErasureExpr *E, SGFContext C) {
if (auto result = tryEmitAsBridgingConversion(SGF, E, false, C)) {
return RValue(SGF, E, *result);
}
auto &existentialTL = SGF.getTypeLowering(E->getType());
auto concreteFormalType = E->getSubExpr()->getType()->getCanonicalType();
auto archetype = OpenedArchetypeType::getAny(E->getType());
AbstractionPattern abstractionPattern(archetype);
auto &concreteTL = SGF.getTypeLowering(abstractionPattern,
concreteFormalType);
ManagedValue mv = SGF.emitExistentialErasure(E, concreteFormalType,
concreteTL, existentialTL,
E->getConformances(), C,
[&](SGFContext C) -> ManagedValue {
return SGF.emitRValueAsOrig(E->getSubExpr(),
abstractionPattern,
concreteTL, C);
});
return RValue(SGF, E, mv);
}
RValue SILGenFunction::emitAnyHashableErasure(SILLocation loc,
ManagedValue value,
Type type,
ProtocolConformanceRef conformance,
SGFContext C) {
// Ensure that the intrinsic function exists.
auto convertFn = SGM.getConvertToAnyHashable(loc);
if (!convertFn)
return emitUndefRValue(
loc, getASTContext().getAnyHashableDecl()->getDeclaredInterfaceType());
// Construct the substitution for T: Hashable.
auto subMap = SubstitutionMap::getProtocolSubstitutions(
conformance.getRequirement(), type, conformance);
return emitApplyOfLibraryIntrinsic(loc, convertFn, subMap, value, C);
}
RValue RValueEmitter::visitAnyHashableErasureExpr(AnyHashableErasureExpr *E,
SGFContext C) {
// Emit the source value into a temporary.
auto sourceOrigType = AbstractionPattern::getOpaque();
auto source =
SGF.emitMaterializedRValueAsOrig(E->getSubExpr(), sourceOrigType);
return SGF.emitAnyHashableErasure(E, source,
E->getSubExpr()->getType(),
E->getConformance(), C);
}
/// Treating this as a successful operation, turn a CMV into a +1 MV.
ManagedValue SILGenFunction::getManagedValue(SILLocation loc,
ConsumableManagedValue value) {
// If the consumption rules say that this is already +1 given a
// successful operation, just use the value.
if (value.isOwned())
return value.getFinalManagedValue();
SILType valueTy = value.getType();
auto &valueTL = getTypeLowering(valueTy);
// If the type is trivial, it's always +1.
if (valueTL.isTrivial())
return ManagedValue::forUnmanaged(value.getValue());
// If it's an object...
if (valueTy.isObject()) {
// See if we have more accurate information from the ownership kind. This
// detects trivial cases of enums.
if (value.getOwnershipKind() == OwnershipKind::None)
return ManagedValue::forUnmanaged(value.getValue());
// Otherwise, copy the value and return.
return value.getFinalManagedValue().copy(*this, loc);
}
// Otherwise, produce a temporary and copy into that.
auto temporary = emitTemporary(loc, valueTL);
valueTL.emitCopyInto(B, loc, value.getValue(), temporary->getAddress(),
IsNotTake, IsInitialization);
temporary->finishInitialization(*this);
return temporary->getManagedAddress();
}
RValue RValueEmitter::visitForcedCheckedCastExpr(ForcedCheckedCastExpr *E,
SGFContext C) {
return emitUnconditionalCheckedCast(SGF, E, E->getSubExpr(), E->getType(),
E->getCastKind(), C);
}
RValue RValueEmitter::
visitConditionalCheckedCastExpr(ConditionalCheckedCastExpr *E,
SGFContext C) {
ProfileCounter trueCount = ProfileCounter();
ProfileCounter falseCount = ProfileCounter();
auto parent = SGF.getPGOParent(E);
if (parent) {
auto &Node = parent.getValue();
auto *NodeS = Node.get<Stmt *>();
if (auto *IS = dyn_cast<IfStmt>(NodeS)) {
trueCount = SGF.loadProfilerCount(IS->getThenStmt());
if (auto *ElseStmt = IS->getElseStmt()) {
falseCount = SGF.loadProfilerCount(ElseStmt);
}
}
}
ManagedValue operand = SGF.emitRValueAsSingleValue(E->getSubExpr());
return emitConditionalCheckedCast(SGF, E, operand, E->getSubExpr()->getType(),
E->getType(), E->getCastKind(), C,
trueCount, falseCount);
}
static RValue emitBoolLiteral(SILGenFunction &SGF, SILLocation loc,
SILValue builtinBool,
SGFContext C) {
// Call the Bool(_builtinBooleanLiteral:) initializer
ASTContext &ctx = SGF.getASTContext();
auto init = ctx.getBoolBuiltinInitDecl();
auto builtinArgType = CanType(BuiltinIntegerType::get(1, ctx));
RValue builtinArg(SGF, ManagedValue::forUnmanaged(builtinBool),
builtinArgType);
PreparedArguments builtinArgs((AnyFunctionType::Param(builtinArgType)));
builtinArgs.add(loc, std::move(builtinArg));
auto result =
SGF.emitApplyAllocatingInitializer(loc, ConcreteDeclRef(init),
std::move(builtinArgs), Type(),
C);
return result;
}
RValue RValueEmitter::visitIsExpr(IsExpr *E, SGFContext C) {
SILValue isa = emitIsa(SGF, E, E->getSubExpr(),
E->getCastType(), E->getCastKind());
return emitBoolLiteral(SGF, E, isa, C);
}
RValue RValueEmitter::visitEnumIsCaseExpr(EnumIsCaseExpr *E,
SGFContext C) {
// Get the enum value.
auto subExpr = SGF.emitRValueAsSingleValue(E->getSubExpr(),
SGFContext(SGFContext::AllowImmediatePlusZero));
// Test its case.
auto i1Ty = SILType::getBuiltinIntegerType(1, SGF.getASTContext());
auto t = SGF.B.createIntegerLiteral(E, i1Ty, 1);
auto f = SGF.B.createIntegerLiteral(E, i1Ty, 0);
SILValue selected;
if (subExpr.getType().isAddress()) {
selected = SGF.B.createSelectEnumAddr(E, subExpr.getValue(), i1Ty, f,
{{E->getEnumElement(), t}});
} else {
selected = SGF.B.createSelectEnum(E, subExpr.getValue(), i1Ty, f,
{{E->getEnumElement(), t}});
}
return emitBoolLiteral(SGF, E, selected, C);
}
RValue RValueEmitter::visitCoerceExpr(CoerceExpr *E, SGFContext C) {
if (auto result = tryEmitAsBridgingConversion(SGF, E->getSubExpr(), true, C))
return RValue(SGF, E, *result);
return visit(E->getSubExpr(), C);
}
RValue RValueEmitter::visitUnderlyingToOpaqueExpr(UnderlyingToOpaqueExpr *E,
SGFContext C) {
// The opaque type has the layout of the underlying type, abstracted as
// a type parameter.
auto &opaqueTL = SGF.getTypeLowering(E->getType());
auto &underlyingTL = SGF.getTypeLowering(AbstractionPattern::getOpaque(),
E->getSubExpr()->getType());
auto &underlyingSubstTL = SGF.getTypeLowering(E->getSubExpr()->getType());
if (underlyingSubstTL.getLoweredType() == opaqueTL.getLoweredType()) {
return SGF.emitRValue(E->getSubExpr(), C);
}
// If the opaque type is address only, initialize in place.
if (opaqueTL.getLoweredType().isAddress()) {
auto opaqueAddr = SGF.getBufferForExprResult(
E, opaqueTL.getLoweredType(), C);
// Initialize the buffer as the underlying type.
auto underlyingAddr = SGF.B.createUncheckedAddrCast(E,
opaqueAddr,
underlyingTL.getLoweredType().getAddressType());
auto underlyingInit = SGF.useBufferAsTemporary(underlyingAddr, underlyingTL);
// Try to emit directly into the buffer if no reabstraction is necessary.
ManagedValue underlying;
if (underlyingSubstTL.getLoweredType() == underlyingTL.getLoweredType()) {
underlying = SGF.emitRValueAsSingleValue(E->getSubExpr(),
SGFContext(underlyingInit.get()));
} else {
// Otherwise, emit the underlying value then bring it to the right
// abstraction level.
underlying = SGF.emitRValueAsSingleValue(E->getSubExpr());
underlying = SGF.emitSubstToOrigValue(E, underlying,
AbstractionPattern::getOpaque(),
E->getSubExpr()->getType()->getCanonicalType());
}
if (!underlying.isInContext()) {
underlyingInit->copyOrInitValueInto(SGF, E, underlying, /*init*/ true);
underlyingInit->finishInitialization(SGF);
}
// Kill the cleanup on the underlying value, and hand off the opaque buffer
// as the result.
underlyingInit->getManagedAddress().forward(SGF);
auto opaque = SGF.manageBufferForExprResult(opaqueAddr, opaqueTL, C);
return RValue(SGF, E, opaque);
}
// If the opaque type is loadable, emit the subexpression and bitcast it.
auto value = SGF.emitRValueAsSingleValue(E->getSubExpr());
if (underlyingSubstTL.getLoweredType() != underlyingTL.getLoweredType()) {
value = SGF.emitSubstToOrigValue(E, value, AbstractionPattern::getOpaque(),
E->getSubExpr()->getType()->getCanonicalType());
}
if (value.getType() == opaqueTL.getLoweredType())
return RValue(SGF, E, value);
auto cast = SGF.B.createUncheckedReinterpretCast(E, value.forward(SGF),
opaqueTL.getLoweredType());
value = SGF.emitManagedRValueWithCleanup(cast);
return RValue(SGF, E, value);
}
VarargsInfo Lowering::emitBeginVarargs(SILGenFunction &SGF, SILLocation loc,
CanType baseTy, CanType arrayTy,
unsigned numElements) {
// Reabstract the base type against the array element type.
auto baseAbstraction = AbstractionPattern::getOpaque();
auto &baseTL = SGF.getTypeLowering(baseAbstraction, baseTy);
// Allocate the array.
SILValue numEltsVal = SGF.B.createIntegerLiteral(loc,
SILType::getBuiltinWordType(SGF.getASTContext()),
numElements);
// The first result is the array value.
ManagedValue array;
// The second result is a RawPointer to the base address of the array.
SILValue basePtr;
std::tie(array, basePtr)
= SGF.emitUninitializedArrayAllocation(arrayTy, numEltsVal, loc);
// Temporarily deactivate the main array cleanup.
if (array.hasCleanup())
SGF.Cleanups.setCleanupState(array.getCleanup(), CleanupState::Dormant);
// Push a new cleanup to deallocate the array.
auto abortCleanup =
SGF.enterDeallocateUninitializedArrayCleanup(array.getValue());
// Turn the pointer into an address.
basePtr = SGF.B.createPointerToAddress(
loc, basePtr, baseTL.getLoweredType().getAddressType(),
/*isStrict*/ true,
/*isInvariant*/ false);
return VarargsInfo(array, abortCleanup, basePtr, baseTL, baseAbstraction);
}
ManagedValue Lowering::emitEndVarargs(SILGenFunction &SGF, SILLocation loc,
VarargsInfo &&varargs,
unsigned numElements) {
// Kill the abort cleanup.
SGF.Cleanups.setCleanupState(varargs.getAbortCleanup(), CleanupState::Dead);
// Reactivate the result cleanup.
auto array = varargs.getArray();
if (array.hasCleanup())
SGF.Cleanups.setCleanupState(array.getCleanup(), CleanupState::Active);
// Array literals only need to be finalized, if the array is really allocated.
// In case of zero elements, no allocation is done, but the empty-array
// singleton is used. "Finalization" means to emit an end_cow_mutation
// instruction on the array. As the empty-array singleton is a read-only and
// shared object, it's not legal to do a end_cow_mutation on it.
if (numElements == 0)
return array;
return SGF.emitUninitializedArrayFinalization(loc, std::move(array));
}
RValue RValueEmitter::visitTupleExpr(TupleExpr *E, SGFContext C) {
auto type = cast<TupleType>(E->getType()->getCanonicalType());
// If we have an Initialization, emit the tuple elements into its elements.
if (Initialization *I = C.getEmitInto()) {
bool implodeTuple = false;
if (I->canPerformInPlaceInitialization() &&
I->isInPlaceInitializationOfGlobal() &&
SGF.getLoweredType(type).isTrivial(SGF.F)) {
// Implode tuples in initialization of globals if they are
// of trivial types.
implodeTuple = true;
}
if (!implodeTuple && I->canSplitIntoTupleElements()) {
SmallVector<InitializationPtr, 4> subInitializationBuf;
auto subInitializations =
I->splitIntoTupleElements(SGF, RegularLocation(E), type,
subInitializationBuf);
assert(subInitializations.size() == E->getElements().size() &&
"initialization for tuple has wrong number of elements");
for (unsigned i = 0, size = subInitializations.size(); i < size; ++i)
SGF.emitExprInto(E->getElement(i), subInitializations[i].get());
I->finishInitialization(SGF);
return RValue::forInContext();
}
}
llvm::SmallVector<RValue, 8> tupleElts;
bool hasAtleastOnePlusOneValue = false;
for (Expr *elt : E->getElements()) {
RValue RV = SGF.emitRValue(elt);
hasAtleastOnePlusOneValue |= RV.isPlusOne(SGF);
tupleElts.emplace_back(std::move(RV));
}
// Once we have found if we have any plus one arguments, add each element of
// tuple elts into result, making sure each value is at plus 1.
RValue result(type);
if (hasAtleastOnePlusOneValue) {
for (unsigned i : indices(tupleElts)) {
result.addElement(std::move(tupleElts[i]).ensurePlusOne(SGF, E));
}
} else {
for (unsigned i : indices(tupleElts)) {
result.addElement(std::move(tupleElts[i]));
}
}
return result;
}
RValue RValueEmitter::visitMemberRefExpr(MemberRefExpr *e,
SGFContext resultCtx) {
assert(!e->getType()->is<LValueType>() &&
"RValueEmitter shouldn't be called on lvalues");
assert(isa<VarDecl>(e->getMember().getDecl()));
// Everything else should use the l-value logic.
// Any writebacks for this access are tightly scoped.
FormalEvaluationScope scope(SGF);
LValue lv = SGF.emitLValue(e, SGFAccessKind::OwnedObjectRead);
// Otherwise, we can't load at +0 without further analysis, since the formal
// access into the lvalue will end immediately.
return SGF.emitLoadOfLValue(e, std::move(lv),
resultCtx.withFollowingSideEffects());
}
RValue RValueEmitter::visitDynamicMemberRefExpr(DynamicMemberRefExpr *E,
SGFContext C) {
return SGF.emitDynamicMemberRefExpr(E, C);
}
RValue RValueEmitter::
visitDotSyntaxBaseIgnoredExpr(DotSyntaxBaseIgnoredExpr *E, SGFContext C) {
visit(E->getLHS());
return visit(E->getRHS());
}
RValue RValueEmitter::visitSubscriptExpr(SubscriptExpr *E, SGFContext C) {
// Any writebacks for this access are tightly scoped.
FormalEvaluationScope scope(SGF);
LValue lv = SGF.emitLValue(E, SGFAccessKind::OwnedObjectRead);
// We can't load at +0 without further analysis, since the formal access into
// the lvalue will end immediately.
return SGF.emitLoadOfLValue(E, std::move(lv), C.withFollowingSideEffects());
}
RValue RValueEmitter::visitDynamicSubscriptExpr(
DynamicSubscriptExpr *E, SGFContext C) {
return SGF.emitDynamicSubscriptExpr(E, C);
}
RValue RValueEmitter::visitTupleElementExpr(TupleElementExpr *E,
SGFContext C) {
assert(!E->getType()->is<LValueType>() &&
"RValueEmitter shouldn't be called on lvalues");
// If our client is ok with a +0 result, then we can compute our base as +0
// and return its element that way. It would not be ok to reuse the Context's
// address buffer though, since our base value will a different type than the
// element.
SGFContext SubContext = C.withFollowingProjection();
return visit(E->getBase(), SubContext).extractElement(E->getFieldNumber());
}
RValue
SILGenFunction::emitApplyOfDefaultArgGenerator(SILLocation loc,
ConcreteDeclRef defaultArgsOwner,
unsigned destIndex,
CanType resultType,
AbstractionPattern origResultType,
SGFContext C) {
SILDeclRef generator
= SILDeclRef::getDefaultArgGenerator(defaultArgsOwner.getDecl(),
destIndex);
auto fnRef = ManagedValue::forUnmanaged(emitGlobalFunctionRef(loc,generator));
auto fnType = fnRef.getType().castTo<SILFunctionType>();
SubstitutionMap subs;
if (fnType->isPolymorphic())
subs = defaultArgsOwner.getSubstitutions();
auto substFnType =
fnType->substGenericArgs(SGM.M, subs, getTypeExpansionContext());
CalleeTypeInfo calleeTypeInfo(substFnType, origResultType, resultType);
ResultPlanPtr resultPtr =
ResultPlanBuilder::computeResultPlan(*this, calleeTypeInfo, loc, C);
ArgumentScope argScope(*this, loc);
SmallVector<ManagedValue, 4> captures;
emitCaptures(loc, generator, CaptureEmission::ImmediateApplication,
captures);
return emitApply(std::move(resultPtr), std::move(argScope), loc, fnRef,
subs, captures, calleeTypeInfo, ApplyOptions::None, C, None);
}
RValue SILGenFunction::emitApplyOfStoredPropertyInitializer(
SILLocation loc,
VarDecl *var,
SubstitutionMap subs,
CanType resultType,
AbstractionPattern origResultType,
SGFContext C) {
SILDeclRef constant(var, SILDeclRef::Kind::StoredPropertyInitializer);
auto fnRef = ManagedValue::forUnmanaged(emitGlobalFunctionRef(loc, constant));
auto fnType = fnRef.getType().castTo<SILFunctionType>();
auto substFnType =
fnType->substGenericArgs(SGM.M, subs, getTypeExpansionContext());
CalleeTypeInfo calleeTypeInfo(substFnType, origResultType, resultType);
ResultPlanPtr resultPlan =
ResultPlanBuilder::computeResultPlan(*this, calleeTypeInfo, loc, C);
ArgumentScope argScope(*this, loc);
return emitApply(std::move(resultPlan), std::move(argScope), loc, fnRef,
subs, {}, calleeTypeInfo, ApplyOptions::None, C, None);
}
RValue RValueEmitter::visitDestructureTupleExpr(DestructureTupleExpr *E,
SGFContext C) {
// Emit the sub-expression tuple and destructure it into elements.
SmallVector<RValue, 4> elements;
visit(E->getSubExpr()).extractElements(elements);
// Bind each element of the input tuple to its corresponding
// opaque value.
for (unsigned i = 0, e = E->getDestructuredElements().size();
i != e; ++i) {
auto *opaqueElt = E->getDestructuredElements()[i];
assert(!SGF.OpaqueValues.count(opaqueElt));
auto opaqueMV = std::move(elements[i]).getAsSingleValue(SGF, E);
SGF.OpaqueValues[opaqueElt] = opaqueMV;
}
// Emit the result expression written in terms of the above
// opaque values.
auto result = visit(E->getResultExpr(), C);
// Clean up.
for (unsigned i = 0, e = E->getDestructuredElements().size();
i != e; ++i) {
auto *opaqueElt = E->getDestructuredElements()[i];
SGF.OpaqueValues.erase(opaqueElt);
}
return result;
}
static SILValue emitMetatypeOfDelegatingInitExclusivelyBorrowedSelf(
SILGenFunction &SGF, SILLocation loc, DeclRefExpr *dre, SILType metaTy) {
SGFContext ctx;
auto *vd = cast<ParamDecl>(dre->getDecl());
ManagedValue selfValue;
Scope S(SGF, loc);
Optional<FormalEvaluationScope> FES;
// If we have not exclusively borrowed self, we need to do so now.
if (SGF.SelfInitDelegationState == SILGenFunction::WillExclusiveBorrowSelf) {
// We need to use a full scope here to ensure that any underlying
// "normal cleanup" borrows are cleaned up.
selfValue = SGF.emitRValueAsSingleValue(dre);
} else {
// If we already exclusively borrowed self, then we need to emit self
// using formal evaluation primitives.
assert(SGF.SelfInitDelegationState ==
SILGenFunction::DidExclusiveBorrowSelf);
// This needs to be inlined since there is a Formal Evaluation Scope
// in emitRValueForDecl that causing any borrow for this LValue to be
// popped too soon.
FES.emplace(SGF);
CanType formalRValueType = dre->getType()->getCanonicalType();
selfValue = SGF.emitAddressOfLocalVarDecl(dre, vd, formalRValueType,
SGFAccessKind::OwnedObjectRead);
selfValue = SGF.emitFormalEvaluationRValueForSelfInDelegationInit(
loc, formalRValueType,
selfValue.getLValueAddress(), ctx)
.getAsSingleValue(SGF, loc);
}
return SGF.B.createValueMetatype(loc, metaTy, selfValue.getValue());
}
SILValue SILGenFunction::emitMetatypeOfValue(SILLocation loc, Expr *baseExpr) {
Type formalBaseType = baseExpr->getType()->getWithoutSpecifierType();
CanType baseTy = formalBaseType->getCanonicalType();
// For class, archetype, and protocol types, look up the dynamic metatype.
if (baseTy.isAnyExistentialType()) {
SILType metaTy = getLoweredLoadableType(
CanExistentialMetatypeType::get(baseTy));
auto base = emitRValueAsSingleValue(baseExpr,
SGFContext::AllowImmediatePlusZero).getValue();
return B.createExistentialMetatype(loc, metaTy, base);
}
SILType metaTy = getLoweredLoadableType(CanMetatypeType::get(baseTy));
// If the lowered metatype has a thick representation, we need to derive it
// dynamically from the instance.
if (metaTy.castTo<MetatypeType>()->getRepresentation()
!= MetatypeRepresentation::Thin) {
if (inExclusiveBorrowSelfSection(SelfInitDelegationState)) {
if (auto *dre = dyn_cast<DeclRefExpr>(baseExpr)) {
if (isa<ParamDecl>(dre->getDecl()) &&
dre->getDecl()->getName() == getASTContext().Id_self &&
dre->getDecl()->isImplicit()) {
return emitMetatypeOfDelegatingInitExclusivelyBorrowedSelf(
*this, loc, dre, metaTy);
}
}
}
Scope S(*this, loc);
auto base = emitRValueAsSingleValue(baseExpr, SGFContext::AllowImmediatePlusZero);
return S.popPreservingValue(B.createValueMetatype(loc, metaTy, base))
.getValue();
}
// Otherwise, ignore the base and return the static thin metatype.
emitIgnoredExpr(baseExpr);
return B.createMetatype(loc, metaTy);
}
RValue RValueEmitter::visitDynamicTypeExpr(DynamicTypeExpr *E, SGFContext C) {
auto metatype = SGF.emitMetatypeOfValue(E, E->getBase());
return RValue(SGF, E, ManagedValue::forUnmanaged(metatype));
}
RValue RValueEmitter::visitCaptureListExpr(CaptureListExpr *E, SGFContext C) {
// Ensure that weak captures are in a separate scope.
DebugScope scope(SGF, CleanupLocation(E));
// CaptureListExprs evaluate their bound variables.
for (auto capture : E->getCaptureList()) {
SGF.visit(capture.Var);
SGF.visit(capture.Init);
}
// Then they evaluate to their body.
return visit(E->getClosureBody(), C);
}
/// Returns the wrapped value placeholder that is meant to be substituted
/// in for the given autoclosure. This autoclosure placeholder is created
/// when \c init(wrappedValue:) takes an autoclosure for the \c wrappedValue
/// parameter.
static PropertyWrapperValuePlaceholderExpr *
wrappedValueAutoclosurePlaceholder(const AbstractClosureExpr *e) {
if (auto ace = dyn_cast<AutoClosureExpr>(e)) {
if (auto ce = dyn_cast<CallExpr>(ace->getSingleExpressionBody())) {
return dyn_cast<PropertyWrapperValuePlaceholderExpr>(ce->getFn());
}
}
return nullptr;
}
RValue RValueEmitter::visitAbstractClosureExpr(AbstractClosureExpr *e,
SGFContext C) {
if (auto *placeholder = wrappedValueAutoclosurePlaceholder(e))
return visitPropertyWrapperValuePlaceholderExpr(placeholder, C);
// Emit the closure body.
SGF.SGM.emitClosure(e);
SubstitutionMap subs;
if (e->getCaptureInfo().hasGenericParamCaptures())
subs = SGF.getForwardingSubstitutionMap();
// Generate the closure value (if any) for the closure expr's function
// reference.
auto refType = e->getType()->getCanonicalType();
SILLocation L = e;
L.markAutoGenerated();
ManagedValue result = SGF.emitClosureValue(L, SILDeclRef(e),
refType, subs);
return RValue(SGF, e, refType, result);
}
RValue RValueEmitter::
visitInterpolatedStringLiteralExpr(InterpolatedStringLiteralExpr *E,
SGFContext C) {
RValue interpolation;
{
TapExpr *ETap = E->getAppendingExpr();
// Inlined from TapExpr:
// TODO: This is only necessary because constant evaluation requires that
// the box for the var gets defined before the initializer happens.
auto Var = ETap->getVar();
auto VarType = ETap->getType()->getCanonicalType();
Scope outerScope(SGF, CleanupLocation(ETap));
// Initialize the var with our SubExpr.
auto VarInit =
SGF.emitInitializationForVarDecl(Var, /*forceImmutable=*/false);
{
// Modified from TapExpr to evaluate the SubExpr directly rather than
// indirectly through the OpaqueValue system.
PreparedArguments builderInitArgs;
RValue literalCapacity = visit(E->getLiteralCapacityExpr(), SGFContext());
RValue interpolationCount =
visit(E->getInterpolationCountExpr(), SGFContext());
builderInitArgs.emplace(
{AnyFunctionType::Param(literalCapacity.getType()),
AnyFunctionType::Param(interpolationCount.getType())});
builderInitArgs.add(E, std::move(literalCapacity));
builderInitArgs.add(E, std::move(interpolationCount));
RValue subexpr_result = SGF.emitApplyAllocatingInitializer(
E, E->getBuilderInit(), std::move(builderInitArgs), Type(),
SGFContext(VarInit.get()));
if (!subexpr_result.isInContext()) {
ArgumentSource(
SILLocation(E),
std::move(subexpr_result).ensurePlusOne(SGF, SILLocation(E)))
.forwardInto(SGF, VarInit.get());
}
}
// Emit the body and let it mutate the var if it chooses.
SGF.emitStmt(ETap->getBody());
// Retrieve and return the var, making it +1 so it survives the scope.
auto result = SGF.emitRValueForDecl(SILLocation(ETap), Var, VarType,
AccessSemantics::Ordinary, SGFContext());
result = std::move(result).ensurePlusOne(SGF, SILLocation(ETap));
interpolation = outerScope.popPreservingValue(std::move(result));
}
PreparedArguments resultInitArgs;
resultInitArgs.emplace(AnyFunctionType::Param(interpolation.getType()));
resultInitArgs.add(E, std::move(interpolation));
return SGF.emitApplyAllocatingInitializer(
E, E->getInitializer(), std::move(resultInitArgs), Type(), C);
}
RValue RValueEmitter::
visitObjectLiteralExpr(ObjectLiteralExpr *E, SGFContext C) {
ConcreteDeclRef init = E->getInitializer();
auto *decl = cast<ConstructorDecl>(init.getDecl());
AnyFunctionType *fnTy = decl->getMethodInterfaceType()
.subst(init.getSubstitutions())
->getAs<AnyFunctionType>();
PreparedArguments args(fnTy->getParams(), E->getArg());
return SGF.emitApplyAllocatingInitializer(SILLocation(E), init,
std::move(args), E->getType(), C);
}
RValue RValueEmitter::
visitEditorPlaceholderExpr(EditorPlaceholderExpr *E, SGFContext C) {
return visit(E->getSemanticExpr(), C);
}
RValue RValueEmitter::visitObjCSelectorExpr(ObjCSelectorExpr *e, SGFContext C) {
SILType loweredSelectorTy = SGF.getLoweredType(e->getType());
// Dig out the declaration of the Selector type.
auto selectorDecl = e->getType()->getAs<StructType>()->getDecl();
// Dig out the type of its pointer.
Type selectorMemberTy;
for (auto member : selectorDecl->getMembers()) {
if (auto var = dyn_cast<VarDecl>(member)) {
if (!var->isStatic() && var->hasStorage()) {
selectorMemberTy = var->getInterfaceType();
break;
}
}
}
if (!selectorMemberTy) {
SGF.SGM.diagnose(e, diag::objc_selector_malformed);
return RValue(SGF, e, SGF.emitUndef(loweredSelectorTy));
}
// Form the selector string.
llvm::SmallString<64> selectorScratch;
auto selectorString =
e->getMethod()->getObjCSelector().getString(selectorScratch);
// Create an Objective-C selector string literal.
auto selectorLiteral =
SGF.B.createStringLiteral(e, selectorString,
StringLiteralInst::Encoding::ObjCSelector);
// Create the pointer struct from the raw pointer.
SILType loweredPtrTy = SGF.getLoweredType(selectorMemberTy);
auto ptrValue = SGF.B.createStruct(e, loweredPtrTy, { selectorLiteral });
// Wrap that up in a Selector and return it.
auto selectorValue = SGF.B.createStruct(e, loweredSelectorTy, { ptrValue });
return RValue(SGF, e, ManagedValue::forUnmanaged(selectorValue));
}
static ManagedValue
emitKeyPathRValueBase(SILGenFunction &subSGF,
AbstractStorageDecl *storage,
SILLocation loc,
SILValue paramArg,
CanType &baseType,
SubstitutionMap subs) {
// If the storage is at global scope, then the base value () is a formality.
// There no real argument to pass to the underlying accessors.
if (!storage->getDeclContext()->isTypeContext())
return ManagedValue();
auto paramOrigValue =
ManagedValue::forBorrowedRValue(paramArg).copy(subSGF, loc);
auto paramSubstValue = subSGF.emitOrigToSubstValue(loc, paramOrigValue,
AbstractionPattern::getOpaque(),
baseType);
// Pop open an existential container base.
if (baseType->isAnyExistentialType()) {
// Use the opened archetype from the AST for a protocol member, or make a
// new one (which we'll upcast immediately below) for a class member.
ArchetypeType *opened;
if (storage->getDeclContext()->getSelfClassDecl()) {
opened = OpenedArchetypeType::get(baseType);
} else {
opened = subs.getReplacementTypes()[0]->castTo<ArchetypeType>();
}
assert(opened->isOpenedExistential());
FormalEvaluationScope scope(subSGF);
baseType = opened->getCanonicalType();
auto openedOpaqueValue = subSGF.emitOpenExistential(loc, paramSubstValue,
subSGF.getLoweredType(baseType),
AccessKind::Read);
// Maybe we could peephole this if we know the property load can borrow the
// base value…
paramSubstValue = openedOpaqueValue.ensurePlusOne(subSGF, loc);
}
// Upcast a class instance to the property's declared type if necessary.
if (auto propertyClass = storage->getDeclContext()->getSelfClassDecl()) {
if (baseType->getClassOrBoundGenericClass() != propertyClass) {
baseType = baseType->getSuperclassForDecl(propertyClass)
->getCanonicalType();
paramSubstValue = subSGF.B.createUpcast(loc, paramSubstValue,
SILType::getPrimitiveObjectType(baseType));
}
}
// …or pop open an existential container.
return paramSubstValue;
}
using IndexTypePair = std::pair<CanType, SILType>;
/// Helper function to load the captured indexes out of a key path component
/// in order to invoke the accessors on that key path. A component with captured
/// indexes passes down a pointer to those captures to the accessor thunks,
/// which we can copy out of to produce values we can pass to the real
/// accessor functions.
static PreparedArguments
loadIndexValuesForKeyPathComponent(SILGenFunction &SGF, SILLocation loc,
AbstractStorageDecl *storage,
ArrayRef<IndexTypePair> indexes,
SILValue pointer) {
// If not a subscript, do nothing.
if (!isa<SubscriptDecl>(storage))
return PreparedArguments();
SmallVector<AnyFunctionType::Param, 8> indexParams;
for (auto &elt : indexes) {
// FIXME: Varargs?
indexParams.emplace_back(SGF.F.mapTypeIntoContext(elt.first));
}
PreparedArguments indexValues(indexParams);
if (indexes.empty()) {
assert(indexValues.isValid());
return indexValues;
}
auto indexLoweredTy =
SGF.getLoweredType(
AnyFunctionType::composeInput(SGF.getASTContext(), indexParams,
/*canonicalVararg=*/false));
auto addr = SGF.B.createPointerToAddress(loc, pointer,
indexLoweredTy.getAddressType(),
/*isStrict*/ false);
for (unsigned i : indices(indexes)) {
SILValue eltAddr = addr;
if (indexes.size() > 1) {
eltAddr = SGF.B.createTupleElementAddr(loc, eltAddr, i);
}
auto ty = SGF.F.mapTypeIntoContext(indexes[i].second);
auto value = SGF.emitLoad(loc, eltAddr,
SGF.getTypeLowering(ty),
SGFContext(), IsNotTake);
auto substType =
SGF.F.mapTypeIntoContext(indexes[i].first)->getCanonicalType();
indexValues.add(loc, RValue(SGF, loc, substType, value));
}
assert(indexValues.isValid());
return indexValues;
}
static AccessorDecl *
getRepresentativeAccessorForKeyPath(AbstractStorageDecl *storage) {
if (storage->requiresOpaqueGetter())
return storage->getOpaqueAccessor(AccessorKind::Get);
assert(storage->requiresOpaqueReadCoroutine());
return storage->getOpaqueAccessor(AccessorKind::Read);
}
static SILFunction *getOrCreateKeyPathGetter(SILGenModule &SGM,
SILLocation loc,
AbstractStorageDecl *property,
SubstitutionMap subs,
GenericEnvironment *genericEnv,
ResilienceExpansion expansion,
ArrayRef<IndexTypePair> indexes,
CanType baseType,
CanType propertyType) {
// If the storage declaration is from a protocol, chase the override chain
// back to the declaration whose getter introduced the witness table
// entry.
if (isa<ProtocolDecl>(property->getDeclContext())) {
auto accessor = getRepresentativeAccessorForKeyPath(property);
if (!SILDeclRef::requiresNewWitnessTableEntry(accessor)) {
// Find the getter that does have a witness table entry.
auto wtableAccessor =
cast<AccessorDecl>(SILDeclRef::getOverriddenWitnessTableEntry(accessor));
// Substitute the 'Self' type of the base protocol.
subs = SILGenModule::mapSubstitutionsForWitnessOverride(
accessor, wtableAccessor, subs);
property = wtableAccessor->getStorage();
}
}
auto genericSig =
genericEnv ? genericEnv->getGenericSignature().getCanonicalSignature()
: nullptr;
if (genericSig && genericSig->areAllParamsConcrete()) {
genericSig = nullptr;
genericEnv = nullptr;
}
// Build the signature of the thunk as expected by the keypath runtime.
auto signature = [&]() {
CanType loweredBaseTy, loweredPropTy;
AbstractionPattern opaque = </