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)); }
ManagedValue SILGenBuilder::createUncheckedTakeEnumDataAddr( SILLocation loc, ManagedValue operand, EnumElementDecl *element, SILType ty) { // First see if we have a cleanup. If we do, we are going to forward and emit // a managed buffer with cleanup. if (operand.hasCleanup()) { return gen.emitManagedBufferWithCleanup( SILBuilder::createUncheckedTakeEnumDataAddr(loc, operand.forward(gen), element, ty)); } SILValue result = SILBuilder::createUncheckedTakeEnumDataAddr( loc, operand.getUnmanagedValue(), element, ty); if (operand.isLValue()) return ManagedValue::forLValue(result); return ManagedValue::forUnmanaged(result); }