mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
This means that it can only have a guaranteed object as an operandand that we validate that all uses of the result address of open_existential_box occur only within the lifetime of said object's borrow scope.
385 lines
17 KiB
C++
385 lines
17 KiB
C++
//===--- SILGenBuilder.h ----------------------------------------*- C++ -*-===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// \file
|
|
///
|
|
/// This file defines SILGenBuilder, a subclass of SILBuilder that provides APIs
|
|
/// that traffic in ManagedValue. The intention is that if one is using a
|
|
/// SILGenBuilder, the SILGenBuilder will handle preserving ownership invariants
|
|
/// (or assert upon failure) freeing the implementor of such concerns.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_SILGEN_SILGENBUILDER_H
|
|
#define SWIFT_SILGEN_SILGENBUILDER_H
|
|
|
|
#include "Cleanup.h"
|
|
#include "JumpDest.h"
|
|
#include "ManagedValue.h"
|
|
#include "RValue.h"
|
|
#include "swift/SIL/SILBuilder.h"
|
|
#include "swift/Basic/ProfileCounter.h"
|
|
|
|
namespace swift {
|
|
namespace Lowering {
|
|
|
|
class SILGenFunction;
|
|
class SGFContext;
|
|
|
|
/// A subclass of SILBuilder that wraps APIs to vend ManagedValues.
|
|
/// APIs only vend ManagedValues.
|
|
class SILGenBuilder : public SILBuilder {
|
|
SILGenFunction &SGF;
|
|
|
|
public:
|
|
SILGenBuilder(SILGenFunction &SGF);
|
|
SILGenBuilder(SILGenFunction &SGF, SILBasicBlock *insertBB,
|
|
SmallVectorImpl<SILInstruction *> *insertedInsts = nullptr);
|
|
SILGenBuilder(SILGenFunction &SGF, SILBasicBlock *insertBB,
|
|
SILBasicBlock::iterator insertInst);
|
|
|
|
// Create a new builder, inheriting the given builder's context and debug
|
|
// scope.
|
|
SILGenBuilder(SILGenBuilder &builder, SILBasicBlock *insertBB)
|
|
: SILBuilder(insertBB, builder.getCurrentDebugScope(),
|
|
builder.getBuilderContext()),
|
|
SGF(builder.SGF) {}
|
|
|
|
SILGenModule &getSILGenModule() const;
|
|
SILGenFunction &getSILGenFunction() const { return SGF; }
|
|
|
|
using SILBuilder::createInitExistentialValue;
|
|
ManagedValue
|
|
createInitExistentialValue(SILLocation loc, SILType existentialType,
|
|
CanType formalConcreteType, ManagedValue concrete,
|
|
ArrayRef<ProtocolConformanceRef> conformances);
|
|
using SILBuilder::createInitExistentialRef;
|
|
ManagedValue
|
|
createInitExistentialRef(SILLocation loc, SILType existentialType,
|
|
CanType formalConcreteType, ManagedValue concrete,
|
|
ArrayRef<ProtocolConformanceRef> conformances);
|
|
|
|
using SILBuilder::createPartialApply;
|
|
ManagedValue createPartialApply(SILLocation loc, SILValue fn,
|
|
SubstitutionMap subs,
|
|
ArrayRef<ManagedValue> args,
|
|
ParameterConvention calleeConvention);
|
|
ManagedValue createPartialApply(SILLocation loc, ManagedValue fn,
|
|
SubstitutionMap subs,
|
|
ArrayRef<ManagedValue> args,
|
|
ParameterConvention calleeConvention) {
|
|
return createPartialApply(loc, fn.getValue(), subs, args,
|
|
calleeConvention);
|
|
}
|
|
|
|
using SILBuilder::createStructExtract;
|
|
ManagedValue createStructExtract(SILLocation loc, ManagedValue base,
|
|
VarDecl *decl);
|
|
|
|
using SILBuilder::createRefElementAddr;
|
|
ManagedValue createRefElementAddr(SILLocation loc, ManagedValue operand,
|
|
VarDecl *field, SILType resultTy);
|
|
|
|
using SILBuilder::createCopyValue;
|
|
|
|
/// Emit a +1 copy on \p originalValue that lives until the end of the current
|
|
/// lexical scope.
|
|
ManagedValue createCopyValue(SILLocation loc, ManagedValue originalValue);
|
|
|
|
/// Emit a +1 copy on \p originalValue that lives until the end of the current
|
|
/// lexical scope.
|
|
///
|
|
/// This reuses a passed in lowering.
|
|
ManagedValue createCopyValue(SILLocation loc, ManagedValue originalValue,
|
|
const TypeLowering &lowering);
|
|
|
|
/// Emit a +1 copy of \p originalValue into newAddr that lives until the end
|
|
/// of the current Formal Evaluation Scope.
|
|
ManagedValue createFormalAccessCopyAddr(SILLocation loc,
|
|
ManagedValue originalAddr,
|
|
SILValue newAddr, IsTake_t isTake,
|
|
IsInitialization_t isInit);
|
|
|
|
/// Emit a +1 copy of \p originalValue into newAddr that lives until the end
|
|
/// Formal Evaluation Scope.
|
|
ManagedValue createFormalAccessCopyValue(SILLocation loc,
|
|
ManagedValue originalValue);
|
|
|
|
#define ALWAYS_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, ...) \
|
|
using SILBuilder::createStrongCopy##Name##Value; \
|
|
ManagedValue createStrongCopy##Name##Value(SILLocation loc, \
|
|
ManagedValue originalValue);
|
|
#define UNCHECKED_REF_STORAGE(Name, ...) \
|
|
using SILBuilder::createStrongCopy##Name##Value; \
|
|
ManagedValue createStrongCopy##Name##Value(SILLocation loc, \
|
|
ManagedValue originalValue);
|
|
#include "swift/AST/ReferenceStorage.def"
|
|
|
|
ManagedValue createOwnedPhiArgument(SILType type);
|
|
ManagedValue createGuaranteedPhiArgument(SILType type);
|
|
|
|
/// For arguments from terminators that are "transforming terminators". These
|
|
/// types of guaranteed arguments are validated as part of the operand of the
|
|
/// transforming terminator since transforming terminators are guaranteed to
|
|
/// be the only predecessor of our parent block.
|
|
///
|
|
/// NOTE: Two examples of transforming terminators are switch_enum,
|
|
/// checked_cast_br.
|
|
ManagedValue createGuaranteedTransformingTerminatorArgument(SILType type);
|
|
|
|
using SILBuilder::createMarkUninitialized;
|
|
ManagedValue createMarkUninitialized(ValueDecl *decl, ManagedValue operand,
|
|
MarkUninitializedInst::Kind muKind);
|
|
|
|
using SILBuilder::createAllocRef;
|
|
ManagedValue createAllocRef(SILLocation loc, SILType refType, bool objc,
|
|
bool canAllocOnStack,
|
|
ArrayRef<SILType> elementTypes,
|
|
ArrayRef<ManagedValue> elementCountOperands);
|
|
using SILBuilder::createAllocRefDynamic;
|
|
ManagedValue
|
|
createAllocRefDynamic(SILLocation loc, ManagedValue operand, SILType refType,
|
|
bool objc, ArrayRef<SILType> elementTypes,
|
|
ArrayRef<ManagedValue> elementCountOperands);
|
|
|
|
using SILBuilder::createTuple;
|
|
ManagedValue createTuple(SILLocation loc, SILType type,
|
|
ArrayRef<ManagedValue> elements);
|
|
using SILBuilder::createTupleExtract;
|
|
ManagedValue createTupleExtract(SILLocation loc, ManagedValue value,
|
|
unsigned index, SILType type);
|
|
ManagedValue createTupleExtract(SILLocation loc, ManagedValue value,
|
|
unsigned index);
|
|
using SILBuilder::createTupleElementAddr;
|
|
ManagedValue createTupleElementAddr(SILLocation loc, ManagedValue addr,
|
|
unsigned index, SILType type);
|
|
ManagedValue createTupleElementAddr(SILLocation loc, ManagedValue addr,
|
|
unsigned index);
|
|
|
|
using SILBuilder::createLoadBorrow;
|
|
ManagedValue createLoadBorrow(SILLocation loc, ManagedValue base);
|
|
ManagedValue createFormalAccessLoadBorrow(SILLocation loc, ManagedValue base);
|
|
|
|
using SILBuilder::createStoreBorrow;
|
|
void createStoreBorrow(SILLocation loc, ManagedValue value, SILValue address);
|
|
|
|
/// Create a store_borrow if we have a non-trivial value and a store [trivial]
|
|
/// otherwise.
|
|
void createStoreBorrowOrTrivial(SILLocation loc, ManagedValue value,
|
|
SILValue address);
|
|
|
|
/// Prepares a buffer to receive the result of an expression, either using the
|
|
/// 'emit into' initialization buffer if available, or allocating a temporary
|
|
/// allocation if not. After the buffer has been prepared, the rvalueEmitter
|
|
/// closure will be called with the buffer ready for initialization. After the
|
|
/// emitter has been called, the buffer will complete its initialization.
|
|
///
|
|
/// \return an empty value if the buffer was taken from the context.
|
|
ManagedValue bufferForExpr(SILLocation loc, SILType ty,
|
|
const TypeLowering &lowering, SGFContext context,
|
|
llvm::function_ref<void(SILValue)> rvalueEmitter);
|
|
|
|
using SILBuilder::createUncheckedEnumData;
|
|
ManagedValue createUncheckedEnumData(SILLocation loc, ManagedValue operand,
|
|
EnumElementDecl *element);
|
|
|
|
using SILBuilder::createUncheckedTakeEnumDataAddr;
|
|
ManagedValue createUncheckedTakeEnumDataAddr(SILLocation loc, ManagedValue operand,
|
|
EnumElementDecl *element, SILType ty);
|
|
|
|
ManagedValue createLoadTake(SILLocation loc, ManagedValue addr);
|
|
ManagedValue createLoadTake(SILLocation loc, ManagedValue addr,
|
|
const TypeLowering &lowering);
|
|
ManagedValue createLoadCopy(SILLocation loc, ManagedValue addr);
|
|
ManagedValue createLoadCopy(SILLocation loc, ManagedValue addr,
|
|
const TypeLowering &lowering);
|
|
|
|
/// Create a SILArgument for an input parameter. Asserts if used to create a
|
|
/// function argument for an out parameter.
|
|
ManagedValue createInputFunctionArgument(SILType type, ValueDecl *decl);
|
|
|
|
/// Create a SILArgument for an input parameter. Uses \p loc to create any
|
|
/// copies necessary. Asserts if used to create a function argument for an out
|
|
/// parameter.
|
|
///
|
|
/// *NOTE* This API purposely used an Optional<SILLocation> to distinguish
|
|
/// this API from the ValueDecl * API in C++. This is necessary since
|
|
/// ValueDecl * can implicitly convert to SILLocation. The optional forces the
|
|
/// user to be explicit that they want to use this API.
|
|
ManagedValue createInputFunctionArgument(SILType type,
|
|
Optional<SILLocation> loc);
|
|
|
|
using SILBuilder::createEnum;
|
|
ManagedValue createEnum(SILLocation loc, ManagedValue payload,
|
|
EnumElementDecl *decl, SILType type);
|
|
|
|
ManagedValue createSemanticLoadBorrow(SILLocation loc, ManagedValue addr);
|
|
|
|
ManagedValue
|
|
formalAccessBufferForExpr(SILLocation loc, SILType ty,
|
|
const TypeLowering &lowering, SGFContext context,
|
|
llvm::function_ref<void(SILValue)> rvalueEmitter);
|
|
|
|
using SILBuilder::createUnconditionalCheckedCastValue;
|
|
ManagedValue
|
|
createUnconditionalCheckedCastValue(SILLocation loc,
|
|
ManagedValue op,
|
|
CanType srcFormalTy,
|
|
SILType destLoweredTy,
|
|
CanType destFormalTy);
|
|
using SILBuilder::createUnconditionalCheckedCast;
|
|
ManagedValue createUnconditionalCheckedCast(SILLocation loc,
|
|
ManagedValue op,
|
|
SILType destLoweredTy,
|
|
CanType destFormalTy);
|
|
|
|
using SILBuilder::createCheckedCastBranch;
|
|
void createCheckedCastBranch(SILLocation loc, bool isExact,
|
|
ManagedValue op,
|
|
SILType destLoweredTy,
|
|
CanType destFormalTy,
|
|
SILBasicBlock *trueBlock,
|
|
SILBasicBlock *falseBlock,
|
|
ProfileCounter Target1Count,
|
|
ProfileCounter Target2Count);
|
|
|
|
using SILBuilder::createCheckedCastValueBranch;
|
|
void createCheckedCastValueBranch(SILLocation loc,
|
|
ManagedValue op,
|
|
CanType srcFormalTy,
|
|
SILType destLoweredTy,
|
|
CanType destFormalTy,
|
|
SILBasicBlock *trueBlock,
|
|
SILBasicBlock *falseBlock);
|
|
|
|
using SILBuilder::createUpcast;
|
|
ManagedValue createUpcast(SILLocation loc, ManagedValue original,
|
|
SILType type);
|
|
|
|
using SILBuilder::createUncheckedTrivialBitCast;
|
|
ManagedValue createUncheckedTrivialBitCast(SILLocation loc,
|
|
ManagedValue original,
|
|
SILType type);
|
|
|
|
using SILBuilder::createUncheckedRefCast;
|
|
ManagedValue createUncheckedRefCast(SILLocation loc, ManagedValue original,
|
|
SILType type);
|
|
|
|
using SILBuilder::createUncheckedAddrCast;
|
|
ManagedValue createUncheckedAddrCast(SILLocation loc, ManagedValue op,
|
|
SILType resultTy);
|
|
|
|
using SILBuilder::createUncheckedBitCast;
|
|
ManagedValue createUncheckedBitCast(SILLocation loc, ManagedValue original,
|
|
SILType type);
|
|
|
|
using SILBuilder::createOpenExistentialRef;
|
|
ManagedValue createOpenExistentialRef(SILLocation loc, ManagedValue arg,
|
|
SILType openedType);
|
|
|
|
using SILBuilder::createOpenExistentialValue;
|
|
ManagedValue createOpenExistentialValue(SILLocation loc,
|
|
ManagedValue original, SILType type);
|
|
|
|
using SILBuilder::createOpenExistentialBoxValue;
|
|
ManagedValue createOpenExistentialBoxValue(SILLocation loc,
|
|
ManagedValue original, SILType type);
|
|
|
|
using SILBuilder::createOpenExistentialBox;
|
|
ManagedValue createOpenExistentialBox(SILLocation loc, ManagedValue original,
|
|
SILType type);
|
|
|
|
using SILBuilder::createOpenExistentialMetatype;
|
|
ManagedValue createOpenExistentialMetatype(SILLocation loc,
|
|
ManagedValue value,
|
|
SILType openedType);
|
|
|
|
/// Convert a @convention(block) value to AnyObject.
|
|
ManagedValue createBlockToAnyObject(SILLocation loc, ManagedValue block,
|
|
SILType type);
|
|
|
|
using SILBuilder::createOptionalSome;
|
|
ManagedValue createOptionalSome(SILLocation Loc, ManagedValue Arg);
|
|
ManagedValue createManagedOptionalNone(SILLocation Loc, SILType Type);
|
|
|
|
// TODO: Rename this to createFunctionRef once all calls to createFunctionRef
|
|
// are removed.
|
|
ManagedValue createManagedFunctionRef(SILLocation loc, SILFunction *f);
|
|
|
|
using SILBuilder::createConvertFunction;
|
|
ManagedValue createConvertFunction(SILLocation loc, ManagedValue fn,
|
|
SILType resultTy,
|
|
bool WithoutActuallyEscaping = false);
|
|
|
|
using SILBuilder::createConvertEscapeToNoEscape;
|
|
ManagedValue
|
|
createConvertEscapeToNoEscape(SILLocation loc, ManagedValue fn,
|
|
SILType resultTy);
|
|
|
|
using SILBuilder::createStore;
|
|
/// Forward \p value into \p address.
|
|
///
|
|
/// This will forward value's cleanup (if it has one) into the equivalent
|
|
/// cleanup on address. In practice this means if the value is non-trivial,
|
|
/// the memory location will at end of scope have a destroy_addr applied to
|
|
/// it.
|
|
ManagedValue createStore(SILLocation loc, ManagedValue value,
|
|
SILValue address, StoreOwnershipQualifier qualifier);
|
|
|
|
using SILBuilder::createSuperMethod;
|
|
ManagedValue createSuperMethod(SILLocation loc, ManagedValue operand,
|
|
SILDeclRef member, SILType methodTy);
|
|
|
|
using SILBuilder::createObjCSuperMethod;
|
|
ManagedValue createObjCSuperMethod(SILLocation loc, ManagedValue operand,
|
|
SILDeclRef member, SILType methodTy);
|
|
|
|
using SILBuilder::createValueMetatype;
|
|
ManagedValue createValueMetatype(SILLocation loc, SILType metatype,
|
|
ManagedValue base);
|
|
|
|
using SILBuilder::createBridgeObjectToRef;
|
|
ManagedValue createBridgeObjectToRef(SILLocation loc, ManagedValue mv,
|
|
SILType destType);
|
|
|
|
using SILBuilder::createRefToBridgeObject;
|
|
ManagedValue createRefToBridgeObject(SILLocation loc, ManagedValue mv,
|
|
SILValue bits);
|
|
|
|
using SILBuilder::createBranch;
|
|
BranchInst *createBranch(SILLocation Loc, SILBasicBlock *TargetBlock,
|
|
ArrayRef<ManagedValue> Args);
|
|
|
|
using SILBuilder::createReturn;
|
|
ReturnInst *createReturn(SILLocation Loc, ManagedValue ReturnValue);
|
|
|
|
using SILBuilder::emitDestructureValueOperation;
|
|
/// Perform either a tuple or struct destructure and then pass its components
|
|
/// as managed value one by one with an index to the closure.
|
|
void emitDestructureValueOperation(
|
|
SILLocation loc, ManagedValue value,
|
|
function_ref<void(unsigned, ManagedValue)> func);
|
|
|
|
using SILBuilder::createProjectBox;
|
|
ManagedValue createProjectBox(SILLocation loc, ManagedValue mv,
|
|
unsigned index);
|
|
|
|
using SILBuilder::createMarkDependence;
|
|
ManagedValue createMarkDependence(SILLocation loc, ManagedValue value,
|
|
ManagedValue base);
|
|
};
|
|
|
|
} // namespace Lowering
|
|
} // namespace swift
|
|
|
|
#endif
|