10#include "../utils/Matchers.h"
11#include "../utils/OptionsUtils.h"
12#include "clang/AST/ASTContext.h"
13#include "clang/ASTMatchers/ASTMatchFinder.h"
14#include "clang/Lex/Token.h"
31 "declaration uses identifier '%0', which is %select{a reserved "
32 "identifier|not a reserved identifier|reserved in the global namespace}1";
42llvm::SmallVector<llvm::Regex>
43ReservedIdentifierCheck::parseAllowedIdentifiers()
const {
44 llvm::SmallVector<llvm::Regex> AllowedIdentifiers;
45 AllowedIdentifiers.reserve(AllowedIdentifiersRaw.size());
47 for (
const auto &Identifier : AllowedIdentifiersRaw) {
48 AllowedIdentifiers.emplace_back(Identifier.str());
49 if (!AllowedIdentifiers.back().isValid()) {
51 AllowedIdentifiers.pop_back();
55 return AllowedIdentifiers;
61 Invert(Options.get(
"Invert", false)),
62 AllowedIdentifiersRaw(utils::options::parseStringList(
63 Options.get(
"AllowedIdentifiers",
""))),
64 AllowedIdentifiers(parseAllowedIdentifiers()) {}
75 std::unique_copy(Str.begin(), Str.end(), std::back_inserter(Result),
76 [
C](
char A,
char B) { return A == C && B == C; });
81 const LangOptions &LangOpts) {
82 if (LangOpts.CPlusPlus)
83 return Name.contains(
"__");
84 return Name.starts_with(
"__");
87static std::optional<std::string>
95 return Name.size() >= 2 &&
Name[0] ==
'_' && std::isupper(
Name[1]);
100 return std::string(
Name.drop_front(1));
105 bool IsInGlobalNamespace,
107 return !IsMacro && IsInGlobalNamespace &&
Name.starts_with(
"_");
110static std::optional<std::string>
114 return std::string(
Name.drop_front(1));
119 assert(!
Name.empty());
120 if (
Name[0] ==
'_' || std::isupper(
Name[0]))
127static std::optional<RenamerClangTidyCheck::FailureInfo>
129 const LangOptions &LangOpts,
bool Invert,
130 ArrayRef<llvm::Regex> AllowedIdentifiers) {
131 assert(!
Name.empty());
133 if (llvm::any_of(AllowedIdentifiers, [&](
const llvm::Regex &Regex) {
134 return Regex.match(
Name);
144 std::optional<FailureInfo>
Info;
145 auto AppendFailure = [&](StringRef
Kind, std::string &&Fixup) {
147 Info = FailureInfo{std::string(
Kind), std::move(Fixup)};
150 Info->Fixup = std::move(Fixup);
153 auto InProgressFixup = [&] {
154 return llvm::transformOptional(
156 [](
const FailureInfo &
Info) {
return StringRef(
Info.Fixup); })
164 InProgressFixup(), IsInGlobalNamespace, IsMacro))
177std::optional<RenamerClangTidyCheck::FailureInfo>
178ReservedIdentifierCheck::getDeclFailureInfo(
const NamedDecl *
Decl,
179 const SourceManager &)
const {
180 assert(
Decl &&
Decl->getIdentifier() && !
Decl->getName().empty() &&
181 "Decl must be an explicit identifier with a name.");
183 if (
Decl->isImplicit())
187 Decl->getName(), isa<TranslationUnitDecl>(
Decl->getDeclContext()),
191std::optional<RenamerClangTidyCheck::FailureInfo>
192ReservedIdentifierCheck::getMacroFailureInfo(
const Token &MacroNameTok,
193 const SourceManager &)
const {
199RenamerClangTidyCheck::DiagInfo
200ReservedIdentifierCheck::getDiagInfo(
const NamingCheckId &
ID,
201 const NamingCheckFailure &Failure)
const {
202 return DiagInfo{
Message, [&](DiagnosticBuilder &Diag) {
const FunctionDecl * Decl
llvm::SmallString< 256U > Name
void store(ClangTidyOptions::OptionMap &Options, StringRef LocalName, StringRef Value) const
Stores an option with the check-local name LocalName with string value Value to Options.
DiagnosticBuilder configurationDiag(StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning) const
Adds a diagnostic to report errors in the check's configuration.
const LangOptions & getLangOpts() const
Returns the language options from the context.
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
Base class for clang-tidy checks that want to flag declarations and/or macros for renaming based on c...
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
Derived classes that override this function should call this method from the overridden method.
ReservedIdentifierCheck(StringRef Name, ClangTidyContext *Context)
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
Should store all options supported by this check with their current values or default values for opti...
static std::optional< std::string > getDoubleUnderscoreFixup(StringRef Name, const LangOptions &LangOpts)
static const char DoubleUnderscoreTag[]
static const char GlobalUnderscoreTag[]
static const char Message[]
static std::optional< std::string > getUnderscoreGlobalNamespaceFixup(StringRef Name, bool IsInGlobalNamespace, bool IsMacro)
static const char UnderscoreCapitalTag[]
static std::string getNonReservedFixup(std::string Name)
static const char NonReservedTag[]
static std::optional< RenamerClangTidyCheck::FailureInfo > getFailureInfoImpl(StringRef Name, bool IsInGlobalNamespace, bool IsMacro, const LangOptions &LangOpts, bool Invert, ArrayRef< llvm::Regex > AllowedIdentifiers)
static std::string collapseConsecutive(StringRef Str, char C)
static bool hasReservedDoubleUnderscore(StringRef Name, const LangOptions &LangOpts)
static bool startsWithUnderscoreCapital(StringRef Name)
static bool startsWithUnderscoreInGlobalNamespace(StringRef Name, bool IsInGlobalNamespace, bool IsMacro)
static std::optional< std::string > getUnderscoreCapitalFixup(StringRef Name)
static int getMessageSelectIndex(StringRef Tag)
std::string serializeStringList(ArrayRef< StringRef > Strings)
Serialize a sequence of names that can be parsed by parseStringList.
llvm::StringMap< ClangTidyValue > OptionMap
Information describing a failed check.