[PATCH] [clang-tidy] Add new IdentifierCase check.

Alexander Kornienko alexfh at google.com
Wed Aug 5 05:10:11 PDT 2015


Thanks! Looking at the patch now.

-- Alexander Kornienko

On Mon, Aug 3, 2015 at 11:27 AM, Beren Minor <beren.minor at gmail.com> wrote:

> 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/20150805/433ae123/attachment-0001.html>


More information about the cfe-commits mailing list