//===--- IdentifierNamingCheck.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 "IdentifierNamingCheck.h"

#include "../utils/ASTUtils.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"

#define DEBUG_TYPE "clang-tidy"

using namespace clang::ast_matchers;

namespace llvm {
/// Specialisation of DenseMapInfo to allow NamingCheckId objects in DenseMaps
template <>
struct DenseMapInfo<
    clang::tidy::readability::IdentifierNamingCheck::NamingCheckId> {
  using NamingCheckId =
      clang::tidy::readability::IdentifierNamingCheck::NamingCheckId;

  static inline NamingCheckId getEmptyKey() {
    return NamingCheckId(
        clang::SourceLocation::getFromRawEncoding(static_cast<unsigned>(-1)),
        "EMPTY");
  }

  static inline NamingCheckId getTombstoneKey() {
    return NamingCheckId(
        clang::SourceLocation::getFromRawEncoding(static_cast<unsigned>(-2)),
        "TOMBSTONE");
  }

  static unsigned getHashValue(NamingCheckId Val) {
    assert(Val != getEmptyKey() && "Cannot hash the empty key!");
    assert(Val != getTombstoneKey() && "Cannot hash the tombstone key!");

    std::hash<NamingCheckId::second_type> SecondHash;
    return Val.first.getRawEncoding() + SecondHash(Val.second);
  }

  static bool isEqual(const NamingCheckId &LHS, const NamingCheckId &RHS) {
    if (RHS == getEmptyKey())
      return LHS == getEmptyKey();
    if (RHS == getTombstoneKey())
      return LHS == getTombstoneKey();
    return LHS == RHS;
  }
};
} // namespace llvm

namespace clang {
namespace tidy {
namespace readability {

// clang-format off
#define NAMING_KEYS(m) \
    m(Namespace) \
    m(InlineNamespace) \
    m(EnumConstant) \
    m(ConstexprVariable) \
    m(ConstantMember) \
    m(PrivateMember) \
    m(ProtectedMember) \
    m(PublicMember) \
    m(Member) \
    m(ClassConstant) \
    m(ClassMember) \
    m(GlobalConstant) \
    m(GlobalConstantPointer) \
    m(GlobalPointer) \
    m(GlobalVariable) \
    m(LocalConstant) \
    m(LocalConstantPointer) \
    m(LocalPointer) \
    m(LocalVariable) \
    m(StaticConstant) \
    m(StaticVariable) \
    m(Constant) \
    m(Variable) \
    m(ConstantParameter) \
    m(ParameterPack) \
    m(Parameter) \
    m(PointerParameter) \
    m(ConstantPointerParameter) \
    m(AbstractClass) \
    m(Struct) \
    m(Class) \
    m(Union) \
    m(Enum) \
    m(GlobalFunction) \
    m(ConstexprFunction) \
    m(Function) \
    m(ConstexprMethod) \
    m(VirtualMethod) \
    m(ClassMethod) \
    m(PrivateMethod) \
    m(ProtectedMethod) \
    m(PublicMethod) \
    m(Method) \
    m(Typedef) \
    m(TypeTemplateParameter) \
    m(ValueTemplateParameter) \
    m(TemplateTemplateParameter) \
    m(TemplateParameter) \
    m(TypeAlias) \
    m(MacroDefinition) \
    m(ObjcIvar) \

enum StyleKind {
#define ENUMERATE(v) SK_ ## v,
  NAMING_KEYS(ENUMERATE)
#undef ENUMERATE
  SK_Count,
  SK_Invalid
};

static StringRef const StyleNames[] = {
#define STRINGIZE(v) #v,
  NAMING_KEYS(STRINGIZE)
#undef STRINGIZE
};

#undef NAMING_KEYS
// clang-format on

namespace {
/// Callback supplies macros to IdentifierNamingCheck::checkMacro
class IdentifierNamingCheckPPCallbacks : public PPCallbacks {
public:
  IdentifierNamingCheckPPCallbacks(Preprocessor *PP,
                                   IdentifierNamingCheck *Check)
      : PP(PP), Check(Check) {}

  /// MacroDefined calls checkMacro for macros in the main file
  void MacroDefined(const Token &MacroNameTok,
                    const MacroDirective *MD) override {
    Check->checkMacro(PP->getSourceManager(), MacroNameTok, MD->getMacroInfo());
  }

  /// MacroExpands calls expandMacro for macros in the main file
  void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
                    SourceRange /*Range*/,
                    const MacroArgs * /*Args*/) override {
    Check->expandMacro(MacroNameTok, MD.getMacroInfo());
  }

private:
  Preprocessor *PP;
  IdentifierNamingCheck *Check;
};
} // namespace

IdentifierNamingCheck::IdentifierNamingCheck(StringRef Name,
                                             ClangTidyContext *Context)
    : ClangTidyCheck(Name, Context) {
  auto const fromString = [](StringRef Str) {
    return llvm::StringSwitch<llvm::Optional<CaseType>>(Str)
        .Case("aNy_CasE", CT_AnyCase)
        .Case("lower_case", CT_LowerCase)
        .Case("UPPER_CASE", CT_UpperCase)
        .Case("camelBack", CT_CamelBack)
        .Case("CamelCase", CT_CamelCase)
        .Case("Camel_Snake_Case", CT_CamelSnakeCase)
        .Case("camel_Snake_Back", CT_CamelSnakeBack)
        .Default(llvm::None);
  };

  for (auto const &Name : StyleNames) {
    auto const caseOptional =
        fromString(Options.get((Name + "Case").str(), ""));
    auto prefix = Options.get((Name + "Prefix").str(), "");
    auto postfix = Options.get((Name + "Suffix").str(), "");

    if (caseOptional || !prefix.empty() || !postfix.empty()) {
      NamingStyles.push_back(NamingStyle(caseOptional, prefix, postfix));
    } else {
      NamingStyles.push_back(llvm::None);
    }
  }

  IgnoreFailedSplit = Options.get("IgnoreFailedSplit", 0);
}

IdentifierNamingCheck::~IdentifierNamingCheck() = default;

void IdentifierNamingCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
  auto const toString = [](CaseType Type) {
    switch (Type) {
    case CT_AnyCase:
      return "aNy_CasE";
    case CT_LowerCase:
      return "lower_case";
    case CT_CamelBack:
      return "camelBack";
    case CT_UpperCase:
      return "UPPER_CASE";
    case CT_CamelCase:
      return "CamelCase";
    case CT_CamelSnakeCase:
      return "Camel_Snake_Case";
    case CT_CamelSnakeBack:
      return "camel_Snake_Back";
    }

    llvm_unreachable("Unknown Case Type");
  };

  for (size_t i = 0; i < SK_Count; ++i) {
    if (NamingStyles[i]) {
      if (NamingStyles[i]->Case) {
        Options.store(Opts, (StyleNames[i] + "Case").str(),
                      toString(*NamingStyles[i]->Case));
      }
      Options.store(Opts, (StyleNames[i] + "Prefix").str(),
                    NamingStyles[i]->Prefix);
      Options.store(Opts, (StyleNames[i] + "Suffix").str(),
                    NamingStyles[i]->Suffix);
    }
  }

  Options.store(Opts, "IgnoreFailedSplit", IgnoreFailedSplit);
}

void IdentifierNamingCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(namedDecl().bind("decl"), this);
  Finder->addMatcher(usingDecl().bind("using"), this);
  Finder->addMatcher(declRefExpr().bind("declRef"), this);
  Finder->addMatcher(cxxConstructorDecl().bind("classRef"), this);
  Finder->addMatcher(cxxDestructorDecl().bind("classRef"), this);
  Finder->addMatcher(typeLoc().bind("typeLoc"), this);
  Finder->addMatcher(nestedNameSpecifierLoc().bind("nestedNameLoc"), this);
}

void IdentifierNamingCheck::registerPPCallbacks(
    const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
  ModuleExpanderPP->addPPCallbacks(
      std::make_unique<IdentifierNamingCheckPPCallbacks>(ModuleExpanderPP,
                                                          this));
}

static bool matchesStyle(StringRef Name,
                         IdentifierNamingCheck::NamingStyle Style) {
  static llvm::Regex Matchers[] = {
      llvm::Regex("^.*$"),
      llvm::Regex("^[a-z][a-z0-9_]*$"),
      llvm::Regex("^[a-z][a-zA-Z0-9]*$"),
      llvm::Regex("^[A-Z][A-Z0-9_]*$"),
      llvm::Regex("^[A-Z][a-zA-Z0-9]*$"),
      llvm::Regex("^[A-Z]([a-z0-9]*(_[A-Z])?)*"),
      llvm::Regex("^[a-z]([a-z0-9]*(_[A-Z])?)*"),
  };

  bool Matches = true;
  if (Name.startswith(Style.Prefix))
    Name = Name.drop_front(Style.Prefix.size());
  else
    Matches = false;

  if (Name.endswith(Style.Suffix))
    Name = Name.drop_back(Style.Suffix.size());
  else
    Matches = false;

  // Ensure the name doesn't have any extra underscores beyond those specified
  // in the prefix and suffix.
  if (Name.startswith("_") || Name.endswith("_"))
    Matches = false;

  if (Style.Case && !Matchers[static_cast<size_t>(*Style.Case)].match(Name))
    Matches = false;

  return Matches;
}

static std::string fixupWithCase(StringRef Name,
                                 IdentifierNamingCheck::CaseType Case) {
  static llvm::Regex Splitter(
      "([a-z0-9A-Z]*)(_+)|([A-Z]?[a-z0-9]+)([A-Z]|$)|([A-Z]+)([A-Z]|$)");

  SmallVector<StringRef, 8> Substrs;
  Name.split(Substrs, "_", -1, false);

  SmallVector<StringRef, 8> Words;
  for (auto Substr : Substrs) {
    while (!Substr.empty()) {
      SmallVector<StringRef, 8> Groups;
      if (!Splitter.match(Substr, &Groups))
        break;

      if (Groups[2].size() > 0) {
        Words.push_back(Groups[1]);
        Substr = Substr.substr(Groups[0].size());
      } else if (Groups[3].size() > 0) {
        Words.push_back(Groups[3]);
        Substr = Substr.substr(Groups[0].size() - Groups[4].size());
      } else if (Groups[5].size() > 0) {
        Words.push_back(Groups[5]);
        Substr = Substr.substr(Groups[0].size() - Groups[6].size());
      }
    }
  }

  if (Words.empty())
    return Name;

  std::string Fixup;
  switch (Case) {
  case IdentifierNamingCheck::CT_AnyCase:
    Fixup += Name;
    break;

  case IdentifierNamingCheck::CT_LowerCase:
    for (auto const &Word : Words) {
      if (&Word != &Words.front())
        Fixup += "_";
      Fixup += Word.lower();
    }
    break;

  case IdentifierNamingCheck::CT_UpperCase:
    for (auto const &Word : Words) {
      if (&Word != &Words.front())
        Fixup += "_";
      Fixup += Word.upper();
    }
    break;

  case IdentifierNamingCheck::CT_CamelCase:
    for (auto const &Word : Words) {
      Fixup += Word.substr(0, 1).upper();
      Fixup += Word.substr(1).lower();
    }
    break;

  case IdentifierNamingCheck::CT_CamelBack:
    for (auto const &Word : Words) {
      if (&Word == &Words.front()) {
        Fixup += Word.lower();
      } else {
        Fixup += Word.substr(0, 1).upper();
        Fixup += Word.substr(1).lower();
      }
    }
    break;

  case IdentifierNamingCheck::CT_CamelSnakeCase:
    for (auto const &Word : Words) {
      if (&Word != &Words.front())
        Fixup += "_";
      Fixup += Word.substr(0, 1).upper();
      Fixup += Word.substr(1).lower();
    }
    break;

  case IdentifierNamingCheck::CT_CamelSnakeBack:
    for (auto const &Word : Words) {
      if (&Word != &Words.front()) {
        Fixup += "_";
        Fixup += Word.substr(0, 1).upper();
      } else {
        Fixup += Word.substr(0, 1).lower();
      }
      Fixup += Word.substr(1).lower();
    }
    break;
  }

  return Fixup;
}

static std::string
fixupWithStyle(StringRef Name,
               const IdentifierNamingCheck::NamingStyle &Style) {
  const std::string Fixed = fixupWithCase(
      Name, Style.Case.getValueOr(IdentifierNamingCheck::CaseType::CT_AnyCase));
  StringRef Mid = StringRef(Fixed).trim("_");
  if (Mid.empty())
    Mid = "_";
  return (Style.Prefix + Mid + Style.Suffix).str();
}

static StyleKind findStyleKind(
    const NamedDecl *D,
    const std::vector<llvm::Optional<IdentifierNamingCheck::NamingStyle>>
        &NamingStyles) {
  assert(D && D->getIdentifier() && !D->getName().empty() && !D->isImplicit() &&
         "Decl must be an explicit identifier with a name.");

  if (isa<ObjCIvarDecl>(D) && NamingStyles[SK_ObjcIvar])
    return SK_ObjcIvar;
  
  if (isa<TypedefDecl>(D) && NamingStyles[SK_Typedef])
    return SK_Typedef;

  if (isa<TypeAliasDecl>(D) && NamingStyles[SK_TypeAlias])
    return SK_TypeAlias;

  if (const auto *Decl = dyn_cast<NamespaceDecl>(D)) {
    if (Decl->isAnonymousNamespace())
      return SK_Invalid;

    if (Decl->isInline() && NamingStyles[SK_InlineNamespace])
      return SK_InlineNamespace;

    if (NamingStyles[SK_Namespace])
      return SK_Namespace;
  }

  if (isa<EnumDecl>(D) && NamingStyles[SK_Enum])
    return SK_Enum;

  if (isa<EnumConstantDecl>(D)) {
    if (NamingStyles[SK_EnumConstant])
      return SK_EnumConstant;

    if (NamingStyles[SK_Constant])
      return SK_Constant;

    return SK_Invalid;
  }

  if (const auto *Decl = dyn_cast<CXXRecordDecl>(D)) {
    if (Decl->isAnonymousStructOrUnion())
      return SK_Invalid;

    if (!Decl->getCanonicalDecl()->isThisDeclarationADefinition())
      return SK_Invalid;

    if (Decl->hasDefinition() && Decl->isAbstract() &&
        NamingStyles[SK_AbstractClass])
      return SK_AbstractClass;

    if (Decl->isStruct() && NamingStyles[SK_Struct])
      return SK_Struct;

    if (Decl->isStruct() && NamingStyles[SK_Class])
      return SK_Class;

    if (Decl->isClass() && NamingStyles[SK_Class])
      return SK_Class;

    if (Decl->isClass() && NamingStyles[SK_Struct])
      return SK_Struct;

    if (Decl->isUnion() && NamingStyles[SK_Union])
      return SK_Union;

    if (Decl->isEnum() && NamingStyles[SK_Enum])
      return SK_Enum;

    return SK_Invalid;
  }

  if (const auto *Decl = dyn_cast<FieldDecl>(D)) {
    QualType Type = Decl->getType();

    if (!Type.isNull() && Type.isConstQualified()) {
      if (NamingStyles[SK_ConstantMember])
        return SK_ConstantMember;

      if (NamingStyles[SK_Constant])
        return SK_Constant;
    }

    if (Decl->getAccess() == AS_private && NamingStyles[SK_PrivateMember])
      return SK_PrivateMember;

    if (Decl->getAccess() == AS_protected && NamingStyles[SK_ProtectedMember])
      return SK_ProtectedMember;

    if (Decl->getAccess() == AS_public && NamingStyles[SK_PublicMember])
      return SK_PublicMember;

    if (NamingStyles[SK_Member])
      return SK_Member;

    return SK_Invalid;
  }

  if (const auto *Decl = dyn_cast<ParmVarDecl>(D)) {
    QualType Type = Decl->getType();

    if (Decl->isConstexpr() && NamingStyles[SK_ConstexprVariable])
      return SK_ConstexprVariable;

    if (!Type.isNull() && Type.isConstQualified()) {
      if (Type.getTypePtr()->isAnyPointerType() && NamingStyles[SK_ConstantPointerParameter])
        return SK_ConstantPointerParameter;

      if (NamingStyles[SK_ConstantParameter])
        return SK_ConstantParameter;

      if (NamingStyles[SK_Constant])
        return SK_Constant;
    }

    if (Decl->isParameterPack() && NamingStyles[SK_ParameterPack])
      return SK_ParameterPack;

    if (!Type.isNull() && Type.getTypePtr()->isAnyPointerType() && NamingStyles[SK_PointerParameter])
        return SK_PointerParameter;

    if (NamingStyles[SK_Parameter])
      return SK_Parameter;

    return SK_Invalid;
  }

  if (const auto *Decl = dyn_cast<VarDecl>(D)) {
    QualType Type = Decl->getType();

    if (Decl->isConstexpr() && NamingStyles[SK_ConstexprVariable])
      return SK_ConstexprVariable;

    if (!Type.isNull() && Type.isConstQualified()) {
      if (Decl->isStaticDataMember() && NamingStyles[SK_ClassConstant])
        return SK_ClassConstant;

      if (Decl->isFileVarDecl() && Type.getTypePtr()->isAnyPointerType() && NamingStyles[SK_GlobalConstantPointer])
        return SK_GlobalConstantPointer;

      if (Decl->isFileVarDecl() && NamingStyles[SK_GlobalConstant])
        return SK_GlobalConstant;

      if (Decl->isStaticLocal() && NamingStyles[SK_StaticConstant])
        return SK_StaticConstant;

      if (Decl->isLocalVarDecl() && Type.getTypePtr()->isAnyPointerType() && NamingStyles[SK_LocalConstantPointer])
        return SK_LocalConstantPointer;

      if (Decl->isLocalVarDecl() && NamingStyles[SK_LocalConstant])
        return SK_LocalConstant;

      if (Decl->isFunctionOrMethodVarDecl() && NamingStyles[SK_LocalConstant])
        return SK_LocalConstant;

      if (NamingStyles[SK_Constant])
        return SK_Constant;
    }

    if (Decl->isStaticDataMember() && NamingStyles[SK_ClassMember])
      return SK_ClassMember;

    if (Decl->isFileVarDecl() && Type.getTypePtr()->isAnyPointerType() && NamingStyles[SK_GlobalPointer])
      return SK_GlobalPointer;

    if (Decl->isFileVarDecl() && NamingStyles[SK_GlobalVariable])
      return SK_GlobalVariable;

    if (Decl->isStaticLocal() && NamingStyles[SK_StaticVariable])
      return SK_StaticVariable;
 
    if (Decl->isLocalVarDecl() && Type.getTypePtr()->isAnyPointerType() && NamingStyles[SK_LocalPointer])
      return SK_LocalPointer;

    if (Decl->isLocalVarDecl() && NamingStyles[SK_LocalVariable])
      return SK_LocalVariable;

    if (Decl->isFunctionOrMethodVarDecl() && NamingStyles[SK_LocalVariable])
      return SK_LocalVariable;

    if (NamingStyles[SK_Variable])
      return SK_Variable;

    return SK_Invalid;
  }

  if (const auto *Decl = dyn_cast<CXXMethodDecl>(D)) {
    if (Decl->isMain() || !Decl->isUserProvided() ||
        Decl->size_overridden_methods() > 0)
      return SK_Invalid;

    // If this method has the same name as any base method, this is likely
    // necessary even if it's not an override. e.g. CRTP.
    auto FindHidden = [&](const CXXBaseSpecifier *S, clang::CXXBasePath &P) {
      return CXXRecordDecl::FindOrdinaryMember(S, P, Decl->getDeclName());
    };
    CXXBasePaths UnusedPaths;
    if (Decl->getParent()->lookupInBases(FindHidden, UnusedPaths))
      return SK_Invalid;

    if (Decl->isConstexpr() && NamingStyles[SK_ConstexprMethod])
      return SK_ConstexprMethod;

    if (Decl->isConstexpr() && NamingStyles[SK_ConstexprFunction])
      return SK_ConstexprFunction;

    if (Decl->isStatic() && NamingStyles[SK_ClassMethod])
      return SK_ClassMethod;

    if (Decl->isVirtual() && NamingStyles[SK_VirtualMethod])
      return SK_VirtualMethod;

    if (Decl->getAccess() == AS_private && NamingStyles[SK_PrivateMethod])
      return SK_PrivateMethod;

    if (Decl->getAccess() == AS_protected && NamingStyles[SK_ProtectedMethod])
      return SK_ProtectedMethod;

    if (Decl->getAccess() == AS_public && NamingStyles[SK_PublicMethod])
      return SK_PublicMethod;

    if (NamingStyles[SK_Method])
      return SK_Method;

    if (NamingStyles[SK_Function])
      return SK_Function;

    return SK_Invalid;
  }

  if (const auto *Decl = dyn_cast<FunctionDecl>(D)) {
    if (Decl->isMain())
      return SK_Invalid;

    if (Decl->isConstexpr() && NamingStyles[SK_ConstexprFunction])
      return SK_ConstexprFunction;

    if (Decl->isGlobal() && NamingStyles[SK_GlobalFunction])
      return SK_GlobalFunction;

    if (NamingStyles[SK_Function])
      return SK_Function;
  }

  if (isa<TemplateTypeParmDecl>(D)) {
    if (NamingStyles[SK_TypeTemplateParameter])
      return SK_TypeTemplateParameter;

    if (NamingStyles[SK_TemplateParameter])
      return SK_TemplateParameter;

    return SK_Invalid;
  }

  if (isa<NonTypeTemplateParmDecl>(D)) {
    if (NamingStyles[SK_ValueTemplateParameter])
      return SK_ValueTemplateParameter;

    if (NamingStyles[SK_TemplateParameter])
      return SK_TemplateParameter;

    return SK_Invalid;
  }

  if (isa<TemplateTemplateParmDecl>(D)) {
    if (NamingStyles[SK_TemplateTemplateParameter])
      return SK_TemplateTemplateParameter;

    if (NamingStyles[SK_TemplateParameter])
      return SK_TemplateParameter;

    return SK_Invalid;
  }

  return SK_Invalid;
}

static void addUsage(IdentifierNamingCheck::NamingCheckFailureMap &Failures,
                     const IdentifierNamingCheck::NamingCheckId &Decl,
                     SourceRange Range, SourceManager *SourceMgr = nullptr) {
  // Do nothing if the provided range is invalid.
  if (Range.getBegin().isInvalid() || Range.getEnd().isInvalid())
    return;

  // If we have a source manager, use it to convert to the spelling location for
  // performing the fix. This is necessary because macros can map the same
  // spelling location to different source locations, and we only want to fix
  // the token once, before it is expanded by the macro.
  SourceLocation FixLocation = Range.getBegin();
  if (SourceMgr)
    FixLocation = SourceMgr->getSpellingLoc(FixLocation);
  if (FixLocation.isInvalid())
    return;

  // Try to insert the identifier location in the Usages map, and bail out if it
  // is already in there
  auto &Failure = Failures[Decl];
  if (!Failure.RawUsageLocs.insert(FixLocation.getRawEncoding()).second)
    return;

  if (!Failure.ShouldFix)
    return;

  Failure.ShouldFix = utils::rangeCanBeFixed(Range, SourceMgr);
}

/// Convenience method when the usage to be added is a NamedDecl
static void addUsage(IdentifierNamingCheck::NamingCheckFailureMap &Failures,
                     const NamedDecl *Decl, SourceRange Range,
                     SourceManager *SourceMgr = nullptr) {
  return addUsage(Failures,
                  IdentifierNamingCheck::NamingCheckId(Decl->getLocation(),
                                                       Decl->getNameAsString()),
                  Range, SourceMgr);
}

void IdentifierNamingCheck::check(const MatchFinder::MatchResult &Result) {
  if (const auto *Decl =
          Result.Nodes.getNodeAs<CXXConstructorDecl>("classRef")) {
    if (Decl->isImplicit())
      return;

    addUsage(NamingCheckFailures, Decl->getParent(),
             Decl->getNameInfo().getSourceRange());

    for (const auto *Init : Decl->inits()) {
      if (!Init->isWritten() || Init->isInClassMemberInitializer())
        continue;
      if (const auto *FD = Init->getAnyMember())
        addUsage(NamingCheckFailures, FD,
                 SourceRange(Init->getMemberLocation()));
      // Note: delegating constructors and base class initializers are handled
      // via the "typeLoc" matcher.
    }
    return;
  }

  if (const auto *Decl =
          Result.Nodes.getNodeAs<CXXDestructorDecl>("classRef")) {
    if (Decl->isImplicit())
      return;

    SourceRange Range = Decl->getNameInfo().getSourceRange();
    if (Range.getBegin().isInvalid())
      return;
    // The first token that will be found is the ~ (or the equivalent trigraph),
    // we want instead to replace the next token, that will be the identifier.
    Range.setBegin(CharSourceRange::getTokenRange(Range).getEnd());

    addUsage(NamingCheckFailures, Decl->getParent(), Range);
    return;
  }

  if (const auto *Loc = Result.Nodes.getNodeAs<TypeLoc>("typeLoc")) {
    NamedDecl *Decl = nullptr;
    if (const auto &Ref = Loc->getAs<TagTypeLoc>()) {
      Decl = Ref.getDecl();
    } else if (const auto &Ref = Loc->getAs<InjectedClassNameTypeLoc>()) {
      Decl = Ref.getDecl();
    } else if (const auto &Ref = Loc->getAs<UnresolvedUsingTypeLoc>()) {
      Decl = Ref.getDecl();
    } else if (const auto &Ref = Loc->getAs<TemplateTypeParmTypeLoc>()) {
      Decl = Ref.getDecl();
    }

    if (Decl) {
      addUsage(NamingCheckFailures, Decl, Loc->getSourceRange());
      return;
    }

    if (const auto &Ref = Loc->getAs<TemplateSpecializationTypeLoc>()) {
      const auto *Decl =
          Ref.getTypePtr()->getTemplateName().getAsTemplateDecl();

      SourceRange Range(Ref.getTemplateNameLoc(), Ref.getTemplateNameLoc());
      if (const auto *ClassDecl = dyn_cast<TemplateDecl>(Decl)) {
        if (const auto *TemplDecl = ClassDecl->getTemplatedDecl())
          addUsage(NamingCheckFailures, TemplDecl, Range);
        return;
      }
    }

    if (const auto &Ref =
            Loc->getAs<DependentTemplateSpecializationTypeLoc>()) {
      if (const auto *Decl = Ref.getTypePtr()->getAsTagDecl())
        addUsage(NamingCheckFailures, Decl, Loc->getSourceRange());
      return;
    }
  }

  if (const auto *Loc =
          Result.Nodes.getNodeAs<NestedNameSpecifierLoc>("nestedNameLoc")) {
    if (NestedNameSpecifier *Spec = Loc->getNestedNameSpecifier()) {
      if (NamespaceDecl *Decl = Spec->getAsNamespace()) {
        addUsage(NamingCheckFailures, Decl, Loc->getLocalSourceRange());
        return;
      }
    }
  }

  if (const auto *Decl = Result.Nodes.getNodeAs<UsingDecl>("using")) {
    for (const auto &Shadow : Decl->shadows()) {
      addUsage(NamingCheckFailures, Shadow->getTargetDecl(),
               Decl->getNameInfo().getSourceRange());
    }
    return;
  }

  if (const auto *DeclRef = Result.Nodes.getNodeAs<DeclRefExpr>("declRef")) {
    SourceRange Range = DeclRef->getNameInfo().getSourceRange();
    addUsage(NamingCheckFailures, DeclRef->getDecl(), Range,
             Result.SourceManager);
    return;
  }

  if (const auto *Decl = Result.Nodes.getNodeAs<NamedDecl>("decl")) {
    if (!Decl->getIdentifier() || Decl->getName().empty() || Decl->isImplicit())
      return;

    // Fix type aliases in value declarations
    if (const auto *Value = Result.Nodes.getNodeAs<ValueDecl>("decl")) {
      if (const auto *TypePtr = Value->getType().getTypePtrOrNull()) {
        if (const auto *Typedef = TypePtr->getAs<TypedefType>()) {
          addUsage(NamingCheckFailures, Typedef->getDecl(),
                   Value->getSourceRange());
        }
      }
    }

    // Fix type aliases in function declarations
    if (const auto *Value = Result.Nodes.getNodeAs<FunctionDecl>("decl")) {
      if (const auto *Typedef =
              Value->getReturnType().getTypePtr()->getAs<TypedefType>()) {
        addUsage(NamingCheckFailures, Typedef->getDecl(),
                 Value->getSourceRange());
      }
      for (unsigned i = 0; i < Value->getNumParams(); ++i) {
        if (const auto *Typedef = Value->parameters()[i]
                                      ->getType()
                                      .getTypePtr()
                                      ->getAs<TypedefType>()) {
          addUsage(NamingCheckFailures, Typedef->getDecl(),
                   Value->getSourceRange());
        }
      }
    }

    // Ignore ClassTemplateSpecializationDecl which are creating duplicate
    // replacements with CXXRecordDecl
    if (isa<ClassTemplateSpecializationDecl>(Decl))
      return;

    StyleKind SK = findStyleKind(Decl, NamingStyles);
    if (SK == SK_Invalid)
      return;

    if (!NamingStyles[SK])
      return;

    const NamingStyle &Style = *NamingStyles[SK];
    StringRef Name = Decl->getName();
    if (matchesStyle(Name, Style))
      return;

    std::string KindName = fixupWithCase(StyleNames[SK], CT_LowerCase);
    std::replace(KindName.begin(), KindName.end(), '_', ' ');

    std::string Fixup = fixupWithStyle(Name, Style);
    if (StringRef(Fixup).equals(Name)) {
      if (!IgnoreFailedSplit) {
        LLVM_DEBUG(llvm::dbgs()
                   << Decl->getBeginLoc().printToString(*Result.SourceManager)
                   << llvm::format(": unable to split words for %s '%s'\n",
                                   KindName.c_str(), Name.str().c_str()));
      }
    } else {
      NamingCheckFailure &Failure = NamingCheckFailures[NamingCheckId(
          Decl->getLocation(), Decl->getNameAsString())];
      SourceRange Range =
          DeclarationNameInfo(Decl->getDeclName(), Decl->getLocation())
              .getSourceRange();

      Failure.Fixup = std::move(Fixup);
      Failure.KindName = std::move(KindName);
      addUsage(NamingCheckFailures, Decl, Range);
    }
  }
}

void IdentifierNamingCheck::checkMacro(SourceManager &SourceMgr,
                                       const Token &MacroNameTok,
                                       const MacroInfo *MI) {
  if (!NamingStyles[SK_MacroDefinition])
    return;

  StringRef Name = MacroNameTok.getIdentifierInfo()->getName();
  const NamingStyle &Style = *NamingStyles[SK_MacroDefinition];
  if (matchesStyle(Name, Style))
    return;

  std::string KindName =
      fixupWithCase(StyleNames[SK_MacroDefinition], CT_LowerCase);
  std::replace(KindName.begin(), KindName.end(), '_', ' ');

  std::string Fixup = fixupWithStyle(Name, Style);
  if (StringRef(Fixup).equals(Name)) {
    if (!IgnoreFailedSplit) {
      LLVM_DEBUG(llvm::dbgs()
                 << MacroNameTok.getLocation().printToString(SourceMgr)
                 << llvm::format(": unable to split words for %s '%s'\n",
                                 KindName.c_str(), Name.str().c_str()));
    }
  } else {
    NamingCheckId ID(MI->getDefinitionLoc(), Name);
    NamingCheckFailure &Failure = NamingCheckFailures[ID];
    SourceRange Range(MacroNameTok.getLocation(), MacroNameTok.getEndLoc());

    Failure.Fixup = std::move(Fixup);
    Failure.KindName = std::move(KindName);
    addUsage(NamingCheckFailures, ID, Range);
  }
}

void IdentifierNamingCheck::expandMacro(const Token &MacroNameTok,
                                        const MacroInfo *MI) {
  StringRef Name = MacroNameTok.getIdentifierInfo()->getName();
  NamingCheckId ID(MI->getDefinitionLoc(), Name);

  auto Failure = NamingCheckFailures.find(ID);
  if (Failure == NamingCheckFailures.end())
    return;

  SourceRange Range(MacroNameTok.getLocation(), MacroNameTok.getEndLoc());
  addUsage(NamingCheckFailures, ID, Range);
}

void IdentifierNamingCheck::onEndOfTranslationUnit() {
  for (const auto &Pair : NamingCheckFailures) {
    const NamingCheckId &Decl = Pair.first;
    const NamingCheckFailure &Failure = Pair.second;

    if (Failure.KindName.empty())
      continue;

    if (Failure.ShouldFix) {
      auto Diag = diag(Decl.first, "invalid case style for %0 '%1'")
                  << Failure.KindName << Decl.second;

      for (const auto &Loc : Failure.RawUsageLocs) {
        // We assume that the identifier name is made of one token only. This is
        // always the case as we ignore usages in macros that could build
        // identifier names by combining multiple tokens.
        //
        // For destructors, we alread take care of it by remembering the
        // location of the start of the identifier and not the start of the
        // tilde.
        //
        // Other multi-token identifiers, such as operators are not checked at
        // all.
        Diag << FixItHint::CreateReplacement(
            SourceRange(SourceLocation::getFromRawEncoding(Loc)),
            Failure.Fixup);
      }
    }
  }
}

} // namespace readability
} // namespace tidy
} // namespace clang
