brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.3 KiB · 08c40d4 Raw
98 lines · cpp
1//===----------------------------------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "UseUncaughtExceptionsCheck.h"10#include "clang/ASTMatchers/ASTMatchFinder.h"11#include "clang/Lex/Lexer.h"12 13using namespace clang::ast_matchers;14 15namespace clang::tidy::modernize {16 17void UseUncaughtExceptionsCheck::registerMatchers(MatchFinder *Finder) {18  const std::string MatchText = "::std::uncaught_exception";19 20  // Using declaration: warning and fix-it.21  Finder->addMatcher(22      usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(hasName(MatchText))))23          .bind("using_decl"),24      this);25 26  // DeclRefExpr: warning, no fix-it.27  Finder->addMatcher(28      declRefExpr(to(functionDecl(hasName(MatchText))), unless(callExpr()))29          .bind("decl_ref_expr"),30      this);31 32  auto DirectCallToUncaughtException = callee(expr(ignoringImpCasts(33      declRefExpr(hasDeclaration(functionDecl(hasName(MatchText)))))));34 35  // CallExpr: warning, fix-it.36  Finder->addMatcher(callExpr(DirectCallToUncaughtException,37                              unless(hasAncestor(initListExpr())))38                         .bind("call_expr"),39                     this);40  // CallExpr in initialisation list: warning, fix-it with avoiding narrowing41  // conversions.42  Finder->addMatcher(43      callExpr(DirectCallToUncaughtException, hasAncestor(initListExpr()))44          .bind("init_call_expr"),45      this);46}47 48void UseUncaughtExceptionsCheck::check(const MatchFinder::MatchResult &Result) {49  SourceLocation BeginLoc;50  SourceLocation EndLoc;51  const auto *C = Result.Nodes.getNodeAs<CallExpr>("init_call_expr");52  bool WarnOnly = false;53 54  if (C) {55    BeginLoc = C->getBeginLoc();56    EndLoc = C->getEndLoc();57  } else if (const auto *E = Result.Nodes.getNodeAs<CallExpr>("call_expr")) {58    BeginLoc = E->getBeginLoc();59    EndLoc = E->getEndLoc();60  } else if (const auto *D =61                 Result.Nodes.getNodeAs<DeclRefExpr>("decl_ref_expr")) {62    BeginLoc = D->getBeginLoc();63    EndLoc = D->getEndLoc();64    WarnOnly = true;65  } else {66    const auto *U = Result.Nodes.getNodeAs<UsingDecl>("using_decl");67    assert(U && "Null pointer, no node provided");68    BeginLoc = U->getNameInfo().getBeginLoc();69    EndLoc = U->getNameInfo().getEndLoc();70  }71 72  auto Diag = diag(BeginLoc, "'std::uncaught_exception' is deprecated, use "73                             "'std::uncaught_exceptions' instead");74 75  if (!BeginLoc.isMacroID()) {76    StringRef Text =77        Lexer::getSourceText(CharSourceRange::getTokenRange(BeginLoc, EndLoc),78                             *Result.SourceManager, getLangOpts());79 80    Text.consume_back("()");81    const int TextLength = Text.size();82 83    if (WarnOnly) {84      return;85    }86 87    if (!C) {88      Diag << FixItHint::CreateInsertion(BeginLoc.getLocWithOffset(TextLength),89                                         "s");90    } else {91      Diag << FixItHint::CreateReplacement(C->getSourceRange(),92                                           "std::uncaught_exceptions() > 0");93    }94  }95}96 97} // namespace clang::tidy::modernize98