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

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace cppcoreguidelines {

static bool needsConstCast(QualType SourceType, QualType DestType) {
  SourceType = SourceType.getNonReferenceType();
  DestType = DestType.getNonReferenceType();
  while (SourceType->isPointerType() && DestType->isPointerType()) {
    SourceType = SourceType->getPointeeType();
    DestType = DestType->getPointeeType();
    if (SourceType.isConstQualified() && !DestType.isConstQualified())
      return true;
  }
  return false;
}

void ProTypeCstyleCastCheck::registerMatchers(MatchFinder *Finder) {
  if (!getLangOpts().CPlusPlus)
    return;

  Finder->addMatcher(
      cStyleCastExpr(unless(isInTemplateInstantiation())).bind("cast"), this);
}

void ProTypeCstyleCastCheck::check(const MatchFinder::MatchResult &Result) {
  const auto *MatchedCast = Result.Nodes.getNodeAs<CStyleCastExpr>("cast");

  if (MatchedCast->getCastKind() == CK_BitCast ||
      MatchedCast->getCastKind() == CK_LValueBitCast ||
      MatchedCast->getCastKind() == CK_IntegralToPointer ||
      MatchedCast->getCastKind() == CK_PointerToIntegral ||
      MatchedCast->getCastKind() == CK_ReinterpretMemberPointer) {
    diag(MatchedCast->getLocStart(),
         "do not use C-style cast to convert between unrelated types");
    return;
  }

  QualType SourceType = MatchedCast->getSubExpr()->getType();

  if (MatchedCast->getCastKind() == CK_BaseToDerived) {
    const auto *SourceDecl = SourceType->getPointeeCXXRecordDecl();
    if (!SourceDecl) // The cast is from object to reference.
      SourceDecl = SourceType->getAsCXXRecordDecl();
    if (!SourceDecl)
      return;

    if (SourceDecl->isPolymorphic()) {
      // Leave type spelling exactly as it was (unlike
      // getTypeAsWritten().getAsString() which would spell enum types 'enum
      // X').
      StringRef DestTypeString = Lexer::getSourceText(
          CharSourceRange::getTokenRange(
              MatchedCast->getLParenLoc().getLocWithOffset(1),
              MatchedCast->getRParenLoc().getLocWithOffset(-1)),
          *Result.SourceManager, getLangOpts());

      auto diag_builder = diag(
          MatchedCast->getLocStart(),
          "do not use C-style cast to downcast from a base to a derived class; "
          "use dynamic_cast instead");

      const Expr *SubExpr =
          MatchedCast->getSubExprAsWritten()->IgnoreImpCasts();
      std::string CastText = ("dynamic_cast<" + DestTypeString + ">").str();
      if (!isa<ParenExpr>(SubExpr)) {
        CastText.push_back('(');
        diag_builder << FixItHint::CreateInsertion(
            Lexer::getLocForEndOfToken(SubExpr->getLocEnd(), 0,
                                       *Result.SourceManager, getLangOpts()),
            ")");
      }
      auto ParenRange = CharSourceRange::getTokenRange(
          MatchedCast->getLParenLoc(), MatchedCast->getRParenLoc());
      diag_builder << FixItHint::CreateReplacement(ParenRange, CastText);
    } else {
      diag(
          MatchedCast->getLocStart(),
          "do not use C-style cast to downcast from a base to a derived class");
    }
    return;
  }

  if (MatchedCast->getCastKind() == CK_NoOp &&
      needsConstCast(SourceType, MatchedCast->getType())) {
    diag(MatchedCast->getLocStart(),
         "do not use C-style cast to cast away constness");
  }
}

} // namespace cppcoreguidelines
} // namespace tidy
} // namespace clang
