//===--- ProTypeMemberInitCheck.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 "ProTypeMemberInitCheck.h"
#include "../utils/LexerUtils.h"
#include "../utils/Matchers.h"
#include "../utils/TypeTraits.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/SmallPtrSet.h"

using namespace clang::ast_matchers;
using namespace clang::tidy::matchers;
using llvm::SmallPtrSet;
using llvm::SmallPtrSetImpl;

namespace clang {
namespace tidy {
namespace cppcoreguidelines {

namespace {

AST_MATCHER(CXXRecordDecl, hasDefaultConstructor) {
  return Node.hasDefaultConstructor();
}

// Iterate over all the fields in a record type, both direct and indirect (e.g.
// if the record contains an anonmyous struct).
template <typename T, typename Func>
void forEachField(const RecordDecl &Record, const T &Fields, Func &&Fn) {
  for (const FieldDecl *F : Fields) {
    if (F->isAnonymousStructOrUnion()) {
      if (const CXXRecordDecl *R = F->getType()->getAsCXXRecordDecl())
        forEachField(*R, R->fields(), Fn);
    } else {
      Fn(F);
    }
  }
}

void removeFieldsInitializedInBody(
    const Stmt &Stmt, ASTContext &Context,
    SmallPtrSetImpl<const FieldDecl *> &FieldDecls) {
  auto Matches =
      match(findAll(binaryOperator(
                hasOperatorName("="),
                hasLHS(memberExpr(member(fieldDecl().bind("fieldDecl")))))),
            Stmt, Context);
  for (const auto &Match : Matches)
    FieldDecls.erase(Match.getNodeAs<FieldDecl>("fieldDecl"));
}

StringRef getName(const FieldDecl *Field) { return Field->getName(); }

StringRef getName(const RecordDecl *Record) {
  // Get the typedef name if this is a C-style anonymous struct and typedef.
  if (const TypedefNameDecl *Typedef = Record->getTypedefNameForAnonDecl())
    return Typedef->getName();
  return Record->getName();
}

// Creates comma separated list of decls requiring initialization in order of
// declaration.
template <typename R, typename T>
std::string
toCommaSeparatedString(const R &OrderedDecls,
                       const SmallPtrSetImpl<const T *> &DeclsToInit) {
  SmallVector<StringRef, 16> Names;
  for (const T *Decl : OrderedDecls) {
    if (DeclsToInit.count(Decl))
      Names.emplace_back(getName(Decl));
  }
  return llvm::join(Names.begin(), Names.end(), ", ");
}

SourceLocation getLocationForEndOfToken(const ASTContext &Context,
                                        SourceLocation Location) {
  return Lexer::getLocForEndOfToken(Location, 0, Context.getSourceManager(),
                                    Context.getLangOpts());
}

// There are 3 kinds of insertion placements:
enum class InitializerPlacement {
  // 1. The fields are inserted after an existing CXXCtorInitializer stored in
  // Where. This will be the case whenever there is a written initializer before
  // the fields available.
  After,

  // 2. The fields are inserted before the first existing initializer stored in
  // Where.
  Before,

  // 3. There are no written initializers and the fields will be inserted before
  // the constructor's body creating a new initializer list including the ':'.
  New
};

// An InitializerInsertion contains a list of fields and/or base classes to
// insert into the initializer list of a constructor. We use this to ensure
// proper absolute ordering according to the class declaration relative to the
// (perhaps improper) ordering in the existing initializer list, if any.
struct IntializerInsertion {
  IntializerInsertion(InitializerPlacement Placement,
                      const CXXCtorInitializer *Where)
      : Placement(Placement), Where(Where) {}

  SourceLocation getLocation(const ASTContext &Context,
                             const CXXConstructorDecl &Constructor) const {
    assert((Where != nullptr || Placement == InitializerPlacement::New) &&
           "Location should be relative to an existing initializer or this "
           "insertion represents a new initializer list.");
    SourceLocation Location;
    switch (Placement) {
    case InitializerPlacement::New:
      Location = utils::lexer::getPreviousToken(
                     Constructor.getBody()->getBeginLoc(),
                     Context.getSourceManager(), Context.getLangOpts())
                     .getLocation();
      break;
    case InitializerPlacement::Before:
      Location = utils::lexer::getPreviousToken(
                     Where->getSourceRange().getBegin(),
                     Context.getSourceManager(), Context.getLangOpts())
                     .getLocation();
      break;
    case InitializerPlacement::After:
      Location = Where->getRParenLoc();
      break;
    }
    return getLocationForEndOfToken(Context, Location);
  }

  std::string codeToInsert() const {
    assert(!Initializers.empty() && "No initializers to insert");
    std::string Code;
    llvm::raw_string_ostream Stream(Code);
    std::string joined =
        llvm::join(Initializers.begin(), Initializers.end(), "(), ");
    switch (Placement) {
    case InitializerPlacement::New:
      Stream << " : " << joined << "()";
      break;
    case InitializerPlacement::Before:
      Stream << " " << joined << "(),";
      break;
    case InitializerPlacement::After:
      Stream << ", " << joined << "()";
      break;
    }
    return Stream.str();
  }

  InitializerPlacement Placement;
  const CXXCtorInitializer *Where;
  SmallVector<std::string, 4> Initializers;
};

// Convenience utility to get a RecordDecl from a QualType.
const RecordDecl *getCanonicalRecordDecl(const QualType &Type) {
  if (const auto *RT = Type.getCanonicalType()->getAs<RecordType>())
    return RT->getDecl();
  return nullptr;
}

template <typename R, typename T>
SmallVector<IntializerInsertion, 16>
computeInsertions(const CXXConstructorDecl::init_const_range &Inits,
                  const R &OrderedDecls,
                  const SmallPtrSetImpl<const T *> &DeclsToInit) {
  SmallVector<IntializerInsertion, 16> Insertions;
  Insertions.emplace_back(InitializerPlacement::New, nullptr);

  typename R::const_iterator Decl = std::begin(OrderedDecls);
  for (const CXXCtorInitializer *Init : Inits) {
    if (Init->isWritten()) {
      if (Insertions.size() == 1)
        Insertions.emplace_back(InitializerPlacement::Before, Init);

      // Gets either the field or base class being initialized by the provided
      // initializer.
      const auto *InitDecl =
          Init->isAnyMemberInitializer()
              ? static_cast<const NamedDecl *>(Init->getAnyMember())
              : Init->getBaseClass()->getAsCXXRecordDecl();

      // Add all fields between current field up until the next intializer.
      for (; Decl != std::end(OrderedDecls) && *Decl != InitDecl; ++Decl) {
        if (const auto *D = dyn_cast<T>(*Decl)) {
          if (DeclsToInit.count(D) > 0)
            Insertions.back().Initializers.emplace_back(getName(D));
        }
      }

      Insertions.emplace_back(InitializerPlacement::After, Init);
    }
  }

  // Add remaining decls that require initialization.
  for (; Decl != std::end(OrderedDecls); ++Decl) {
    if (const auto *D = dyn_cast<T>(*Decl)) {
      if (DeclsToInit.count(D) > 0)
        Insertions.back().Initializers.emplace_back(getName(D));
    }
  }
  return Insertions;
}

// Gets the list of bases and members that could possibly be initialized, in
// order as they appear in the class declaration.
void getInitializationsInOrder(const CXXRecordDecl &ClassDecl,
                               SmallVectorImpl<const NamedDecl *> &Decls) {
  Decls.clear();
  for (const auto &Base : ClassDecl.bases()) {
    // Decl may be null if the base class is a template parameter.
    if (const NamedDecl *Decl = getCanonicalRecordDecl(Base.getType())) {
      Decls.emplace_back(Decl);
    }
  }
  forEachField(ClassDecl, ClassDecl.fields(),
               [&](const FieldDecl *F) { Decls.push_back(F); });
}

template <typename T>
void fixInitializerList(const ASTContext &Context, DiagnosticBuilder &Diag,
                        const CXXConstructorDecl *Ctor,
                        const SmallPtrSetImpl<const T *> &DeclsToInit) {
  // Do not propose fixes in macros since we cannot place them correctly.
  if (Ctor->getBeginLoc().isMacroID())
    return;

  SmallVector<const NamedDecl *, 16> OrderedDecls;
  getInitializationsInOrder(*Ctor->getParent(), OrderedDecls);

  for (const auto &Insertion :
       computeInsertions(Ctor->inits(), OrderedDecls, DeclsToInit)) {
    if (!Insertion.Initializers.empty())
      Diag << FixItHint::CreateInsertion(Insertion.getLocation(Context, *Ctor),
                                         Insertion.codeToInsert());
  }
}

} // anonymous namespace

ProTypeMemberInitCheck::ProTypeMemberInitCheck(StringRef Name,
                                               ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context),
      IgnoreArrays(Options.get("IgnoreArrays", false)) {}

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

  auto IsUserProvidedNonDelegatingConstructor =
      allOf(isUserProvided(),
            unless(anyOf(isInstantiated(), isDelegatingConstructor())));
  auto IsNonTrivialDefaultConstructor = allOf(
      isDefaultConstructor(), unless(isUserProvided()),
      hasParent(cxxRecordDecl(unless(isTriviallyDefaultConstructible()))));
  Finder->addMatcher(
      cxxConstructorDecl(isDefinition(),
                         anyOf(IsUserProvidedNonDelegatingConstructor,
                               IsNonTrivialDefaultConstructor))
          .bind("ctor"),
      this);

  // Match classes with a default constructor that is defaulted or is not in the
  // AST.
  Finder->addMatcher(
      cxxRecordDecl(
          isDefinition(), unless(isInstantiated()), hasDefaultConstructor(),
          anyOf(has(cxxConstructorDecl(isDefaultConstructor(), isDefaulted(),
                                       unless(isImplicit()))),
                unless(has(cxxConstructorDecl()))),
          unless(isTriviallyDefaultConstructible()))
          .bind("record"),
      this);

  auto HasDefaultConstructor = hasInitializer(
      cxxConstructExpr(unless(requiresZeroInitialization()),
                       hasDeclaration(cxxConstructorDecl(
                           isDefaultConstructor(), unless(isUserProvided())))));
  Finder->addMatcher(
      varDecl(isDefinition(), HasDefaultConstructor,
              hasAutomaticStorageDuration(),
              hasType(recordDecl(has(fieldDecl()),
                                 isTriviallyDefaultConstructible())))
          .bind("var"),
      this);
}

void ProTypeMemberInitCheck::check(const MatchFinder::MatchResult &Result) {
  if (const auto *Ctor = Result.Nodes.getNodeAs<CXXConstructorDecl>("ctor")) {
    // Skip declarations delayed by late template parsing without a body.
    if (!Ctor->getBody())
      return;
    checkMissingMemberInitializer(*Result.Context, *Ctor->getParent(), Ctor);
    checkMissingBaseClassInitializer(*Result.Context, *Ctor->getParent(), Ctor);
  } else if (const auto *Record =
                 Result.Nodes.getNodeAs<CXXRecordDecl>("record")) {
    assert(Record->hasDefaultConstructor() &&
           "Matched record should have a default constructor");
    checkMissingMemberInitializer(*Result.Context, *Record, nullptr);
    checkMissingBaseClassInitializer(*Result.Context, *Record, nullptr);
  } else if (const auto *Var = Result.Nodes.getNodeAs<VarDecl>("var")) {
    checkUninitializedTrivialType(*Result.Context, Var);
  }
}

void ProTypeMemberInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "IgnoreArrays", IgnoreArrays);
}

// FIXME: Copied from clang/lib/Sema/SemaDeclCXX.cpp.
static bool isIncompleteOrZeroLengthArrayType(ASTContext &Context, QualType T) {
  if (T->isIncompleteArrayType())
    return true;

  while (const ConstantArrayType *ArrayT = Context.getAsConstantArrayType(T)) {
    if (!ArrayT->getSize())
      return true;

    T = ArrayT->getElementType();
  }

  return false;
}

static bool isEmpty(ASTContext &Context, const QualType &Type) {
  if (const CXXRecordDecl *ClassDecl = Type->getAsCXXRecordDecl()) {
    return ClassDecl->isEmpty();
  }
  return isIncompleteOrZeroLengthArrayType(Context, Type);
}

void ProTypeMemberInitCheck::checkMissingMemberInitializer(
    ASTContext &Context, const CXXRecordDecl &ClassDecl,
    const CXXConstructorDecl *Ctor) {
  bool IsUnion = ClassDecl.isUnion();

  if (IsUnion && ClassDecl.hasInClassInitializer())
    return;

  // Gather all fields (direct and indirect) that need to be initialized.
  SmallPtrSet<const FieldDecl *, 16> FieldsToInit;
  forEachField(ClassDecl, ClassDecl.fields(), [&](const FieldDecl *F) {
    if (!F->hasInClassInitializer() &&
        utils::type_traits::isTriviallyDefaultConstructible(F->getType(),
                                                            Context) &&
        !isEmpty(Context, F->getType()) && !F->isUnnamedBitfield())
      FieldsToInit.insert(F);
  });
  if (FieldsToInit.empty())
    return;

  if (Ctor) {
    for (const CXXCtorInitializer *Init : Ctor->inits()) {
      // Remove any fields that were explicitly written in the initializer list
      // or in-class.
      if (Init->isAnyMemberInitializer() && Init->isWritten()) {
        if (IsUnion)
          return; // We can only initialize one member of a union.
        FieldsToInit.erase(Init->getAnyMember());
      }
    }
    removeFieldsInitializedInBody(*Ctor->getBody(), Context, FieldsToInit);
  }

  // Collect all fields in order, both direct fields and indirect fields from
  // anonmyous record types.
  SmallVector<const FieldDecl *, 16> OrderedFields;
  forEachField(ClassDecl, ClassDecl.fields(),
               [&](const FieldDecl *F) { OrderedFields.push_back(F); });

  // Collect all the fields we need to initialize, including indirect fields.
  SmallPtrSet<const FieldDecl *, 16> AllFieldsToInit;
  forEachField(ClassDecl, FieldsToInit,
               [&](const FieldDecl *F) { AllFieldsToInit.insert(F); });
  if (AllFieldsToInit.empty())
    return;

  DiagnosticBuilder Diag =
      diag(Ctor ? Ctor->getBeginLoc() : ClassDecl.getLocation(),
           IsUnion
               ? "union constructor should initialize one of these fields: %0"
               : "constructor does not initialize these fields: %0")
      << toCommaSeparatedString(OrderedFields, AllFieldsToInit);

  // Do not propose fixes for constructors in macros since we cannot place them
  // correctly.
  if (Ctor && Ctor->getBeginLoc().isMacroID())
    return;

  // Collect all fields but only suggest a fix for the first member of unions,
  // as initializing more than one union member is an error.
  SmallPtrSet<const FieldDecl *, 16> FieldsToFix;
  SmallPtrSet<const RecordDecl *, 4> UnionsSeen;
  forEachField(ClassDecl, OrderedFields, [&](const FieldDecl *F) {
    if (!FieldsToInit.count(F))
      return;
    // Don't suggest fixes for enums because we don't know a good default.
    // Don't suggest fixes for bitfields because in-class initialization is not
    // possible until C++2a.
    if (F->getType()->isEnumeralType() ||
        (!getLangOpts().CPlusPlus2a && F->isBitField()))
      return;
    if (!F->getParent()->isUnion() || UnionsSeen.insert(F->getParent()).second)
      FieldsToFix.insert(F);
  });
  if (FieldsToFix.empty())
    return;

  // Use in-class initialization if possible.
  if (Context.getLangOpts().CPlusPlus11) {
    for (const FieldDecl *Field : FieldsToFix) {
      Diag << FixItHint::CreateInsertion(
          getLocationForEndOfToken(Context, Field->getSourceRange().getEnd()),
          "{}");
    }
  } else if (Ctor) {
    // Otherwise, rewrite the constructor's initializer list.
    fixInitializerList(Context, Diag, Ctor, FieldsToFix);
  }
}

void ProTypeMemberInitCheck::checkMissingBaseClassInitializer(
    const ASTContext &Context, const CXXRecordDecl &ClassDecl,
    const CXXConstructorDecl *Ctor) {

  // Gather any base classes that need to be initialized.
  SmallVector<const RecordDecl *, 4> AllBases;
  SmallPtrSet<const RecordDecl *, 4> BasesToInit;
  for (const CXXBaseSpecifier &Base : ClassDecl.bases()) {
    if (const auto *BaseClassDecl = getCanonicalRecordDecl(Base.getType())) {
      AllBases.emplace_back(BaseClassDecl);
      if (!BaseClassDecl->field_empty() &&
          utils::type_traits::isTriviallyDefaultConstructible(Base.getType(),
                                                              Context))
        BasesToInit.insert(BaseClassDecl);
    }
  }

  if (BasesToInit.empty())
    return;

  // Remove any bases that were explicitly written in the initializer list.
  if (Ctor) {
    if (Ctor->isImplicit())
      return;

    for (const CXXCtorInitializer *Init : Ctor->inits()) {
      if (Init->isBaseInitializer() && Init->isWritten())
        BasesToInit.erase(Init->getBaseClass()->getAsCXXRecordDecl());
    }
  }

  if (BasesToInit.empty())
    return;

  DiagnosticBuilder Diag =
      diag(Ctor ? Ctor->getBeginLoc() : ClassDecl.getLocation(),
           "constructor does not initialize these bases: %0")
      << toCommaSeparatedString(AllBases, BasesToInit);

  if (Ctor)
    fixInitializerList(Context, Diag, Ctor, BasesToInit);
}

void ProTypeMemberInitCheck::checkUninitializedTrivialType(
    const ASTContext &Context, const VarDecl *Var) {
  DiagnosticBuilder Diag =
      diag(Var->getBeginLoc(), "uninitialized record type: %0") << Var;

  Diag << FixItHint::CreateInsertion(
      getLocationForEndOfToken(Context, Var->getSourceRange().getEnd()),
      Context.getLangOpts().CPlusPlus11 ? "{}" : " = {}");
}

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