//===--- UseUncaughtExceptionsCheck.cpp - clang-tidy--------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "UseUncaughtExceptionsCheck.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/Lexer.h"

using namespace clang::ast_matchers;

namespace clang::tidy::modernize {

void UseUncaughtExceptionsCheck::registerMatchers(MatchFinder *Finder) {
  std::string MatchText = "::std::uncaught_exception";

  // Using declaration: warning and fix-it.
  Finder->addMatcher(
      usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(hasName(MatchText))))
          .bind("using_decl"),
      this);

  // DeclRefExpr: warning, no fix-it.
  Finder->addMatcher(
      declRefExpr(to(functionDecl(hasName(MatchText))), unless(callExpr()))
          .bind("decl_ref_expr"),
      this);

  auto DirectCallToUncaughtException = callee(expr(ignoringImpCasts(
      declRefExpr(hasDeclaration(functionDecl(hasName(MatchText)))))));

  // CallExpr: warning, fix-it.
  Finder->addMatcher(callExpr(DirectCallToUncaughtException,
                              unless(hasAncestor(initListExpr())))
                         .bind("call_expr"),
                     this);
  // CallExpr in initialisation list: warning, fix-it with avoiding narrowing
  // conversions.
  Finder->addMatcher(
      callExpr(DirectCallToUncaughtException, hasAncestor(initListExpr()))
          .bind("init_call_expr"),
      this);
}

void UseUncaughtExceptionsCheck::check(const MatchFinder::MatchResult &Result) {
  SourceLocation BeginLoc;
  SourceLocation EndLoc;
  const auto *C = Result.Nodes.getNodeAs<CallExpr>("init_call_expr");
  bool WarnOnly = false;

  if (C) {
    BeginLoc = C->getBeginLoc();
    EndLoc = C->getEndLoc();
  } else if (const auto *E = Result.Nodes.getNodeAs<CallExpr>("call_expr")) {
    BeginLoc = E->getBeginLoc();
    EndLoc = E->getEndLoc();
  } else if (const auto *D =
                 Result.Nodes.getNodeAs<DeclRefExpr>("decl_ref_expr")) {
    BeginLoc = D->getBeginLoc();
    EndLoc = D->getEndLoc();
    WarnOnly = true;
  } else {
    const auto *U = Result.Nodes.getNodeAs<UsingDecl>("using_decl");
    assert(U && "Null pointer, no node provided");
    BeginLoc = U->getNameInfo().getBeginLoc();
    EndLoc = U->getNameInfo().getEndLoc();
  }

  auto Diag = diag(BeginLoc, "'std::uncaught_exception' is deprecated, use "
                             "'std::uncaught_exceptions' instead");

  if (!BeginLoc.isMacroID()) {
    StringRef Text =
        Lexer::getSourceText(CharSourceRange::getTokenRange(BeginLoc, EndLoc),
                             *Result.SourceManager, getLangOpts());

    Text.consume_back("()");
    int TextLength = Text.size();

    if (WarnOnly) {
      return;
    }

    if (!C) {
      Diag << FixItHint::CreateInsertion(BeginLoc.getLocWithOffset(TextLength),
                                         "s");
    } else {
      Diag << FixItHint::CreateReplacement(C->getSourceRange(),
                                           "std::uncaught_exceptions() > 0");
    }
  }
}

} // namespace clang::tidy::modernize
