clang-tools  7.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 
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(declRefExpr(allOf(to(functionDecl(hasName(MatchText))),
34  unless(callExpr())))
35  .bind("decl_ref_expr"),
36  this);
37 
38  // CallExpr: warning, fix-it.
39  Finder->addMatcher(
40  callExpr(allOf(hasDeclaration(functionDecl(hasName(MatchText))),
41  unless(hasAncestor(initListExpr()))))
42  .bind("call_expr"),
43  this);
44  // CallExpr in initialisation list: warning, fix-it with avoiding narrowing
45  // conversions.
46  Finder->addMatcher(
47  callExpr(allOf(hasAncestor(initListExpr()),
48  hasDeclaration(functionDecl(hasName(MatchText)))))
49  .bind("init_call_expr"),
50  this);
51 }
52 
53 void UseUncaughtExceptionsCheck::check(const MatchFinder::MatchResult &Result) {
54  SourceLocation BeginLoc;
55  SourceLocation EndLoc;
56  const CallExpr *C = Result.Nodes.getNodeAs<CallExpr>("init_call_expr");
57  bool WarnOnly = false;
58 
59  if (C) {
60  BeginLoc = C->getLocStart();
61  EndLoc = C->getLocEnd();
62  } else if (const auto *E = Result.Nodes.getNodeAs<CallExpr>("call_expr")) {
63  BeginLoc = E->getLocStart();
64  EndLoc = E->getLocEnd();
65  } else if (const auto *D =
66  Result.Nodes.getNodeAs<DeclRefExpr>("decl_ref_expr")) {
67  BeginLoc = D->getLocStart();
68  EndLoc = D->getLocEnd();
69  WarnOnly = true;
70  } else {
71  const auto *U = Result.Nodes.getNodeAs<UsingDecl>("using_decl");
72  assert(U && "Null pointer, no node provided");
73  BeginLoc = U->getNameInfo().getBeginLoc();
74  EndLoc = U->getNameInfo().getEndLoc();
75  }
76 
77  auto Diag = diag(BeginLoc, "'std::uncaught_exception' is deprecated, use "
78  "'std::uncaught_exceptions' instead");
79 
80  if (!BeginLoc.isMacroID()) {
81  StringRef Text =
82  Lexer::getSourceText(CharSourceRange::getTokenRange(BeginLoc, EndLoc),
83  *Result.SourceManager, getLangOpts());
84 
85  Text.consume_back("()");
86  int TextLength = Text.size();
87 
88  if (WarnOnly) {
89  return;
90  }
91 
92  if (!C) {
93  Diag << FixItHint::CreateInsertion(BeginLoc.getLocWithOffset(TextLength),
94  "s");
95  } else {
96  Diag << FixItHint::CreateReplacement(C->getSourceRange(),
97  "std::uncaught_exceptions() > 0");
98  }
99  }
100 }
101 
102 } // namespace modernize
103 } // namespace tidy
104 } // namespace clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//