Index: clang-tidy/cppcoreguidelines/CMakeLists.txt =================================================================== --- clang-tidy/cppcoreguidelines/CMakeLists.txt +++ clang-tidy/cppcoreguidelines/CMakeLists.txt @@ -2,6 +2,7 @@ add_clang_library(clangTidyCppCoreGuidelinesModule CppCoreGuidelinesTidyModule.cpp + EnumAllCapsCheck.cpp ProBoundsArrayToPointerDecayCheck.cpp ProBoundsConstantArrayIndexCheck.cpp ProBoundsPointerArithmeticCheck.cpp Index: clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp =================================================================== --- clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp +++ clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp @@ -11,6 +11,7 @@ #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" #include "../misc/AssignOperatorSignatureCheck.h" +#include "EnumAllCapsCheck.h" #include "ProBoundsArrayToPointerDecayCheck.h" #include "ProBoundsConstantArrayIndexCheck.h" #include "ProBoundsPointerArithmeticCheck.h" @@ -29,6 +30,8 @@ class CppCoreGuidelinesModule : public ClangTidyModule { public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { + CheckFactories.registerCheck( + "cppcoreguidelines-enum-all-caps"); CheckFactories.registerCheck( "cppcoreguidelines-pro-bounds-array-to-pointer-decay"); CheckFactories.registerCheck( Index: clang-tidy/cppcoreguidelines/EnumAllCapsCheck.h =================================================================== --- /dev/null +++ clang-tidy/cppcoreguidelines/EnumAllCapsCheck.h @@ -0,0 +1,36 @@ +//===--- EnumAllCapsCheck.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_CPPCOREGUIDELINES_ENUMALLCAPS_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_ENUMALLCAPS_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace cppcoreguidelines { + +/// This check flags all ALL_CAPS enumerations +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-enum-all-caps.html +class EnumAllCapsCheck : public ClangTidyCheck { +public: + EnumAllCapsCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace cppcoreguidelines +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_ENUMALLCAPS_H + Index: clang-tidy/cppcoreguidelines/EnumAllCapsCheck.cpp =================================================================== --- /dev/null +++ clang-tidy/cppcoreguidelines/EnumAllCapsCheck.cpp @@ -0,0 +1,55 @@ +//===--- EnumAllCapsCheck.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 "EnumAllCapsCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +#include +#include +#include + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace cppcoreguidelines { + +void EnumAllCapsCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(enumConstantDecl().bind("enum"), this); +} + +void EnumAllCapsCheck::check(const MatchFinder::MatchResult &Result) { + const auto *MatchedDecl = Result.Nodes.getNodeAs("enum"); + unsigned AlphabeticLetters = 0; + bool AllCapsed = true; + for (auto symbol : MatchedDecl->getName()) { + if (std::isalpha(symbol)) { + AlphabeticLetters++; + if (!std::isupper(symbol)) { + AllCapsed = false; + } + } + } + if (!AllCapsed) { + return; + } + if (AlphabeticLetters <= 1) { + return; + } + std::string HintedLowercaseName = MatchedDecl->getName(); + std::transform(HintedLowercaseName.begin(), HintedLowercaseName.end(), + HintedLowercaseName.begin(), ::tolower); + diag(MatchedDecl->getLocation(), "Don’t use ALL_CAPS for enumerators") + << FixItHint::CreateInsertion(MatchedDecl->getLocation(), + HintedLowercaseName); +} +} +} // namespace tidy +} // namespace clang Index: docs/clang-tidy/checks/cppcoreguidelines-enum-all-caps.rst =================================================================== --- /dev/null +++ docs/clang-tidy/checks/cppcoreguidelines-enum-all-caps.rst @@ -0,0 +1,9 @@ +cppcoreguidelines-enum-all-caps +============================= + +This check flags all ALL_CAPS enumerations. + +Enumerations should not be named using ALL_CAPS to avoid clashes with macros. + +This rule is part of the "Enumerations" profile of the C++ Core Guidelines, see +https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-enum5-dont-use-all_caps-for-enumerators Index: docs/clang-tidy/checks/list.rst =================================================================== --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -6,6 +6,7 @@ cert-static-object-exception cert-thrown-exception-type cert-variadic-function-def + cppcoreguidelines-enum-all-caps cppcoreguidelines-pro-bounds-array-to-pointer-decay cppcoreguidelines-pro-bounds-constant-array-index cppcoreguidelines-pro-bounds-pointer-arithmetic Index: test/clang-tidy/cppcoreguidelines-enum-all-caps.cpp =================================================================== --- /dev/null +++ test/clang-tidy/cppcoreguidelines-enum-all-caps.cpp @@ -0,0 +1,20 @@ +// RUN: clang-tidy -checks=cppcoreguidelines-enum-all-caps %s + +enum color { +RED = 0xFF0000, +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: Don’t use ALL_CAPS for enumerators [cppcoreguidelines-enum-all-caps] +// CHECK-FIXES: red +BLUE_COLOR = 0x0000FF, +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: Don’t use ALL_CAPS for enumerators [cppcoreguidelines-enum-all-caps] +// CHECK-FIXES: blue_color +COOL_GREEN_123 +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: Don’t use ALL_CAPS for enumerators [cppcoreguidelines-enum-all-caps] +// CHECK-FIXES: cool_green_123 +}; + +// These are OK +enum star_wars_character { + Chewbacca = 0, + Yoda = 1, + Darth_Vader = 2 +};