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

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace bugprone {

namespace {
// Check if the given type is related to std::enable_if.
AST_MATCHER(QualType, isEnableIf) {
  auto CheckTemplate = [](const TemplateSpecializationType *Spec) {
    if (!Spec || !Spec->getTemplateName().getAsTemplateDecl()) {
      return false;
    }
    const NamedDecl *TypeDecl =
        Spec->getTemplateName().getAsTemplateDecl()->getTemplatedDecl();
    return TypeDecl->isInStdNamespace() &&
           (TypeDecl->getName().equals("enable_if") ||
            TypeDecl->getName().equals("enable_if_t"));
  };
  const Type *BaseType = Node.getTypePtr();
  // Case: pointer or reference to enable_if.
  while (BaseType->isPointerType() || BaseType->isReferenceType()) {
    BaseType = BaseType->getPointeeType().getTypePtr();
  }
  // Case: type parameter dependent (enable_if<is_integral<T>>).
  if (const auto *Dependent = BaseType->getAs<DependentNameType>()) {
    BaseType = Dependent->getQualifier()->getAsType();
  }
  if (!BaseType)
    return false;
  if (CheckTemplate(BaseType->getAs<TemplateSpecializationType>())) {
    return true; // Case: enable_if_t< >.
  } else if (const auto *Elaborated = BaseType->getAs<ElaboratedType>()) {
    if (const auto *Qualifier = Elaborated->getQualifier()->getAsType()) {
      if (CheckTemplate(Qualifier->getAs<TemplateSpecializationType>())) {
        return true; // Case: enable_if< >::type.
      }
    }
  }
  return false;
}
AST_MATCHER_P(TemplateTypeParmDecl, hasDefaultArgument,
              clang::ast_matchers::internal::Matcher<QualType>, TypeMatcher) {
  return Node.hasDefaultArgument() &&
         TypeMatcher.matches(Node.getDefaultArgument(), Finder, Builder);
}
} // namespace

void ForwardingReferenceOverloadCheck::registerMatchers(MatchFinder *Finder) {
  // Forwarding references require C++11 or later.
  if (!getLangOpts().CPlusPlus11)
    return;

  auto ForwardingRefParm =
      parmVarDecl(
          hasType(qualType(rValueReferenceType(),
                           references(templateTypeParmType(hasDeclaration(
                               templateTypeParmDecl().bind("type-parm-decl")))),
                           unless(references(isConstQualified())))))
          .bind("parm-var");

  DeclarationMatcher findOverload =
      cxxConstructorDecl(
          hasParameter(0, ForwardingRefParm),
          unless(hasAnyParameter(
              // No warning: enable_if as constructor parameter.
              parmVarDecl(hasType(isEnableIf())))),
          unless(hasParent(functionTemplateDecl(has(templateTypeParmDecl(
              // No warning: enable_if as type parameter.
              hasDefaultArgument(isEnableIf())))))))
          .bind("ctor");
  Finder->addMatcher(findOverload, this);
}

void ForwardingReferenceOverloadCheck::check(
    const MatchFinder::MatchResult &Result) {
  const auto *ParmVar = Result.Nodes.getNodeAs<ParmVarDecl>("parm-var");
  const auto *TypeParmDecl =
      Result.Nodes.getNodeAs<TemplateTypeParmDecl>("type-parm-decl");

  // Get the FunctionDecl and FunctionTemplateDecl containing the function
  // parameter.
  const auto *FuncForParam = dyn_cast<FunctionDecl>(ParmVar->getDeclContext());
  if (!FuncForParam)
    return;
  const FunctionTemplateDecl *FuncTemplate =
      FuncForParam->getDescribedFunctionTemplate();
  if (!FuncTemplate)
    return;

  // Check that the template type parameter belongs to the same function
  // template as the function parameter of that type. (This implies that type
  // deduction will happen on the type.)
  const TemplateParameterList *Params = FuncTemplate->getTemplateParameters();
  if (!llvm::is_contained(*Params, TypeParmDecl))
    return;

  // Every parameter after the first must have a default value.
  const auto *Ctor = Result.Nodes.getNodeAs<CXXConstructorDecl>("ctor");
  for (auto Iter = Ctor->param_begin() + 1; Iter != Ctor->param_end(); ++Iter) {
    if (!(*Iter)->hasDefaultArg())
      return;
  }
  bool EnabledCopy = false, DisabledCopy = false, EnabledMove = false,
       DisabledMove = false;
  for (const auto *OtherCtor : Ctor->getParent()->ctors()) {
    if (OtherCtor->isCopyOrMoveConstructor()) {
      if (OtherCtor->isDeleted() || OtherCtor->getAccess() == AS_private)
        (OtherCtor->isCopyConstructor() ? DisabledCopy : DisabledMove) = true;
      else
        (OtherCtor->isCopyConstructor() ? EnabledCopy : EnabledMove) = true;
    }
  }
  bool Copy = (!EnabledMove && !DisabledMove && !DisabledCopy) || EnabledCopy;
  bool Move = !DisabledMove || EnabledMove;
  if (!Copy && !Move)
    return;
  diag(Ctor->getLocation(),
       "constructor accepting a forwarding reference can "
       "hide the %select{copy|move|copy and move}0 constructor%s1")
      << (Copy && Move ? 2 : (Copy ? 0 : 1)) << Copy + Move;
  for (const auto *OtherCtor : Ctor->getParent()->ctors()) {
    if (OtherCtor->isCopyOrMoveConstructor() && !OtherCtor->isDeleted() &&
        OtherCtor->getAccess() != AS_private) {
      diag(OtherCtor->getLocation(),
           "%select{copy|move}0 constructor declared here", DiagnosticIDs::Note)
          << OtherCtor->isMoveConstructor();
    }
  }
}

} // namespace bugprone
} // namespace tidy
} // namespace clang
