//===--- UndelegatedConstructorCheck.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 "UndelegatedConstructorCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/Lex/Lexer.h"

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace bugprone {

namespace {
AST_MATCHER_P(Stmt, ignoringTemporaryExpr,
              ast_matchers::internal::Matcher<Stmt>, InnerMatcher) {
  const Stmt *E = &Node;
  for (;;) {
    // Temporaries with non-trivial dtors.
    if (const auto *EWC = dyn_cast<ExprWithCleanups>(E))
      E = EWC->getSubExpr();
    // Temporaries with zero or more than two ctor arguments.
    else if (const auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
      E = BTE->getSubExpr();
    // Temporaries with exactly one ctor argument.
    else if (const auto *FCE = dyn_cast<CXXFunctionalCastExpr>(E))
      E = FCE->getSubExpr();
    else
      break;
  }

  return InnerMatcher.matches(*E, Finder, Builder);
}

// Finds a node if it's a base of an already bound node.
AST_MATCHER_P(CXXRecordDecl, baseOfBoundNode, std::string, ID) {
  return Builder->removeBindings(
      [&](const ast_matchers::internal::BoundNodesMap &Nodes) {
        const auto *Derived = Nodes.getNodeAs<CXXRecordDecl>(ID);
        return Derived != &Node && !Derived->isDerivedFrom(&Node);
      });
}
} // namespace

void UndelegatedConstructorCheck::registerMatchers(MatchFinder *Finder) {
  // We look for calls to constructors of the same type in constructors. To do
  // this we have to look through a variety of nodes that occur in the path,
  // depending on the type's destructor and the number of arguments on the
  // constructor call, this is handled by ignoringTemporaryExpr. Ignore template
  // instantiations to reduce the number of duplicated warnings.
  //
  // Only register the matchers for C++11; the functionality currently does not
  // provide any benefit to other languages, despite being benign.
  if (!getLangOpts().CPlusPlus11)
    return;

  Finder->addMatcher(
      compoundStmt(
          hasParent(
              cxxConstructorDecl(ofClass(cxxRecordDecl().bind("parent")))),
          forEach(ignoringTemporaryExpr(
              cxxConstructExpr(hasDeclaration(cxxConstructorDecl(ofClass(
                                   cxxRecordDecl(baseOfBoundNode("parent"))))))
                  .bind("construct"))),
          unless(isInTemplateInstantiation())),
      this);
}

void UndelegatedConstructorCheck::check(
    const MatchFinder::MatchResult &Result) {
  const auto *E = Result.Nodes.getNodeAs<CXXConstructExpr>("construct");
  diag(E->getBeginLoc(), "did you intend to call a delegated constructor? "
                         "A temporary object is created here instead");
}

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