ManagedValue SILGenBuilder::createTupleExtract(SILLocation loc, ManagedValue base, unsigned index, SILType type) { ManagedValue borrowedBase = SGF.emitManagedBeginBorrow(loc, base.getValue()); SILValue extract = createTupleExtract(loc, borrowedBase.getValue(), index, type); return ManagedValue::forUnmanaged(extract); }
ManagedValue SILGenBuilder::createStructExtract(SILLocation loc, ManagedValue base, VarDecl *decl) { ManagedValue borrowedBase = gen.emitManagedBeginBorrow(loc, base.getValue()); SILValue extract = SILBuilder::createStructExtract(loc, borrowedBase.getValue(), decl); return ManagedValue::forUnmanaged(extract); }
ManagedValue SILGenBuilder::createLoadBorrow(SILLocation loc, ManagedValue base) { if (SGF.getTypeLowering(base.getType()).isTrivial()) { auto *i = createLoad(loc, base.getValue(), LoadOwnershipQualifier::Trivial); return ManagedValue::forUnmanaged(i); } auto *i = createLoadBorrow(loc, base.getValue()); return SGF.emitManagedBorrowedRValueWithCleanup(base.getValue(), i); }
ManagedValue SILGenBuilder::createFormalAccessLoadBorrow(SILLocation loc, ManagedValue base) { if (getFunction().getTypeLowering(base.getType()).isTrivial()) { auto *i = SILBuilder::createLoad(loc, base.getValue(), LoadOwnershipQualifier::Trivial); return ManagedValue::forUnmanaged(i); } SILValue baseValue = base.getValue(); auto *i = SILBuilder::createLoadBorrow(loc, baseValue); return gen.emitFormalEvaluationManagedBorrowedRValueWithCleanup(loc, baseValue, i); }
ManagedValue SILGenBuilder::createObjCSuperMethod(SILLocation loc, ManagedValue operand, SILDeclRef member, SILType methodTy) { SILValue v = createObjCSuperMethod(loc, operand.getValue(), member, methodTy); return ManagedValue::forUnmanaged(v); }
static ManagedValue emitBridgeCollectionToNative(SILGenFunction &gen, SILLocation loc, SILDeclRef bridgeFnRef, ManagedValue collection, SILType nativeTy) { SILValue bridgeFn = gen.emitGlobalFunctionRef(loc, bridgeFnRef); auto collectionTy = nativeTy.getSwiftRValueType()->castTo<BoundGenericType>(); auto subs = collectionTy->getSubstitutions(gen.SGM.M.getSwiftModule(), nullptr); auto substFnType = bridgeFn.getType().substGenericArgs(gen.SGM.M, subs); Type inputType = collection.getType().getSwiftRValueType(); if (!inputType->getOptionalObjectType()) { SILType loweredOptTy = gen.SGM.getLoweredType(OptionalType::get(inputType)); auto *someDecl = gen.getASTContext().getOptionalSomeDecl(); auto *enumInst = gen.B.createEnum(loc, collection.getValue(), someDecl, loweredOptTy); collection = ManagedValue(enumInst, collection.getCleanup()); } SILValue result = gen.B.createApply(loc, bridgeFn, substFnType, nativeTy, subs, { collection.forward(gen) }); return gen.emitManagedRValueWithCleanup(result); }
/// Perform a foreign error check by testing whether the error was nil. static void emitErrorIsNonNilErrorCheck(SILGenFunction &gen, SILLocation loc, ManagedValue errorSlot, bool suppressErrorCheck) { // If we're suppressing the check, just don't check. if (suppressErrorCheck) return; SILValue optionalError = gen.B.createLoad(loc, errorSlot.getValue()); OptionalTypeKind optKind; optionalError->getType().getAnyOptionalObjectType(gen.SGM.M, optKind); ASTContext &ctx = gen.getASTContext(); // Switch on the optional error. SILBasicBlock *errorBB = gen.createBasicBlock(FunctionSection::Postmatter); SILBasicBlock *contBB = gen.createBasicBlock(); gen.B.createSwitchEnum(loc, optionalError, /*default*/ nullptr, { { ctx.getOptionalSomeDecl(optKind), errorBB }, { ctx.getOptionalNoneDecl(optKind), contBB } }); // Emit the error block. Just be lazy and reload the error there. gen.emitForeignErrorBlock(loc, errorBB, errorSlot); // Return the result. gen.B.emitBlock(contBB); return; }
ManagedValue SILGenBuilder::createUncheckedTrivialBitCast(SILLocation loc, ManagedValue original, SILType type) { SILValue result = SGF.B.createUncheckedTrivialBitCast(loc, original.getValue(), type); return ManagedValue::forUnmanaged(result); }
uint16_t SILGenFunction::emitProlog(ArrayRef<ParameterList *> paramLists, Type resultType, DeclContext *DC, bool throws) { // Create the indirect result parameters. auto *genericSig = DC->getGenericSignatureOfContext(); resultType = resultType->getCanonicalType(genericSig); emitIndirectResultParameters(*this, resultType, DC); // Emit the argument variables in calling convention order. ArgumentInitHelper emitter(*this, F); for (ParameterList *paramList : reversed(paramLists)) { // Add the SILArguments and use them to initialize the local argument // values. for (auto ¶m : *paramList) emitter.emitParam(param); } // Record the ArgNo of the artificial $error inout argument. unsigned ArgNo = emitter.getNumArgs(); if (throws) { RegularLocation Loc = RegularLocation::getAutoGeneratedLocation(); if (auto *AFD = dyn_cast<AbstractFunctionDecl>(DC)) Loc = AFD->getThrowsLoc(); else if (auto *ACE = dyn_cast<AbstractClosureExpr>(DC)) Loc = ACE->getLoc(); auto NativeErrorTy = SILType::getExceptionType(getASTContext()); ManagedValue Undef = emitUndef(Loc, NativeErrorTy); SILDebugVariable DbgVar("$error", /*Constant*/ false, ++ArgNo); B.createDebugValue(Loc, Undef.getValue(), DbgVar); } return ArgNo; }
ManagedValue SILGenFunction::emitPreconditionOptionalHasValue(SILLocation loc, ManagedValue optional) { // Generate code to the optional is present, and if not, abort with a message // (provided by the stdlib). SILBasicBlock *contBB = createBasicBlock(); SILBasicBlock *failBB = createBasicBlock(); bool hadCleanup = optional.hasCleanup(); bool hadLValue = optional.isLValue(); auto noneDecl = getASTContext().getOptionalNoneDecl(); auto someDecl = getASTContext().getOptionalSomeDecl(); if (optional.getType().isAddress()) { // We forward in the creation routine for // unchecked_take_enum_data_addr. switch_enum_addr is a +0 operation. B.createSwitchEnumAddr(loc, optional.getValue(), /*defaultDest*/ nullptr, {{someDecl, contBB}, {noneDecl, failBB}}); } else { B.createSwitchEnum(loc, optional.forward(*this), /*defaultDest*/ nullptr, {{someDecl, contBB}, {noneDecl, failBB}}); } B.emitBlock(failBB); // Call the standard library implementation of _diagnoseUnexpectedNilOptional. if (auto diagnoseFailure = getASTContext().getDiagnoseUnexpectedNilOptional(nullptr)) { ManagedValue args[4]; emitSourceLocationArgs(*this, loc, args); emitApplyOfLibraryIntrinsic(loc, diagnoseFailure, SubstitutionMap(), args, SGFContext()); } B.createUnreachable(loc); B.clearInsertionPoint(); B.emitBlock(contBB); ManagedValue result; SILType payloadType = optional.getType().getAnyOptionalObjectType(); if (payloadType.isObject()) { result = B.createOwnedPHIArgument(payloadType); } else { result = B.createUncheckedTakeEnumDataAddr(loc, optional, someDecl, payloadType); } if (hadCleanup) { return result; } if (hadLValue) { return ManagedValue::forLValue(result.forward(*this)); } return ManagedValue::forUnmanaged(result.forward(*this)); }
SILValue RValue::getUnmanagedSingleValue(SILGenFunction &SGF, SILLocation l) const & { assert(isComplete() && "rvalue is not complete"); ManagedValue mv = implodeTupleValues<ImplodeKind::Unmanaged>(values, SGF, type, l); return mv.getValue(); }
ManagedValue SILGenBuilder::createFormalAccessCopyAddr( SILLocation loc, ManagedValue originalAddr, SILValue newAddr, IsTake_t isTake, IsInitialization_t isInit) { SILBuilder::createCopyAddr(loc, originalAddr.getValue(), newAddr, isTake, isInit); return gen.emitFormalAccessManagedBufferWithCleanup(loc, newAddr); }
ManagedValue SILGenBuilder::createOpenExistentialMetatype(SILLocation loc, ManagedValue value, SILType openedType) { SILValue result = SILGenBuilder::createOpenExistentialMetatype( loc, value.getValue(), openedType); return ManagedValue::forTrivialRValue(result); }
ManagedValue SILGenBuilder::createUncheckedBitCast(SILLocation loc, ManagedValue value, SILType type) { CleanupCloner cloner(*this, value); SILValue cast = createUncheckedBitCast(loc, value.getValue(), type); // Currently SILBuilder::createUncheckedBitCast only produces these // instructions. We assert here to make sure if this changes, this code is // updated. assert((isa<UncheckedTrivialBitCastInst>(cast) || isa<UncheckedRefCastInst>(cast) || isa<UncheckedBitwiseCastInst>(cast)) && "SILGenBuilder is out of sync with SILBuilder."); // If we have a trivial inst, just return early. if (isa<UncheckedTrivialBitCastInst>(cast)) return ManagedValue::forUnmanaged(cast); // If we perform an unchecked bitwise case, then we are producing a new RC // identity implying that we need a copy of the casted value to be returned so // that the inputs/outputs of the case have separate ownership. if (isa<UncheckedBitwiseCastInst>(cast)) { return ManagedValue::forUnmanaged(cast).copy(SGF, loc); } // Otherwise, we forward the cleanup of the input value and place the cleanup // on the cast value since unchecked_ref_cast is "forwarding". value.forward(SGF); return cloner.clone(cast); }
ManagedValue SILGenFunction::emitCheckedGetOptionalValueFrom(SILLocation loc, ManagedValue src, const TypeLowering &optTL, SGFContext C) { emitPreconditionOptionalHasValue(loc, src.getValue()); return emitUncheckedGetOptionalValueFrom(loc, src, optTL, C); }
ManagedValue SILGenBuilder::createStructExtract(SILLocation loc, ManagedValue base, VarDecl *decl) { ManagedValue borrowedBase = base.formalAccessBorrow(SGF, loc); SILValue extract = createStructExtract(loc, borrowedBase.getValue(), decl); return ManagedValue::forUnmanaged(extract); }
/// Specialized emitter for Builtin.reinterpretCast. static ManagedValue emitBuiltinReinterpretCast(SILGenFunction &SGF, SILLocation loc, SubstitutionMap substitutions, ArrayRef<ManagedValue> args, SGFContext C) { assert(args.size() == 1 && "reinterpretCast should be given one argument"); assert(substitutions.getReplacementTypes().size() == 2 && "reinterpretCast should have two subs"); auto &fromTL = SGF.getTypeLowering(substitutions.getReplacementTypes()[0]); auto &toTL = SGF.getTypeLowering(substitutions.getReplacementTypes()[1]); // If casting between address types, cast the address. if (fromTL.isAddress() || toTL.isAddress()) { SILValue fromAddr; // If the from value is not an address, move it to a buffer. if (!fromTL.isAddress()) { fromAddr = SGF.emitTemporaryAllocation(loc, args[0].getValue()->getType()); fromTL.emitStore(SGF.B, loc, args[0].getValue(), fromAddr, StoreOwnershipQualifier::Init); } else { fromAddr = args[0].getValue(); } auto toAddr = SGF.B.createUncheckedAddrCast(loc, fromAddr, toTL.getLoweredType().getAddressType()); // Load and retain the destination value if it's loadable. Leave the cleanup // on the original value since we don't know anything about it's type. if (!toTL.isAddress()) { return SGF.emitManagedLoadCopy(loc, toAddr, toTL); } // Leave the cleanup on the original value. if (toTL.isTrivial()) return ManagedValue::forUnmanaged(toAddr); // Initialize the +1 result buffer without taking the incoming value. The // source and destination cleanups will be independent. return SGF.B.bufferForExpr( loc, toTL.getLoweredType(), toTL, C, [&](SILValue bufferAddr) { SGF.B.createCopyAddr(loc, toAddr, bufferAddr, IsNotTake, IsInitialization); }); } // Create the appropriate bitcast based on the source and dest types. ManagedValue in = args[0]; SILType resultTy = toTL.getLoweredType(); if (resultTy.isTrivial(SGF.F)) return SGF.B.createUncheckedTrivialBitCast(loc, in, resultTy); // If we can perform a ref cast, just return. if (auto refCast = SGF.B.tryCreateUncheckedRefCast(loc, in, resultTy)) return refCast; // Otherwise leave the original cleanup and retain the cast value. SILValue out = SGF.B.createUncheckedBitwiseCast(loc, in.getValue(), resultTy); return SGF.emitManagedRetain(loc, out, toTL); }
ManagedValue SILGenBuilder::createTupleElementAddr(SILLocation Loc, ManagedValue Base, unsigned Index, SILType Type) { SILValue TupleEltAddr = createTupleElementAddr(Loc, Base.getValue(), Index, Type); return ManagedValue::forUnmanaged(TupleEltAddr); }
ManagedValue SILGenBuilder::createRefElementAddr(SILLocation loc, ManagedValue operand, VarDecl *field, SILType resultTy) { operand = operand.formalAccessBorrow(SGF, loc); SILValue result = createRefElementAddr(loc, operand.getValue(), field); return ManagedValue::forUnmanaged(result); }
ManagedValue SILGenBuilder::createOpenExistentialBoxValue(SILLocation loc, ManagedValue original, SILType type) { ManagedValue borrowedExistential = original.formalAccessBorrow(SGF, loc); SILValue openedExistential = createOpenExistentialBoxValue(loc, borrowedExistential.getValue(), type); return ManagedValue::forUnmanaged(openedExistential); }
static ManagedValue emitNativeToCBridgedNonoptionalValue(SILGenFunction &gen, SILLocation loc, ManagedValue v, SILType bridgedTy) { CanType loweredBridgedTy = bridgedTy.getSwiftRValueType(); CanType loweredNativeTy = v.getType().getSwiftRValueType(); if (loweredNativeTy == loweredBridgedTy) return v; // FIXME: Handle this via an _ObjectiveCBridgeable query rather than // hardcoding String -> NSString. if (loweredNativeTy == gen.SGM.Types.getStringType() && loweredBridgedTy == gen.SGM.Types.getNSStringType()) { if (auto result = emitBridgeNativeToObjectiveC(gen, loc, v)) return *result; return gen.emitUndef(loc, bridgedTy); } // If the input is a native type with a bridged mapping, convert it. #define BRIDGE_TYPE(BridgedModule,BridgedType, NativeModule,NativeType,Opt) \ if (loweredNativeTy == gen.SGM.Types.get##NativeType##Type() \ && loweredBridgedTy == gen.SGM.Types.get##BridgedType##Type()) { \ return emitBridge##NativeType##To##BridgedType(gen, loc, v); \ } #include "swift/SIL/BridgedTypes.def" // Bridge thick to Objective-C metatypes. if (auto bridgedMetaTy = dyn_cast<AnyMetatypeType>(loweredBridgedTy)) { if (bridgedMetaTy->getRepresentation() == MetatypeRepresentation::ObjC) { SILValue native = gen.B.emitThickToObjCMetatype(loc, v.getValue(), SILType::getPrimitiveObjectType(loweredBridgedTy)); return ManagedValue(native, v.getCleanup()); } } // Bridge native functions to blocks. auto bridgedFTy = dyn_cast<SILFunctionType>(loweredBridgedTy); if (bridgedFTy && bridgedFTy->getRepresentation() == SILFunctionType::Representation::Block){ auto nativeFTy = cast<SILFunctionType>(loweredNativeTy); if (nativeFTy->getRepresentation() != SILFunctionType::Representation::Block) return gen.emitFuncToBlock(loc, v, bridgedFTy); } // If the native type conforms to _ObjectiveCBridgeable, use its // _bridgeToObjectiveC witness. if (auto conformance = gen.SGM.getConformanceToObjectiveCBridgeable(loc, loweredNativeTy)) { if (auto result = emitBridgeNativeToObjectiveC(gen, loc, v, conformance)) return *result; return gen.emitUndef(loc, bridgedTy); } return v; }
static ManagedValue emitCBridgedToNativeValue(SILGenFunction &gen, SILLocation loc, ManagedValue v, SILType nativeTy) { CanType loweredNativeTy = nativeTy.getSwiftRValueType(); CanType loweredBridgedTy = v.getType().getSwiftRValueType(); if (loweredNativeTy == loweredBridgedTy) return v; if (loweredNativeTy.getAnyOptionalObjectType()) { return gen.emitOptionalToOptional(loc, v, nativeTy, emitCBridgedToNativeValue); } // Bridge Bool to ObjCBool or DarwinBoolean when requested. if (loweredNativeTy == gen.SGM.Types.getBoolType()) { if (loweredBridgedTy == gen.SGM.Types.getObjCBoolType()) { return emitBridgeForeignBoolToBool(gen, loc, v, gen.SGM.getObjCBoolToBoolFn()); } if (loweredBridgedTy == gen.SGM.Types.getDarwinBooleanType()) { return emitBridgeForeignBoolToBool(gen, loc, v, gen.SGM.getDarwinBooleanToBoolFn()); } } // Bridge Objective-C to thick metatypes. if (auto bridgedMetaTy = dyn_cast<AnyMetatypeType>(loweredBridgedTy)){ if (bridgedMetaTy->getRepresentation() == MetatypeRepresentation::ObjC) { SILValue native = gen.B.emitObjCToThickMetatype(loc, v.getValue(), gen.getLoweredType(loweredNativeTy)); return ManagedValue(native, v.getCleanup()); } } // Bridge blocks back into native function types. auto bridgedFTy = dyn_cast<SILFunctionType>(loweredBridgedTy); if (bridgedFTy && bridgedFTy->getRepresentation() == SILFunctionType::Representation::Block){ auto nativeFTy = cast<SILFunctionType>(loweredNativeTy); if (nativeFTy->getRepresentation() != SILFunctionType::Representation::Block) return gen.emitBlockToFunc(loc, v, nativeFTy); } // Bridge via _ObjectiveCBridgeable. if (auto conformance = gen.SGM.getConformanceToObjectiveCBridgeable(loc, loweredNativeTy)) { if (auto result = emitBridgeObjectiveCToNative(gen, loc, v, conformance)) return *result; assert(gen.SGM.getASTContext().Diags.hadAnyError() && "Bridging code should have complained"); return gen.emitUndef(loc, nativeTy); } return v; }
/// Bridge a native function to a block with a thunk. ManagedValue SILGenFunction::emitFuncToBlock(SILLocation loc, ManagedValue fn, CanSILFunctionType blockTy) { // Build the invoke function signature. The block will capture the original // function value. auto fnTy = fn.getType().castTo<SILFunctionType>(); auto storageTy = SILBlockStorageType::get(fnTy); // Build the invoke function type. SmallVector<SILParameterInfo, 4> params; params.push_back(SILParameterInfo(storageTy, ParameterConvention::Indirect_InoutAliasable)); std::copy(blockTy->getParameters().begin(), blockTy->getParameters().end(), std::back_inserter(params)); auto invokeTy = SILFunctionType::get(nullptr, SILFunctionType::ExtInfo() .withRepresentation(SILFunctionType::Representation:: CFunctionPointer), ParameterConvention::Direct_Unowned, params, blockTy->getAllResults(), blockTy->getOptionalErrorResult(), getASTContext()); // Create the invoke function. Borrow the mangling scheme from reabstraction // thunks, which is what we are in spirit. auto thunk = SGM.getOrCreateReabstractionThunk(nullptr, invokeTy, fnTy, blockTy, F.isFragile()); // Build it if necessary. if (thunk->empty()) { SILGenFunction thunkSGF(SGM, *thunk); auto loc = RegularLocation::getAutoGeneratedLocation(); buildFuncToBlockInvokeBody(thunkSGF, loc, blockTy, storageTy, fnTy); } // Form the block on the stack. auto storageAddrTy = SILType::getPrimitiveAddressType(storageTy); auto storage = emitTemporaryAllocation(loc, storageAddrTy); auto capture = B.createProjectBlockStorage(loc, storage); // Store the function to the block without claiming it, so that it still // gets cleaned up in scope. Copying the block will create an independent // reference. B.createStore(loc, fn.getValue(), capture); auto invokeFn = B.createFunctionRef(loc, thunk); auto stackBlock = B.createInitBlockStorageHeader(loc, storage, invokeFn, SILType::getPrimitiveObjectType(blockTy)); // Copy the block so we have an independent heap object we can hand off. auto heapBlock = B.createCopyBlock(loc, stackBlock); return emitManagedRValueWithCleanup(heapBlock); }
ManagedValue SILGenBuilder::tryCreateUncheckedRefCast(SILLocation loc, ManagedValue original, SILType type) { CleanupCloner cloner(*this, original); SILValue result = tryCreateUncheckedRefCast(loc, original.getValue(), type); if (!result) return ManagedValue(); original.forward(SGF); return cloner.clone(result); }
ManagedValue SILGenBuilder::createCopyUnownedValue(SILLocation loc, ManagedValue originalValue) { auto unownedType = originalValue.getType().castTo<UnownedStorageType>(); assert(unownedType->isLoadable(ResilienceExpansion::Maximal)); (void)unownedType; SILValue result = SILBuilder::createCopyUnownedValue(loc, originalValue.getValue()); return gen.emitManagedRValueWithCleanup(result); }
ManagedValue SILGenBuilder::createUnsafeCopyUnownedValue(SILLocation loc, ManagedValue originalValue) { auto unmanagedType = originalValue.getType().getAs<UnmanagedStorageType>(); SILValue result = SILBuilder::createUnmanagedToRef( loc, originalValue.getValue(), SILType::getPrimitiveObjectType(unmanagedType.getReferentType())); SILBuilder::createUnmanagedRetainValue(loc, result, getDefaultAtomicity()); return gen.emitManagedRValueWithCleanup(result); }
static std::pair<ManagedValue, SILDeclRef> getNextUncurryLevelRef(SILGenFunction &SGF, SILLocation loc, SILDeclRef thunk, ManagedValue selfArg, SubstitutionMap curriedSubs) { auto *vd = thunk.getDecl(); // Reference the next uncurrying level of the function. SILDeclRef next = SILDeclRef(vd, thunk.kind); assert(!next.isCurried); auto constantInfo = SGF.SGM.Types.getConstantInfo(next); // If the function is natively foreign, reference its foreign entry point. if (requiresForeignToNativeThunk(vd)) return {ManagedValue::forUnmanaged(SGF.emitGlobalFunctionRef(loc, next)), next}; // If the thunk is a curry thunk for a direct method reference, we are // doing a direct dispatch (eg, a fragile 'super.foo()' call). if (thunk.isDirectReference) return {ManagedValue::forUnmanaged(SGF.emitGlobalFunctionRef(loc, next)), next}; if (auto *func = dyn_cast<AbstractFunctionDecl>(vd)) { if (getMethodDispatch(func) == MethodDispatch::Class) { // Use the dynamic thunk if dynamic. if (vd->isObjCDynamic()) { return {SGF.emitDynamicMethodRef(loc, next, constantInfo.SILFnType), next}; } auto methodTy = SGF.SGM.Types.getConstantOverrideType(next); SILValue result = SGF.emitClassMethodRef(loc, selfArg.getValue(), next, methodTy); return {ManagedValue::forUnmanaged(result), next.getOverriddenVTableEntry()}; } // If the fully-uncurried reference is to a generic method, look up the // witness. if (constantInfo.SILFnType->getRepresentation() == SILFunctionTypeRepresentation::WitnessMethod) { auto protocol = func->getDeclContext()->getSelfProtocolDecl(); auto origSelfType = protocol->getSelfInterfaceType()->getCanonicalType(); auto substSelfType = origSelfType.subst(curriedSubs)->getCanonicalType(); auto conformance = curriedSubs.lookupConformance(origSelfType, protocol); auto result = SGF.B.createWitnessMethod(loc, substSelfType, *conformance, next, constantInfo.getSILType()); return {ManagedValue::forUnmanaged(result), next}; } } // Otherwise, emit a direct call. return {ManagedValue::forUnmanaged(SGF.emitGlobalFunctionRef(loc, next)), next}; }
ManagedValue SILGenBuilder::createLoadCopy(SILLocation loc, ManagedValue v, const TypeLowering &lowering) { assert(lowering.getLoweredType().getAddressType() == v.getType()); SILValue result = lowering.emitLoadOfCopy(*this, loc, v.getValue(), IsNotTake); if (lowering.isTrivial()) return ManagedValue::forUnmanaged(result); assert((!lowering.isAddressOnly() || !SGF.silConv.useLoweredAddresses()) && "cannot retain an unloadable type"); return SGF.emitManagedRValueWithCleanup(result, lowering); }
void SILGenFunction::emitClassMemberDestruction(ManagedValue selfValue, ClassDecl *cd, CleanupLocation cleanupLoc) { selfValue = selfValue.borrow(*this, cleanupLoc); for (VarDecl *vd : cd->getStoredProperties()) { const TypeLowering &ti = getTypeLowering(vd->getType()); if (!ti.isTrivial()) { SILValue addr = B.createRefElementAddr(cleanupLoc, selfValue.getValue(), vd, ti.getLoweredType().getAddressType()); B.createDestroyAddr(cleanupLoc, addr); } } }
ManagedValue SILGenBuilder::createUncheckedEnumData(SILLocation loc, ManagedValue operand, EnumElementDecl *element) { if (operand.hasCleanup()) { SILValue newValue = SILBuilder::createUncheckedEnumData(loc, operand.forward(gen), element); return gen.emitManagedRValueWithCleanup(newValue); } ManagedValue borrowedBase = operand.borrow(gen, loc); SILValue newValue = SILBuilder::createUncheckedEnumData( loc, borrowedBase.getValue(), element); return ManagedValue::forUnmanaged(newValue); }