//===--- UseDefaultMemberInitCheck.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 "UseDefaultMemberInitCheck.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 modernize {

static StringRef getValueOfValueInit(const QualType InitType) {
  switch (InitType->getScalarTypeKind()) {
  case Type::STK_CPointer:
  case Type::STK_BlockPointer:
  case Type::STK_ObjCObjectPointer:
  case Type::STK_MemberPointer:
    return "nullptr";

  case Type::STK_Bool:
    return "false";

  case Type::STK_Integral:
    switch (InitType->castAs<BuiltinType>()->getKind()) {
    case BuiltinType::Char_U:
    case BuiltinType::UChar:
    case BuiltinType::Char_S:
    case BuiltinType::SChar:
      return "'\\0'";
    case BuiltinType::WChar_U:
    case BuiltinType::WChar_S:
      return "L'\\0'";
    case BuiltinType::Char16:
      return "u'\\0'";
    case BuiltinType::Char32:
      return "U'\\0'";
    default:
      return "0";
    }

  case Type::STK_Floating:
    switch (InitType->castAs<BuiltinType>()->getKind()) {
    case BuiltinType::Half:
    case BuiltinType::Float:
      return "0.0f";
    default:
      return "0.0";
    }

  case Type::STK_FloatingComplex:
  case Type::STK_IntegralComplex:
    return getValueOfValueInit(
        InitType->castAs<ComplexType>()->getElementType());

  case Type::STK_FixedPoint:
    switch (InitType->castAs<BuiltinType>()->getKind()) {
    case BuiltinType::ShortAccum:
    case BuiltinType::SatShortAccum:
      return "0.0hk";
    case BuiltinType::Accum:
    case BuiltinType::SatAccum:
      return "0.0k";
    case BuiltinType::LongAccum:
    case BuiltinType::SatLongAccum:
      return "0.0lk";
    case BuiltinType::UShortAccum:
    case BuiltinType::SatUShortAccum:
      return "0.0uhk";
    case BuiltinType::UAccum:
    case BuiltinType::SatUAccum:
      return "0.0uk";
    case BuiltinType::ULongAccum:
    case BuiltinType::SatULongAccum:
      return "0.0ulk";
    case BuiltinType::ShortFract:
    case BuiltinType::SatShortFract:
      return "0.0hr";
    case BuiltinType::Fract:
    case BuiltinType::SatFract:
      return "0.0r";
    case BuiltinType::LongFract:
    case BuiltinType::SatLongFract:
      return "0.0lr";
    case BuiltinType::UShortFract:
    case BuiltinType::SatUShortFract:
      return "0.0uhr";
    case BuiltinType::UFract:
    case BuiltinType::SatUFract:
      return "0.0ur";
    case BuiltinType::ULongFract:
    case BuiltinType::SatULongFract:
      return "0.0ulr";
    default:
      llvm_unreachable("Unhandled fixed point BuiltinType");
    }
  }
  llvm_unreachable("Invalid scalar type kind");
}

static bool isZero(const Expr *E) {
  switch (E->getStmtClass()) {
  case Stmt::CXXNullPtrLiteralExprClass:
  case Stmt::ImplicitValueInitExprClass:
    return true;
  case Stmt::InitListExprClass:
    return cast<InitListExpr>(E)->getNumInits() == 0;
  case Stmt::CharacterLiteralClass:
    return !cast<CharacterLiteral>(E)->getValue();
  case Stmt::CXXBoolLiteralExprClass:
    return !cast<CXXBoolLiteralExpr>(E)->getValue();
  case Stmt::IntegerLiteralClass:
    return !cast<IntegerLiteral>(E)->getValue();
  case Stmt::FloatingLiteralClass: {
    llvm::APFloat Value = cast<FloatingLiteral>(E)->getValue();
    return Value.isZero() && !Value.isNegative();
  }
  default:
    return false;
  }
}

static const Expr *ignoreUnaryPlus(const Expr *E) {
  auto *UnaryOp = dyn_cast<UnaryOperator>(E);
  if (UnaryOp && UnaryOp->getOpcode() == UO_Plus)
    return UnaryOp->getSubExpr();
  return E;
}

static const Expr *getInitializer(const Expr *E) {
  auto *InitList = dyn_cast<InitListExpr>(E);
  if (InitList && InitList->getNumInits() == 1)
    return InitList->getInit(0);
  return E;
}

static bool sameValue(const Expr *E1, const Expr *E2) {
  E1 = ignoreUnaryPlus(getInitializer(E1->IgnoreParenImpCasts()));
  E2 = ignoreUnaryPlus(getInitializer(E2->IgnoreParenImpCasts()));

  if (isZero(E1) && isZero(E2))
    return true;

  if (E1->getStmtClass() != E2->getStmtClass())
    return false;

  switch (E1->getStmtClass()) {
  case Stmt::UnaryOperatorClass:
    return sameValue(cast<UnaryOperator>(E1)->getSubExpr(),
                     cast<UnaryOperator>(E2)->getSubExpr());
  case Stmt::CharacterLiteralClass:
    return cast<CharacterLiteral>(E1)->getValue() ==
           cast<CharacterLiteral>(E2)->getValue();
  case Stmt::CXXBoolLiteralExprClass:
    return cast<CXXBoolLiteralExpr>(E1)->getValue() ==
           cast<CXXBoolLiteralExpr>(E2)->getValue();
  case Stmt::IntegerLiteralClass:
    return cast<IntegerLiteral>(E1)->getValue() ==
           cast<IntegerLiteral>(E2)->getValue();
  case Stmt::FloatingLiteralClass:
    return cast<FloatingLiteral>(E1)->getValue().bitwiseIsEqual(
        cast<FloatingLiteral>(E2)->getValue());
  case Stmt::StringLiteralClass:
    return cast<StringLiteral>(E1)->getString() ==
           cast<StringLiteral>(E2)->getString();
  case Stmt::DeclRefExprClass:
    return cast<DeclRefExpr>(E1)->getDecl() == cast<DeclRefExpr>(E2)->getDecl();
  default:
    return false;
  }
}

UseDefaultMemberInitCheck::UseDefaultMemberInitCheck(StringRef Name,
                                                     ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      UseAssignment(Options.get("UseAssignment", 0) != 0),
      IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true) != 0) {}

void UseDefaultMemberInitCheck::storeOptions(
    ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "UseAssignment", UseAssignment);
  Options.store(Opts, "IgnoreMacros", IgnoreMacros);
}

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

  auto Init =
      anyOf(stringLiteral(), characterLiteral(), integerLiteral(),
            unaryOperator(anyOf(hasOperatorName("+"), hasOperatorName("-")),
                          hasUnaryOperand(integerLiteral())),
            floatLiteral(),
            unaryOperator(anyOf(hasOperatorName("+"), hasOperatorName("-")),
                          hasUnaryOperand(floatLiteral())),
            cxxBoolLiteral(), cxxNullPtrLiteralExpr(), implicitValueInitExpr(),
            declRefExpr(to(enumConstantDecl())));

  Finder->addMatcher(
      cxxConstructorDecl(
          isDefaultConstructor(), unless(isInstantiated()),
          forEachConstructorInitializer(
              cxxCtorInitializer(
                  forField(unless(anyOf(getLangOpts().CPlusPlus2a
                                            ? unless(anything())
                                            : isBitField(),
                                        hasInClassInitializer(anything()),
                                        hasParent(recordDecl(isUnion()))))),
                  isWritten(), withInitializer(ignoringImplicit(Init)))
                  .bind("default"))),
      this);

  Finder->addMatcher(
      cxxConstructorDecl(
          unless(ast_matchers::isTemplateInstantiation()),
          forEachConstructorInitializer(
              cxxCtorInitializer(forField(hasInClassInitializer(anything())),
                                 isWritten(),
                                 withInitializer(ignoringImplicit(Init)))
                  .bind("existing"))),
      this);
}

void UseDefaultMemberInitCheck::check(const MatchFinder::MatchResult &Result) {
  if (const auto *Default =
          Result.Nodes.getNodeAs<CXXCtorInitializer>("default"))
    checkDefaultInit(Result, Default);
  else if (const auto *Existing =
               Result.Nodes.getNodeAs<CXXCtorInitializer>("existing"))
    checkExistingInit(Result, Existing);
  else
    llvm_unreachable("Bad Callback. No node provided.");
}

void UseDefaultMemberInitCheck::checkDefaultInit(
    const MatchFinder::MatchResult &Result, const CXXCtorInitializer *Init) {
  const FieldDecl *Field = Init->getAnyMember();

  SourceLocation StartLoc = Field->getBeginLoc();
  if (StartLoc.isMacroID() && IgnoreMacros)
    return;

  SourceLocation FieldEnd =
      Lexer::getLocForEndOfToken(Field->getSourceRange().getEnd(), 0,
                                 *Result.SourceManager, getLangOpts());
  SourceLocation LParenEnd = Lexer::getLocForEndOfToken(
      Init->getLParenLoc(), 0, *Result.SourceManager, getLangOpts());
  CharSourceRange InitRange =
      CharSourceRange::getCharRange(LParenEnd, Init->getRParenLoc());

  bool ValueInit = isa<ImplicitValueInitExpr>(Init->getInit());
  bool CanAssign = UseAssignment && (!ValueInit || !Init->getInit()->getType()->isEnumeralType());

  auto Diag =
      diag(Field->getLocation(), "use default member initializer for %0")
      << Field
      << FixItHint::CreateInsertion(FieldEnd, CanAssign ? " = " : "{")
      << FixItHint::CreateInsertionFromRange(FieldEnd, InitRange);

  if (CanAssign && ValueInit)
    Diag << FixItHint::CreateInsertion(
        FieldEnd, getValueOfValueInit(Init->getInit()->getType()));

  if (!CanAssign)
    Diag << FixItHint::CreateInsertion(FieldEnd, "}");

  Diag << FixItHint::CreateRemoval(Init->getSourceRange());
}

void UseDefaultMemberInitCheck::checkExistingInit(
    const MatchFinder::MatchResult &Result, const CXXCtorInitializer *Init) {
  const FieldDecl *Field = Init->getAnyMember();

  if (!sameValue(Field->getInClassInitializer(), Init->getInit()))
    return;

  diag(Init->getSourceLocation(), "member initializer for %0 is redundant")
      << Field
      << FixItHint::CreateRemoval(Init->getSourceRange());
}

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