[PATCH] [clang-tidy] Add new IdentifierCase check.
Beren Minor
beren.minor at gmail.com
Mon Aug 3 02:27:24 PDT 2015
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.minor at 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 <alexfh at 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.minor at 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 <alexfh at 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.minor at 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 at cs.uiuc.edu
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>>
>>>>
>>>> -- Alexander Kornienko
>>>>
>>>
>>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150803/1d5431c4/attachment.html>
More information about the cfe-commits
mailing list