clang-tools 10.0.0

UseUncaughtExceptionsCheck.cpp
Go to the documentation of this file.
1 //===--- UseUncaughtExceptionsCheck.cpp - clang-tidy--------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "UseUncaughtExceptionsCheck.h"
10 #include "clang/AST/ASTContext.h"
11 #include "clang/ASTMatchers/ASTMatchFinder.h"
12
13 using namespace clang::ast_matchers;
14
15 namespace clang {
16 namespace tidy {
17 namespace modernize {
18
19 void UseUncaughtExceptionsCheck::registerMatchers(MatchFinder *Finder) {
20 if (!getLangOpts().CPlusPlus17)
21 return;
22
23 std::string MatchText = "::std::uncaught_exception";
24
25 // Using declaration: warning and fix-it.
26 Finder->addMatcher(
27 usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(hasName(MatchText))))
28 .bind("using_decl"),
29 this);
30
31 // DeclRefExpr: warning, no fix-it.
32 Finder->addMatcher(
33 declRefExpr(to(functionDecl(hasName(MatchText))), unless(callExpr()))
34 .bind("decl_ref_expr"),
35 this);
36
37 // CallExpr: warning, fix-it.
38 Finder->addMatcher(callExpr(hasDeclaration(functionDecl(hasName(MatchText))),
39 unless(hasAncestor(initListExpr())))
40 .bind("call_expr"),
41 this);
42 // CallExpr in initialisation list: warning, fix-it with avoiding narrowing
43 // conversions.
44 Finder->addMatcher(callExpr(hasAncestor(initListExpr()),
45 hasDeclaration(functionDecl(hasName(MatchText))))
46 .bind("init_call_expr"),
47 this);
48 }
49
50 void UseUncaughtExceptionsCheck::check(const MatchFinder::MatchResult &Result) {
51 SourceLocation BeginLoc;
52 SourceLocation EndLoc;
53 const CallExpr *C = Result.Nodes.getNodeAs<CallExpr>("init_call_expr");
54 bool WarnOnly = false;
55
56 if (C) {
57 BeginLoc = C->getBeginLoc();
58 EndLoc = C->getEndLoc();
59 } else if (const auto *E = Result.Nodes.getNodeAs<CallExpr>("call_expr")) {
60 BeginLoc = E->getBeginLoc();
61 EndLoc = E->getEndLoc();
62 } else if (const auto *D =
63 Result.Nodes.getNodeAs<DeclRefExpr>("decl_ref_expr")) {
64 BeginLoc = D->getBeginLoc();
65 EndLoc = D->getEndLoc();
66 WarnOnly = true;
67 } else {
68 const auto *U = Result.Nodes.getNodeAs<UsingDecl>("using_decl");
69 assert(U && "Null pointer, no node provided");
70 BeginLoc = U->getNameInfo().getBeginLoc();
71 EndLoc = U->getNameInfo().getEndLoc();
72 }
73
74 auto Diag = diag(BeginLoc, "'std::uncaught_exception' is deprecated, use "
75 "'std::uncaught_exceptions' instead");
76
77 if (!BeginLoc.isMacroID()) {
78 StringRef Text =
79 Lexer::getSourceText(CharSourceRange::getTokenRange(BeginLoc, EndLoc),
80 *Result.SourceManager, getLangOpts());
81
82 Text.consume_back("()");
83 int TextLength = Text.size();
84
85 if (WarnOnly) {
86 return;
87 }
88
89 if (!C) {
90 Diag << FixItHint::CreateInsertion(BeginLoc.getLocWithOffset(TextLength),
91 "s");
92 } else {
93 Diag << FixItHint::CreateReplacement(C->getSourceRange(),
94 "std::uncaught_exceptions() > 0");
95 }
96 }
97 }
98
99 } // namespace modernize
100 } // namespace tidy
101 } // namespace clang
clang::ast_matchers
Definition: AbseilMatcher.h:14
UseUncaughtExceptionsCheck.h
Text
std::string Text
Definition: HTMLGenerator.cpp:80
clang::clangd::getTokenRange
llvm::Optional< Range > getTokenRange(const SourceManager &SM, const LangOptions &LangOpts, SourceLocation TokLoc)
Returns the taken range at TokLoc.
Definition: SourceCode.cpp:227
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
E
const Expr * E
Definition: AvoidBindCheck.cpp:82