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