Alexander, I have uploaded the patch to phabricator with the changes you mentioned: http://reviews.llvm.org/D10933
-- Beren Minor On Fri, Jul 3, 2015 at 2:13 PM, Beren Minor <beren.mi...@gmail.com> wrote: > No worries, I don't think I will be very active this month either. > > -- > Beren Minor > > On Fri, Jul 3, 2015 at 10:28 AM, Alexander Kornienko <ale...@google.com> > wrote: > >> Awesome! Waiting for the next patch. Please note though, that the next >> week I'm OOO and won't be able to reply. >> >> -- Alexander Kornienko >> On 3 Jul 2015 10:13, "Beren Minor" <beren.mi...@gmail.com> wrote: >> >>> Hi Alexander, >>> >>> Thanks for taking the time to review and reply, I wasn't sure of how to >>> submit patches to clang-tools-extra. I will upload the diffs to phabricator >>> from now on. >>> >>> I had in mind of the issue of fixing only declarations and the fact that >>> it will break the code when one apply the fixes automatically. I will add a >>> DeclRef matcher to fix the references as well and, for now, output a fix >>> only if the declaration is in the TU main file and not in a macro expansion. >>> >>> Best, >>> -- >>> Beren Minor >>> >>> On Tue, Jun 30, 2015 at 4:55 PM, Alexander Kornienko <ale...@google.com> >>> wrote: >>> >>>> Hi Beren, >>>> >>>> Sorry for the delay. You can put me to CC on clang-tidy related patches >>>> to get faster reviews ;) It would also be more convenient to review patches >>>> using Phabricator <http://reviews.llvm.org>, so I'd appreciate if you >>>> could upload your patch there. >>>> >>>> Thanks for making the effort and implementing this as a clang-tidy >>>> check. The check seems to be generic enough to cover many frequently used >>>> styles, so it's really nice to have it. >>>> >>>> However, there's one issue with this check in its current form: >>>> applying its fixes will break the code, because it only fixes declarations, >>>> not usages. Fixing all usages of entities declared in headers may be >>>> complicated, and it needs to be done in all translation units using this >>>> header and also in all currently preprocessed-out code. So we may need to >>>> limit the scope of automatic fixes to safe cases by default and only >>>> perform unsafe replacements when specifically asked to do so. Clang-tidy >>>> doesn't yet have a concept of "unsafe fixes", but we need something like >>>> this for this check. >>>> >>>> A few other random comments: >>>> >>>> diff --git a/clang-tidy/readability/CMakeLists.txt >>>>> b/clang-tidy/readability/CMakeLists.txt >>>>> index 5248620..b3baaee 100644 >>>>> --- a/clang-tidy/readability/CMakeLists.txt >>>>> +++ b/clang-tidy/readability/CMakeLists.txt >>>>> @@ -5,6 +5,7 @@ add_clang_library(clangTidyReadabilityModule >>>>> ContainerSizeEmptyCheck.cpp >>>>> ElseAfterReturnCheck.cpp >>>>> FunctionSizeCheck.cpp >>>>> + IdentifierCaseCheck.cpp >>>>> NamedParameterCheck.cpp >>>>> NamespaceCommentCheck.cpp >>>>> ReadabilityTidyModule.cpp >>>>> diff --git a/clang-tidy/readability/IdentifierCaseCheck.cpp >>>>> b/clang-tidy/readability/IdentifierCaseCheck.cpp >>>>> new file mode 100644 >>>>> index 0000000..5172f58 >>>>> --- /dev/null >>>>> +++ b/clang-tidy/readability/IdentifierCaseCheck.cpp >>>>> @@ -0,0 +1,606 @@ >>>>> +//===--- FunctionSize.cpp - clang-tidy >>>>> ------------------------------------===// >>>>> +// >>>>> +// The LLVM Compiler Infrastructure >>>>> +// >>>>> +// This file is distributed under the University of Illinois Open >>>>> Source >>>>> +// License. See LICENSE.TXT for details. >>>>> +// >>>>> >>>>> +//===----------------------------------------------------------------------===// >>>>> + >>>>> +#include "IdentifierCaseCheck.h" >>>>> +#include "clang/ASTMatchers/ASTMatchFinder.h" >>>>> + >>>>> +using namespace clang::ast_matchers; >>>>> + >>>>> +namespace clang { >>>>> +namespace tidy { >>>>> +namespace readability { >>>>> + >>>>> +static llvm::StringRef const CaseStyleKeys[] = { >>>>> + "Namespace", >>>>> + "InlineNamespace", >>>>> + >>>>> + "EnumConstant", >>>>> + "ConstexprVariable", >>>>> + "MemberConstant", >>>>> + "MemberPrivate", >>>>> + "MemberProtected", >>>>> + "MemberPublic", >>>>> + "Member", >>>>> + "ClassConstant", >>>>> + "ClassMember", >>>>> + "GlobalConstant", >>>>> + "GlobalVariable", >>>>> + "LocalConstant", >>>>> + "LocalVariable", >>>>> + "StaticConstant", >>>>> + "StaticVariable", >>>>> + "Constant", >>>>> + "Variable", >>>>> + >>>>> + "ParameterConstant", >>>>> + "ParameterPack", >>>>> + "Parameter", >>>>> + >>>>> + "Abstract", >>>>> + "Struct", >>>>> + "Class", >>>>> + "Union", >>>>> + "Enum", >>>>> + >>>>> + "GlobalFunction", >>>>> + "ConstexprFunction", >>>>> + "Function", >>>>> + >>>>> + "ConstexprMethod", >>>>> + "VirtualMethod", >>>>> + "ClassMethod", >>>>> + "MethodPrivate", >>>>> + "MethodProtected", >>>>> + "MethodPublic", >>>>> + "Method", >>>>> + >>>>> + "Typedef", >>>>> + >>>>> + "TypeTemplateParameter", >>>>> + "ValueTemplateParameter", >>>>> + "TemplateTemplateParameter", >>>>> + "TemplateParameter", >>>>> +}; >>>>> + >>>>> +IdentifierCaseCheck::IdentifierCaseCheck(StringRef Name, >>>>> + ClangTidyContext *Context) >>>>> + : ClangTidyCheck(Name, Context) { >>>>> + auto const fromString = [](llvm::StringRef Str) { >>>>> + if (Str.equals("any") || Str.equals("aNy_CasE")) { >>>>> + return AnyCase; >>>>> + } else if (Str.equals("lower") || Str.equals("lower_case")) { >>>> >>>> >>>> Please no "else" after "return". >>>> <http://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return> >>>> >>>> + return LowerCase; >>>>> + } else if (Str.equals("camelBack")) { >>>>> + return CamelBack; >>>>> + } else if (Str.equals("upper") || Str.equals("UPPER_CASE")) { >>>>> + return UpperCase; >>>>> + } else if (Str.equals("CamelCase")) { >>>>> + return CamelCase; >>>>> + } else { >>>>> + return AnyCase; >>>>> + } >>>>> + }; >>>>> + >>>>> + for (const auto &Key : CaseStyleKeys) { >>>>> + CaseConfigs[Key] = >>>>> + CaseConfig(fromString(Options.get((Key + "Case").str(), >>>>> "aNy_CasE")), >>>>> + Options.get((Key + "Prefix").str(), ""), >>>>> + Options.get((Key + "Suffix").str(), "")); >>>>> + } >>>>> + >>>>> + IgnoreFailedSplit = Options.get("IgnoreFailedSplit", 0); >>>>> +} >>>>> + >>>>> +void IdentifierCaseCheck::storeOptions(ClangTidyOptions::OptionMap >>>>> &Opts) { >>>>> + auto const toString = [](CaseType Type) { >>>>> + switch (Type) { >>>>> + default: >>>>> + case AnyCase: >>>>> + return "aNy_CasE"; >>>>> + case LowerCase: >>>>> + return "lower_case"; >>>>> + case CamelBack: >>>>> + return "camelBack"; >>>>> + case UpperCase: >>>>> + return "UPPER_CASE"; >>>>> + case CamelCase: >>>>> + return "CamelCase"; >>>>> + } >>>>> + }; >>>>> + >>>>> + for (const auto &Key : CaseStyleKeys) { >>>>> + Options.store(Opts, (Key + "Case").str(), >>>>> toString(CaseConfigs[Key].Case)); >>>>> + Options.store(Opts, (Key + "Prefix").str(), >>>>> CaseConfigs[Key].Prefix); >>>>> + Options.store(Opts, (Key + "Suffix").str(), >>>>> CaseConfigs[Key].Suffix); >>>>> + } >>>>> + >>>>> + Options.store(Opts, "IgnoreFailedSplit", IgnoreFailedSplit); >>>>> +} >>>>> + >>>>> +void IdentifierCaseCheck::registerMatchers(MatchFinder *Finder) { >>>>> + Finder->addMatcher(namedDecl().bind("decl"), this); >>>>> +} >>>>> + >>>>> +void IdentifierCaseCheck::check(const MatchFinder::MatchResult >>>>> &Result) { >>>>> + if (const auto *Decl = Result.Nodes.getNodeAs<NamedDecl>("decl")) { >>>>> + if (!Decl->getIdentifier()) >>>>> + return; >>>>> + >>>>> + if (Decl->getName().empty()) >>>>> + return; >>>>> + >>>>> + if (Decl->isImplicit()) >>>>> + return; >>>>> + } >>>>> + >>>>> + auto KindName = "identifier"; >>>>> >>>> >>>> Can we use an enumeration or at least string constants instead of >>>> string literals? Compiler won't tell you if there's a typo in one of the >>>> literals. >>>> >>>> >>>>> + auto Style = CaseConfig(); >>>>> + >>>>> + if (Result.Nodes.getNodeAs<TypedefDecl>("decl")) { >>>>> + if (false) { >>>>> + // >>>>> >>>> >>>> Please remove this and other dead or commented out code. >>>> >>>> + } else if (CaseConfigs["Typedef"].isSet()) { >>>>> + KindName = "typedef"; >>>>> + Style = CaseConfigs["Typedef"]; >>>>> + } >>>>> + } >>>>> + if (const auto *Decl = >>>>> Result.Nodes.getNodeAs<NamespaceDecl>("decl")) { >>>>> + if (Decl->isAnonymousNamespace()) >>>>> + return; >>>>> + >>>>> + if (false) { >>>>> + // >>>>> >>>> >>>> ditto >>>> >>>> >>>>> + } else if (Decl->isInline() && >>>>> CaseConfigs["InlineNamespace"].isSet()) { >>>>> + KindName = "inline namespace"; >>>>> + Style = CaseConfigs["InlineNamespace"]; >>>>> + } else if (CaseConfigs["Namespace"].isSet()) { >>>>> + KindName = "namespace"; >>>>> + Style = CaseConfigs["Namespace"]; >>>>> + } >>>>> + } >>>>> + if (const auto *Decl = >>>>> Result.Nodes.getNodeAs<CXXRecordDecl>("decl")) { >>>>> + if (Decl->isAnonymousStructOrUnion()) >>>>> + return; >>>>> + >>>>> + if (false) { >>>> >>>> + // } else if (Decl->isLambda() && CaseConfigs["Lambda"].isSet()) >>>>> { >>>>> + // } else if (Decl->isInterface() && >>>>> CaseConfigs["Interface"].isSet()) { >>>>> + } else if (Decl->hasDefinition() && Decl->isAbstract() && >>>>> + CaseConfigs["Abstract"].isSet()) { >>>>> + KindName = "abstract class"; >>>>> + Style = CaseConfigs["Abstract"]; >>>>> + } else if (Decl->isStruct() && CaseConfigs["Struct"].isSet()) { >>>>> + KindName = "struct"; >>>>> + Style = CaseConfigs["Struct"]; >>>>> + } else if (Decl->isStruct() && CaseConfigs["Class"].isSet()) { >>>>> + KindName = "struct"; >>>>> + Style = CaseConfigs["Class"]; >>>>> + } else if (Decl->isClass() && CaseConfigs["Class"].isSet()) { >>>>> + KindName = "class"; >>>>> + Style = CaseConfigs["Class"]; >>>>> + } else if (Decl->isClass() && CaseConfigs["Struct"].isSet()) { >>>>> + KindName = "class"; >>>>> + Style = CaseConfigs["Struct"]; >>>>> + } else if (Decl->isUnion() && CaseConfigs["Union"].isSet()) { >>>>> + KindName = "union"; >>>>> + Style = CaseConfigs["Union"]; >>>>> + } else if (Decl->isEnum() && CaseConfigs["Enum"].isSet()) { >>>>> + KindName = "enum"; >>>>> + Style = CaseConfigs["Enum"]; >>>>> + } >>>>> + } >>>>> + // if (Result.Nodes.getNodeAs<ClassTemplateDecl>("decl")); >>>>> + // if >>>>> (Result.Nodes.getNodeAs<ClassTemplateSpecializationDecl>("decl")); >>>> >>>> + >>>>> + if (const auto *Decl = Result.Nodes.getNodeAs<FieldDecl>("decl")) { >>>>> + auto Type = Decl->getType(); >>>>> + >>>>> + if (false) { >>>>> + // } else if (!Type.isNull() && >>>>> Type.isLocalRestrictQualified()) { >>>>> + // } else if (!Type.isNull() && >>>>> Type.isLocalVolatileQualified()) { >>>>> + // } else if (!Type.isNull() && Type.getAsString() == "") { >>>> >>>> + } else if (!Type.isNull() && Type.isLocalConstQualified() && >>>>> + CaseConfigs["MemberConstant"].isSet()) { >>>>> + KindName = "constant member"; >>>>> + Style = CaseConfigs["MemberConstant"]; >>>>> + } else if (!Type.isNull() && Type.isLocalConstQualified() && >>>>> + CaseConfigs["Constant"].isSet()) { >>>>> + KindName = "constant member"; >>>>> + Style = CaseConfigs["Constant"]; >>>>> + } else if (Decl->getAccess() == clang::AS_private && >>>>> + CaseConfigs["MemberPrivate"].isSet()) { >>>>> + KindName = "private member"; >>>>> + Style = CaseConfigs["MemberPrivate"]; >>>>> + } else if (Decl->getAccess() == clang::AS_protected && >>>>> + CaseConfigs["MemberProtected"].isSet()) { >>>>> + KindName = "protected member"; >>>>> + Style = CaseConfigs["MemberProtected"]; >>>>> + } else if (Decl->getAccess() == clang::AS_public && >>>>> + CaseConfigs["MemberPublic"].isSet()) { >>>>> + KindName = "public member"; >>>>> + Style = CaseConfigs["MemberPublic"]; >>>>> + } else if (CaseConfigs["Member"].isSet()) { >>>>> + KindName = "member"; >>>>> + Style = CaseConfigs["Member"]; >>>>> + } >>>>> + } else if (const auto *Decl = >>>>> Result.Nodes.getNodeAs<ParmVarDecl>("decl")) { >>>>> + auto Type = Decl->getType(); >>>>> + >>>>> + if (false) { >>>>> + // } else if (!Type.isNull() && >>>>> Type.isLocalRestrictQualified()) { >>>>> + // } else if (!Type.isNull() && >>>>> Type.isLocalVolatileQualified()) { >>>>> + // } else if (!Type.isNull() && Type.getAsString() == "") { >>>>> + } else if (Decl->isConstexpr() && >>>>> + CaseConfigs["ConstexprVariable"].isSet()) { >>>>> + KindName = "constexpr"; >>>>> + Style = CaseConfigs["ConstexprVariable"]; >>>>> + } else if (!Type.isNull() && Type.isLocalConstQualified() && >>>>> + CaseConfigs["ParameterConstant"].isSet()) { >>>>> + KindName = "constant parameter"; >>>>> + Style = CaseConfigs["Constant"]; >>>>> + } else if (!Type.isNull() && Type.isLocalConstQualified() && >>>>> + CaseConfigs["Constant"].isSet()) { >>>>> + KindName = "constant parameter"; >>>>> + Style = CaseConfigs["Constant"]; >>>>> + } else if (Decl->isParameterPack() && >>>>> + CaseConfigs["ParameterPack"].isSet()) { >>>>> + KindName = "parameter pack"; >>>>> + Style = CaseConfigs["ParameterPack"]; >>>>> + } else if (CaseConfigs["Parameter"].isSet()) { >>>>> + KindName = "parameter"; >>>>> + Style = CaseConfigs["Parameter"]; >>>>> + } >>>>> + } else if (const auto *Decl = >>>>> Result.Nodes.getNodeAs<VarDecl>("decl")) { >>>>> + auto Type = Decl->getType(); >>>>> + >>>>> + if (false) { >>>>> + // } else if (!Type.isNull() && >>>>> Type.isLocalRestrictQualified()) { >>>>> + // } else if (!Type.isNull() && >>>>> Type.isLocalVolatileQualified()) { >>>>> + // } else if (!Type.isNull() && Type.getAsString() == "") { >>>>> + } else if (Decl->isConstexpr() && >>>>> + CaseConfigs["ConstexprVariable"].isSet()) { >>>>> + KindName = "constexpr"; >>>>> + Style = CaseConfigs["ConstexprVariable"]; >>>>> + } else if (!Type.isNull() && Type.isLocalConstQualified() && >>>>> + Decl->isStaticDataMember() && >>>>> + CaseConfigs["ClassConstant"].isSet()) { >>>>> + KindName = "class constant"; >>>>> + Style = CaseConfigs["ClassConstant"]; >>>>> + } else if (!Type.isNull() && Type.isLocalConstQualified() && >>>>> + Decl->isFileVarDecl() && >>>>> CaseConfigs["GlobalConstant"].isSet()) { >>>>> + KindName = "global constant"; >>>>> + Style = CaseConfigs["GlobalConstant"]; >>>>> + } else if (!Type.isNull() && Type.isLocalConstQualified() && >>>>> + Decl->isStaticLocal() && >>>>> CaseConfigs["StaticConstant"].isSet()) { >>>>> + KindName = "static constant"; >>>>> + Style = CaseConfigs["StaticConstant"]; >>>>> + } else if (!Type.isNull() && Type.isLocalConstQualified() && >>>>> + Decl->isLocalVarDecl() && >>>>> CaseConfigs["LocalConstant"].isSet()) { >>>>> + KindName = "local constant"; >>>>> + Style = CaseConfigs["LocalConstant"]; >>>>> + } else if (!Type.isNull() && Type.isLocalConstQualified() && >>>>> + Decl->isFunctionOrMethodVarDecl() && >>>>> + CaseConfigs["LocalConstant"].isSet()) { >>>>> + KindName = "local constant"; >>>>> + Style = CaseConfigs["LocalConstant"]; >>>>> + } else if (!Type.isNull() && Type.isLocalConstQualified() && >>>>> + CaseConfigs["Constant"].isSet()) { >>>>> + KindName = "constant"; >>>>> + Style = CaseConfigs["Constant"]; >>>>> + >>>>> + // } else if (Decl->isWeak()) { >>>>> + } else if (Decl->isStaticDataMember() && >>>>> + CaseConfigs["ClassMember"].isSet()) { >>>>> + KindName = "class member"; >>>>> + Style = CaseConfigs["ClassMember"]; >>>>> + } else if (Decl->isFileVarDecl() && >>>>> CaseConfigs["GlobalVariable"].isSet()) { >>>>> + KindName = "global variable"; >>>>> + Style = CaseConfigs["GlobalVariable"]; >>>>> + } else if (Decl->isStaticLocal() && >>>>> CaseConfigs["StaticVariable"].isSet()) { >>>>> + KindName = "static variable"; >>>>> + Style = CaseConfigs["StaticVariable"]; >>>>> + } else if (Decl->isLocalVarDecl() && >>>>> CaseConfigs["LocalVariable"].isSet()) { >>>>> + KindName = "local variable"; >>>>> + Style = CaseConfigs["LocalVariable"]; >>>>> + } else if (Decl->isFunctionOrMethodVarDecl() && >>>>> + CaseConfigs["LocalVariable"].isSet()) { >>>>> + KindName = "local variable"; >>>>> + Style = CaseConfigs["LocalVariable"]; >>>>> + >>>>> + // } else if (Decl->isExceptionVariable() && >>>>> + // CaseConfigs["ExceptionVariable"].isSet()) { >>>>> + // } else if (Decl->isNRVOVariable()) { >>>>> + // } else if (Decl->isCXXForRangeDecl()) { >>>>> + } else if (CaseConfigs["Variable"].isSet()) { >>>>> + KindName = "variable"; >>>>> + Style = CaseConfigs["Variable"]; >>>>> + } >>>>> + } >>>>> + >>>>> + if (const auto *Decl = >>>>> Result.Nodes.getNodeAs<CXXMethodDecl>("decl")) { >>>>> + if (Decl->isMain()) >>>>> + return; >>>>> + >>>>> + if (!Decl->isUserProvided()) >>>>> + return; >>>>> + >>>>> + if (Decl->isUsualDeallocationFunction()) >>>>> + return; >>>>> + >>>>> + if (Decl->isCopyAssignmentOperator()) >>>>> + return; >>>>> + >>>>> + if (Decl->isMoveAssignmentOperator()) >>>>> + return; >>>>> + >>>>> + if (Decl->size_overridden_methods() > 0) >>>>> + return; >>>>> >>>> >>>> I'd merge all above checks to one `if`. >>>> >>>> >>>>> + >>>>> + if (false) { >>>>> + // } else if (Decl->isVariadic()) { >>>>> + } else if (Decl->isConstexpr() && >>>>> CaseConfigs["ConstexprMethod"].isSet()) { >>>>> + KindName = "constexpr method"; >>>>> + Style = CaseConfigs["ConstexprMethod"]; >>>>> + } else if (Decl->isConstexpr() && >>>>> + CaseConfigs["ConstexprFunction"].isSet()) { >>>>> + KindName = "constexpr method"; >>>>> + Style = CaseConfigs["ConstexprFunction"]; >>>>> + >>>>> + // } else if (Decl->isPure()) { >>>>> + // } else if (Decl->isTrivial()) { >>>>> + // } else if (Decl->isVirtualAsWritten()) { >>>>> + // } else if (Decl->isGlobal()) { >>>>> + // } else if (Decl->isInlineSpecified()) { >>>>> + // } else if (Decl->isOverloadedOperator()) { >>>>> + // } else if (Decl->isFunctionTemplateSpecialization()) { >>>>> + >>>>> + } else if (Decl->isStatic() && >>>>> CaseConfigs["ClassMethod"].isSet()) { >>>>> + KindName = "class method"; >>>>> + Style = CaseConfigs["ClassMethod"]; >>>>> + >>>>> + // } else if (Decl->isConst()) { >>>>> + // } else if (Decl->isVolatile()) { >>>>> + } else if (Decl->isVirtual() && >>>>> CaseConfigs["VirtualMethod"].isSet()) { >>>>> + KindName = "virtual method"; >>>>> + Style = CaseConfigs["VirtualMethod"]; >>>>> + } else if (Decl->getAccess() == clang::AS_private && >>>>> + CaseConfigs["MethodPrivate"].isSet()) { >>>>> + KindName = "private method"; >>>>> + Style = CaseConfigs["MethodPrivate"]; >>>>> + } else if (Decl->getAccess() == clang::AS_protected && >>>>> + CaseConfigs["MethodProtected"].isSet()) { >>>>> + KindName = "protected method"; >>>>> + Style = CaseConfigs["MethodProtected"]; >>>>> + } else if (Decl->getAccess() == clang::AS_public && >>>>> + CaseConfigs["MethodPublic"].isSet()) { >>>>> + KindName = "public method"; >>>>> + Style = CaseConfigs["MethodPublic"]; >>>>> + } else if (CaseConfigs["Method"].isSet()) { >>>>> + KindName = "method"; >>>>> + Style = CaseConfigs["Method"]; >>>>> + } else if (CaseConfigs["Function"].isSet()) { >>>>> + KindName = "method"; >>>>> + Style = CaseConfigs["Function"]; >>>>> + } >>>>> + } else if (const auto *Decl = >>>>> Result.Nodes.getNodeAs<FunctionDecl>("decl")) { >>>>> + if (Decl->isMain()) >>>>> + return; >>>>> + >>>>> + if (false) { >>>>> + // } else if (Decl->isVariadic()) { >>>>> + } else if (Decl->isConstexpr() && >>>>> + CaseConfigs["ConstexprFunction"].isSet()) { >>>>> + KindName = "constexpr function"; >>>>> + Style = CaseConfigs["ConstexprFunction"]; >>>>> + >>>>> + // } else if (Decl->isPure()) { >>>>> + // } else if (Decl->isTrivial()) { >>>>> + // } else if (Decl->isVirtualAsWritten()) { >>>>> + } else if (Decl->isGlobal() && >>>>> CaseConfigs["GlobalFunction"].isSet()) { >>>>> + KindName = "global function"; >>>>> + Style = CaseConfigs["GlobalFunction"]; >>>>> + >>>>> + // } else if (Decl->isInlineSpecified()) { >>>>> + // } else if (Decl->isOverloadedOperator()) { >>>>> + // } else if (Decl->isFunctionTemplateSpecialization()) { >>>>> + } else if (CaseConfigs["Function"].isSet()) { >>>>> + KindName = "function"; >>>>> + Style = CaseConfigs["Function"]; >>>>> + } >>>>> + } >>>>> + >>>>> + // if (Result.Nodes.getNodeAs<FunctionTemplateDecl>("decl")); >>>>> + // if (Result.Nodes.getNodeAs<UsingDecl>("decl")); >>>>> + // if (Result.Nodes.getNodeAs<UsingDirectiveDecl>("decl")); >>>>> + // if (Result.Nodes.getNodeAs<UnresolvedUsingValueDecl>("decl")); >>>>> + >>>>> + if (Result.Nodes.getNodeAs<EnumDecl>("decl")) { >>>>> + if (false) { >>>>> + // >>>>> + } else if (CaseConfigs["Enum"].isSet()) { >>>>> + KindName = "enum"; >>>>> + Style = CaseConfigs["Enum"]; >>>>> + } >>>>> + } >>>>> + if (Result.Nodes.getNodeAs<EnumConstantDecl>("decl")) { >>>>> + if (false) { >>>>> + // >>>>> + } else if (CaseConfigs["EnumConstant"].isSet()) { >>>>> + KindName = "enum constant"; >>>>> + Style = CaseConfigs["EnumConstant"]; >>>>> + } else if (CaseConfigs["Constant"].isSet()) { >>>>> + KindName = "enum constant"; >>>>> + Style = CaseConfigs["Constant"]; >>>>> + } >>>>> + } >>>>> + >>>>> + if (Result.Nodes.getNodeAs<TemplateTypeParmDecl>("decl")) { >>>>> + if (false) { >>>>> + // >>>>> + } else if (CaseConfigs["TypeTemplateParameter"].isSet()) { >>>>> + KindName = "type template parameter"; >>>>> + Style = CaseConfigs["TypeTemplateParameter"]; >>>>> + } else if (CaseConfigs["TemplateParameter"].isSet()) { >>>>> + KindName = "template parameter"; >>>>> + Style = CaseConfigs["TemplateParameter"]; >>>>> + } >>>>> + } else if (Result.Nodes.getNodeAs<NonTypeTemplateParmDecl>("decl")) >>>>> { >>>>> + if (false) { >>>>> + // >>>>> + } else if (CaseConfigs["ValueTemplateParameter"].isSet()) { >>>>> + KindName = "value template parameter"; >>>>> + Style = CaseConfigs["ValueTemplateParameter"]; >>>>> + } else if (CaseConfigs["TemplateParameter"].isSet()) { >>>>> + KindName = "template parameter"; >>>>> + Style = CaseConfigs["TemplateParameter"]; >>>>> + } >>>>> + } else if >>>>> (Result.Nodes.getNodeAs<TemplateTemplateParmDecl>("decl")) { >>>>> + if (false) { >>>>> + // >>>>> + } else if (CaseConfigs["TemplateTemplateParameter"].isSet()) { >>>>> + KindName = "template template parameter"; >>>>> + Style = CaseConfigs["TemplateTemplateParameter"]; >>>>> + } else if (CaseConfigs["TemplateParameter"].isSet()) { >>>>> + KindName = "template parameter"; >>>>> + Style = CaseConfigs["TemplateParameter"]; >>>>> + } >>>>> + } >>>>> + >>>>> + if (!Style.isSet()) >>>>> + return; >>>>> + >>>>> + auto matchesStyle = [](llvm::StringRef Name, CaseConfig Style) { >>>>> + static llvm::Regex Matchers[] = { >>>>> + llvm::Regex(llvm::StringRef("^.*$")), >>>>> + llvm::Regex(llvm::StringRef("^[a-z][a-z0-9_]*$")), >>>>> + llvm::Regex(llvm::StringRef("^[a-z][a-zA-Z0-9]*$")), >>>>> + llvm::Regex(llvm::StringRef("^[A-Z][A-Z0-9_]*$")), >>>>> + llvm::Regex(llvm::StringRef("^[A-Z][a-zA-Z0-9]*$")), >>>>> + }; >>>>> + >>>>> + 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; >>>>> + >>>>> + if (!Matchers[static_cast<size_t>(Style.Case)].match(Name)) >>>>> + Matches = false; >>>>> + >>>>> + return Matches; >>>>> + }; >>>>> + >>>>> + if (const auto *Decl = Result.Nodes.getNodeAs<NamedDecl>("decl")) { >>>>> + if (matchesStyle(Decl->getName(), Style)) >>>>> + return; >>>>> + >>>>> + auto fixupWithStyle = [](std::string Name, CaseConfig Style) { >>>>> + static auto Splitter = llvm::Regex(llvm::StringRef( >>>>> + >>>>> "(([a-z0-9A-Z]*)(_+)|([A-Z]?[a-z0-9]+)([A-Z]|$)|([A-Z]+)([A-Z]|$))")); >>>>> + >>>>> + auto Words = llvm::SmallVector<std::string, 8>(); >>>>> + auto Substrs = llvm::SmallVector<llvm::StringRef, 8>(); >>>>> + llvm::StringRef(Name).split(Substrs, "_", -1, false); >>>>> + for (std::string Substr : Substrs) { >>>>> + while (!Substr.empty()) { >>>>> + auto Groups = llvm::SmallVector<llvm::StringRef, 8>(); >>>>> + if (!Splitter.match(Substr, &Groups)) >>>>> + break; >>>>> + >>>>> + if (Groups[3].size() > 0) { >>>>> + Words.emplace_back(std::move(Groups[2])); >>>>> + Substr = Substr.substr(Groups[0].size()); >>>>> + >>>>> + } else if (Groups[4].size() > 0) { >>>>> + Words.emplace_back(std::move(Groups[4])); >>>>> + Substr = Substr.substr(Groups[0].size() - >>>>> Groups[5].size()); >>>>> + >>>>> + } else if (Groups[6].size() > 0) { >>>>> + Words.emplace_back(std::move(Groups[6])); >>>>> + Substr = Substr.substr(Groups[0].size() - >>>>> Groups[7].size()); >>>>> + } >>>>> + } >>>>> + } >>>>> + >>>>> + if (Words.empty()) { >>>>> + return Name; >>>>> + } >>>>> + >>>>> + std::string Fixup = Style.Prefix; >>>>> + switch (Style.Case) { >>>>> + case AnyCase: >>>>> + Fixup += Name; >>>>> + break; >>>>> + >>>>> + case LowerCase: >>>>> + for (auto const &Word : Words) { >>>>> + if (&Word != &Words.front()) >>>>> + Fixup += "_"; >>>>> + Fixup += llvm::StringRef(Word).lower(); >>>>> + } >>>>> + break; >>>>> + >>>>> + case UpperCase: >>>>> + for (auto const &Word : Words) { >>>>> + if (&Word != &Words.front()) >>>>> + Fixup += "_"; >>>>> + Fixup += llvm::StringRef(Word).upper(); >>>>> + } >>>>> + break; >>>>> + >>>>> + case CamelCase: >>>>> + for (auto const &Word : Words) { >>>>> + Fixup += llvm::StringRef(Word).substr(0, 1).upper(); >>>>> + Fixup += llvm::StringRef(Word).substr(1).lower(); >>>>> + } >>>>> + break; >>>>> + >>>>> + case CamelBack: >>>>> + for (auto const &Word : Words) { >>>>> + if (&Word == &Words.front()) { >>>>> + Fixup += llvm::StringRef(Word).lower(); >>>>> + } else { >>>>> + Fixup += llvm::StringRef(Word).substr(0, 1).upper(); >>>>> + Fixup += llvm::StringRef(Word).substr(1).lower(); >>>>> + } >>>>> + } >>>>> + break; >>>>> + } >>>>> + Fixup += Style.Suffix; >>>>> + >>>>> + return Fixup; >>>>> + }; >>>>> + >>>>> + auto Name = Decl->getName(); >>>>> + auto Fixup = fixupWithStyle(Name, Style); >>>>> + if (llvm::StringRef(Fixup).equals(Name)) { >>>>> >>>> >>>> No need for `llvm::` here. `StringRef` is visible in the `clang` >>>> namespace. >>>> >>>> >>>>> + if (!IgnoreFailedSplit) { >>>>> + diag(Decl->getLocStart(), "unable to split words for %0 '%1'") >>>>> + << KindName << Name; >>>>> + } >>>>> + } else { >>>>> + auto Range = >>>>> + clang::DeclarationNameInfo(Decl->getDeclName(), >>>>> Decl->getLocation()) >>>>> >>>> >>>> No need for `clang::` here. >>>> >>>> >>>>> + .getSourceRange(); >>>> >>>> + auto Diagn = diag(Decl->getLocStart(), "invalid case style for >>>>> %0 '%1'"); >>>>> + Diagn << KindName << Decl->getName(); >>>>> + Diagn << FixItHint::CreateReplacement( >>>>> + CharSourceRange::getTokenRange(Range), Fixup); >>>>> >>>> >>>> No need for the `Diagn` variable, just make these a single statement. >>>> >>>> >>>>> + } >>>>> + } >>>>> +} >>>>> + >>>>> +} // namespace readability >>>>> +} // namespace tidy >>>>> +} // namespace clang >>>>> diff --git a/clang-tidy/readability/IdentifierCaseCheck.h >>>>> b/clang-tidy/readability/IdentifierCaseCheck.h >>>>> new file mode 100644 >>>>> index 0000000..a7c8aee >>>>> --- /dev/null >>>>> +++ b/clang-tidy/readability/IdentifierCaseCheck.h >>>>> @@ -0,0 +1,61 @@ >>>>> +//===--- IdentifierCaseCheck.h - clang-tidy -----------------------*- >>>>> C++ >>>>> +//-*-===// >>>>> +// >>>>> +// The LLVM Compiler Infrastructure >>>>> +// >>>>> +// This file is distributed under the University of Illinois Open >>>>> Source >>>>> +// License. See LICENSE.TXT for details. >>>>> +// >>>>> >>>>> +//===----------------------------------------------------------------------===// >>>>> + >>>>> +#ifndef >>>>> LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERCASECHECK_H >>>>> +#define >>>>> LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERCASECHECK_H >>>>> + >>>>> +#include "../ClangTidy.h" >>>>> + >>>>> +namespace clang { >>>>> +namespace tidy { >>>>> +namespace readability { >>>>> + >>>>> +/// \brief Checks for identifiers case mismatch. >>>>> +class IdentifierCaseCheck : public ClangTidyCheck { >>>>> +public: >>>>> + IdentifierCaseCheck(StringRef Name, ClangTidyContext *Context); >>>>> + >>>>> + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; >>>>> + void registerMatchers(ast_matchers::MatchFinder *Finder) override; >>>>> + void check(const ast_matchers::MatchFinder::MatchResult &Result) >>>>> override; >>>>> + >>>>> +private: >>>>> + enum CaseType { >>>>> + AnyCase = 0, >>>>> + LowerCase, >>>>> + CamelBack, >>>>> + UpperCase, >>>>> + CamelCase, >>>>> + }; >>>>> + >>>>> + struct CaseConfig { >>>>> + CaseConfig() : Case(CaseType::AnyCase), Prefix(""), Suffix("") {} >>>>> >>>> >>>> No need to initialize std::string with "". >>>> >>>> >>>>> + >>>>> + CaseConfig(CaseType Case, std::string Prefix, std::string Suffix) >>>>> + : Case(Case), Prefix(std::move(Prefix)), >>>>> Suffix(std::move(Suffix)) {} >>>>> + >>>>> + CaseType Case; >>>>> + std::string Prefix; >>>>> + std::string Suffix; >>>>> + >>>>> + bool isSet() { >>>>> + return !(Case == CaseType::AnyCase && Prefix.empty() && >>>>> Suffix.empty()); >>>>> + } >>>>> + }; >>>>> + >>>>> + std::map<std::string, CaseConfig> CaseConfigs; >>>>> + bool IgnoreFailedSplit; >>>>> +}; >>>>> + >>>>> +} // namespace readability >>>>> +} // namespace tidy >>>>> +} // namespace clang >>>>> + >>>>> +#endif // >>>>> LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERCASECHECK_H >>>>> diff --git a/clang-tidy/readability/ReadabilityTidyModule.cpp >>>>> b/clang-tidy/readability/ReadabilityTidyModule.cpp >>>>> index bf118f8..7f1f71f 100644 >>>>> --- a/clang-tidy/readability/ReadabilityTidyModule.cpp >>>>> +++ b/clang-tidy/readability/ReadabilityTidyModule.cpp >>>>> @@ -14,6 +14,7 @@ >>>>> #include "ContainerSizeEmptyCheck.h" >>>>> #include "ElseAfterReturnCheck.h" >>>>> #include "FunctionSizeCheck.h" >>>>> +#include "IdentifierCaseCheck.h" >>>>> #include "NamedParameterCheck.h" >>>>> #include "RedundantSmartptrGetCheck.h" >>>>> #include "RedundantStringCStrCheck.h" >>>>> @@ -35,6 +36,8 @@ public: >>>>> "readability-else-after-return"); >>>>> CheckFactories.registerCheck<FunctionSizeCheck>( >>>>> "readability-function-size"); >>>>> + CheckFactories.registerCheck<IdentifierCaseCheck>( >>>>> + "readability-identifier-case"); >>>>> >>>> >>>> The check is not only about case. I think, "readability-naming" or >>>> "readability-identifier-naming" would be a better name. >>>> >>>> >>>>> CheckFactories.registerCheck<readability::NamedParameterCheck>( >>>>> "readability-named-parameter"); >>>>> CheckFactories.registerCheck<RedundantSmartptrGetCheck>( >>>>> diff --git a/test/clang-tidy/readability-identifier-case.cpp >>>>> b/test/clang-tidy/readability-identifier-case.cpp >>>>> new file mode 100644 >>>>> index 0000000..f978639 >>>>> --- /dev/null >>>>> +++ b/test/clang-tidy/readability-identifier-case.cpp >>>>> @@ -0,0 +1,185 @@ >>>>> +// RUN: $(dirname %s)/check_clang_tidy.sh %s >>>>> readability-identifier-case %t -config='{CheckOptions: [{key: >>>>> readability-identifier-case.AbstractCase, value: CamelCase}, {key: >>>>> readability-identifier-case.AbstractPrefix, value: 'A'}, {key: >>>>> readability-identifier-case.ClassCase, value: CamelCase}, {key: >>>>> readability-identifier-case.ClassPrefix, value: 'C'}, {key: >>>>> readability-identifier-case.ClassConstantCase, value: CamelCase}, {key: >>>>> readability-identifier-case.ClassConstantPrefix, value: 'k'}, {key: >>>>> readability-identifier-case.ClassMemberCase, value: CamelCase}, {key: >>>>> readability-identifier-case.ClassMethodCase, value: camelBack}, {key: >>>>> readability-identifier-case.ConstantCase, value: UPPER_CASE}, {key: >>>>> readability-identifier-case.ConstantSuffix, value: '_CST'}, {key: >>>>> readability-identifier-case.ConstexprFunctionCase, value: lower_case}, >>>>> {key: readability-identifier-case.ConstexprMethodCase, value: lower_case}, >>>>> {key: readability-identifier-case.ConstexprVariableCase, value: >>>>> lower_case}, {key: readability-identifier-case.EnumCase, value: >>>>> CamelCase}, >>>>> {key: readability-identifier-case.EnumPrefix, value: 'E'}, {key: >>>>> readability-identifier-case.EnumConstantCase, value: UPPER_CASE}, {key: >>>>> readability-identifier-case.FunctionCase, value: camelBack}, {key: >>>>> readability-identifier-case.GlobalConstantCase, value: UPPER_CASE}, {key: >>>>> readability-identifier-case.GlobalFunctionCase, value: CamelCase}, {key: >>>>> readability-identifier-case.GlobalVariableCase, value: lower_case}, {key: >>>>> readability-identifier-case.GlobalVariablePrefix, value: 'g_'}, {key: >>>>> readability-identifier-case.InlineNamespaceCase, value: lower_case}, {key: >>>>> readability-identifier-case.LocalConstantCase, value: CamelCase}, {key: >>>>> readability-identifier-case.LocalConstantPrefix, value: 'k'}, {key: >>>>> readability-identifier-case.LocalVariableCase, value: lower_case}, {key: >>>>> readability-identifier-case.MemberCase, value: CamelCase}, {key: >>>>> readability-identifier-case.MemberPrefix, value: 'm_'}, {key: >>>>> readability-identifier-case.MemberConstantCase, value: lower_case}, {key: >>>>> readability-identifier-case.MemberPrivatePrefix, value: '__'}, {key: >>>>> readability-identifier-case.MemberProtectedPrefix, value: '_'}, {key: >>>>> readability-identifier-case.MemberPublicCase, value: lower_case}, {key: >>>>> readability-identifier-case.MethodCase, value: camelBack}, {key: >>>>> readability-identifier-case.MethodPrivatePrefix, value: '__'}, {key: >>>>> readability-identifier-case.MethodProtectedPrefix, value: '_'}, {key: >>>>> readability-identifier-case.NamespaceCase, value: lower_case}, {key: >>>>> readability-identifier-case.ParameterCase, value: camelBack}, {key: >>>>> readability-identifier-case.ParameterPrefix, value: 'a_'}, {key: >>>>> readability-identifier-case.ParameterConstantCase, value: camelBack}, >>>>> {key: >>>>> readability-identifier-case.ParameterConstantPrefix, value: 'i_'}, {key: >>>>> readability-identifier-case.ParameterPackCase, value: camelBack}, {key: >>>>> readability-identifier-case.PureFunctionCase, value: lower_case}, {key: >>>>> readability-identifier-case.PureMethodCase, value: camelBack}, {key: >>>>> readability-identifier-case.StaticConstantCase, value: UPPER_CASE}, {key: >>>>> readability-identifier-case.StaticVariableCase, value: camelBack}, {key: >>>>> readability-identifier-case.StaticVariablePrefix, value: 's_'}, {key: >>>>> readability-identifier-case.StructCase, value: lower_case}, {key: >>>>> readability-identifier-case.TemplateParameterCase, value: UPPER_CASE}, >>>>> {key: readability-identifier-case.TemplateTemplateParameterCase, value: >>>>> CamelCase}, {key: readability-identifier-case.TemplateUsingCase, value: >>>>> lower_case}, {key: readability-identifier-case.TemplateUsingPrefix, value: >>>>> 'u_'}, {key: readability-identifier-case.TypeTemplateParameterCase, value: >>>>> camelBack}, {key: readability-identifier-case.TypeTemplateParameterSuffix, >>>>> value: '_t'}, {key: readability-identifier-case.TypedefCase, value: >>>>> lower_case}, {key: readability-identifier-case.TypedefSuffix, value: >>>>> '_t'}, >>>>> {key: readability-identifier-case.UnionCase, value: CamelCase}, {key: >>>>> readability-identifier-case.UnionPrefix, value: 'U'}, {key: >>>>> readability-identifier-case.UsingCase, value: lower_case}, {key: >>>>> readability-identifier-case.ValueTemplateParameterCase, value: camelBack}, >>>>> {key: readability-identifier-case.VariableCase, value: lower_case}, {key: >>>>> readability-identifier-case.VirtualMethodCase, value: UPPER_CASE}, {key: >>>>> readability-identifier-case.VirtualMethodPrefix, value: 'v_'}, {key: >>>>> readability-identifier-case.IgnoreFailedSplit, value: 0}]}' -- -std=c++11 >>>>> +// REQUIRES: shell >>>>> + >>>>> +namespace FOO_NS { >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for >>>>> namespace 'FOO_NS' [readability-identifier-case] >>>>> +// CHECK-FIXES: foo_ns >>>>> +inline namespace InlineNamespace { >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for >>>>> inline namespace 'InlineNamespace' [readability-identifier-case] >>>>> +// CHECK-FIXES: inline_namespace >>>>> + >>>>> +enum my_enumeration { >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for >>>>> enum 'my_enumeration' [readability-identifier-case] >>>>> +// CHECK-FIXES: EMyEnumeration >>>>> + MyConstant = 1, >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> enum constant 'MyConstant' [readability-identifier-case] >>>>> +// CHECK-FIXES: MY_CONSTANT >>>>> + your_CONST = 1, >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> enum constant 'your_CONST' [readability-identifier-case] >>>>> +// CHECK-FIXES: YOUR_CONST >>>>> + THIS_ConstValue = 1, >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> enum constant 'THIS_ConstValue' [readability-identifier-case] >>>>> +// CHECK-FIXES: THIS_CONST_VALUE >>>>> +}; >>>>> + >>>>> +constexpr int ConstExpr_variable = 3; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for >>>>> constexpr 'ConstExpr_variable' [readability-identifier-case] >>>>> +// CHECK-FIXES: const_expr_variable >>>>> + >>>>> +class my_class { >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for >>>>> class 'my_class' [readability-identifier-case] >>>>> +// CHECK-FIXES: CMyClass >>>>> + my_class(); >>>>> + >>>>> + const int MEMBER_one_1 = 1; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: invalid case style for >>>>> constant member 'MEMBER_one_1' [readability-identifier-case] >>>>> +// CHECK-FIXES: member_one_1 >>>>> + int member2 = 2; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: invalid case style for >>>>> private member 'member2' [readability-identifier-case] >>>>> +// CHECK-FIXES: __member2 >>>>> + >>>>> +private: >>>>> + int private_member = 3; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> private member 'private_member' [readability-identifier-case] >>>>> +// CHECK-FIXES: __private_member >>>>> + >>>>> +protected: >>>>> + int ProtMember; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> protected member 'ProtMember' [readability-identifier-case] >>>>> +// CHECK-FIXES: _ProtMember >>>>> + >>>>> +public: >>>>> + int PubMem; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> public member 'PubMem' [readability-identifier-case] >>>>> +// CHECK-FIXES: pub_mem >>>>> + >>>>> + static const int classConstant; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> class constant 'classConstant' [readability-identifier-case] >>>>> +// CHECK-FIXES: kClassConstant >>>>> + static int ClassMember_2; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> class member 'ClassMember_2' [readability-identifier-case] >>>>> +// CHECK-FIXES: ClassMember2 >>>>> +}; >>>>> + >>>>> +const int my_class::classConstant = 4; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for >>>>> class constant 'classConstant' [readability-identifier-case] >>>>> +// CHECK-FIXES: kClassConstant >>>>> +int my_class::ClassMember_2 = 5; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for >>>>> class member 'ClassMember_2' [readability-identifier-case] >>>>> +// CHECK-FIXES: ClassMember2 >>>>> + >>>>> +const int global_Constant = 6; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for >>>>> global constant 'global_Constant' [readability-identifier-case] >>>>> +// CHECK-FIXES: GLOBAL_CONSTANT >>>>> +int Global_variable = 7; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for >>>>> global variable 'Global_variable' [readability-identifier-case] >>>>> +// CHECK-FIXES: g_global_variable >>>>> + >>>>> +void global_function(int PARAMETER_1, int const CONST_parameter) { >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for >>>>> global function 'global_function' [readability-identifier-case] >>>>> +// CHECK-FIXES: GlobalFunction >>>>> +// CHECK-MESSAGES: :[[@LINE-3]]:22: warning: invalid case style for >>>>> parameter 'PARAMETER_1' [readability-identifier-case] >>>>> +// CHECK-FIXES: a_parameter1 >>>>> +// CHECK-MESSAGES: :[[@LINE-5]]:39: warning: invalid case style for >>>>> constant parameter 'CONST_parameter' [readability-identifier-case] >>>>> +// CHECK-FIXES: CONST_PARAMETER_CST >>>>> + static const int THIS_static_ConsTant = 4; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> static constant 'THIS_static_ConsTant' [readability-identifier-case] >>>>> +// CHECK-FIXES: THIS_STATIC_CONS_TANT >>>>> + static int THIS_static_variable; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> static variable 'THIS_static_variable' [readability-identifier-case] >>>>> +// CHECK-FIXES: s_thisStaticVariable >>>>> + int const local_Constant = 3; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> local constant 'local_Constant' [readability-identifier-case] >>>>> +// CHECK-FIXES: kLocalConstant >>>>> + int LOCAL_VARIABLE; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> local variable 'LOCAL_VARIABLE' [readability-identifier-case] >>>>> +// CHECK-FIXES: local_variable >>>>> + >>>>> + int LOCAL_Array__[] = {0, 1, 2}; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> local variable 'LOCAL_Array__' [readability-identifier-case] >>>>> +// CHECK-FIXES: local_array >>>>> + >>>>> + for (auto _ : LOCAL_Array__) { >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: unable to split words >>>>> for local variable '_' [readability-identifier-case] >>>>> + } >>>>> +} >>>>> + >>>>> +template<typename ... TYPE_parameters> >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: invalid case style for >>>>> type template parameter 'TYPE_parameters' [readability-identifier-case] >>>>> +// CHECK-FIXES: typeParameters_t >>>>> +void Global_Fun(TYPE_parameters... PARAMETER_PACK) { >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for >>>>> global function 'Global_Fun' [readability-identifier-case] >>>>> +// CHECK-FIXES: GlobalFun >>>>> +// CHECK-MESSAGES: :[[@LINE-3]]:17: warning: invalid case style for >>>>> parameter pack 'PARAMETER_PACK' [readability-identifier-case] >>>>> +// CHECK-FIXES: parameterPack >>>>> +} >>>>> + >>>>> +template<template<typename> class TPL_parameter, int COUNT_params, >>>>> typename ... TYPE_parameters> >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: invalid case style for >>>>> template template parameter 'TPL_parameter' [readability-identifier-case] >>>>> +// CHECK-FIXES: TplParameter >>>>> +// CHECK-MESSAGES: :[[@LINE-3]]:50: warning: invalid case style for >>>>> value template parameter 'COUNT_params' [readability-identifier-case] >>>>> +// CHECK-FIXES: countParams >>>>> +// CHECK-MESSAGES: :[[@LINE-5]]:68: warning: invalid case style for >>>>> type template parameter 'TYPE_parameters' [readability-identifier-case] >>>>> +// CHECK-FIXES: typeParameters_t >>>>> +class test_CLASS { >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for >>>>> class 'test_CLASS' [readability-identifier-case] >>>>> +// CHECK-FIXES: CTestClass >>>>> +}; >>>>> + >>>>> +class abstract_class { >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for >>>>> abstract class 'abstract_class' [readability-identifier-case] >>>>> +// CHECK-FIXES: AAbstractClass >>>>> + virtual ~abstract_class() = 0; >>>>> + virtual void VIRTUAL_METHOD(); >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> virtual method 'VIRTUAL_METHOD' [readability-identifier-case] >>>>> +// CHECK-FIXES: v_VIRTUAL_METHOD >>>>> + void non_Virtual_METHOD() {} >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> private method 'non_Virtual_METHOD' [readability-identifier-case] >>>>> +// CHECK-FIXES: __non_Virtual_METHOD >>>>> + static void CLASS_METHOD() {} >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> class method 'CLASS_METHOD' [readability-identifier-case] >>>>> +// CHECK-FIXES: classMethod >>>>> + >>>>> + constexpr int CST_expr_Method() { return 2; } >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> constexpr method 'CST_expr_Method' [readability-identifier-case] >>>>> +// CHECK-FIXES: cst_expr_method >>>>> + >>>>> +private: >>>>> + void PRIVate_Method(); >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> private method 'PRIVate_Method' [readability-identifier-case] >>>>> +// CHECK-FIXES: __PRIVate_Method >>>>> +protected: >>>>> + void protected_Method(); >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> protected method 'protected_Method' [readability-identifier-case] >>>>> +// CHECK-FIXES: _protected_Method >>>>> +public: >>>>> + void public_Method(); >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for >>>>> method 'public_Method' [readability-identifier-case] >>>>> +// CHECK-FIXES: publicMethod >>>>> +}; >>>>> + >>>>> +constexpr int CE_function() { return 3; } >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for >>>>> constexpr function 'CE_function' [readability-identifier-case] >>>>> +// CHECK-FIXES: ce_function >>>>> + >>>>> +struct THIS___Structure { >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for >>>>> struct 'THIS___Structure' [readability-identifier-case] >>>>> +// CHECK-FIXES: this_structure >>>>> + THIS___Structure(); >>>>> + >>>>> + union __MyUnion_is_wonderful__ {}; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: invalid case style for >>>>> union '__MyUnion_is_wonderful__' [readability-identifier-case] >>>>> +// CHECK-FIXES: UMyUnionIsWonderful >>>>> +}; >>>>> + >>>>> +typedef THIS___Structure struct_type; >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for >>>>> typedef 'struct_type' [readability-identifier-case] >>>>> +// CHECK-FIXES: struct_type_t >>>>> + >>>>> +static void static_Function() { >>>>> +// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for >>>>> function 'static_Function' [readability-identifier-case] >>>>> +// CHECK-FIXES: staticFunction >>>>> +} >>>>> + >>>>> +} >>>>> +} >>>>> -- >>>>> >>>> >>>> >>>> >>>> On Sat, Jun 27, 2015 at 12:01 PM, Beren Minor <beren.mi...@gmail.com> >>>> wrote: >>>> >>>>> Hello, >>>>> >>>>> I have implemented a new check for clang-tidy, that some people might >>>>> find useful >>>>> and I would like to offer it for upstream integration. I'm not sure >>>>> how I should proceed, >>>>> so please tell me if this is not the right way to do. >>>>> >>>>> This check will try to enforce coding guidelines on the identifiers >>>>> casing. >>>>> It supports lower_case, UPPER_CASE, camelBack and CamelCase casing and >>>>> tries to convert from one to another if a mismatch is detected. >>>>> >>>>> It also supports a fixed prefix and suffix that will be prepended or >>>>> appended >>>>> to the identifiers, regardless of the casing. >>>>> >>>>> Many configuration options are available, in order to be able to create >>>>> different rules for different kind of identifier. In general, the >>>>> rules are falling back to a more generic rule if the specific case is >>>>> not >>>>> configured. >>>>> >>>>> Best, >>>>> -- >>>>> Beren Minor >>>>> >>>>> _______________________________________________ >>>>> cfe-commits mailing list >>>>> cfe-commits@cs.uiuc.edu >>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >>>> >>>> >>>> -- Alexander Kornienko >>>> >>> >>> >
_______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits