clang-tools 8.0.0

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