clang-tools  11.0.0
IdentifierNamingCheck.cpp
Go to the documentation of this file.
1 //===--- IdentifierNamingCheck.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 
11 #include "clang/AST/CXXInheritance.h"
12 #include "clang/Lex/PPCallbacks.h"
13 #include "clang/Lex/Preprocessor.h"
14 #include "llvm/ADT/ArrayRef.h"
15 #include "llvm/ADT/DenseMapInfo.h"
16 #include "llvm/Support/Debug.h"
17 #include "llvm/Support/Error.h"
18 #include "llvm/Support/Format.h"
19 #include "llvm/Support/Regex.h"
20 
21 #define DEBUG_TYPE "clang-tidy"
22 
23 // FixItHint
24 
25 using namespace clang::ast_matchers;
26 
27 namespace clang {
28 namespace tidy {
29 
30 llvm::ArrayRef<
31  std::pair<readability::IdentifierNamingCheck::CaseType, StringRef>>
32 OptionEnumMapping<
34  static constexpr std::pair<readability::IdentifierNamingCheck::CaseType,
35  StringRef>
36  Mapping[] = {
37  {readability::IdentifierNamingCheck::CT_AnyCase, "aNy_CasE"},
38  {readability::IdentifierNamingCheck::CT_LowerCase, "lower_case"},
39  {readability::IdentifierNamingCheck::CT_UpperCase, "UPPER_CASE"},
40  {readability::IdentifierNamingCheck::CT_CamelBack, "camelBack"},
41  {readability::IdentifierNamingCheck::CT_CamelCase, "CamelCase"},
42  {readability::IdentifierNamingCheck::CT_CamelSnakeCase,
43  "Camel_Snake_Case"},
44  {readability::IdentifierNamingCheck::CT_CamelSnakeBack,
45  "camel_Snake_Back"}};
46  return llvm::makeArrayRef(Mapping);
47 }
48 
49 namespace readability {
50 
51 // clang-format off
52 #define NAMING_KEYS(m) \
53  m(Namespace) \
54  m(InlineNamespace) \
55  m(EnumConstant) \
56  m(ConstexprVariable) \
57  m(ConstantMember) \
58  m(PrivateMember) \
59  m(ProtectedMember) \
60  m(PublicMember) \
61  m(Member) \
62  m(ClassConstant) \
63  m(ClassMember) \
64  m(GlobalConstant) \
65  m(GlobalConstantPointer) \
66  m(GlobalPointer) \
67  m(GlobalVariable) \
68  m(LocalConstant) \
69  m(LocalConstantPointer) \
70  m(LocalPointer) \
71  m(LocalVariable) \
72  m(StaticConstant) \
73  m(StaticVariable) \
74  m(Constant) \
75  m(Variable) \
76  m(ConstantParameter) \
77  m(ParameterPack) \
78  m(Parameter) \
79  m(PointerParameter) \
80  m(ConstantPointerParameter) \
81  m(AbstractClass) \
82  m(Struct) \
83  m(Class) \
84  m(Union) \
85  m(Enum) \
86  m(GlobalFunction) \
87  m(ConstexprFunction) \
88  m(Function) \
89  m(ConstexprMethod) \
90  m(VirtualMethod) \
91  m(ClassMethod) \
92  m(PrivateMethod) \
93  m(ProtectedMethod) \
94  m(PublicMethod) \
95  m(Method) \
96  m(Typedef) \
97  m(TypeTemplateParameter) \
98  m(ValueTemplateParameter) \
99  m(TemplateTemplateParameter) \
100  m(TemplateParameter) \
101  m(TypeAlias) \
102  m(MacroDefinition) \
103  m(ObjcIvar) \
104 
105 enum StyleKind {
106 #define ENUMERATE(v) SK_ ## v,
108 #undef ENUMERATE
111 };
112 
113 static StringRef const StyleNames[] = {
114 #define STRINGIZE(v) #v,
116 #undef STRINGIZE
117 };
118 
119 #undef NAMING_KEYS
120 // clang-format on
121 
122 IdentifierNamingCheck::IdentifierNamingCheck(StringRef Name,
123  ClangTidyContext *Context)
124  : RenamerClangTidyCheck(Name, Context),
125  IgnoreFailedSplit(Options.get("IgnoreFailedSplit", false)),
126  IgnoreMainLikeFunctions(Options.get("IgnoreMainLikeFunctions", false)) {
127 
128  for (auto const &Name : StyleNames) {
129  auto CaseOptional = [&]() -> llvm::Optional<CaseType> {
130  auto ValueOr = Options.get<CaseType>((Name + "Case").str());
131  if (ValueOr)
132  return *ValueOr;
133  llvm::logAllUnhandledErrors(
134  llvm::handleErrors(ValueOr.takeError(),
135  [](const MissingOptionError &) -> llvm::Error {
136  return llvm::Error::success();
137  }),
138  llvm::errs(), "warning: ");
139  return llvm::None;
140  }();
141 
142  auto prefix = Options.get((Name + "Prefix").str(), "");
143  auto postfix = Options.get((Name + "Suffix").str(), "");
144 
145  if (CaseOptional || !prefix.empty() || !postfix.empty()) {
146  NamingStyles.push_back(NamingStyle(CaseOptional, prefix, postfix));
147  } else {
148  NamingStyles.push_back(llvm::None);
149  }
150  }
151 }
152 
154 
157  for (size_t i = 0; i < SK_Count; ++i) {
158  if (NamingStyles[i]) {
159  if (NamingStyles[i]->Case) {
160  Options.store(Opts, (StyleNames[i] + "Case").str(),
161  *NamingStyles[i]->Case);
162  }
163  Options.store(Opts, (StyleNames[i] + "Prefix").str(),
164  NamingStyles[i]->Prefix);
165  Options.store(Opts, (StyleNames[i] + "Suffix").str(),
166  NamingStyles[i]->Suffix);
167  }
168  }
169 
170  Options.store(Opts, "IgnoreFailedSplit", IgnoreFailedSplit);
171  Options.store(Opts, "IgnoreMainLikeFunctions", IgnoreMainLikeFunctions);
172 }
173 
174 static bool matchesStyle(StringRef Name,
176  static llvm::Regex Matchers[] = {
177  llvm::Regex("^.*$"),
178  llvm::Regex("^[a-z][a-z0-9_]*$"),
179  llvm::Regex("^[a-z][a-zA-Z0-9]*$"),
180  llvm::Regex("^[A-Z][A-Z0-9_]*$"),
181  llvm::Regex("^[A-Z][a-zA-Z0-9]*$"),
182  llvm::Regex("^[A-Z]([a-z0-9]*(_[A-Z])?)*"),
183  llvm::Regex("^[a-z]([a-z0-9]*(_[A-Z])?)*"),
184  };
185 
186  if (Name.startswith(Style.Prefix))
187  Name = Name.drop_front(Style.Prefix.size());
188  else
189  return false;
190 
191  if (Name.endswith(Style.Suffix))
192  Name = Name.drop_back(Style.Suffix.size());
193  else
194  return false;
195 
196  // Ensure the name doesn't have any extra underscores beyond those specified
197  // in the prefix and suffix.
198  if (Name.startswith("_") || Name.endswith("_"))
199  return false;
200 
201  if (Style.Case && !Matchers[static_cast<size_t>(*Style.Case)].match(Name))
202  return false;
203 
204  return true;
205 }
206 
207 static std::string fixupWithCase(StringRef Name,
209  static llvm::Regex Splitter(
210  "([a-z0-9A-Z]*)(_+)|([A-Z]?[a-z0-9]+)([A-Z]|$)|([A-Z]+)([A-Z]|$)");
211 
212  SmallVector<StringRef, 8> Substrs;
213  Name.split(Substrs, "_", -1, false);
214 
215  SmallVector<StringRef, 8> Words;
216  for (auto Substr : Substrs) {
217  while (!Substr.empty()) {
218  SmallVector<StringRef, 8> Groups;
219  if (!Splitter.match(Substr, &Groups))
220  break;
221 
222  if (Groups[2].size() > 0) {
223  Words.push_back(Groups[1]);
224  Substr = Substr.substr(Groups[0].size());
225  } else if (Groups[3].size() > 0) {
226  Words.push_back(Groups[3]);
227  Substr = Substr.substr(Groups[0].size() - Groups[4].size());
228  } else if (Groups[5].size() > 0) {
229  Words.push_back(Groups[5]);
230  Substr = Substr.substr(Groups[0].size() - Groups[6].size());
231  }
232  }
233  }
234 
235  if (Words.empty())
236  return std::string(Name);
237 
238  std::string Fixup;
239  switch (Case) {
241  Fixup += Name;
242  break;
243 
245  for (auto const &Word : Words) {
246  if (&Word != &Words.front())
247  Fixup += "_";
248  Fixup += Word.lower();
249  }
250  break;
251 
253  for (auto const &Word : Words) {
254  if (&Word != &Words.front())
255  Fixup += "_";
256  Fixup += Word.upper();
257  }
258  break;
259 
261  for (auto const &Word : Words) {
262  Fixup += Word.substr(0, 1).upper();
263  Fixup += Word.substr(1).lower();
264  }
265  break;
266 
268  for (auto const &Word : Words) {
269  if (&Word == &Words.front()) {
270  Fixup += Word.lower();
271  } else {
272  Fixup += Word.substr(0, 1).upper();
273  Fixup += Word.substr(1).lower();
274  }
275  }
276  break;
277 
279  for (auto const &Word : Words) {
280  if (&Word != &Words.front())
281  Fixup += "_";
282  Fixup += Word.substr(0, 1).upper();
283  Fixup += Word.substr(1).lower();
284  }
285  break;
286 
288  for (auto const &Word : Words) {
289  if (&Word != &Words.front()) {
290  Fixup += "_";
291  Fixup += Word.substr(0, 1).upper();
292  } else {
293  Fixup += Word.substr(0, 1).lower();
294  }
295  Fixup += Word.substr(1).lower();
296  }
297  break;
298  }
299 
300  return Fixup;
301 }
302 
303 static bool isParamInMainLikeFunction(const ParmVarDecl &ParmDecl,
304  bool IncludeMainLike) {
305  const auto *FDecl =
306  dyn_cast_or_null<FunctionDecl>(ParmDecl.getParentFunctionOrMethod());
307  if (!FDecl)
308  return false;
309  if (FDecl->isMain())
310  return true;
311  if (!IncludeMainLike)
312  return false;
313  if (FDecl->getAccess() != AS_public && FDecl->getAccess() != AS_none)
314  return false;
315  enum MainType { None, Main, WMain };
316  auto IsCharPtrPtr = [](QualType QType) -> MainType {
317  if (QType.isNull())
318  return None;
319  if (QType = QType->getPointeeType(), QType.isNull())
320  return None;
321  if (QType = QType->getPointeeType(), QType.isNull())
322  return None;
323  if (QType->isCharType())
324  return Main;
325  if (QType->isWideCharType())
326  return WMain;
327  return None;
328  };
329  auto IsIntType = [](QualType QType) {
330  if (QType.isNull())
331  return false;
332  if (const auto *Builtin =
333  dyn_cast<BuiltinType>(QType->getUnqualifiedDesugaredType())) {
334  return Builtin->getKind() == BuiltinType::Int;
335  }
336  return false;
337  };
338  if (!IsIntType(FDecl->getReturnType()))
339  return false;
340  if (FDecl->getNumParams() < 2 || FDecl->getNumParams() > 3)
341  return false;
342  if (!IsIntType(FDecl->parameters()[0]->getType()))
343  return false;
344  MainType Type = IsCharPtrPtr(FDecl->parameters()[1]->getType());
345  if (Type == None)
346  return false;
347  if (FDecl->getNumParams() == 3 &&
348  IsCharPtrPtr(FDecl->parameters()[2]->getType()) != Type)
349  return false;
350 
351  if (Type == Main) {
352  static llvm::Regex Matcher(
353  "(^[Mm]ain([_A-Z]|$))|([a-z0-9_]Main([_A-Z]|$))|(_main(_|$))");
354  assert(Matcher.isValid() && "Invalid Matcher for main like functions.");
355  return Matcher.match(FDecl->getName());
356  } else {
357  static llvm::Regex Matcher("(^((W[Mm])|(wm))ain([_A-Z]|$))|([a-z0-9_]W[Mm]"
358  "ain([_A-Z]|$))|(_wmain(_|$))");
359  assert(Matcher.isValid() && "Invalid Matcher for wmain like functions.");
360  return Matcher.match(FDecl->getName());
361  }
362 }
363 
364 static std::string
366  const IdentifierNamingCheck::NamingStyle &Style) {
367  const std::string Fixed = fixupWithCase(
368  Name, Style.Case.getValueOr(IdentifierNamingCheck::CaseType::CT_AnyCase));
369  StringRef Mid = StringRef(Fixed).trim("_");
370  if (Mid.empty())
371  Mid = "_";
372  return (Style.Prefix + Mid + Style.Suffix).str();
373 }
374 
376  const NamedDecl *D,
377  const std::vector<llvm::Optional<IdentifierNamingCheck::NamingStyle>>
378  &NamingStyles,
379  bool IgnoreMainLikeFunctions) {
380  assert(D && D->getIdentifier() && !D->getName().empty() && !D->isImplicit() &&
381  "Decl must be an explicit identifier with a name.");
382 
383  if (isa<ObjCIvarDecl>(D) && NamingStyles[SK_ObjcIvar])
384  return SK_ObjcIvar;
385 
386  if (isa<TypedefDecl>(D) && NamingStyles[SK_Typedef])
387  return SK_Typedef;
388 
389  if (isa<TypeAliasDecl>(D) && NamingStyles[SK_TypeAlias])
390  return SK_TypeAlias;
391 
392  if (const auto *Decl = dyn_cast<NamespaceDecl>(D)) {
393  if (Decl->isAnonymousNamespace())
394  return SK_Invalid;
395 
396  if (Decl->isInline() && NamingStyles[SK_InlineNamespace])
397  return SK_InlineNamespace;
398 
399  if (NamingStyles[SK_Namespace])
400  return SK_Namespace;
401  }
402 
403  if (isa<EnumDecl>(D) && NamingStyles[SK_Enum])
404  return SK_Enum;
405 
406  if (isa<EnumConstantDecl>(D)) {
407  if (NamingStyles[SK_EnumConstant])
408  return SK_EnumConstant;
409 
410  if (NamingStyles[SK_Constant])
411  return SK_Constant;
412 
413  return SK_Invalid;
414  }
415 
416  if (const auto *Decl = dyn_cast<CXXRecordDecl>(D)) {
417  if (Decl->isAnonymousStructOrUnion())
418  return SK_Invalid;
419 
420  if (!Decl->getCanonicalDecl()->isThisDeclarationADefinition())
421  return SK_Invalid;
422 
423  if (Decl->hasDefinition() && Decl->isAbstract() &&
424  NamingStyles[SK_AbstractClass])
425  return SK_AbstractClass;
426 
427  if (Decl->isStruct() && NamingStyles[SK_Struct])
428  return SK_Struct;
429 
430  if (Decl->isStruct() && NamingStyles[SK_Class])
431  return SK_Class;
432 
433  if (Decl->isClass() && NamingStyles[SK_Class])
434  return SK_Class;
435 
436  if (Decl->isClass() && NamingStyles[SK_Struct])
437  return SK_Struct;
438 
439  if (Decl->isUnion() && NamingStyles[SK_Union])
440  return SK_Union;
441 
442  if (Decl->isEnum() && NamingStyles[SK_Enum])
443  return SK_Enum;
444 
445  return SK_Invalid;
446  }
447 
448  if (const auto *Decl = dyn_cast<FieldDecl>(D)) {
449  QualType Type = Decl->getType();
450 
451  if (!Type.isNull() && Type.isConstQualified()) {
452  if (NamingStyles[SK_ConstantMember])
453  return SK_ConstantMember;
454 
455  if (NamingStyles[SK_Constant])
456  return SK_Constant;
457  }
458 
459  if (Decl->getAccess() == AS_private && NamingStyles[SK_PrivateMember])
460  return SK_PrivateMember;
461 
462  if (Decl->getAccess() == AS_protected && NamingStyles[SK_ProtectedMember])
463  return SK_ProtectedMember;
464 
465  if (Decl->getAccess() == AS_public && NamingStyles[SK_PublicMember])
466  return SK_PublicMember;
467 
468  if (NamingStyles[SK_Member])
469  return SK_Member;
470 
471  return SK_Invalid;
472  }
473 
474  if (const auto *Decl = dyn_cast<ParmVarDecl>(D)) {
475  if (isParamInMainLikeFunction(*Decl, IgnoreMainLikeFunctions))
476  return SK_Invalid;
477  QualType Type = Decl->getType();
478 
479  if (Decl->isConstexpr() && NamingStyles[SK_ConstexprVariable])
480  return SK_ConstexprVariable;
481 
482  if (!Type.isNull() && Type.isConstQualified()) {
483  if (Type.getTypePtr()->isAnyPointerType() && NamingStyles[SK_ConstantPointerParameter])
484  return SK_ConstantPointerParameter;
485 
486  if (NamingStyles[SK_ConstantParameter])
487  return SK_ConstantParameter;
488 
489  if (NamingStyles[SK_Constant])
490  return SK_Constant;
491  }
492 
493  if (Decl->isParameterPack() && NamingStyles[SK_ParameterPack])
494  return SK_ParameterPack;
495 
496  if (!Type.isNull() && Type.getTypePtr()->isAnyPointerType() && NamingStyles[SK_PointerParameter])
497  return SK_PointerParameter;
498 
499  if (NamingStyles[SK_Parameter])
500  return SK_Parameter;
501 
502  return SK_Invalid;
503  }
504 
505  if (const auto *Decl = dyn_cast<VarDecl>(D)) {
506  QualType Type = Decl->getType();
507 
508  if (Decl->isConstexpr() && NamingStyles[SK_ConstexprVariable])
509  return SK_ConstexprVariable;
510 
511  if (!Type.isNull() && Type.isConstQualified()) {
512  if (Decl->isStaticDataMember() && NamingStyles[SK_ClassConstant])
513  return SK_ClassConstant;
514 
515  if (Decl->isFileVarDecl() && Type.getTypePtr()->isAnyPointerType() && NamingStyles[SK_GlobalConstantPointer])
516  return SK_GlobalConstantPointer;
517 
518  if (Decl->isFileVarDecl() && NamingStyles[SK_GlobalConstant])
519  return SK_GlobalConstant;
520 
521  if (Decl->isStaticLocal() && NamingStyles[SK_StaticConstant])
522  return SK_StaticConstant;
523 
524  if (Decl->isLocalVarDecl() && Type.getTypePtr()->isAnyPointerType() && NamingStyles[SK_LocalConstantPointer])
525  return SK_LocalConstantPointer;
526 
527  if (Decl->isLocalVarDecl() && NamingStyles[SK_LocalConstant])
528  return SK_LocalConstant;
529 
530  if (Decl->isFunctionOrMethodVarDecl() && NamingStyles[SK_LocalConstant])
531  return SK_LocalConstant;
532 
533  if (NamingStyles[SK_Constant])
534  return SK_Constant;
535  }
536 
537  if (Decl->isStaticDataMember() && NamingStyles[SK_ClassMember])
538  return SK_ClassMember;
539 
540  if (Decl->isFileVarDecl() && Type.getTypePtr()->isAnyPointerType() && NamingStyles[SK_GlobalPointer])
541  return SK_GlobalPointer;
542 
543  if (Decl->isFileVarDecl() && NamingStyles[SK_GlobalVariable])
544  return SK_GlobalVariable;
545 
546  if (Decl->isStaticLocal() && NamingStyles[SK_StaticVariable])
547  return SK_StaticVariable;
548 
549  if (Decl->isLocalVarDecl() && Type.getTypePtr()->isAnyPointerType() && NamingStyles[SK_LocalPointer])
550  return SK_LocalPointer;
551 
552  if (Decl->isLocalVarDecl() && NamingStyles[SK_LocalVariable])
553  return SK_LocalVariable;
554 
555  if (Decl->isFunctionOrMethodVarDecl() && NamingStyles[SK_LocalVariable])
556  return SK_LocalVariable;
557 
558  if (NamingStyles[SK_Variable])
559  return SK_Variable;
560 
561  return SK_Invalid;
562  }
563 
564  if (const auto *Decl = dyn_cast<CXXMethodDecl>(D)) {
565  if (Decl->isMain() || !Decl->isUserProvided() ||
566  Decl->size_overridden_methods() > 0)
567  return SK_Invalid;
568 
569  // If this method has the same name as any base method, this is likely
570  // necessary even if it's not an override. e.g. CRTP.
571  auto FindHidden = [&](const CXXBaseSpecifier *S, clang::CXXBasePath &P) {
572  return CXXRecordDecl::FindOrdinaryMember(S, P, Decl->getDeclName());
573  };
574  CXXBasePaths UnusedPaths;
575  if (Decl->getParent()->lookupInBases(FindHidden, UnusedPaths))
576  return SK_Invalid;
577 
578  if (Decl->isConstexpr() && NamingStyles[SK_ConstexprMethod])
579  return SK_ConstexprMethod;
580 
581  if (Decl->isConstexpr() && NamingStyles[SK_ConstexprFunction])
582  return SK_ConstexprFunction;
583 
584  if (Decl->isStatic() && NamingStyles[SK_ClassMethod])
585  return SK_ClassMethod;
586 
587  if (Decl->isVirtual() && NamingStyles[SK_VirtualMethod])
588  return SK_VirtualMethod;
589 
590  if (Decl->getAccess() == AS_private && NamingStyles[SK_PrivateMethod])
591  return SK_PrivateMethod;
592 
593  if (Decl->getAccess() == AS_protected && NamingStyles[SK_ProtectedMethod])
594  return SK_ProtectedMethod;
595 
596  if (Decl->getAccess() == AS_public && NamingStyles[SK_PublicMethod])
597  return SK_PublicMethod;
598 
599  if (NamingStyles[SK_Method])
600  return SK_Method;
601 
602  if (NamingStyles[SK_Function])
603  return SK_Function;
604 
605  return SK_Invalid;
606  }
607 
608  if (const auto *Decl = dyn_cast<FunctionDecl>(D)) {
609  if (Decl->isMain())
610  return SK_Invalid;
611 
612  if (Decl->isConstexpr() && NamingStyles[SK_ConstexprFunction])
613  return SK_ConstexprFunction;
614 
615  if (Decl->isGlobal() && NamingStyles[SK_GlobalFunction])
616  return SK_GlobalFunction;
617 
618  if (NamingStyles[SK_Function])
619  return SK_Function;
620  }
621 
622  if (isa<TemplateTypeParmDecl>(D)) {
623  if (NamingStyles[SK_TypeTemplateParameter])
624  return SK_TypeTemplateParameter;
625 
626  if (NamingStyles[SK_TemplateParameter])
627  return SK_TemplateParameter;
628 
629  return SK_Invalid;
630  }
631 
632  if (isa<NonTypeTemplateParmDecl>(D)) {
633  if (NamingStyles[SK_ValueTemplateParameter])
634  return SK_ValueTemplateParameter;
635 
636  if (NamingStyles[SK_TemplateParameter])
637  return SK_TemplateParameter;
638 
639  return SK_Invalid;
640  }
641 
642  if (isa<TemplateTemplateParmDecl>(D)) {
643  if (NamingStyles[SK_TemplateTemplateParameter])
644  return SK_TemplateTemplateParameter;
645 
646  if (NamingStyles[SK_TemplateParameter])
647  return SK_TemplateParameter;
648 
649  return SK_Invalid;
650  }
651 
652  return SK_Invalid;
653 }
654 
655 llvm::Optional<RenamerClangTidyCheck::FailureInfo>
656 IdentifierNamingCheck::GetDeclFailureInfo(const NamedDecl *Decl,
657  const SourceManager &SM) const {
658  StyleKind SK = findStyleKind(Decl, NamingStyles, IgnoreMainLikeFunctions);
659  if (SK == SK_Invalid)
660  return None;
661 
662  if (!NamingStyles[SK])
663  return None;
664 
665  const NamingStyle &Style = *NamingStyles[SK];
666  StringRef Name = Decl->getName();
667  if (matchesStyle(Name, Style))
668  return None;
669 
670  std::string KindName = fixupWithCase(StyleNames[SK], CT_LowerCase);
671  std::replace(KindName.begin(), KindName.end(), '_', ' ');
672 
673  std::string Fixup = fixupWithStyle(Name, Style);
674  if (StringRef(Fixup).equals(Name)) {
675  if (!IgnoreFailedSplit) {
676  LLVM_DEBUG(llvm::dbgs()
677  << Decl->getBeginLoc().printToString(SM)
678  << llvm::format(": unable to split words for %s '%s'\n",
679  KindName.c_str(), Name.str().c_str()));
680  }
681  return None;
682  }
683  return FailureInfo{std::move(KindName), std::move(Fixup)};
684 }
685 
686 llvm::Optional<RenamerClangTidyCheck::FailureInfo>
687 IdentifierNamingCheck::GetMacroFailureInfo(const Token &MacroNameTok,
688  const SourceManager &SM) const {
689  if (!NamingStyles[SK_MacroDefinition])
690  return None;
691 
692  StringRef Name = MacroNameTok.getIdentifierInfo()->getName();
693  const NamingStyle &Style = *NamingStyles[SK_MacroDefinition];
694  if (matchesStyle(Name, Style))
695  return None;
696 
697  std::string KindName =
698  fixupWithCase(StyleNames[SK_MacroDefinition], CT_LowerCase);
699  std::replace(KindName.begin(), KindName.end(), '_', ' ');
700 
701  std::string Fixup = fixupWithStyle(Name, Style);
702  if (StringRef(Fixup).equals(Name)) {
703  if (!IgnoreFailedSplit) {
704  LLVM_DEBUG(llvm::dbgs()
705  << MacroNameTok.getLocation().printToString(SM)
706  << llvm::format(": unable to split words for %s '%s'\n",
707  KindName.c_str(), Name.str().c_str()));
708  }
709  return None;
710  }
711  return FailureInfo{std::move(KindName), std::move(Fixup)};
712 }
713 
714 RenamerClangTidyCheck::DiagInfo
715 IdentifierNamingCheck::GetDiagInfo(const NamingCheckId &ID,
716  const NamingCheckFailure &Failure) const {
717  return DiagInfo{"invalid case style for %0 '%1'",
718  [&](DiagnosticBuilder &diag) {
719  diag << Failure.Info.KindName << ID.second;
720  }};
721 }
722 
723 } // namespace readability
724 } // namespace tidy
725 } // namespace clang
Suffix
std::string Suffix
Definition: AddUsing.cpp:96
clang::tidy::MissingOptionError
Definition: ClangTidyCheck.h:45
clang::tidy::readability::isParamInMainLikeFunction
static bool isParamInMainLikeFunction(const ParmVarDecl &ParmDecl, bool IncludeMainLike)
Definition: IdentifierNamingCheck.cpp:303
clang::tidy::readability::IdentifierNamingCheck::CT_UpperCase
Definition: IdentifierNamingCheck.h:44
Type
NodeType Type
Definition: HTMLGenerator.cpp:73
clang::tidy::readability::IdentifierNamingCheck::CT_CamelSnakeBack
Definition: IdentifierNamingCheck.h:47
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::readability::IdentifierNamingCheck::~IdentifierNamingCheck
~IdentifierNamingCheck()
clang::tidy::readability::fixupWithStyle
static std::string fixupWithStyle(StringRef Name, const IdentifierNamingCheck::NamingStyle &Style)
Definition: IdentifierNamingCheck.cpp:365
IdentifierNamingCheck.h
clang::tidy::readability::StyleNames
static const StringRef StyleNames[]
Definition: IdentifierNamingCheck.cpp:113
NAMING_KEYS
#define NAMING_KEYS(m)
Definition: IdentifierNamingCheck.cpp:52
clang::tidy::readability::SK_Invalid
Definition: IdentifierNamingCheck.cpp:110
clang::tidy::readability::IdentifierNamingCheck::CT_AnyCase
Definition: IdentifierNamingCheck.h:41
clang::ast_matchers
Definition: AbseilMatcher.h:14
clang::tidy::readability::fixupWithCase
static std::string fixupWithCase(StringRef Name, IdentifierNamingCheck::CaseType Case)
Definition: IdentifierNamingCheck.cpp:207
clang::tidy::readability::IdentifierNamingCheck::CaseType
CaseType
Definition: IdentifierNamingCheck.h:40
clang::tidy::ClangTidyCheck::OptionsView::get
llvm::Expected< std::string > get(StringRef LocalName) const
Read a named option from the Context.
Definition: ClangTidyCheck.cpp:72
Decl
const FunctionDecl * Decl
Definition: AvoidBindCheck.cpp:100
clang::tidy::handleErrors
void handleErrors(llvm::ArrayRef< ClangTidyError > Errors, ClangTidyContext &Context, bool Fix, unsigned &WarningsAsErrorsCount, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS)
Displays the found Errors to the users.
Definition: ClangTidy.cpp:576
clang::tidy::ClangTidyCheck::Options
OptionsView Options
Definition: ClangTidyCheck.h:471
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::readability::IdentifierNamingCheck::CT_CamelCase
Definition: IdentifierNamingCheck.h:45
clang::clangd::replace
static std::string replace(llvm::StringRef Haystack, llvm::StringRef Needle, llvm::StringRef Repl)
Definition: TestIndex.cpp:30
clang::tidy::readability::SK_Count
Definition: IdentifierNamingCheck.cpp:109
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:55
clang::tidy::readability::StyleKind
StyleKind
Definition: IdentifierNamingCheck.cpp:105
clang::tidy::readability::IdentifierNamingCheck::NamingStyle
Definition: IdentifierNamingCheck.h:50
Word
std::string Word
Definition: FuzzyMatchTests.cpp:40
clang::tidy::readability::IdentifierNamingCheck::CT_CamelSnakeCase
Definition: IdentifierNamingCheck.h:46
clang::tidy::RenamerClangTidyCheck
Base class for clang-tidy checks that want to flag declarations and/or macros for renaming based on c...
Definition: RenamerClangTidyCheck.h:28
clang::tidy::readability::matchesStyle
static bool matchesStyle(StringRef Name, IdentifierNamingCheck::NamingStyle Style)
Definition: IdentifierNamingCheck.cpp:174
STRINGIZE
#define STRINGIZE(v)
clang::tidy::readability::IdentifierNamingCheck::CT_LowerCase
Definition: IdentifierNamingCheck.h:42
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::tidy::objc::@503::NamingStyle
NamingStyle
Definition: PropertyDeclarationCheck.cpp:32
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:152
clang::tidy::readability::findStyleKind
static StyleKind findStyleKind(const NamedDecl *D, const std::vector< llvm::Optional< IdentifierNamingCheck::NamingStyle >> &NamingStyles, bool IgnoreMainLikeFunctions)
Definition: IdentifierNamingCheck.cpp:375
clang::tidy::readability::IdentifierNamingCheck::CT_CamelBack
Definition: IdentifierNamingCheck.h:43
ENUMERATE
#define ENUMERATE(v)
Definition: IdentifierNamingCheck.cpp:106
clang::tidy::readability::IdentifierNamingCheck::storeOptions
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
Should store all options supported by this check with their current values or default values for opti...
Definition: IdentifierNamingCheck.cpp:155
clang::tidy::ClangTidyOptions::OptionMap
std::map< std::string, ClangTidyValue > OptionMap
Definition: ClangTidyOptions.h:111