//===--- UseNodiscardCheck.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 "UseNodiscardCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"

using namespace clang::ast_matchers;

namespace clang::tidy::modernize {

static bool doesNoDiscardMacroExist(ASTContext &Context,
                                    const llvm::StringRef &MacroId) {
  // Don't check for the Macro existence if we are using an attribute
  // either a C++17 standard attribute or pre C++17 syntax
  if (MacroId.starts_with("[[") || MacroId.starts_with("__attribute__"))
    return true;

  // Otherwise look up the macro name in the context to see if its defined.
  return Context.Idents.get(MacroId).hasMacroDefinition();
}

namespace {
AST_MATCHER(CXXMethodDecl, isOverloadedOperator) {
  // Don't put ``[[nodiscard]]`` in front of operators.
  return Node.isOverloadedOperator();
}
AST_MATCHER(CXXMethodDecl, isConversionOperator) {
  // Don't put ``[[nodiscard]]`` in front of a conversion decl
  // like operator bool().
  return isa<CXXConversionDecl>(Node);
}
AST_MATCHER(CXXMethodDecl, hasClassMutableFields) {
  // Don't put ``[[nodiscard]]`` on functions on classes with
  // mutable member variables.
  return Node.getParent()->hasMutableFields();
}
AST_MATCHER(ParmVarDecl, hasParameterPack) {
  // Don't put ``[[nodiscard]]`` on functions with parameter pack arguments.
  return Node.isParameterPack();
}
AST_MATCHER(CXXMethodDecl, hasTemplateReturnType) {
  // Don't put ``[[nodiscard]]`` in front of functions returning a template
  // type.
  return Node.getReturnType()->isTemplateTypeParmType() ||
         Node.getReturnType()->isInstantiationDependentType();
}
AST_MATCHER(CXXMethodDecl, isDefinitionOrInline) {
  // A function definition, with optional inline but not the declaration.
  return !(Node.isThisDeclarationADefinition() && Node.isOutOfLine());
}
AST_MATCHER(QualType, isInstantiationDependentType) {
  return Node->isInstantiationDependentType();
}
AST_MATCHER(QualType, isNonConstReferenceOrPointer) {
  // If the function has any non-const-reference arguments
  //    bool foo(A &a)
  // or pointer arguments
  //    bool foo(A*)
  // then they may not care about the return value because of passing data
  // via the arguments.
  return (Node->isTemplateTypeParmType() || Node->isPointerType() ||
          (Node->isReferenceType() &&
           !Node.getNonReferenceType().isConstQualified()) ||
          Node->isInstantiationDependentType());
}
} // namespace

UseNodiscardCheck::UseNodiscardCheck(StringRef Name, ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      NoDiscardMacro(Options.get("ReplacementString", "[[nodiscard]]")) {}

void UseNodiscardCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "ReplacementString", NoDiscardMacro);
}

void UseNodiscardCheck::registerMatchers(MatchFinder *Finder) {
  auto FunctionObj =
      cxxRecordDecl(hasAnyName("::std::function", "::boost::function"));

  // Find all non-void const methods which have not already been marked to
  // warn on unused result.
  Finder->addMatcher(
      cxxMethodDecl(
          isConst(), isDefinitionOrInline(),
          unless(anyOf(
              returns(voidType()),
              returns(
                  hasDeclaration(decl(hasAttr(clang::attr::WarnUnusedResult)))),
              isNoReturn(), isOverloadedOperator(), isVariadic(),
              hasTemplateReturnType(), hasClassMutableFields(),
              isConversionOperator(), hasAttr(clang::attr::WarnUnusedResult),
              hasType(isInstantiationDependentType()),
              hasAnyParameter(
                  anyOf(parmVarDecl(anyOf(hasType(FunctionObj),
                                          hasType(references(FunctionObj)))),
                        hasType(isNonConstReferenceOrPointer()),
                        hasParameterPack())))))
          .bind("no_discard"),
      this);
}

void UseNodiscardCheck::check(const MatchFinder::MatchResult &Result) {
  const auto *MatchedDecl = Result.Nodes.getNodeAs<CXXMethodDecl>("no_discard");
  // Don't make replacements if the location is invalid or in a macro.
  SourceLocation Loc = MatchedDecl->getLocation();
  if (Loc.isInvalid() || Loc.isMacroID())
    return;

  SourceLocation RetLoc = MatchedDecl->getInnerLocStart();

  ASTContext &Context = *Result.Context;

  auto Diag = diag(RetLoc, "function %0 should be marked %1")
              << MatchedDecl << NoDiscardMacro;

  // Check for the existence of the keyword being used as the ``[[nodiscard]]``.
  if (!doesNoDiscardMacroExist(Context, NoDiscardMacro))
    return;

  // Possible false positives include:
  // 1. A const member function which returns a variable which is ignored
  // but performs some external I/O operation and the return value could be
  // ignored.
  Diag << FixItHint::CreateInsertion(RetLoc, (NoDiscardMacro + " ").str());
}

bool UseNodiscardCheck::isLanguageVersionSupported(
    const LangOptions &LangOpts) const {
  // If we use ``[[nodiscard]]`` attribute, we require at least C++17. Use a
  // macro or ``__attribute__`` with pre c++17 compilers by using
  // ReplacementString option.

  if (NoDiscardMacro == "[[nodiscard]]")
    return LangOpts.CPlusPlus17;

  return LangOpts.CPlusPlus;
}

} // namespace clang::tidy::modernize
