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); } }
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; } } }