clang-tools  3.8.0
IdentifierNamingCheck.cpp
Go to the documentation of this file.
1 //===--- IdentifierNamingCheck.cpp - clang-tidy ---------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "IdentifierNamingCheck.h"
11 
12 #include "llvm/Support/Debug.h"
13 #include "llvm/Support/Format.h"
14 #include "clang/ASTMatchers/ASTMatchFinder.h"
15 
16 #define DEBUG_TYPE "clang-tidy"
17 
18 using namespace clang::ast_matchers;
19 
20 namespace clang {
21 namespace tidy {
22 namespace readability {
23 
24 // clang-format off
25 #define NAMING_KEYS(m) \
26  m(Namespace) \
27  m(InlineNamespace) \
28  m(EnumConstant) \
29  m(ConstexprVariable) \
30  m(ConstantMember) \
31  m(PrivateMember) \
32  m(ProtectedMember) \
33  m(PublicMember) \
34  m(Member) \
35  m(ClassConstant) \
36  m(ClassMember) \
37  m(GlobalConstant) \
38  m(GlobalVariable) \
39  m(LocalConstant) \
40  m(LocalVariable) \
41  m(StaticConstant) \
42  m(StaticVariable) \
43  m(Constant) \
44  m(Variable) \
45  m(ConstantParameter) \
46  m(ParameterPack) \
47  m(Parameter) \
48  m(AbstractClass) \
49  m(Struct) \
50  m(Class) \
51  m(Union) \
52  m(Enum) \
53  m(GlobalFunction) \
54  m(ConstexprFunction) \
55  m(Function) \
56  m(ConstexprMethod) \
57  m(VirtualMethod) \
58  m(ClassMethod) \
59  m(PrivateMethod) \
60  m(ProtectedMethod) \
61  m(PublicMethod) \
62  m(Method) \
63  m(Typedef) \
64  m(TypeTemplateParameter) \
65  m(ValueTemplateParameter) \
66  m(TemplateTemplateParameter) \
67  m(TemplateParameter) \
68 
69 enum StyleKind {
70 #define ENUMERATE(v) SK_ ## v,
72 #undef ENUMERATE
75 };
76 
77 static StringRef const StyleNames[] = {
78 #define STRINGIZE(v) #v,
80 #undef STRINGIZE
81 };
82 
83 #undef NAMING_KEYS
84 // clang-format on
85 
86 IdentifierNamingCheck::IdentifierNamingCheck(StringRef Name,
88  : ClangTidyCheck(Name, Context) {
89  auto const fromString = [](StringRef Str) {
90  return llvm::StringSwitch<CaseType>(Str)
91  .Case("lower_case", CT_LowerCase)
92  .Case("UPPER_CASE", CT_UpperCase)
93  .Case("camelBack", CT_CamelBack)
94  .Case("CamelCase", CT_CamelCase)
95  .Default(CT_AnyCase);
96  };
97 
98  for (auto const &Name : StyleNames) {
99  NamingStyles.push_back(
100  NamingStyle(fromString(Options.get((Name + "Case").str(), "")),
101  Options.get((Name + "Prefix").str(), ""),
102  Options.get((Name + "Suffix").str(), "")));
103  }
104 
105  IgnoreFailedSplit = Options.get("IgnoreFailedSplit", 0);
106 }
107 
109  auto const toString = [](CaseType Type) {
110  switch (Type) {
111  case CT_AnyCase:
112  return "aNy_CasE";
113  case CT_LowerCase:
114  return "lower_case";
115  case CT_CamelBack:
116  return "camelBack";
117  case CT_UpperCase:
118  return "UPPER_CASE";
119  case CT_CamelCase:
120  return "CamelCase";
121  }
122 
123  llvm_unreachable("Unknown Case Type");
124  };
125 
126  for (size_t i = 0; i < SK_Count; ++i) {
127  Options.store(Opts, (StyleNames[i] + "Case").str(),
128  toString(NamingStyles[i].Case));
129  Options.store(Opts, (StyleNames[i] + "Prefix").str(),
130  NamingStyles[i].Prefix);
131  Options.store(Opts, (StyleNames[i] + "Suffix").str(),
132  NamingStyles[i].Suffix);
133  }
134 
135  Options.store(Opts, "IgnoreFailedSplit", IgnoreFailedSplit);
136 }
137 
139  Finder->addMatcher(namedDecl().bind("decl"), this);
140  Finder->addMatcher(usingDecl().bind("using"), this);
141  Finder->addMatcher(declRefExpr().bind("declRef"), this);
142  Finder->addMatcher(cxxConstructorDecl().bind("classRef"), this);
143  Finder->addMatcher(cxxDestructorDecl().bind("classRef"), this);
144  Finder->addMatcher(typeLoc().bind("typeLoc"), this);
145  Finder->addMatcher(nestedNameSpecifierLoc().bind("nestedNameLoc"), this);
146 }
147 
148 static bool matchesStyle(StringRef Name,
150  static llvm::Regex Matchers[] = {
151  llvm::Regex("^.*$"),
152  llvm::Regex("^[a-z][a-z0-9_]*$"),
153  llvm::Regex("^[a-z][a-zA-Z0-9]*$"),
154  llvm::Regex("^[A-Z][A-Z0-9_]*$"),
155  llvm::Regex("^[A-Z][a-zA-Z0-9]*$"),
156  };
157 
158  bool Matches = true;
159  if (Name.startswith(Style.Prefix))
160  Name = Name.drop_front(Style.Prefix.size());
161  else
162  Matches = false;
163 
164  if (Name.endswith(Style.Suffix))
165  Name = Name.drop_back(Style.Suffix.size());
166  else
167  Matches = false;
168 
169  if (!Matchers[static_cast<size_t>(Style.Case)].match(Name))
170  Matches = false;
171 
172  return Matches;
173 }
174 
175 static std::string fixupWithCase(StringRef Name,
177  static llvm::Regex Splitter(
178  "([a-z0-9A-Z]*)(_+)|([A-Z]?[a-z0-9]+)([A-Z]|$)|([A-Z]+)([A-Z]|$)");
179 
180  SmallVector<StringRef, 8> Substrs;
181  Name.split(Substrs, "_", -1, false);
182 
183  SmallVector<StringRef, 8> Words;
184  for (auto Substr : Substrs) {
185  while (!Substr.empty()) {
186  SmallVector<StringRef, 8> Groups;
187  if (!Splitter.match(Substr, &Groups))
188  break;
189 
190  if (Groups[2].size() > 0) {
191  Words.push_back(Groups[1]);
192  Substr = Substr.substr(Groups[0].size());
193  } else if (Groups[3].size() > 0) {
194  Words.push_back(Groups[3]);
195  Substr = Substr.substr(Groups[0].size() - Groups[4].size());
196  } else if (Groups[5].size() > 0) {
197  Words.push_back(Groups[5]);
198  Substr = Substr.substr(Groups[0].size() - Groups[6].size());
199  }
200  }
201  }
202 
203  if (Words.empty())
204  return Name;
205 
206  std::string Fixup;
207  switch (Case) {
209  Fixup += Name;
210  break;
211 
213  for (auto const &Word : Words) {
214  if (&Word != &Words.front())
215  Fixup += "_";
216  Fixup += Word.lower();
217  }
218  break;
219 
221  for (auto const &Word : Words) {
222  if (&Word != &Words.front())
223  Fixup += "_";
224  Fixup += Word.upper();
225  }
226  break;
227 
229  for (auto const &Word : Words) {
230  Fixup += Word.substr(0, 1).upper();
231  Fixup += Word.substr(1).lower();
232  }
233  break;
234 
236  for (auto const &Word : Words) {
237  if (&Word == &Words.front()) {
238  Fixup += Word.lower();
239  } else {
240  Fixup += Word.substr(0, 1).upper();
241  Fixup += Word.substr(1).lower();
242  }
243  }
244  break;
245  }
246 
247  return Fixup;
248 }
249 
250 static std::string fixupWithStyle(StringRef Name,
252  return Style.Prefix + fixupWithCase(Name, Style.Case) + Style.Suffix;
253 }
254 
256  const NamedDecl *D,
257  const std::vector<IdentifierNamingCheck::NamingStyle> &NamingStyles) {
258  if (isa<TypedefDecl>(D) && NamingStyles[SK_Typedef].isSet())
259  return SK_Typedef;
260 
261  if (const auto *Decl = dyn_cast<NamespaceDecl>(D)) {
262  if (Decl->isAnonymousNamespace())
263  return SK_Invalid;
264 
265  if (Decl->isInline() && NamingStyles[SK_InlineNamespace].isSet())
266  return SK_InlineNamespace;
267 
268  if (NamingStyles[SK_Namespace].isSet())
269  return SK_Namespace;
270  }
271 
272  if (isa<EnumDecl>(D) && NamingStyles[SK_Enum].isSet())
273  return SK_Enum;
274 
275  if (isa<EnumConstantDecl>(D)) {
276  if (NamingStyles[SK_EnumConstant].isSet())
277  return SK_EnumConstant;
278 
279  if (NamingStyles[SK_Constant].isSet())
280  return SK_Constant;
281 
282  return SK_Invalid;
283  }
284 
285  if (const auto *Decl = dyn_cast<CXXRecordDecl>(D)) {
286  if (Decl->isAnonymousStructOrUnion())
287  return SK_Invalid;
288 
289  if (Decl->hasDefinition() && Decl->isAbstract() &&
290  NamingStyles[SK_AbstractClass].isSet())
291  return SK_AbstractClass;
292 
293  if (Decl->isStruct() && NamingStyles[SK_Struct].isSet())
294  return SK_Struct;
295 
296  if (Decl->isStruct() && NamingStyles[SK_Class].isSet())
297  return SK_Class;
298 
299  if (Decl->isClass() && NamingStyles[SK_Class].isSet())
300  return SK_Class;
301 
302  if (Decl->isClass() && NamingStyles[SK_Struct].isSet())
303  return SK_Struct;
304 
305  if (Decl->isUnion() && NamingStyles[SK_Union].isSet())
306  return SK_Union;
307 
308  if (Decl->isEnum() && NamingStyles[SK_Enum].isSet())
309  return SK_Enum;
310 
311  return SK_Invalid;
312  }
313 
314  if (const auto *Decl = dyn_cast<FieldDecl>(D)) {
315  QualType Type = Decl->getType();
316 
317  if (!Type.isNull() && Type.isLocalConstQualified() &&
318  NamingStyles[SK_ConstantMember].isSet())
319  return SK_ConstantMember;
320 
321  if (!Type.isNull() && Type.isLocalConstQualified() &&
322  NamingStyles[SK_Constant].isSet())
323  return SK_Constant;
324 
325  if (Decl->getAccess() == AS_private &&
326  NamingStyles[SK_PrivateMember].isSet())
327  return SK_PrivateMember;
328 
329  if (Decl->getAccess() == AS_protected &&
330  NamingStyles[SK_ProtectedMember].isSet())
331  return SK_ProtectedMember;
332 
333  if (Decl->getAccess() == AS_public && NamingStyles[SK_PublicMember].isSet())
334  return SK_PublicMember;
335 
336  if (NamingStyles[SK_Member].isSet())
337  return SK_Member;
338 
339  return SK_Invalid;
340  }
341 
342  if (const auto *Decl = dyn_cast<ParmVarDecl>(D)) {
343  QualType Type = Decl->getType();
344 
345  if (Decl->isConstexpr() && NamingStyles[SK_ConstexprVariable].isSet())
346  return SK_ConstexprVariable;
347 
348  if (!Type.isNull() && Type.isLocalConstQualified() &&
349  NamingStyles[SK_ConstantParameter].isSet())
350  return SK_ConstantParameter;
351 
352  if (!Type.isNull() && Type.isLocalConstQualified() &&
353  NamingStyles[SK_Constant].isSet())
354  return SK_Constant;
355 
356  if (Decl->isParameterPack() && NamingStyles[SK_ParameterPack].isSet())
357  return SK_ParameterPack;
358 
359  if (NamingStyles[SK_Parameter].isSet())
360  return SK_Parameter;
361 
362  return SK_Invalid;
363  }
364 
365  if (const auto *Decl = dyn_cast<VarDecl>(D)) {
366  QualType Type = Decl->getType();
367 
368  if (Decl->isConstexpr() && NamingStyles[SK_ConstexprVariable].isSet())
369  return SK_ConstexprVariable;
370 
371  if (!Type.isNull() && Type.isLocalConstQualified() &&
372  Decl->isStaticDataMember() && NamingStyles[SK_ClassConstant].isSet())
373  return SK_ClassConstant;
374 
375  if (!Type.isNull() && Type.isLocalConstQualified() &&
376  Decl->isFileVarDecl() && NamingStyles[SK_GlobalConstant].isSet())
377  return SK_GlobalConstant;
378 
379  if (!Type.isNull() && Type.isLocalConstQualified() &&
380  Decl->isStaticLocal() && NamingStyles[SK_StaticConstant].isSet())
381  return SK_StaticConstant;
382 
383  if (!Type.isNull() && Type.isLocalConstQualified() &&
384  Decl->isLocalVarDecl() && NamingStyles[SK_LocalConstant].isSet())
385  return SK_LocalConstant;
386 
387  if (!Type.isNull() && Type.isLocalConstQualified() &&
388  Decl->isFunctionOrMethodVarDecl() &&
389  NamingStyles[SK_LocalConstant].isSet())
390  return SK_LocalConstant;
391 
392  if (!Type.isNull() && Type.isLocalConstQualified() &&
393  NamingStyles[SK_Constant].isSet())
394  return SK_Constant;
395 
396  if (Decl->isStaticDataMember() && NamingStyles[SK_ClassMember].isSet())
397  return SK_ClassMember;
398 
399  if (Decl->isFileVarDecl() && NamingStyles[SK_GlobalVariable].isSet())
400  return SK_GlobalVariable;
401 
402  if (Decl->isStaticLocal() && NamingStyles[SK_StaticVariable].isSet())
403  return SK_StaticVariable;
404 
405  if (Decl->isLocalVarDecl() && NamingStyles[SK_LocalVariable].isSet())
406  return SK_LocalVariable;
407 
408  if (Decl->isFunctionOrMethodVarDecl() &&
409  NamingStyles[SK_LocalVariable].isSet())
410  return SK_LocalVariable;
411 
412  if (NamingStyles[SK_Variable].isSet())
413  return SK_Variable;
414 
415  return SK_Invalid;
416  }
417 
418  if (const auto *Decl = dyn_cast<CXXMethodDecl>(D)) {
419  if (Decl->isMain() || !Decl->isUserProvided() ||
420  Decl->isUsualDeallocationFunction() ||
421  Decl->isCopyAssignmentOperator() || Decl->isMoveAssignmentOperator() ||
422  Decl->size_overridden_methods() > 0)
423  return SK_Invalid;
424 
425  if (Decl->isConstexpr() && NamingStyles[SK_ConstexprMethod].isSet())
426  return SK_ConstexprMethod;
427 
428  if (Decl->isConstexpr() && NamingStyles[SK_ConstexprFunction].isSet())
429  return SK_ConstexprFunction;
430 
431  if (Decl->isStatic() && NamingStyles[SK_ClassMethod].isSet())
432  return SK_ClassMethod;
433 
434  if (Decl->isVirtual() && NamingStyles[SK_VirtualMethod].isSet())
435  return SK_VirtualMethod;
436 
437  if (Decl->getAccess() == AS_private &&
438  NamingStyles[SK_PrivateMethod].isSet())
439  return SK_PrivateMethod;
440 
441  if (Decl->getAccess() == AS_protected &&
442  NamingStyles[SK_ProtectedMethod].isSet())
443  return SK_ProtectedMethod;
444 
445  if (Decl->getAccess() == AS_public && NamingStyles[SK_PublicMethod].isSet())
446  return SK_PublicMethod;
447 
448  if (NamingStyles[SK_Method].isSet())
449  return SK_Method;
450 
451  if (NamingStyles[SK_Function].isSet())
452  return SK_Function;
453 
454  return SK_Invalid;
455  }
456 
457  if (const auto *Decl = dyn_cast<FunctionDecl>(D)) {
458  if (Decl->isMain())
459  return SK_Invalid;
460 
461  if (Decl->isConstexpr() && NamingStyles[SK_ConstexprFunction].isSet())
462  return SK_ConstexprFunction;
463 
464  if (Decl->isGlobal() && NamingStyles[SK_GlobalFunction].isSet())
465  return SK_GlobalFunction;
466 
467  if (NamingStyles[SK_Function].isSet())
468  return SK_Function;
469  }
470 
471  if (isa<TemplateTypeParmDecl>(D)) {
472  if (NamingStyles[SK_TypeTemplateParameter].isSet())
473  return SK_TypeTemplateParameter;
474 
475  if (NamingStyles[SK_TemplateParameter].isSet())
476  return SK_TemplateParameter;
477 
478  return SK_Invalid;
479  }
480 
481  if (isa<NonTypeTemplateParmDecl>(D)) {
482  if (NamingStyles[SK_ValueTemplateParameter].isSet())
483  return SK_ValueTemplateParameter;
484 
485  if (NamingStyles[SK_TemplateParameter].isSet())
486  return SK_TemplateParameter;
487 
488  return SK_Invalid;
489  }
490 
491  if (isa<TemplateTemplateParmDecl>(D)) {
492  if (NamingStyles[SK_TemplateTemplateParameter].isSet())
493  return SK_TemplateTemplateParameter;
494 
495  if (NamingStyles[SK_TemplateParameter].isSet())
496  return SK_TemplateParameter;
497 
498  return SK_Invalid;
499  }
500 
501  return SK_Invalid;
502 }
503 
505  const NamedDecl *Decl, SourceRange Range,
506  const SourceManager *SM) {
507  // Do nothin if the provided range is invalid
508  if (Range.getBegin().isInvalid() || Range.getEnd().isInvalid())
509  return;
510 
511  // Try to insert the identifier location in the Usages map, and bail out if it
512  // is already in there
513  auto &Failure = Failures[Decl];
514  if (!Failure.RawUsageLocs.insert(Range.getBegin().getRawEncoding()).second)
515  return;
516 
517  Failure.ShouldFix = Failure.ShouldFix && !Range.getBegin().isMacroID() &&
518  !Range.getEnd().isMacroID();
519 }
520 
521 void IdentifierNamingCheck::check(const MatchFinder::MatchResult &Result) {
522  if (const auto *Decl =
523  Result.Nodes.getNodeAs<CXXConstructorDecl>("classRef")) {
524  if (Decl->isImplicit())
525  return;
526 
527  addUsage(NamingCheckFailures, Decl->getParent(),
528  Decl->getNameInfo().getSourceRange(), Result.SourceManager);
529  return;
530  }
531 
532  if (const auto *Decl =
533  Result.Nodes.getNodeAs<CXXDestructorDecl>("classRef")) {
534  if (Decl->isImplicit())
535  return;
536 
537  SourceRange Range = Decl->getNameInfo().getSourceRange();
538  if (Range.getBegin().isInvalid())
539  return;
540  // The first token that will be found is the ~ (or the equivalent trigraph),
541  // we want instead to replace the next token, that will be the identifier.
542  Range.setBegin(CharSourceRange::getTokenRange(Range).getEnd());
543 
544  addUsage(NamingCheckFailures, Decl->getParent(), Range,
545  Result.SourceManager);
546  return;
547  }
548 
549  if (const auto *Loc = Result.Nodes.getNodeAs<TypeLoc>("typeLoc")) {
550  NamedDecl *Decl = nullptr;
551  if (const auto &Ref = Loc->getAs<TagTypeLoc>()) {
552  Decl = Ref.getDecl();
553  } else if (const auto &Ref = Loc->getAs<InjectedClassNameTypeLoc>()) {
554  Decl = Ref.getDecl();
555  } else if (const auto &Ref = Loc->getAs<UnresolvedUsingTypeLoc>()) {
556  Decl = Ref.getDecl();
557  } else if (const auto &Ref = Loc->getAs<TemplateTypeParmTypeLoc>()) {
558  Decl = Ref.getDecl();
559  }
560 
561  if (Decl) {
562  addUsage(NamingCheckFailures, Decl, Loc->getSourceRange(),
563  Result.SourceManager);
564  return;
565  }
566 
567  if (const auto &Ref = Loc->getAs<TemplateSpecializationTypeLoc>()) {
568  const auto *Decl =
569  Ref.getTypePtr()->getTemplateName().getAsTemplateDecl();
570 
571  SourceRange Range(Ref.getTemplateNameLoc(), Ref.getTemplateNameLoc());
572  if (const auto *ClassDecl = dyn_cast<TemplateDecl>(Decl)) {
573  addUsage(NamingCheckFailures, ClassDecl->getTemplatedDecl(), Range,
574  Result.SourceManager);
575  return;
576  }
577  }
578 
579  if (const auto &Ref =
580  Loc->getAs<DependentTemplateSpecializationTypeLoc>()) {
581  addUsage(NamingCheckFailures, Ref.getTypePtr()->getAsTagDecl(),
582  Loc->getSourceRange(), Result.SourceManager);
583  return;
584  }
585  }
586 
587  if (const auto *Loc =
588  Result.Nodes.getNodeAs<NestedNameSpecifierLoc>("nestedNameLoc")) {
589  if (NestedNameSpecifier *Spec = Loc->getNestedNameSpecifier()) {
590  if (NamespaceDecl *Decl = Spec->getAsNamespace()) {
591  addUsage(NamingCheckFailures, Decl, Loc->getLocalSourceRange(),
592  Result.SourceManager);
593  return;
594  }
595  }
596  }
597 
598  if (const auto *Decl = Result.Nodes.getNodeAs<UsingDecl>("using")) {
599  for (const auto &Shadow : Decl->shadows()) {
600  addUsage(NamingCheckFailures, Shadow->getTargetDecl(),
601  Decl->getNameInfo().getSourceRange(), Result.SourceManager);
602  }
603  return;
604  }
605 
606  if (const auto *DeclRef = Result.Nodes.getNodeAs<DeclRefExpr>("declRef")) {
607  SourceRange Range = DeclRef->getNameInfo().getSourceRange();
608  addUsage(NamingCheckFailures, DeclRef->getDecl(), Range,
609  Result.SourceManager);
610  return;
611  }
612 
613  if (const auto *Decl = Result.Nodes.getNodeAs<NamedDecl>("decl")) {
614  if (!Decl->getIdentifier() || Decl->getName().empty() || Decl->isImplicit())
615  return;
616 
617  // Ignore ClassTemplateSpecializationDecl which are creating duplicate
618  // replacements with CXXRecordDecl
619  if (isa<ClassTemplateSpecializationDecl>(Decl))
620  return;
621 
622  StyleKind SK = findStyleKind(Decl, NamingStyles);
623  if (SK == SK_Invalid)
624  return;
625 
626  NamingStyle Style = NamingStyles[SK];
627  StringRef Name = Decl->getName();
628  if (matchesStyle(Name, Style))
629  return;
630 
631  std::string KindName = fixupWithCase(StyleNames[SK], CT_LowerCase);
632  std::replace(KindName.begin(), KindName.end(), '_', ' ');
633 
634  std::string Fixup = fixupWithStyle(Name, Style);
635  if (StringRef(Fixup).equals(Name)) {
636  if (!IgnoreFailedSplit) {
637  DEBUG(llvm::dbgs() << Decl->getLocStart().printToString(
638  *Result.SourceManager)
639  << format(": unable to split words for %s '%s'\n",
640  KindName.c_str(), Name));
641  }
642  } else {
643  NamingCheckFailure &Failure = NamingCheckFailures[Decl];
644  SourceRange Range =
645  DeclarationNameInfo(Decl->getDeclName(), Decl->getLocation())
646  .getSourceRange();
647 
648  Failure.Fixup = std::move(Fixup);
649  Failure.KindName = std::move(KindName);
650  addUsage(NamingCheckFailures, Decl, Range, Result.SourceManager);
651  }
652  }
653 }
654 
656  for (const auto &Pair : NamingCheckFailures) {
657  const NamedDecl &Decl = *Pair.first;
658  const NamingCheckFailure &Failure = Pair.second;
659 
660  if (Failure.KindName.empty())
661  continue;
662 
663  if (Failure.ShouldFix) {
664  auto Diag = diag(Decl.getLocation(), "invalid case style for %0 '%1'")
665  << Failure.KindName << Decl.getName();
666 
667  for (const auto &Loc : Failure.RawUsageLocs) {
668  // We assume that the identifier name is made of one token only. This is
669  // always the case as we ignore usages in macros that could build
670  // identifier names by combining multiple tokens.
671  //
672  // For destructors, we alread take care of it by remembering the
673  // location of the start of the identifier and not the start of the
674  // tilde.
675  //
676  // Other multi-token identifiers, such as operators are not checked at
677  // all.
678  Diag << FixItHint::CreateReplacement(
679  SourceRange(SourceLocation::getFromRawEncoding(Loc)),
680  Failure.Fixup);
681  }
682  }
683  }
684 }
685 
686 } // namespace readability
687 } // namespace tidy
688 } // namespace clang
SourceLocation Loc
'#' location in the include directive
static StyleKind findStyleKind(const NamedDecl *D, const std::vector< IdentifierNamingCheck::NamingStyle > &NamingStyles)
#define ENUMERATE(v)
std::string get(StringRef LocalName, std::string Default) const
Read a named option from the Context.
Definition: ClangTidy.cpp:337
StringHandle Name
std::unique_ptr< ast_matchers::MatchFinder > Finder
Definition: ClangTidy.cpp:188
Holds an identifier name check failure, tracking the kind of the identifer, its possible fixup and th...
static bool matchesStyle(StringRef Name, IdentifierNamingCheck::NamingStyle Style)
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
Base class for all clang-tidy checks.
Definition: ClangTidy.h:102
static void addUsage(IdentifierNamingCheck::NamingCheckFailureMap &Failures, const NamedDecl *Decl, SourceRange Range, const SourceManager *SM)
SourceManager & SM
static std::string fixupWithStyle(StringRef Name, IdentifierNamingCheck::NamingStyle Style)
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: ClangTidy.cpp:344
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register ASTMatchers with Finder.
std::map< std::string, std::string > OptionMap
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::string fixupWithCase(StringRef Name, IdentifierNamingCheck::CaseType Case)
CharSourceRange Range
SourceRange for the file name.
ClangTidyContext & Context
Definition: ClangTidy.cpp:93
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
#define STRINGIZE(v)
static StringRef const StyleNames[]
#define NAMING_KEYS(m)
llvm::DenseSet< unsigned > RawUsageLocs
A set of all the identifier usages starting SourceLocation, in their encoded form.
DiagnosticBuilder diag(SourceLocation Loc, StringRef Description, DiagnosticIDs::Level Level=DiagnosticIDs::Warning)
Add a diagnostic with the check's name.
Definition: ClangTidy.cpp:323
llvm::DenseMap< const NamedDecl *, NamingCheckFailure > NamingCheckFailureMap
const NamedDecl * Result
Definition: USRFinder.cpp:121
bool ShouldFix
Whether the failure should be fixed or not.