Exemplo n.º 1
0
/// Perform a foreign error check by testing whether the call result is zero.
/// The call result is otherwise ignored.
static void
emitResultIsZeroErrorCheck(SILGenFunction &gen, SILLocation loc,
                           ManagedValue result, ManagedValue errorSlot,
                           bool suppressErrorCheck, bool zeroIsError) {
  // Just ignore the call result if we're suppressing the error check.
  if (suppressErrorCheck) {
    return;
  }

  SILValue resultValue =
    emitUnwrapIntegerResult(gen, loc, result.getUnmanagedValue());
  CanType resultType = resultValue->getType().getSwiftRValueType();

  if (!resultType->isBuiltinIntegerType(1)) {
    SILValue zero =
      gen.B.createIntegerLiteral(loc, resultValue->getType(), 0);

    ASTContext &ctx = gen.getASTContext();
    resultValue =
      gen.B.createBuiltinBinaryFunction(loc,
                                        "cmp_ne",
                                        resultValue->getType(),
                                        SILType::getBuiltinIntegerType(1, ctx),
                                        {resultValue, zero});
  }

  SILBasicBlock *errorBB = gen.createBasicBlock(FunctionSection::Postmatter);
  SILBasicBlock *contBB = gen.createBasicBlock();

  if (zeroIsError)
    gen.B.createCondBranch(loc, resultValue, contBB, errorBB);
  else
    gen.B.createCondBranch(loc, resultValue, errorBB, contBB);

  gen.emitForeignErrorBlock(loc, errorBB, errorSlot);

  gen.B.emitBlock(contBB);
}