예제 #1
0
void swift::printSILLocationDescription(llvm::raw_ostream &out,
                                        SILLocation loc,
                                        ASTContext &Context) {
  if (loc.isNull()) {
    out << "<<invalid location>>";
  } else if (!loc.hasASTLocation()) {
    printSourceLocDescription(out, loc.getSourceLoc(), Context);
  } else if (auto decl = loc.getAsASTNode<Decl>()) {
    printDeclDescription(out, decl, Context);
  } else if (auto expr = loc.getAsASTNode<Expr>()) {
    printExprDescription(out, expr, Context);
  } else if (auto stmt = loc.getAsASTNode<Stmt>()) {
    printStmtDescription(out, stmt, Context);
  } else {
    auto pattern = loc.castToASTNode<Pattern>();
    printPatternDescription(out, pattern, Context);
  }
}
예제 #2
0
static void diagnoseUnreachable(const SILInstruction *I,
                                ASTContext &Context) {
  if (auto *UI = dyn_cast<UnreachableInst>(I)){
    SILLocation L = UI->getLoc();

    // Invalid location means that the instruction has been generated by SIL
    // passes, such as DCE. FIXME: we might want to just introduce a separate
    // instruction kind, instead of keeping this invariant.
    //
    // We also do not want to emit diagnostics for code that was
    // transparently inlined. We should have already emitted these
    // diagnostics when we process the callee function prior to
    // inlining it.
    if (!L.hasASTLocation() || L.is<MandatoryInlinedLocation>())
      return;

    // The most common case of getting an unreachable instruction is a
    // missing return statement. In this case, we know that the instruction
    // location will be the enclosing function.
    if (L.isASTNode<AbstractFunctionDecl>() || L.isASTNode<ClosureExpr>()) {
      diagnoseMissingReturn(UI, Context);
      return;
    }

    // A non-exhaustive switch would also produce an unreachable instruction.
    if (L.isASTNode<SwitchStmt>()) {
      diagnose(Context, L.getEndSourceLoc(), diag::non_exhaustive_switch);
      return;
    }

    if (auto *Guard = L.getAsASTNode<GuardStmt>()) {
      diagnose(Context, Guard->getBody()->getEndLoc(),
               diag::guard_body_must_not_fallthrough);
      return;
    }
  }
}