<div dir="ltr">Thanks! Looking at the patch now.<div><br></div><div>-- Alexander Kornienko<br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Aug 3, 2015 at 11:27 AM, Beren Minor <span dir="ltr"><<a href="mailto:beren.minor@gmail.com" target="_blank">beren.minor@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Alexander,<br><br></div>I have uploaded the patch to phabricator with the changes you mentioned:<br><a href="http://reviews.llvm.org/D10933" target="_blank">http://reviews.llvm.org/D10933</a><br><div class="gmail_extra"><br clear="all"><div><div>--<br>Beren Minor</div></div><div><div class="h5">
<br><div class="gmail_quote">On Fri, Jul 3, 2015 at 2:13 PM, Beren Minor <span dir="ltr"><<a href="mailto:beren.minor@gmail.com" target="_blank">beren.minor@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">No worries, I don't think I will be very active this month either.<br></div><div class="gmail_extra"><br clear="all"><div><div>--<br>Beren Minor</div></div><div><div>
<br><div class="gmail_quote">On Fri, Jul 3, 2015 at 10:28 AM, Alexander Kornienko <span dir="ltr"><<a href="mailto:alexfh@google.com" target="_blank">alexfh@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><p dir="ltr">Awesome! Waiting for the next patch. Please note though, that the next week I'm OOO and won't be able to reply.</p><span><font color="#888888">
<p dir="ltr">-- Alexander Kornienko</p></font></span><div><div>
<div class="gmail_quote">On 3 Jul 2015 10:13, "Beren Minor" <<a href="mailto:beren.minor@gmail.com" target="_blank">beren.minor@gmail.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div>Hi Alexander,<br><br></div>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.<br><br></div>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.<br><br></div>Best,<br><div><div><div><div><div class="gmail_extra"><div><div>--<br>Beren Minor</div></div>
<br><div class="gmail_quote">On Tue, Jun 30, 2015 at 4:55 PM, Alexander Kornienko <span dir="ltr"><<a href="mailto:alexfh@google.com" target="_blank">alexfh@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra">Hi Beren,</div><div class="gmail_extra"><br></div><div class="gmail_extra">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 <a href="http://reviews.llvm.org" target="_blank">Phabricator</a>, so I'd appreciate if you could upload your patch there.</div><div class="gmail_extra"><br></div><div class="gmail_extra">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.<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">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.</div><div class="gmail_extra"><br></div><div class="gmail_extra">A few other random comments:</div><div class="gmail_extra"><br></div><div class="gmail_extra"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">diff --git a/clang-tidy/readability/CMakeLists.txt b/clang-tidy/readability/CMakeLists.txt<br>index 5248620..b3baaee 100644<br>--- a/clang-tidy/readability/CMakeLists.txt<br>+++ b/clang-tidy/readability/CMakeLists.txt<br>@@ -5,6 +5,7 @@ add_clang_library(clangTidyReadabilityModule<br> ContainerSizeEmptyCheck.cpp<br> ElseAfterReturnCheck.cpp<br> FunctionSizeCheck.cpp<br>+ IdentifierCaseCheck.cpp<br> NamedParameterCheck.cpp<br> NamespaceCommentCheck.cpp<br> ReadabilityTidyModule.cpp<br>diff --git a/clang-tidy/readability/IdentifierCaseCheck.cpp b/clang-tidy/readability/IdentifierCaseCheck.cpp<br>new file mode 100644<br>index 0000000..5172f58<br>--- /dev/null<br>+++ b/clang-tidy/readability/IdentifierCaseCheck.cpp<br>@@ -0,0 +1,606 @@<br>+//===--- FunctionSize.cpp - clang-tidy ------------------------------------===//<br>+//<br>+// The LLVM Compiler Infrastructure<br>+//<br>+// This file is distributed under the University of Illinois Open Source<br>+// License. See LICENSE.TXT for details.<br>+//<br>+//===----------------------------------------------------------------------===//<br>+<br>+#include "IdentifierCaseCheck.h"<br>+#include "clang/ASTMatchers/ASTMatchFinder.h"<br>+<br>+using namespace clang::ast_matchers;<br>+<br>+namespace clang {<br>+namespace tidy {<br>+namespace readability {<br>+<br>+static llvm::StringRef const CaseStyleKeys[] = {<br>+ "Namespace",<br>+ "InlineNamespace",<br>+<br>+ "EnumConstant",<br>+ "ConstexprVariable",<br>+ "MemberConstant",<br>+ "MemberPrivate",<br>+ "MemberProtected",<br>+ "MemberPublic",<br>+ "Member",<br>+ "ClassConstant",<br>+ "ClassMember",<br>+ "GlobalConstant",<br>+ "GlobalVariable",<br>+ "LocalConstant",<br>+ "LocalVariable",<br>+ "StaticConstant",<br>+ "StaticVariable",<br>+ "Constant",<br>+ "Variable",<br>+<br>+ "ParameterConstant",<br>+ "ParameterPack",<br>+ "Parameter",<br>+<br>+ "Abstract",<br>+ "Struct",<br>+ "Class",<br>+ "Union",<br>+ "Enum",<br>+<br>+ "GlobalFunction",<br>+ "ConstexprFunction",<br>+ "Function",<br>+<br>+ "ConstexprMethod",<br>+ "VirtualMethod",<br>+ "ClassMethod",<br>+ "MethodPrivate",<br>+ "MethodProtected",<br>+ "MethodPublic",<br>+ "Method",<br>+<br>+ "Typedef",<br>+<br>+ "TypeTemplateParameter",<br>+ "ValueTemplateParameter",<br>+ "TemplateTemplateParameter",<br>+ "TemplateParameter",<br>+};<br>+<br>+IdentifierCaseCheck::IdentifierCaseCheck(StringRef Name,<br>+ ClangTidyContext *Context)<br>+ : ClangTidyCheck(Name, Context) {<br>+ auto const fromString = [](llvm::StringRef Str) {<br>+ if (Str.equals("any") || Str.equals("aNy_CasE")) {<br>+ return AnyCase;<br>+ } else if (Str.equals("lower") || Str.equals("lower_case")) {</blockquote><div class="gmail_extra"><br></div><div class="gmail_extra"><a href="http://llvm.org/docs/CodingStandards.html#don-t-use-else-after-a-return" target="_blank">Please no "else" after "return".</a></div><div class="gmail_extra"><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+ return LowerCase;<br>+ } else if (Str.equals("camelBack")) {<br>+ return CamelBack;<br>+ } else if (Str.equals("upper") || Str.equals("UPPER_CASE")) {<br>+ return UpperCase;<br>+ } else if (Str.equals("CamelCase")) {<br>+ return CamelCase;<br>+ } else {<br>+ return AnyCase;<br>+ }<br>+ };<br>+<br>+ for (const auto &Key : CaseStyleKeys) {<br>+ CaseConfigs[Key] =<br>+ CaseConfig(fromString(Options.get((Key + "Case").str(), "aNy_CasE")),<br>+ Options.get((Key + "Prefix").str(), ""),<br>+ Options.get((Key + "Suffix").str(), ""));<br>+ }<br>+<br>+ IgnoreFailedSplit = Options.get("IgnoreFailedSplit", 0);<br>+}<br>+<br>+void IdentifierCaseCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {<br>+ auto const toString = [](CaseType Type) {<br>+ switch (Type) {<br>+ default:<br>+ case AnyCase:<br>+ return "aNy_CasE";<br>+ case LowerCase:<br>+ return "lower_case";<br>+ case CamelBack:<br>+ return "camelBack";<br>+ case UpperCase:<br>+ return "UPPER_CASE";<br>+ case CamelCase:<br>+ return "CamelCase";<br>+ }<br>+ };<br>+<br>+ for (const auto &Key : CaseStyleKeys) {<br>+ Options.store(Opts, (Key + "Case").str(), toString(CaseConfigs[Key].Case));<br>+ Options.store(Opts, (Key + "Prefix").str(), CaseConfigs[Key].Prefix);<br>+ Options.store(Opts, (Key + "Suffix").str(), CaseConfigs[Key].Suffix);<br>+ }<br>+<br>+ Options.store(Opts, "IgnoreFailedSplit", IgnoreFailedSplit);<br>+}<br>+<br>+void IdentifierCaseCheck::registerMatchers(MatchFinder *Finder) {<br>+ Finder->addMatcher(namedDecl().bind("decl"), this);<br>+}<br>+<br>+void IdentifierCaseCheck::check(const MatchFinder::MatchResult &Result) {<br>+ if (const auto *Decl = Result.Nodes.getNodeAs<NamedDecl>("decl")) {<br>+ if (!Decl->getIdentifier())<br>+ return;<br>+<br>+ if (Decl->getName().empty())<br>+ return;<br>+<br>+ if (Decl->isImplicit())<br>+ return;<br>+ }<br>+<br>+ auto KindName = "identifier";<br></blockquote><div><br></div><div>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.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+ auto Style = CaseConfig();<br>+<br>+ if (Result.Nodes.getNodeAs<TypedefDecl>("decl")) {<br>+ if (false) {<br>+ //<br></blockquote><div> </div><div>Please remove this and other dead or commented out code.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+ } else if (CaseConfigs["Typedef"].isSet()) {<br>+ KindName = "typedef";<br>+ Style = CaseConfigs["Typedef"];<br>+ }<br>+ }<br>+ if (const auto *Decl = Result.Nodes.getNodeAs<NamespaceDecl>("decl")) {<br>+ if (Decl->isAnonymousNamespace())<br>+ return;<br>+<br>+ if (false) {<br>+ //<br></blockquote><div><br></div><div>ditto</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+ } else if (Decl->isInline() && CaseConfigs["InlineNamespace"].isSet()) {<br>+ KindName = "inline namespace";<br>+ Style = CaseConfigs["InlineNamespace"];<br>+ } else if (CaseConfigs["Namespace"].isSet()) {<br>+ KindName = "namespace";<br>+ Style = CaseConfigs["Namespace"];<br>+ }<br>+ }<br>+ if (const auto *Decl = Result.Nodes.getNodeAs<CXXRecordDecl>("decl")) {<br>+ if (Decl->isAnonymousStructOrUnion())<br>+ return;<br>+<br>+ if (false) {</blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+ // } else if (Decl->isLambda() && CaseConfigs["Lambda"].isSet()) {<br>+ // } else if (Decl->isInterface() && CaseConfigs["Interface"].isSet()) {<br>+ } else if (Decl->hasDefinition() && Decl->isAbstract() &&<br>+ CaseConfigs["Abstract"].isSet()) {<br>+ KindName = "abstract class";<br>+ Style = CaseConfigs["Abstract"];<br>+ } else if (Decl->isStruct() && CaseConfigs["Struct"].isSet()) {<br>+ KindName = "struct";<br>+ Style = CaseConfigs["Struct"];<br>+ } else if (Decl->isStruct() && CaseConfigs["Class"].isSet()) {<br>+ KindName = "struct";<br>+ Style = CaseConfigs["Class"];<br>+ } else if (Decl->isClass() && CaseConfigs["Class"].isSet()) {<br>+ KindName = "class";<br>+ Style = CaseConfigs["Class"];<br>+ } else if (Decl->isClass() && CaseConfigs["Struct"].isSet()) {<br>+ KindName = "class";<br>+ Style = CaseConfigs["Struct"];<br>+ } else if (Decl->isUnion() && CaseConfigs["Union"].isSet()) {<br>+ KindName = "union";<br>+ Style = CaseConfigs["Union"];<br>+ } else if (Decl->isEnum() && CaseConfigs["Enum"].isSet()) {<br>+ KindName = "enum";<br>+ Style = CaseConfigs["Enum"];<br>+ }<br>+ }<br>+ // if (Result.Nodes.getNodeAs<ClassTemplateDecl>("decl"));<br>+ // if (Result.Nodes.getNodeAs<ClassTemplateSpecializationDecl>("decl"));</blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+<br>+ if (const auto *Decl = Result.Nodes.getNodeAs<FieldDecl>("decl")) {<br>+ auto Type = Decl->getType();<br>+<br>+ if (false) {<br>+ // } else if (!Type.isNull() && Type.isLocalRestrictQualified()) {<br>+ // } else if (!Type.isNull() && Type.isLocalVolatileQualified()) {<br>+ // } else if (!Type.isNull() && Type.getAsString() == "") { </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+ } else if (!Type.isNull() && Type.isLocalConstQualified() &&<br>+ CaseConfigs["MemberConstant"].isSet()) {<br>+ KindName = "constant member";<br>+ Style = CaseConfigs["MemberConstant"];<br>+ } else if (!Type.isNull() && Type.isLocalConstQualified() &&<br>+ CaseConfigs["Constant"].isSet()) {<br>+ KindName = "constant member";<br>+ Style = CaseConfigs["Constant"];<br>+ } else if (Decl->getAccess() == clang::AS_private &&<br>+ CaseConfigs["MemberPrivate"].isSet()) {<br>+ KindName = "private member";<br>+ Style = CaseConfigs["MemberPrivate"];<br>+ } else if (Decl->getAccess() == clang::AS_protected &&<br>+ CaseConfigs["MemberProtected"].isSet()) {<br>+ KindName = "protected member";<br>+ Style = CaseConfigs["MemberProtected"];<br>+ } else if (Decl->getAccess() == clang::AS_public &&<br>+ CaseConfigs["MemberPublic"].isSet()) {<br>+ KindName = "public member";<br>+ Style = CaseConfigs["MemberPublic"];<br>+ } else if (CaseConfigs["Member"].isSet()) {<br>+ KindName = "member";<br>+ Style = CaseConfigs["Member"];<br>+ }<br>+ } else if (const auto *Decl = Result.Nodes.getNodeAs<ParmVarDecl>("decl")) {<br>+ auto Type = Decl->getType();<br>+<br>+ if (false) {<br>+ // } else if (!Type.isNull() && Type.isLocalRestrictQualified()) {<br>+ // } else if (!Type.isNull() && Type.isLocalVolatileQualified()) {<br>+ // } else if (!Type.isNull() && Type.getAsString() == "") {<br>+ } else if (Decl->isConstexpr() &&<br>+ CaseConfigs["ConstexprVariable"].isSet()) {<br>+ KindName = "constexpr";<br>+ Style = CaseConfigs["ConstexprVariable"];<br>+ } else if (!Type.isNull() && Type.isLocalConstQualified() &&<br>+ CaseConfigs["ParameterConstant"].isSet()) {<br>+ KindName = "constant parameter";<br>+ Style = CaseConfigs["Constant"];<br>+ } else if (!Type.isNull() && Type.isLocalConstQualified() &&<br>+ CaseConfigs["Constant"].isSet()) {<br>+ KindName = "constant parameter";<br>+ Style = CaseConfigs["Constant"];<br>+ } else if (Decl->isParameterPack() &&<br>+ CaseConfigs["ParameterPack"].isSet()) {<br>+ KindName = "parameter pack";<br>+ Style = CaseConfigs["ParameterPack"];<br>+ } else if (CaseConfigs["Parameter"].isSet()) {<br>+ KindName = "parameter";<br>+ Style = CaseConfigs["Parameter"];<br>+ }<br>+ } else if (const auto *Decl = Result.Nodes.getNodeAs<VarDecl>("decl")) {<br>+ auto Type = Decl->getType();<br>+<br>+ if (false) {<br>+ // } else if (!Type.isNull() && Type.isLocalRestrictQualified()) {<br>+ // } else if (!Type.isNull() && Type.isLocalVolatileQualified()) {<br>+ // } else if (!Type.isNull() && Type.getAsString() == "") {<br>+ } else if (Decl->isConstexpr() &&<br>+ CaseConfigs["ConstexprVariable"].isSet()) {<br>+ KindName = "constexpr";<br>+ Style = CaseConfigs["ConstexprVariable"];<br>+ } else if (!Type.isNull() && Type.isLocalConstQualified() &&<br>+ Decl->isStaticDataMember() &&<br>+ CaseConfigs["ClassConstant"].isSet()) {<br>+ KindName = "class constant";<br>+ Style = CaseConfigs["ClassConstant"];<br>+ } else if (!Type.isNull() && Type.isLocalConstQualified() &&<br>+ Decl->isFileVarDecl() && CaseConfigs["GlobalConstant"].isSet()) {<br>+ KindName = "global constant";<br>+ Style = CaseConfigs["GlobalConstant"];<br>+ } else if (!Type.isNull() && Type.isLocalConstQualified() &&<br>+ Decl->isStaticLocal() && CaseConfigs["StaticConstant"].isSet()) {<br>+ KindName = "static constant";<br>+ Style = CaseConfigs["StaticConstant"];<br>+ } else if (!Type.isNull() && Type.isLocalConstQualified() &&<br>+ Decl->isLocalVarDecl() && CaseConfigs["LocalConstant"].isSet()) {<br>+ KindName = "local constant";<br>+ Style = CaseConfigs["LocalConstant"];<br>+ } else if (!Type.isNull() && Type.isLocalConstQualified() &&<br>+ Decl->isFunctionOrMethodVarDecl() &&<br>+ CaseConfigs["LocalConstant"].isSet()) {<br>+ KindName = "local constant";<br>+ Style = CaseConfigs["LocalConstant"];<br>+ } else if (!Type.isNull() && Type.isLocalConstQualified() &&<br>+ CaseConfigs["Constant"].isSet()) {<br>+ KindName = "constant";<br>+ Style = CaseConfigs["Constant"];<br>+<br>+ // } else if (Decl->isWeak()) {<br>+ } else if (Decl->isStaticDataMember() &&<br>+ CaseConfigs["ClassMember"].isSet()) {<br>+ KindName = "class member";<br>+ Style = CaseConfigs["ClassMember"];<br>+ } else if (Decl->isFileVarDecl() && CaseConfigs["GlobalVariable"].isSet()) {<br>+ KindName = "global variable";<br>+ Style = CaseConfigs["GlobalVariable"];<br>+ } else if (Decl->isStaticLocal() && CaseConfigs["StaticVariable"].isSet()) {<br>+ KindName = "static variable";<br>+ Style = CaseConfigs["StaticVariable"];<br>+ } else if (Decl->isLocalVarDecl() && CaseConfigs["LocalVariable"].isSet()) {<br>+ KindName = "local variable";<br>+ Style = CaseConfigs["LocalVariable"];<br>+ } else if (Decl->isFunctionOrMethodVarDecl() &&<br>+ CaseConfigs["LocalVariable"].isSet()) {<br>+ KindName = "local variable";<br>+ Style = CaseConfigs["LocalVariable"];<br>+<br>+ // } else if (Decl->isExceptionVariable() &&<br>+ // CaseConfigs["ExceptionVariable"].isSet()) {<br>+ // } else if (Decl->isNRVOVariable()) {<br>+ // } else if (Decl->isCXXForRangeDecl()) {<br>+ } else if (CaseConfigs["Variable"].isSet()) {<br>+ KindName = "variable";<br>+ Style = CaseConfigs["Variable"];<br>+ }<br>+ }<br>+<br>+ if (const auto *Decl = Result.Nodes.getNodeAs<CXXMethodDecl>("decl")) {<br>+ if (Decl->isMain())<br>+ return;<br>+<br>+ if (!Decl->isUserProvided())<br>+ return;<br>+<br>+ if (Decl->isUsualDeallocationFunction())<br>+ return;<br>+<br>+ if (Decl->isCopyAssignmentOperator())<br>+ return;<br>+<br>+ if (Decl->isMoveAssignmentOperator())<br>+ return;<br>+<br>+ if (Decl->size_overridden_methods() > 0)<br>+ return;<br></blockquote><div><br></div><div>I'd merge all above checks to one `if`.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+<br>+ if (false) {<br>+ // } else if (Decl->isVariadic()) {<br>+ } else if (Decl->isConstexpr() && CaseConfigs["ConstexprMethod"].isSet()) {<br>+ KindName = "constexpr method";<br>+ Style = CaseConfigs["ConstexprMethod"];<br>+ } else if (Decl->isConstexpr() &&<br>+ CaseConfigs["ConstexprFunction"].isSet()) {<br>+ KindName = "constexpr method";<br>+ Style = CaseConfigs["ConstexprFunction"];<br>+<br>+ // } else if (Decl->isPure()) {<br>+ // } else if (Decl->isTrivial()) {<br>+ // } else if (Decl->isVirtualAsWritten()) {<br>+ // } else if (Decl->isGlobal()) {<br>+ // } else if (Decl->isInlineSpecified()) {<br>+ // } else if (Decl->isOverloadedOperator()) {<br>+ // } else if (Decl->isFunctionTemplateSpecialization()) {<br>+<br>+ } else if (Decl->isStatic() && CaseConfigs["ClassMethod"].isSet()) {<br>+ KindName = "class method";<br>+ Style = CaseConfigs["ClassMethod"];<br>+<br>+ // } else if (Decl->isConst()) {<br>+ // } else if (Decl->isVolatile()) {<br>+ } else if (Decl->isVirtual() && CaseConfigs["VirtualMethod"].isSet()) {<br>+ KindName = "virtual method";<br>+ Style = CaseConfigs["VirtualMethod"];<br>+ } else if (Decl->getAccess() == clang::AS_private &&<br>+ CaseConfigs["MethodPrivate"].isSet()) {<br>+ KindName = "private method";<br>+ Style = CaseConfigs["MethodPrivate"];<br>+ } else if (Decl->getAccess() == clang::AS_protected &&<br>+ CaseConfigs["MethodProtected"].isSet()) {<br>+ KindName = "protected method";<br>+ Style = CaseConfigs["MethodProtected"];<br>+ } else if (Decl->getAccess() == clang::AS_public &&<br>+ CaseConfigs["MethodPublic"].isSet()) {<br>+ KindName = "public method";<br>+ Style = CaseConfigs["MethodPublic"];<br>+ } else if (CaseConfigs["Method"].isSet()) {<br>+ KindName = "method";<br>+ Style = CaseConfigs["Method"];<br>+ } else if (CaseConfigs["Function"].isSet()) {<br>+ KindName = "method";<br>+ Style = CaseConfigs["Function"];<br>+ }<br>+ } else if (const auto *Decl = Result.Nodes.getNodeAs<FunctionDecl>("decl")) {<br>+ if (Decl->isMain())<br>+ return;<br>+<br>+ if (false) {<br>+ // } else if (Decl->isVariadic()) {<br>+ } else if (Decl->isConstexpr() &&<br>+ CaseConfigs["ConstexprFunction"].isSet()) {<br>+ KindName = "constexpr function";<br>+ Style = CaseConfigs["ConstexprFunction"];<br>+<br>+ // } else if (Decl->isPure()) {<br>+ // } else if (Decl->isTrivial()) {<br>+ // } else if (Decl->isVirtualAsWritten()) {<br>+ } else if (Decl->isGlobal() && CaseConfigs["GlobalFunction"].isSet()) {<br>+ KindName = "global function";<br>+ Style = CaseConfigs["GlobalFunction"];<br>+<br>+ // } else if (Decl->isInlineSpecified()) {<br>+ // } else if (Decl->isOverloadedOperator()) {<br>+ // } else if (Decl->isFunctionTemplateSpecialization()) {<br>+ } else if (CaseConfigs["Function"].isSet()) {<br>+ KindName = "function";<br>+ Style = CaseConfigs["Function"];<br>+ }<br>+ }<br>+<br>+ // if (Result.Nodes.getNodeAs<FunctionTemplateDecl>("decl"));<br>+ // if (Result.Nodes.getNodeAs<UsingDecl>("decl"));<br>+ // if (Result.Nodes.getNodeAs<UsingDirectiveDecl>("decl"));<br>+ // if (Result.Nodes.getNodeAs<UnresolvedUsingValueDecl>("decl"));<br>+<br>+ if (Result.Nodes.getNodeAs<EnumDecl>("decl")) {<br>+ if (false) {<br>+ //<br>+ } else if (CaseConfigs["Enum"].isSet()) {<br>+ KindName = "enum";<br>+ Style = CaseConfigs["Enum"];<br>+ }<br>+ }<br>+ if (Result.Nodes.getNodeAs<EnumConstantDecl>("decl")) {<br>+ if (false) {<br>+ //<br>+ } else if (CaseConfigs["EnumConstant"].isSet()) {<br>+ KindName = "enum constant";<br>+ Style = CaseConfigs["EnumConstant"];<br>+ } else if (CaseConfigs["Constant"].isSet()) {<br>+ KindName = "enum constant";<br>+ Style = CaseConfigs["Constant"];<br>+ }<br>+ }<br>+<br>+ if (Result.Nodes.getNodeAs<TemplateTypeParmDecl>("decl")) {<br>+ if (false) {<br>+ //<br>+ } else if (CaseConfigs["TypeTemplateParameter"].isSet()) {<br>+ KindName = "type template parameter";<br>+ Style = CaseConfigs["TypeTemplateParameter"];<br>+ } else if (CaseConfigs["TemplateParameter"].isSet()) {<br>+ KindName = "template parameter";<br>+ Style = CaseConfigs["TemplateParameter"];<br>+ }<br>+ } else if (Result.Nodes.getNodeAs<NonTypeTemplateParmDecl>("decl")) {<br>+ if (false) {<br>+ //<br>+ } else if (CaseConfigs["ValueTemplateParameter"].isSet()) {<br>+ KindName = "value template parameter";<br>+ Style = CaseConfigs["ValueTemplateParameter"];<br>+ } else if (CaseConfigs["TemplateParameter"].isSet()) {<br>+ KindName = "template parameter";<br>+ Style = CaseConfigs["TemplateParameter"];<br>+ }<br>+ } else if (Result.Nodes.getNodeAs<TemplateTemplateParmDecl>("decl")) {<br>+ if (false) {<br>+ //<br>+ } else if (CaseConfigs["TemplateTemplateParameter"].isSet()) {<br>+ KindName = "template template parameter";<br>+ Style = CaseConfigs["TemplateTemplateParameter"];<br>+ } else if (CaseConfigs["TemplateParameter"].isSet()) {<br>+ KindName = "template parameter";<br>+ Style = CaseConfigs["TemplateParameter"];<br>+ }<br>+ }<br>+<br>+ if (!Style.isSet())<br>+ return;<br>+<br>+ auto matchesStyle = [](llvm::StringRef Name, CaseConfig Style) {<br>+ static llvm::Regex Matchers[] = {<br>+ llvm::Regex(llvm::StringRef("^.*$")),<br>+ llvm::Regex(llvm::StringRef("^[a-z][a-z0-9_]*$")),<br>+ llvm::Regex(llvm::StringRef("^[a-z][a-zA-Z0-9]*$")),<br>+ llvm::Regex(llvm::StringRef("^[A-Z][A-Z0-9_]*$")),<br>+ llvm::Regex(llvm::StringRef("^[A-Z][a-zA-Z0-9]*$")),<br>+ };<br>+<br>+ bool Matches = true;<br>+ if (Name.startswith(Style.Prefix))<br>+ Name = Name.drop_front(Style.Prefix.size());<br>+ else<br>+ Matches = false;<br>+<br>+ if (Name.endswith(Style.Suffix))<br>+ Name = Name.drop_back(Style.Suffix.size());<br>+ else<br>+ Matches = false;<br>+<br>+ if (!Matchers[static_cast<size_t>(Style.Case)].match(Name))<br>+ Matches = false;<br>+<br>+ return Matches;<br>+ };<br>+<br>+ if (const auto *Decl = Result.Nodes.getNodeAs<NamedDecl>("decl")) {<br>+ if (matchesStyle(Decl->getName(), Style))<br>+ return;<br>+<br>+ auto fixupWithStyle = [](std::string Name, CaseConfig Style) {<br>+ static auto Splitter = llvm::Regex(llvm::StringRef(<br>+ "(([a-z0-9A-Z]*)(_+)|([A-Z]?[a-z0-9]+)([A-Z]|$)|([A-Z]+)([A-Z]|$))"));<br>+<br>+ auto Words = llvm::SmallVector<std::string, 8>();<br>+ auto Substrs = llvm::SmallVector<llvm::StringRef, 8>();<br>+ llvm::StringRef(Name).split(Substrs, "_", -1, false);<br>+ for (std::string Substr : Substrs) {<br>+ while (!Substr.empty()) {<br>+ auto Groups = llvm::SmallVector<llvm::StringRef, 8>();<br>+ if (!Splitter.match(Substr, &Groups))<br>+ break;<br>+<br>+ if (Groups[3].size() > 0) {<br>+ Words.emplace_back(std::move(Groups[2]));<br>+ Substr = Substr.substr(Groups[0].size());<br>+<br>+ } else if (Groups[4].size() > 0) {<br>+ Words.emplace_back(std::move(Groups[4]));<br>+ Substr = Substr.substr(Groups[0].size() - Groups[5].size());<br>+<br>+ } else if (Groups[6].size() > 0) {<br>+ Words.emplace_back(std::move(Groups[6]));<br>+ Substr = Substr.substr(Groups[0].size() - Groups[7].size());<br>+ }<br>+ }<br>+ }<br>+<br>+ if (Words.empty()) {<br>+ return Name;<br>+ }<br>+<br>+ std::string Fixup = Style.Prefix;<br>+ switch (Style.Case) {<br>+ case AnyCase:<br>+ Fixup += Name;<br>+ break;<br>+<br>+ case LowerCase:<br>+ for (auto const &Word : Words) {<br>+ if (&Word != &Words.front())<br>+ Fixup += "_";<br>+ Fixup += llvm::StringRef(Word).lower();<br>+ }<br>+ break;<br>+<br>+ case UpperCase:<br>+ for (auto const &Word : Words) {<br>+ if (&Word != &Words.front())<br>+ Fixup += "_";<br>+ Fixup += llvm::StringRef(Word).upper();<br>+ }<br>+ break;<br>+<br>+ case CamelCase:<br>+ for (auto const &Word : Words) {<br>+ Fixup += llvm::StringRef(Word).substr(0, 1).upper();<br>+ Fixup += llvm::StringRef(Word).substr(1).lower();<br>+ }<br>+ break;<br>+<br>+ case CamelBack:<br>+ for (auto const &Word : Words) {<br>+ if (&Word == &Words.front()) {<br>+ Fixup += llvm::StringRef(Word).lower();<br>+ } else {<br>+ Fixup += llvm::StringRef(Word).substr(0, 1).upper();<br>+ Fixup += llvm::StringRef(Word).substr(1).lower();<br>+ }<br>+ }<br>+ break;<br>+ }<br>+ Fixup += Style.Suffix;<br>+<br>+ return Fixup;<br>+ };<br>+<br>+ auto Name = Decl->getName();<br>+ auto Fixup = fixupWithStyle(Name, Style);<br>+ if (llvm::StringRef(Fixup).equals(Name)) {<br></blockquote><div><br></div><div>No need for `llvm::` here. `StringRef` is visible in the `clang` namespace.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+ if (!IgnoreFailedSplit) {<br>+ diag(Decl->getLocStart(), "unable to split words for %0 '%1'")<br>+ << KindName << Name;<br>+ }<br>+ } else {<br>+ auto Range =<br>+ clang::DeclarationNameInfo(Decl->getDeclName(), Decl->getLocation())<br></blockquote><div><br></div><div>No need for `clang::` here.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+ .getSourceRange(); </blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+ auto Diagn = diag(Decl->getLocStart(), "invalid case style for %0 '%1'");<br>+ Diagn << KindName << Decl->getName();<br>+ Diagn << FixItHint::CreateReplacement(<br>+ CharSourceRange::getTokenRange(Range), Fixup);<br></blockquote><div><br></div><div>No need for the `Diagn` variable, just make these a single statement.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+ }<br>+ }<br>+}<br>+<br>+} // namespace readability<br>+} // namespace tidy<br>+} // namespace clang<br>diff --git a/clang-tidy/readability/IdentifierCaseCheck.h b/clang-tidy/readability/IdentifierCaseCheck.h<br>new file mode 100644<br>index 0000000..a7c8aee<br>--- /dev/null<br>+++ b/clang-tidy/readability/IdentifierCaseCheck.h<br>@@ -0,0 +1,61 @@<br>+//===--- IdentifierCaseCheck.h - clang-tidy -----------------------*- C++<br>+//-*-===//<br>+//<br>+// The LLVM Compiler Infrastructure<br>+//<br>+// This file is distributed under the University of Illinois Open Source<br>+// License. See LICENSE.TXT for details.<br>+//<br>+//===----------------------------------------------------------------------===//<br>+<br>+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERCASECHECK_H<br>+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERCASECHECK_H<br>+<br>+#include "../ClangTidy.h"<br>+<br>+namespace clang {<br>+namespace tidy {<br>+namespace readability {<br>+<br>+/// \brief Checks for identifiers case mismatch.<br>+class IdentifierCaseCheck : public ClangTidyCheck {<br>+public:<br>+ IdentifierCaseCheck(StringRef Name, ClangTidyContext *Context);<br>+<br>+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;<br>+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;<br>+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;<br>+<br>+private:<br>+ enum CaseType {<br>+ AnyCase = 0,<br>+ LowerCase,<br>+ CamelBack,<br>+ UpperCase,<br>+ CamelCase,<br>+ };<br>+<br>+ struct CaseConfig {<br>+ CaseConfig() : Case(CaseType::AnyCase), Prefix(""), Suffix("") {}<br></blockquote><div><br></div><div>No need to initialize std::string with "".</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">+<br>+ CaseConfig(CaseType Case, std::string Prefix, std::string Suffix)<br>+ : Case(Case), Prefix(std::move(Prefix)), Suffix(std::move(Suffix)) {}<br>+<br>+ CaseType Case;<br>+ std::string Prefix;<br>+ std::string Suffix;<br>+<br>+ bool isSet() {<br>+ return !(Case == CaseType::AnyCase && Prefix.empty() && Suffix.empty());<br>+ }<br>+ };<br>+<br>+ std::map<std::string, CaseConfig> CaseConfigs;<br>+ bool IgnoreFailedSplit;<br>+};<br>+<br>+} // namespace readability<br>+} // namespace tidy<br>+} // namespace clang<br>+<br>+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IDENTIFIERCASECHECK_H<br>diff --git a/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tidy/readability/ReadabilityTidyModule.cpp<br>index bf118f8..7f1f71f 100644<br>--- a/clang-tidy/readability/ReadabilityTidyModule.cpp<br>+++ b/clang-tidy/readability/ReadabilityTidyModule.cpp<br>@@ -14,6 +14,7 @@<br> #include "ContainerSizeEmptyCheck.h"<br> #include "ElseAfterReturnCheck.h"<br> #include "FunctionSizeCheck.h"<br>+#include "IdentifierCaseCheck.h"<br> #include "NamedParameterCheck.h"<br> #include "RedundantSmartptrGetCheck.h"<br> #include "RedundantStringCStrCheck.h"<br>@@ -35,6 +36,8 @@ public:<br> "readability-else-after-return");<br> CheckFactories.registerCheck<FunctionSizeCheck>(<br> "readability-function-size");<br>+ CheckFactories.registerCheck<IdentifierCaseCheck>(<br>+ "readability-identifier-case");<br></blockquote><div><br></div><div>The check is not only about case. I think, "readability-naming" or "readability-identifier-naming" would be a better name.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> CheckFactories.registerCheck<readability::NamedParameterCheck>(<br> "readability-named-parameter");<br> CheckFactories.registerCheck<RedundantSmartptrGetCheck>(<br>diff --git a/test/clang-tidy/readability-identifier-case.cpp b/test/clang-tidy/readability-identifier-case.cpp<br>new file mode 100644<br>index 0000000..f978639<br>--- /dev/null<br>+++ b/test/clang-tidy/readability-identifier-case.cpp<br>@@ -0,0 +1,185 @@<br>+// 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<br>+// REQUIRES: shell<br>+<br>+namespace FOO_NS {<br>+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for namespace 'FOO_NS' [readability-identifier-case]<br>+// CHECK-FIXES: foo_ns<br>+inline namespace InlineNamespace {<br>+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for inline namespace 'InlineNamespace' [readability-identifier-case]<br>+// CHECK-FIXES: inline_namespace<br>+<br>+enum my_enumeration {<br>+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for enum 'my_enumeration' [readability-identifier-case]<br>+// CHECK-FIXES: EMyEnumeration<br>+ MyConstant = 1,<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for enum constant 'MyConstant' [readability-identifier-case]<br>+// CHECK-FIXES: MY_CONSTANT<br>+ your_CONST = 1,<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for enum constant 'your_CONST' [readability-identifier-case]<br>+// CHECK-FIXES: YOUR_CONST<br>+ THIS_ConstValue = 1,<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for enum constant 'THIS_ConstValue' [readability-identifier-case]<br>+// CHECK-FIXES: THIS_CONST_VALUE<br>+};<br>+<br>+constexpr int ConstExpr_variable = 3;<br>+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for constexpr 'ConstExpr_variable' [readability-identifier-case]<br>+// CHECK-FIXES: const_expr_variable<br>+<br>+class my_class {<br>+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for class 'my_class' [readability-identifier-case]<br>+// CHECK-FIXES: CMyClass<br>+ my_class();<br>+<br>+ const int MEMBER_one_1 = 1;<br>+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: invalid case style for constant member 'MEMBER_one_1' [readability-identifier-case]<br>+// CHECK-FIXES: member_one_1<br>+ int member2 = 2;<br>+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: invalid case style for private member 'member2' [readability-identifier-case]<br>+// CHECK-FIXES: __member2<br>+<br>+private:<br>+ int private_member = 3;<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for private member 'private_member' [readability-identifier-case]<br>+// CHECK-FIXES: __private_member<br>+<br>+protected:<br>+ int ProtMember;<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for protected member 'ProtMember' [readability-identifier-case]<br>+// CHECK-FIXES: _ProtMember<br>+<br>+public:<br>+ int PubMem;<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for public member 'PubMem' [readability-identifier-case]<br>+// CHECK-FIXES: pub_mem<br>+<br>+ static const int classConstant;<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for class constant 'classConstant' [readability-identifier-case]<br>+// CHECK-FIXES: kClassConstant<br>+ static int ClassMember_2;<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for class member 'ClassMember_2' [readability-identifier-case]<br>+// CHECK-FIXES: ClassMember2<br>+};<br>+<br>+const int my_class::classConstant = 4;<br>+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for class constant 'classConstant' [readability-identifier-case]<br>+// CHECK-FIXES: kClassConstant<br>+int my_class::ClassMember_2 = 5;<br>+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for class member 'ClassMember_2' [readability-identifier-case]<br>+// CHECK-FIXES: ClassMember2<br>+<br>+const int global_Constant = 6;<br>+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for global constant 'global_Constant' [readability-identifier-case]<br>+// CHECK-FIXES: GLOBAL_CONSTANT<br>+int Global_variable = 7;<br>+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for global variable 'Global_variable' [readability-identifier-case]<br>+// CHECK-FIXES: g_global_variable<br>+<br>+void global_function(int PARAMETER_1, int const CONST_parameter) {<br>+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for global function 'global_function' [readability-identifier-case]<br>+// CHECK-FIXES: GlobalFunction<br>+// CHECK-MESSAGES: :[[@LINE-3]]:22: warning: invalid case style for parameter 'PARAMETER_1' [readability-identifier-case]<br>+// CHECK-FIXES: a_parameter1<br>+// CHECK-MESSAGES: :[[@LINE-5]]:39: warning: invalid case style for constant parameter 'CONST_parameter' [readability-identifier-case]<br>+// CHECK-FIXES: CONST_PARAMETER_CST<br>+ static const int THIS_static_ConsTant = 4;<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for static constant 'THIS_static_ConsTant' [readability-identifier-case]<br>+// CHECK-FIXES: THIS_STATIC_CONS_TANT<br>+ static int THIS_static_variable;<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for static variable 'THIS_static_variable' [readability-identifier-case]<br>+// CHECK-FIXES: s_thisStaticVariable<br>+ int const local_Constant = 3;<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for local constant 'local_Constant' [readability-identifier-case]<br>+// CHECK-FIXES: kLocalConstant<br>+ int LOCAL_VARIABLE;<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for local variable 'LOCAL_VARIABLE' [readability-identifier-case]<br>+// CHECK-FIXES: local_variable<br>+<br>+ int LOCAL_Array__[] = {0, 1, 2};<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for local variable 'LOCAL_Array__' [readability-identifier-case]<br>+// CHECK-FIXES: local_array<br>+<br>+ for (auto _ : LOCAL_Array__) {<br>+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: unable to split words for local variable '_' [readability-identifier-case]<br>+ }<br>+}<br>+<br>+template<typename ... TYPE_parameters><br>+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: invalid case style for type template parameter 'TYPE_parameters' [readability-identifier-case]<br>+// CHECK-FIXES: typeParameters_t<br>+void Global_Fun(TYPE_parameters... PARAMETER_PACK) {<br>+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for global function 'Global_Fun' [readability-identifier-case]<br>+// CHECK-FIXES: GlobalFun<br>+// CHECK-MESSAGES: :[[@LINE-3]]:17: warning: invalid case style for parameter pack 'PARAMETER_PACK' [readability-identifier-case]<br>+// CHECK-FIXES: parameterPack<br>+}<br>+<br>+template<template<typename> class TPL_parameter, int COUNT_params, typename ... TYPE_parameters><br>+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: invalid case style for template template parameter 'TPL_parameter' [readability-identifier-case]<br>+// CHECK-FIXES: TplParameter<br>+// CHECK-MESSAGES: :[[@LINE-3]]:50: warning: invalid case style for value template parameter 'COUNT_params' [readability-identifier-case]<br>+// CHECK-FIXES: countParams<br>+// CHECK-MESSAGES: :[[@LINE-5]]:68: warning: invalid case style for type template parameter 'TYPE_parameters' [readability-identifier-case]<br>+// CHECK-FIXES: typeParameters_t<br>+class test_CLASS {<br>+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for class 'test_CLASS' [readability-identifier-case]<br>+// CHECK-FIXES: CTestClass<br>+};<br>+<br>+class abstract_class {<br>+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for abstract class 'abstract_class' [readability-identifier-case]<br>+// CHECK-FIXES: AAbstractClass<br>+ virtual ~abstract_class() = 0;<br>+ virtual void VIRTUAL_METHOD();<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for virtual method 'VIRTUAL_METHOD' [readability-identifier-case]<br>+// CHECK-FIXES: v_VIRTUAL_METHOD<br>+ void non_Virtual_METHOD() {}<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for private method 'non_Virtual_METHOD' [readability-identifier-case]<br>+// CHECK-FIXES: __non_Virtual_METHOD<br>+ static void CLASS_METHOD() {}<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for class method 'CLASS_METHOD' [readability-identifier-case]<br>+// CHECK-FIXES: classMethod<br>+<br>+ constexpr int CST_expr_Method() { return 2; }<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for constexpr method 'CST_expr_Method' [readability-identifier-case]<br>+// CHECK-FIXES: cst_expr_method<br>+<br>+private:<br>+ void PRIVate_Method();<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for private method 'PRIVate_Method' [readability-identifier-case]<br>+// CHECK-FIXES: __PRIVate_Method<br>+protected:<br>+ void protected_Method();<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for protected method 'protected_Method' [readability-identifier-case]<br>+// CHECK-FIXES: _protected_Method<br>+public:<br>+ void public_Method();<br>+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: invalid case style for method 'public_Method' [readability-identifier-case]<br>+// CHECK-FIXES: publicMethod<br>+};<br>+<br>+constexpr int CE_function() { return 3; }<br>+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for constexpr function 'CE_function' [readability-identifier-case]<br>+// CHECK-FIXES: ce_function<br>+<br>+struct THIS___Structure {<br>+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for struct 'THIS___Structure' [readability-identifier-case]<br>+// CHECK-FIXES: this_structure<br>+ THIS___Structure();<br>+<br>+ union __MyUnion_is_wonderful__ {};<br>+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: invalid case style for union '__MyUnion_is_wonderful__' [readability-identifier-case]<br>+// CHECK-FIXES: UMyUnionIsWonderful<br>+};<br>+<br>+typedef THIS___Structure struct_type;<br>+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for typedef 'struct_type' [readability-identifier-case]<br>+// CHECK-FIXES: struct_type_t<br>+<br>+static void static_Function() {<br>+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: invalid case style for function 'static_Function' [readability-identifier-case]<br>+// CHECK-FIXES: staticFunction<br>+}<br>+<br>+}<br>+}<br>-- <br></blockquote><div><br></div></div><div class="gmail_extra"><br></div><div class="gmail_extra"><br><div class="gmail_quote"><div><div>On Sat, Jun 27, 2015 at 12:01 PM, Beren Minor <span dir="ltr"><<a href="mailto:beren.minor@gmail.com" target="_blank">beren.minor@gmail.com</a>></span> wrote:<br></div></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div><div><div dir="ltr"><div><div>Hello,<br><br></div>I have implemented a new check for clang-tidy, that some people might find useful<br>and I would like to offer it for upstream integration. I'm not sure how I should proceed,<br></div>so please tell me if this is not the right way to do.<br><div><div><div><br>This check will try to enforce coding guidelines on the identifiers casing.<br>It supports lower_case, UPPER_CASE, camelBack and CamelCase casing and<br>tries to convert from one to another if a mismatch is detected.<br><br>It also supports a fixed prefix and suffix that will be prepended or appended<br>to the identifiers, regardless of the casing.<br><br>Many configuration options are available, in order to be able to create<br>different rules for different kind of identifier. In general, the<br>rules are falling back to a more generic rule if the specific case is not<br>configured.<br><br></div><div>Best,<br clear="all"></div><div><div><div>--<br>Beren Minor</div></div>
</div></div></div></div>
<br></div></div>_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a></blockquote><span><font color="#888888"><div><br></div><div>-- Alexander Kornienko </div></font></span></div>
</div></div>
</blockquote></div><br></div></div></div></div></div></div>
</blockquote></div>
</div></div></blockquote></div><br></div></div></div>
</blockquote></div><br></div></div></div></div>
</blockquote></div><br>
</div></div></div>