clang-tools  13.0.0git
RenamerClangTidyCheck.cpp
Go to the documentation of this file.
1 //===--- RenamerClangTidyCheck.cpp - clang-tidy ---------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "ASTUtils.h"
11 #include "clang/AST/CXXInheritance.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
13 #include "clang/Basic/CharInfo.h"
14 #include "clang/Frontend/CompilerInstance.h"
15 #include "clang/Lex/PPCallbacks.h"
16 #include "clang/Lex/Preprocessor.h"
17 #include "llvm/ADT/DenseMapInfo.h"
18 #include "llvm/ADT/PointerIntPair.h"
19 
20 #define DEBUG_TYPE "clang-tidy"
21 
22 using namespace clang::ast_matchers;
23 
24 namespace llvm {
25 
26 /// Specialisation of DenseMapInfo to allow NamingCheckId objects in DenseMaps
27 template <>
30 
31  static inline NamingCheckId getEmptyKey() {
32  return NamingCheckId(DenseMapInfo<clang::SourceLocation>::getEmptyKey(),
33  "EMPTY");
34  }
35 
36  static inline NamingCheckId getTombstoneKey() {
37  return NamingCheckId(DenseMapInfo<clang::SourceLocation>::getTombstoneKey(),
38  "TOMBSTONE");
39  }
40 
41  static unsigned getHashValue(NamingCheckId Val) {
42  assert(Val != getEmptyKey() && "Cannot hash the empty key!");
43  assert(Val != getTombstoneKey() && "Cannot hash the tombstone key!");
44 
45  std::hash<NamingCheckId::second_type> SecondHash;
46  return DenseMapInfo<clang::SourceLocation>::getHashValue(Val.first) +
47  SecondHash(Val.second);
48  }
49 
50  static bool isEqual(const NamingCheckId &LHS, const NamingCheckId &RHS) {
51  if (RHS == getEmptyKey())
52  return LHS == getEmptyKey();
53  if (RHS == getTombstoneKey())
54  return LHS == getTombstoneKey();
55  return LHS == RHS;
56  }
57 };
58 
59 } // namespace llvm
60 
61 namespace clang {
62 namespace tidy {
63 
64 namespace {
65 
66 /// Callback supplies macros to RenamerClangTidyCheck::checkMacro
67 class RenamerClangTidyCheckPPCallbacks : public PPCallbacks {
68 public:
69  RenamerClangTidyCheckPPCallbacks(Preprocessor *PP,
70  RenamerClangTidyCheck *Check)
71  : PP(PP), Check(Check) {}
72 
73  /// MacroDefined calls checkMacro for macros in the main file
74  void MacroDefined(const Token &MacroNameTok,
75  const MacroDirective *MD) override {
76  if (MD->getMacroInfo()->isBuiltinMacro())
77  return;
78  if (PP->getSourceManager().isWrittenInBuiltinFile(
79  MacroNameTok.getLocation()))
80  return;
81  if (PP->getSourceManager().isWrittenInCommandLineFile(
82  MacroNameTok.getLocation()))
83  return;
84  Check->checkMacro(PP->getSourceManager(), MacroNameTok, MD->getMacroInfo());
85  }
86 
87  /// MacroExpands calls expandMacro for macros in the main file
88  void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
89  SourceRange /*Range*/,
90  const MacroArgs * /*Args*/) override {
91  Check->expandMacro(MacroNameTok, MD.getMacroInfo());
92  }
93 
94 private:
95  Preprocessor *PP;
96  RenamerClangTidyCheck *Check;
97 };
98 
99 } // namespace
100 
101 RenamerClangTidyCheck::RenamerClangTidyCheck(StringRef CheckName,
102  ClangTidyContext *Context)
103  : ClangTidyCheck(CheckName, Context),
104  AggressiveDependentMemberLookup(
105  Options.getLocalOrGlobal("AggressiveDependentMemberLookup", false)) {}
107 
109  Options.store(Opts, "AggressiveDependentMemberLookup",
110  AggressiveDependentMemberLookup);
111 }
112 
113 void RenamerClangTidyCheck::registerMatchers(MatchFinder *Finder) {
114  Finder->addMatcher(namedDecl().bind("decl"), this);
115  Finder->addMatcher(usingDecl().bind("using"), this);
116  Finder->addMatcher(declRefExpr().bind("declRef"), this);
117  Finder->addMatcher(cxxConstructorDecl(unless(isImplicit())).bind("classRef"),
118  this);
119  Finder->addMatcher(cxxDestructorDecl(unless(isImplicit())).bind("classRef"),
120  this);
121  Finder->addMatcher(typeLoc().bind("typeLoc"), this);
122  Finder->addMatcher(nestedNameSpecifierLoc().bind("nestedNameLoc"), this);
123  auto MemberRestrictions =
124  unless(forFunction(anyOf(isDefaulted(), isImplicit())));
125  Finder->addMatcher(memberExpr(MemberRestrictions).bind("memberExpr"), this);
126  Finder->addMatcher(
127  cxxDependentScopeMemberExpr(MemberRestrictions).bind("depMemberExpr"),
128  this);
129 }
130 
132  const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
133  ModuleExpanderPP->addPPCallbacks(
134  std::make_unique<RenamerClangTidyCheckPPCallbacks>(ModuleExpanderPP,
135  this));
136 }
137 
138 /// Returns the function that \p Method is overridding. If There are none or
139 /// multiple overrides it returns nullptr. If the overridden function itself is
140 /// overridding then it will recurse up to find the first decl of the function.
141 static const CXXMethodDecl *getOverrideMethod(const CXXMethodDecl *Method) {
142  if (Method->size_overridden_methods() != 1)
143  return nullptr;
144  while (true) {
145  Method = *Method->begin_overridden_methods();
146  assert(Method && "Overridden method shouldn't be null");
147  unsigned NumOverrides = Method->size_overridden_methods();
148  if (NumOverrides == 0)
149  return Method;
150  if (NumOverrides > 1)
151  return nullptr;
152  }
153 }
154 
156  const RenamerClangTidyCheck::NamingCheckId &Decl, SourceRange Range,
157  SourceManager *SourceMgr) {
158  // Do nothing if the provided range is invalid.
159  if (Range.isInvalid())
160  return;
161 
162  // If we have a source manager, use it to convert to the spelling location for
163  // performing the fix. This is necessary because macros can map the same
164  // spelling location to different source locations, and we only want to fix
165  // the token once, before it is expanded by the macro.
166  SourceLocation FixLocation = Range.getBegin();
167  if (SourceMgr)
168  FixLocation = SourceMgr->getSpellingLoc(FixLocation);
169  if (FixLocation.isInvalid())
170  return;
171 
172  // Try to insert the identifier location in the Usages map, and bail out if it
173  // is already in there
175  NamingCheckFailures[Decl];
176  if (!Failure.RawUsageLocs.insert(FixLocation).second)
177  return;
178 
179  if (!Failure.ShouldFix())
180  return;
181 
182  if (SourceMgr && SourceMgr->isWrittenInScratchSpace(FixLocation))
184 
187 }
188 
189 void RenamerClangTidyCheck::addUsage(const NamedDecl *Decl, SourceRange Range,
190  SourceManager *SourceMgr) {
191  if (const auto *Method = dyn_cast<CXXMethodDecl>(Decl)) {
192  if (const CXXMethodDecl *Overridden = getOverrideMethod(Method))
193  Decl = Overridden;
194  }
195  Decl = cast<NamedDecl>(Decl->getCanonicalDecl());
196  return addUsage(RenamerClangTidyCheck::NamingCheckId(Decl->getLocation(),
197  Decl->getNameAsString()),
198  Range, SourceMgr);
199 }
200 
201 const NamedDecl *findDecl(const RecordDecl &RecDecl, StringRef DeclName) {
202  for (const Decl *D : RecDecl.decls()) {
203  if (const auto *ND = dyn_cast<NamedDecl>(D)) {
204  if (ND->getDeclName().isIdentifier() && ND->getName().equals(DeclName))
205  return ND;
206  }
207  }
208  return nullptr;
209 }
210 
211 namespace {
212 class NameLookup {
213  llvm::PointerIntPair<const NamedDecl *, 1, bool> Data;
214 
215 public:
216  explicit NameLookup(const NamedDecl *ND) : Data(ND, false) {}
217  explicit NameLookup(llvm::NoneType) : Data(nullptr, true) {}
218  explicit NameLookup(std::nullptr_t) : Data(nullptr, false) {}
219  NameLookup() : NameLookup(nullptr) {}
220 
221  bool hasMultipleResolutions() const { return Data.getInt(); }
222  const NamedDecl *getDecl() const {
223  assert(!hasMultipleResolutions() && "Found multiple decls");
224  return Data.getPointer();
225  }
226  operator bool() const { return !hasMultipleResolutions(); }
227  const NamedDecl *operator*() const { return getDecl(); }
228 };
229 } // namespace
230 
231 /// Returns a decl matching the \p DeclName in \p Parent or one of its base
232 /// classes. If \p AggressiveTemplateLookup is `true` then it will check
233 /// template dependent base classes as well.
234 /// If a matching decl is found in multiple base classes then it will return a
235 /// flag indicating the multiple resolutions.
236 NameLookup findDeclInBases(const CXXRecordDecl &Parent, StringRef DeclName,
237  bool AggressiveTemplateLookup) {
238  if (!Parent.hasDefinition())
239  return NameLookup(nullptr);
240  if (const NamedDecl *InClassRef = findDecl(Parent, DeclName))
241  return NameLookup(InClassRef);
242  const NamedDecl *Found = nullptr;
243 
244  for (CXXBaseSpecifier Base : Parent.bases()) {
245  const auto *Record = Base.getType()->getAsCXXRecordDecl();
246  if (!Record && AggressiveTemplateLookup) {
247  if (const auto *TST =
248  Base.getType()->getAs<TemplateSpecializationType>()) {
249  if (const auto *TD = llvm::dyn_cast_or_null<ClassTemplateDecl>(
250  TST->getTemplateName().getAsTemplateDecl()))
251  Record = TD->getTemplatedDecl();
252  }
253  }
254  if (!Record)
255  continue;
256  if (auto Search =
257  findDeclInBases(*Record, DeclName, AggressiveTemplateLookup)) {
258  if (*Search) {
259  if (Found)
260  return NameLookup(
261  llvm::None); // Multiple decls found in different base classes.
262  Found = *Search;
263  continue;
264  }
265  } else
266  return NameLookup(llvm::None); // Propagate multiple resolution back up.
267  }
268  return NameLookup(Found); // If nullptr, decl wasnt found.
269 }
270 
271 void RenamerClangTidyCheck::check(const MatchFinder::MatchResult &Result) {
272  if (const auto *Decl =
273  Result.Nodes.getNodeAs<CXXConstructorDecl>("classRef")) {
274 
275  addUsage(Decl->getParent(), Decl->getNameInfo().getSourceRange(),
276  Result.SourceManager);
277 
278  for (const auto *Init : Decl->inits()) {
279  if (!Init->isWritten() || Init->isInClassMemberInitializer())
280  continue;
281  if (const FieldDecl *FD = Init->getAnyMember())
282  addUsage(FD, SourceRange(Init->getMemberLocation()),
283  Result.SourceManager);
284  // Note: delegating constructors and base class initializers are handled
285  // via the "typeLoc" matcher.
286  }
287  return;
288  }
289 
290  if (const auto *Decl =
291  Result.Nodes.getNodeAs<CXXDestructorDecl>("classRef")) {
292 
293  SourceRange Range = Decl->getNameInfo().getSourceRange();
294  if (Range.getBegin().isInvalid())
295  return;
296  // The first token that will be found is the ~ (or the equivalent trigraph),
297  // we want instead to replace the next token, that will be the identifier.
298  Range.setBegin(CharSourceRange::getTokenRange(Range).getEnd());
299 
300  addUsage(Decl->getParent(), Range, Result.SourceManager);
301  return;
302  }
303 
304  if (const auto *Loc = Result.Nodes.getNodeAs<TypeLoc>("typeLoc")) {
305  UnqualTypeLoc Unqual = Loc->getUnqualifiedLoc();
306  NamedDecl *Decl = nullptr;
307  if (const auto &Ref = Unqual.getAs<TagTypeLoc>())
308  Decl = Ref.getDecl();
309  else if (const auto &Ref = Unqual.getAs<InjectedClassNameTypeLoc>())
310  Decl = Ref.getDecl();
311  else if (const auto &Ref = Unqual.getAs<UnresolvedUsingTypeLoc>())
312  Decl = Ref.getDecl();
313  else if (const auto &Ref = Unqual.getAs<TemplateTypeParmTypeLoc>())
314  Decl = Ref.getDecl();
315  // further TypeLocs handled below
316 
317  if (Decl) {
318  addUsage(Decl, Loc->getSourceRange(), Result.SourceManager);
319  return;
320  }
321 
322  if (const auto &Ref = Loc->getAs<TemplateSpecializationTypeLoc>()) {
323  const TemplateDecl *Decl =
324  Ref.getTypePtr()->getTemplateName().getAsTemplateDecl();
325 
326  SourceRange Range(Ref.getTemplateNameLoc(), Ref.getTemplateNameLoc());
327  if (const auto *ClassDecl = dyn_cast<TemplateDecl>(Decl)) {
328  if (const NamedDecl *TemplDecl = ClassDecl->getTemplatedDecl())
329  addUsage(TemplDecl, Range, Result.SourceManager);
330  return;
331  }
332  }
333 
334  if (const auto &Ref =
335  Loc->getAs<DependentTemplateSpecializationTypeLoc>()) {
336  if (const TagDecl *Decl = Ref.getTypePtr()->getAsTagDecl())
337  addUsage(Decl, Loc->getSourceRange(), Result.SourceManager);
338  return;
339  }
340  }
341 
342  if (const auto *Loc =
343  Result.Nodes.getNodeAs<NestedNameSpecifierLoc>("nestedNameLoc")) {
344  if (const NestedNameSpecifier *Spec = Loc->getNestedNameSpecifier()) {
345  if (const NamespaceDecl *Decl = Spec->getAsNamespace()) {
346  addUsage(Decl, Loc->getLocalSourceRange(), Result.SourceManager);
347  return;
348  }
349  }
350  }
351 
352  if (const auto *Decl = Result.Nodes.getNodeAs<UsingDecl>("using")) {
353  for (const auto *Shadow : Decl->shadows())
354  addUsage(Shadow->getTargetDecl(), Decl->getNameInfo().getSourceRange(),
355  Result.SourceManager);
356  return;
357  }
358 
359  if (const auto *DeclRef = Result.Nodes.getNodeAs<DeclRefExpr>("declRef")) {
360  SourceRange Range = DeclRef->getNameInfo().getSourceRange();
361  addUsage(DeclRef->getDecl(), Range, Result.SourceManager);
362  return;
363  }
364 
365  if (const auto *MemberRef =
366  Result.Nodes.getNodeAs<MemberExpr>("memberExpr")) {
367  SourceRange Range = MemberRef->getMemberNameInfo().getSourceRange();
368  addUsage(MemberRef->getMemberDecl(), Range, Result.SourceManager);
369  return;
370  }
371 
372  if (const auto *DepMemberRef =
373  Result.Nodes.getNodeAs<CXXDependentScopeMemberExpr>(
374  "depMemberExpr")) {
375  QualType BaseType = DepMemberRef->isArrow()
376  ? DepMemberRef->getBaseType()->getPointeeType()
377  : DepMemberRef->getBaseType();
378  if (BaseType.isNull())
379  return;
380  const CXXRecordDecl *Base = BaseType.getTypePtr()->getAsCXXRecordDecl();
381  if (!Base)
382  return;
383  DeclarationName DeclName = DepMemberRef->getMemberNameInfo().getName();
384  if (!DeclName.isIdentifier())
385  return;
386  StringRef DependentName = DeclName.getAsIdentifierInfo()->getName();
387 
388  if (NameLookup Resolved = findDeclInBases(
389  *Base, DependentName, AggressiveDependentMemberLookup)) {
390  if (*Resolved)
391  addUsage(*Resolved, DepMemberRef->getMemberNameInfo().getSourceRange(),
392  Result.SourceManager);
393  }
394  return;
395  }
396 
397  if (const auto *Decl = Result.Nodes.getNodeAs<NamedDecl>("decl")) {
398  // Fix using namespace declarations.
399  if (const auto *UsingNS = dyn_cast<UsingDirectiveDecl>(Decl))
400  addUsage(UsingNS->getNominatedNamespaceAsWritten(),
401  UsingNS->getIdentLocation(), Result.SourceManager);
402 
403  if (!Decl->getIdentifier() || Decl->getName().empty() || Decl->isImplicit())
404  return;
405 
406  const auto *Canonical = cast<NamedDecl>(Decl->getCanonicalDecl());
407  if (Canonical != Decl) {
408  addUsage(Canonical, Decl->getLocation(), Result.SourceManager);
409  return;
410  }
411 
412  // Fix type aliases in value declarations.
413  if (const auto *Value = Result.Nodes.getNodeAs<ValueDecl>("decl")) {
414  if (const Type *TypePtr = Value->getType().getTypePtrOrNull()) {
415  if (const auto *Typedef = TypePtr->getAs<TypedefType>())
416  addUsage(Typedef->getDecl(), Value->getSourceRange(),
417  Result.SourceManager);
418  }
419  }
420 
421  // Fix type aliases in function declarations.
422  if (const auto *Value = Result.Nodes.getNodeAs<FunctionDecl>("decl")) {
423  if (const auto *Typedef =
424  Value->getReturnType().getTypePtr()->getAs<TypedefType>())
425  addUsage(Typedef->getDecl(), Value->getSourceRange(),
426  Result.SourceManager);
427  for (const ParmVarDecl *Param : Value->parameters()) {
428  if (const TypedefType *Typedef =
429  Param->getType().getTypePtr()->getAs<TypedefType>())
430  addUsage(Typedef->getDecl(), Value->getSourceRange(),
431  Result.SourceManager);
432  }
433  }
434 
435  // Fix overridden methods
436  if (const auto *Method = Result.Nodes.getNodeAs<CXXMethodDecl>("decl")) {
437  if (const CXXMethodDecl *Overridden = getOverrideMethod(Method)) {
438  addUsage(Overridden, Method->getLocation());
439  return; // Don't try to add the actual decl as a Failure.
440  }
441  }
442 
443  // Ignore ClassTemplateSpecializationDecl which are creating duplicate
444  // replacements with CXXRecordDecl.
445  if (isa<ClassTemplateSpecializationDecl>(Decl))
446  return;
447 
448  Optional<FailureInfo> MaybeFailure =
449  GetDeclFailureInfo(Decl, *Result.SourceManager);
450  if (!MaybeFailure)
451  return;
452  FailureInfo &Info = *MaybeFailure;
453  NamingCheckFailure &Failure = NamingCheckFailures[NamingCheckId(
454  Decl->getLocation(), Decl->getNameAsString())];
455  SourceRange Range =
456  DeclarationNameInfo(Decl->getDeclName(), Decl->getLocation())
457  .getSourceRange();
458 
459  const IdentifierTable &Idents = Decl->getASTContext().Idents;
460  auto CheckNewIdentifier = Idents.find(Info.Fixup);
461  if (CheckNewIdentifier != Idents.end()) {
462  const IdentifierInfo *Ident = CheckNewIdentifier->second;
463  if (Ident->isKeyword(getLangOpts()))
465  else if (Ident->hasMacroDefinition())
467  } else if (!isValidIdentifier(Info.Fixup)) {
469  }
470 
471  Failure.Info = std::move(Info);
472  addUsage(Decl, Range);
473  }
474 }
475 
477  const Token &MacroNameTok,
478  const MacroInfo *MI) {
479  Optional<FailureInfo> MaybeFailure =
480  GetMacroFailureInfo(MacroNameTok, SourceMgr);
481  if (!MaybeFailure)
482  return;
483  FailureInfo &Info = *MaybeFailure;
484  StringRef Name = MacroNameTok.getIdentifierInfo()->getName();
485  NamingCheckId ID(MI->getDefinitionLoc(), std::string(Name));
486  NamingCheckFailure &Failure = NamingCheckFailures[ID];
487  SourceRange Range(MacroNameTok.getLocation(), MacroNameTok.getEndLoc());
488 
489  Failure.Info = std::move(Info);
490  addUsage(ID, Range);
491 }
492 
493 void RenamerClangTidyCheck::expandMacro(const Token &MacroNameTok,
494  const MacroInfo *MI) {
495  StringRef Name = MacroNameTok.getIdentifierInfo()->getName();
496  NamingCheckId ID(MI->getDefinitionLoc(), std::string(Name));
497 
498  auto Failure = NamingCheckFailures.find(ID);
499  if (Failure == NamingCheckFailures.end())
500  return;
501 
502  SourceRange Range(MacroNameTok.getLocation(), MacroNameTok.getEndLoc());
503  addUsage(ID, Range);
504 }
505 
506 static std::string
508  const std::string &Fixup) {
509  if (Fixup.empty() ||
511  return "; cannot be fixed automatically";
513  return {};
514  if (FixStatus >=
516  return {};
518  return "; cannot be fixed because '" + Fixup +
519  "' would conflict with a keyword";
520  if (FixStatus ==
522  return "; cannot be fixed because '" + Fixup +
523  "' would conflict with a macro definition";
524  llvm_unreachable("invalid ShouldFixStatus");
525 }
526 
528  for (const auto &Pair : NamingCheckFailures) {
529  const NamingCheckId &Decl = Pair.first;
530  const NamingCheckFailure &Failure = Pair.second;
531 
532  if (Failure.Info.KindName.empty())
533  continue;
534 
535  if (Failure.ShouldNotify()) {
536  auto DiagInfo = GetDiagInfo(Decl, Failure);
537  auto Diag = diag(Decl.first,
539  Failure.Info.Fixup));
540  DiagInfo.ApplyArgs(Diag);
541 
542  if (Failure.ShouldFix()) {
543  for (const auto &Loc : Failure.RawUsageLocs) {
544  // We assume that the identifier name is made of one token only. This
545  // is always the case as we ignore usages in macros that could build
546  // identifier names by combining multiple tokens.
547  //
548  // For destructors, we already take care of it by remembering the
549  // location of the start of the identifier and not the start of the
550  // tilde.
551  //
552  // Other multi-token identifiers, such as operators are not checked at
553  // all.
554  Diag << FixItHint::CreateReplacement(SourceRange(Loc),
555  Failure.Info.Fixup);
556  }
557  }
558  }
559  }
560 }
561 
562 } // namespace tidy
563 } // namespace clang
Range
CharSourceRange Range
SourceRange for the file name.
Definition: IncludeOrderCheck.cpp:38
Loc
SourceLocation Loc
Definition: KernelNameRestrictionCheck.cpp:45
Base
std::unique_ptr< GlobalCompilationDatabase > Base
Definition: GlobalCompilationDatabaseTests.cpp:90
llvm
Some operations such as code completion produce a set of candidates.
Definition: YAMLGenerator.cpp:28
clang::tidy::ClangTidyOptions::OptionMap
llvm::StringMap< ClangTidyValue > OptionMap
Definition: ClangTidyOptions.h:115
llvm::DenseMapInfo< clang::tidy::RenamerClangTidyCheck::NamingCheckId >::getHashValue
static unsigned getHashValue(NamingCheckId Val)
Definition: RenamerClangTidyCheck.cpp:41
Type
NodeType Type
Definition: HTMLGenerator.cpp:73
clang::doc::MD
static GeneratorRegistry::Add< MDGenerator > MD(MDGenerator::Format, "Generator for MD output.")
llvm::DenseMapInfo< clang::tidy::RenamerClangTidyCheck::NamingCheckId >::isEqual
static bool isEqual(const NamingCheckId &LHS, const NamingCheckId &RHS)
Definition: RenamerClangTidyCheck.cpp:50
clang::tidy::RenamerClangTidyCheck::FailureInfo::KindName
std::string KindName
Definition: RenamerClangTidyCheck.h:76
clang::tidy::RenamerClangTidyCheck::storeOptions
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
Derived classes that override this function should call this method from the overridden method.
Definition: RenamerClangTidyCheck.cpp:108
clang::tidy::RenamerClangTidyCheck::NamingCheckFailure::ShouldFix
bool ShouldFix() const
Whether the failure should be fixed or not.
Definition: RenamerClangTidyCheck.h:90
clang::tidy::ClangTidyCheck
Base class for all clang-tidy checks.
Definition: ClangTidyCheck.h:54
clang::tidy::RenamerClangTidyCheck::~RenamerClangTidyCheck
~RenamerClangTidyCheck()
clang::tidy::RenamerClangTidyCheck::NamingCheckFailure
Holds an identifier name check failure, tracking the kind of the identifier, its possible fixup and t...
Definition: RenamerClangTidyCheck.h:83
clang::tidy::RenamerClangTidyCheck::DiagInfo
Represents customized diagnostic text and how arguments should be applied.
Definition: RenamerClangTidyCheck.h:145
SourceMgr
llvm::SourceMgr * SourceMgr
Definition: ConfigCompile.cpp:101
clang::tidy::RenamerClangTidyCheck::checkMacro
void checkMacro(SourceManager &sourceMgr, const Token &MacroNameTok, const MacroInfo *MI)
Check Macros for style violations.
Definition: RenamerClangTidyCheck.cpp:476
clang::tidy::ClangTidyCheck::getLangOpts
const LangOptions & getLangOpts() const
Returns the language options from the context.
Definition: ClangTidyCheck.h:420
clang::tidy::RenamerClangTidyCheck::check
void check(const ast_matchers::MatchFinder::MatchResult &Result) override final
ClangTidyChecks that register ASTMatchers should do the actual work in here.
Definition: RenamerClangTidyCheck.cpp:271
clang::ast_matchers
Definition: AbseilMatcher.h:14
clang::tidy::RenamerClangTidyCheck::GetDiagInfo
virtual DiagInfo GetDiagInfo(const NamingCheckId &ID, const NamingCheckFailure &Failure) const =0
Overridden by derived classes, returns a description of the diagnostic that should be emitted for the...
clang::tidy::RenamerClangTidyCheck::GetDeclFailureInfo
virtual llvm::Optional< FailureInfo > GetDeclFailureInfo(const NamedDecl *Decl, const SourceManager &SM) const =0
Overridden by derived classes, returns information about if and how a Decl failed the check.
clang::tidy::RenamerClangTidyCheck::onEndOfTranslationUnit
void onEndOfTranslationUnit() override final
Definition: RenamerClangTidyCheck.cpp:527
clang::tidy::RenamerClangTidyCheck::DiagInfo::Text
std::string Text
Definition: RenamerClangTidyCheck.h:146
ns1::ns2::D
@ D
Definition: CategoricalFeature.h:3
llvm::DenseMapInfo< clang::tidy::RenamerClangTidyCheck::NamingCheckId >::getEmptyKey
static NamingCheckId getEmptyKey()
Definition: RenamerClangTidyCheck.cpp:31
clang::tidy::RenamerClangTidyCheck::NamingCheckFailure::FixStatus
ShouldFixStatus FixStatus
Definition: RenamerClangTidyCheck.h:98
Decl
const FunctionDecl * Decl
Definition: AvoidBindCheck.cpp:100
clang::tidy::RenamerClangTidyCheck::ShouldFixStatus
ShouldFixStatus
This enum will be used in select of the diagnostic message.
Definition: RenamerClangTidyCheck.h:50
clang::tidy::RenamerClangTidyCheck::NamingCheckFailure::ShouldNotify
bool ShouldNotify() const
Definition: RenamerClangTidyCheck.h:94
RenamerClangTidyCheck.h
clang::tidy::RenamerClangTidyCheck::ShouldFixStatus::InsideMacro
@ InsideMacro
If the identifier was used or declared within a macro we won't offer a fixup for safety reasons.
clang::tidy::ClangTidyCheck::Options
OptionsView Options
Definition: ClangTidyCheck.h:416
clang::tidy::RenamerClangTidyCheck::ShouldFixStatus::IgnoreFailureThreshold
@ IgnoreFailureThreshold
Values pass this threshold will be ignored completely i.e no message, no fixup.
clang::tidy::ClangTidyContext
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
Definition: ClangTidyDiagnosticConsumer.h:76
Name
static constexpr llvm::StringLiteral Name
Definition: UppercaseLiteralSuffixCheck.cpp:27
clang::tidy::RenamerClangTidyCheck::NamingCheckFailure::RawUsageLocs
llvm::DenseSet< SourceLocation > RawUsageLocs
A set of all the identifier usages starting SourceLocation.
Definition: RenamerClangTidyCheck.h:101
clang::tidy::RenamerClangTidyCheck::NamingCheckFailure::Info
FailureInfo Info
Definition: RenamerClangTidyCheck.h:84
clang::tidy::RenamerClangTidyCheck::FailureInfo::Fixup
std::string Fixup
Definition: RenamerClangTidyCheck.h:77
llvm::DenseMapInfo< clang::tidy::RenamerClangTidyCheck::NamingCheckId >::getTombstoneKey
static NamingCheckId getTombstoneKey()
Definition: RenamerClangTidyCheck.cpp:36
clang::tidy::ClangTidyCheck::diag
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
Definition: ClangTidyCheck.cpp:25
clang::tidy::RenamerClangTidyCheck::ShouldFixStatus::ShouldFix
@ ShouldFix
clang::tidy::RenamerClangTidyCheck::addUsage
void addUsage(const RenamerClangTidyCheck::NamingCheckId &Decl, SourceRange Range, SourceManager *SourceMgr=nullptr)
Definition: RenamerClangTidyCheck.cpp:155
Parent
const Node * Parent
Definition: ExtractFunction.cpp:152
clang::tidy::getOverrideMethod
static const CXXMethodDecl * getOverrideMethod(const CXXMethodDecl *Method)
Returns the function that Method is overridding.
Definition: RenamerClangTidyCheck.cpp:141
DeclRef
const DeclRefExpr * DeclRef
Definition: UseAfterMoveCheck.cpp:50
clang::tidy::RenamerClangTidyCheck::expandMacro
void expandMacro(const Token &MacroNameTok, const MacroInfo *MI)
Add a usage of a macro if it already has a violation.
Definition: RenamerClangTidyCheck.cpp:493
clang::tidy::RenamerClangTidyCheck::NamingCheckId
std::pair< SourceLocation, std::string > NamingCheckId
Definition: RenamerClangTidyCheck.h:106
clang::tidy::getDiagnosticSuffix
static std::string getDiagnosticSuffix(const RenamerClangTidyCheck::ShouldFixStatus FixStatus, const std::string &Fixup)
Definition: RenamerClangTidyCheck.cpp:507
Info
FunctionInfo Info
Definition: FunctionSizeCheck.cpp:120
ID
static char ID
Definition: Logger.cpp:74
clang::tidy::RenamerClangTidyCheck::registerMatchers
void registerMatchers(ast_matchers::MatchFinder *Finder) override final
Derived classes should not implement any matching logic themselves; this class will do the matching a...
Definition: RenamerClangTidyCheck.cpp:113
ASTUtils.h
clang::tidy::RenamerClangTidyCheck::registerPPCallbacks
void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) override final
Override this to register PPCallbacks in the preprocessor.
Definition: RenamerClangTidyCheck.cpp:131
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::tidy::findDeclInBases
NameLookup findDeclInBases(const CXXRecordDecl &Parent, StringRef DeclName, bool AggressiveTemplateLookup)
Returns a decl matching the DeclName in Parent or one of its base classes.
Definition: RenamerClangTidyCheck.cpp:236
clang::tidy::utils::rangeCanBeFixed
bool rangeCanBeFixed(SourceRange Range, const SourceManager *SM)
Definition: ASTUtils.cpp:88
clang::doc::Record
llvm::SmallVector< uint64_t, 1024 > Record
Definition: BitcodeReader.cpp:18
clang::tidy::RenamerClangTidyCheck::DiagInfo::ApplyArgs
llvm::unique_function< void(DiagnosticBuilder &)> ApplyArgs
Definition: RenamerClangTidyCheck.h:147
llvm::DenseMapInfo< clang::tidy::RenamerClangTidyCheck::NamingCheckId >::NamingCheckId
clang::tidy::RenamerClangTidyCheck::NamingCheckId NamingCheckId
Definition: RenamerClangTidyCheck.cpp:29
clang::tidy::RenamerClangTidyCheck::ShouldFixStatus::ConflictsWithMacroDefinition
@ ConflictsWithMacroDefinition
The fixup will conflict with a macro definition, so we can't fix it automatically.
clang::tidy::ClangTidyCheck::OptionsView::store
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.
Definition: ClangTidyCheck.cpp:120
clang::tidy::findDecl
const NamedDecl * findDecl(const RecordDecl &RecDecl, StringRef DeclName)
Definition: RenamerClangTidyCheck.cpp:201
clang::tidy::RenamerClangTidyCheck::FailureInfo
Information describing a failed check.
Definition: RenamerClangTidyCheck.h:75
clang::tidy::RenamerClangTidyCheck::ShouldFixStatus::FixInvalidIdentifier
@ FixInvalidIdentifier
The fixup results in an identifier that is not a valid c/c++ identifier.
clang::tidy::RenamerClangTidyCheck::GetMacroFailureInfo
virtual llvm::Optional< FailureInfo > GetMacroFailureInfo(const Token &MacroNameTok, const SourceManager &SM) const =0
Overridden by derived classes, returns information about if and how a macro failed the check.
clang::tidy::RenamerClangTidyCheck::ShouldFixStatus::ConflictsWithKeyword
@ ConflictsWithKeyword
The fixup will conflict with a language keyword, so we can't fix it automatically.