//===--- UseNoexceptCheck.cpp - clang-tidy---------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "UseNoexceptCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/Lex/Lexer.h"

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace modernize {

UseNoexceptCheck::UseNoexceptCheck(StringRef Name, ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      NoexceptMacro(Options.get("ReplacementString", "")),
      UseNoexceptFalse(Options.get("UseNoexceptFalse", true)) {}

void UseNoexceptCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "ReplacementString", NoexceptMacro);
  Options.store(Opts, "UseNoexceptFalse", UseNoexceptFalse);
}

void UseNoexceptCheck::registerMatchers(MatchFinder *Finder) {
  if (!getLangOpts().CPlusPlus11)
    return;

  Finder->addMatcher(
      functionDecl(
          cxxMethodDecl(
              hasTypeLoc(loc(functionProtoType(hasDynamicExceptionSpec()))),
              anyOf(hasOverloadedOperatorName("delete[]"),
                    hasOverloadedOperatorName("delete"), cxxDestructorDecl()))
              .bind("del-dtor"))
          .bind("funcDecl"),
      this);

  Finder->addMatcher(
      functionDecl(
          hasTypeLoc(loc(functionProtoType(hasDynamicExceptionSpec()))),
          unless(anyOf(hasOverloadedOperatorName("delete[]"),
                       hasOverloadedOperatorName("delete"),
                       cxxDestructorDecl())))
          .bind("funcDecl"),
      this);

  Finder->addMatcher(
      parmVarDecl(anyOf(hasType(pointerType(pointee(parenType(innerType(
                            functionProtoType(hasDynamicExceptionSpec())))))),
                        hasType(memberPointerType(pointee(parenType(innerType(
                            functionProtoType(hasDynamicExceptionSpec()))))))))
          .bind("parmVarDecl"),
      this);
}

void UseNoexceptCheck::check(const MatchFinder::MatchResult &Result) {
  const FunctionProtoType *FnTy = nullptr;
  bool DtorOrOperatorDel = false;
  SourceRange Range;

  if (const auto *FuncDecl = Result.Nodes.getNodeAs<FunctionDecl>("funcDecl")) {
    DtorOrOperatorDel = Result.Nodes.getNodeAs<FunctionDecl>("del-dtor");
    FnTy = FuncDecl->getType()->getAs<FunctionProtoType>();
    if (const auto *TSI = FuncDecl->getTypeSourceInfo())
      Range =
          TSI->getTypeLoc().castAs<FunctionTypeLoc>().getExceptionSpecRange();
  } else if (const auto *ParmDecl =
                 Result.Nodes.getNodeAs<ParmVarDecl>("parmVarDecl")) {
    FnTy = ParmDecl->getType()
               ->getAs<Type>()
               ->getPointeeType()
               ->getAs<FunctionProtoType>();

    if (const auto *TSI = ParmDecl->getTypeSourceInfo())
      Range = TSI->getTypeLoc()
                  .getNextTypeLoc()
                  .IgnoreParens()
                  .castAs<FunctionProtoTypeLoc>()
                  .getExceptionSpecRange();
  }
  CharSourceRange CRange = Lexer::makeFileCharRange(
      CharSourceRange::getTokenRange(Range), *Result.SourceManager,
      Result.Context->getLangOpts());

  assert(FnTy && "FunctionProtoType is null.");
  bool IsNoThrow = FnTy->isNothrow();
  StringRef ReplacementStr =
      IsNoThrow
          ? NoexceptMacro.empty() ? "noexcept" : NoexceptMacro.c_str()
          : NoexceptMacro.empty()
                ? (DtorOrOperatorDel || UseNoexceptFalse) ? "noexcept(false)"
                                                          : ""
                : "";

  FixItHint FixIt;
  if ((IsNoThrow || NoexceptMacro.empty()) && CRange.isValid())
    FixIt = FixItHint::CreateReplacement(CRange, ReplacementStr);

  diag(Range.getBegin(), "dynamic exception specification '%0' is deprecated; "
                         "consider %select{using '%2'|removing it}1 instead")
      << Lexer::getSourceText(CRange, *Result.SourceManager,
                              Result.Context->getLangOpts())
      << ReplacementStr.empty() << ReplacementStr << FixIt;
}

} // namespace modernize
} // namespace tidy
} // namespace clang
