JonasToth updated this revision to Diff 129893. JonasToth added a comment. - address eugene comments
Repository: rCTE Clang Tools Extra https://reviews.llvm.org/D41648 Files: clang-tidy/cppcoreguidelines/CMakeLists.txt clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp clang-tidy/cppcoreguidelines/MacroUsageCheck.h docs/ReleaseNotes.rst docs/clang-tidy/checks/cppcoreguidelines-macro-usage.rst docs/clang-tidy/checks/list.rst test/clang-tidy/cppcoreguidelines-macro-usage-custom.cpp test/clang-tidy/cppcoreguidelines-macro-usage.cpp
Index: test/clang-tidy/cppcoreguidelines-macro-usage.cpp =================================================================== --- /dev/null +++ test/clang-tidy/cppcoreguidelines-macro-usage.cpp @@ -0,0 +1,15 @@ +// RUN: %check_clang_tidy %s cppcoreguidelines-macro-usage %t + +#ifndef INCLUDE_GUARD +#define INCLUDE_GUARD + +#define PROBLEMATIC_CONSTANT 0 +// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro used to declare a constant; consider using a 'constexpr' constant + +#define PROBLEMATIC_FUNCTION(x, y) ((a) > (b) ? (a) : (b)) +// CHECK-MESSAGES: [[@LINE-1]]:9: warning: function like macro used; consider a (constexpr) template function + +#define PROBLEMATIC_VARIADIC(...) (__VA_ARGS__) +// CHECK-MESSAGES: [[@LINE-1]]:9: warning: variadic macro used; consider using a variadic template + +#endif Index: test/clang-tidy/cppcoreguidelines-macro-usage-custom.cpp =================================================================== --- /dev/null +++ test/clang-tidy/cppcoreguidelines-macro-usage-custom.cpp @@ -0,0 +1,24 @@ +// RUN: %check_clang_tidy %s cppcoreguidelines-macro-usage %t \ +// RUN: -config='{CheckOptions: \ +// RUN: [{key: cppcoreguidelines-macro-usage.AllowedRegexp, value: "DEBUG_*|TEST_*"}]}' -- + +#ifndef INCLUDE_GUARD +#define INCLUDE_GUARD + +#define PROBLEMATIC_CONSTANT 0 +// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro used to declare a constant; consider using a 'constexpr' constant + +#define PROBLEMATIC_FUNCTION(x, y) ((a) > (b) ? (a) : (b)) +// CHECK-MESSAGES: [[@LINE-1]]:9: warning: function like macro used; consider a (constexpr) template function + +#define PROBLEMATIC_VARIADIC(...) (__VA_ARGS__) +// CHECK-MESSAGES: [[@LINE-1]]:9: warning: variadic macro used; consider using a variadic template + +#define DEBUG_CONSTANT 0 +#define DEBUG_FUNCTION(x, y) ((a) > (b) ? (a) : (b)) +#define DEBUG_VARIADIC(...) (__VA_ARGS__) +#define TEST_CONSTANT 0 +#define TEST_FUNCTION(x, y) ((a) > (b) ? (a) : (b)) +#define TEST_VARIADIC(...) (__VA_ARGS__) + +#endif Index: docs/clang-tidy/checks/list.rst =================================================================== --- docs/clang-tidy/checks/list.rst +++ docs/clang-tidy/checks/list.rst @@ -54,6 +54,7 @@ cert-oop11-cpp (redirects to performance-move-constructor-init) <cert-oop11-cpp> cppcoreguidelines-c-copy-assignment-signature (redirects to misc-unconventional-assign-operator) <cppcoreguidelines-c-copy-assignment-signature> cppcoreguidelines-interfaces-global-init + cppcoreguidelines-macro-usage cppcoreguidelines-no-malloc cppcoreguidelines-owning-memory cppcoreguidelines-pro-bounds-array-to-pointer-decay Index: docs/clang-tidy/checks/cppcoreguidelines-macro-usage.rst =================================================================== --- /dev/null +++ docs/clang-tidy/checks/cppcoreguidelines-macro-usage.rst @@ -0,0 +1,12 @@ +.. title:: clang-tidy - cppcoreguidelines-macro-usage + +cppcoreguidelines-macro-usage +============================= + +Find macro usage that is considered problematic because better language +constructs exist for the task. +The relevant sections in the C++ Core Guidelines are +`Enum.1 <https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#enum1-prefer-enumerations-over-macros>`_, +`ES.30 <https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es30-dont-use-macros-for-program-text-manipulation>`_, +`ES.31 <https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es31-dont-use-macros-for-constants-or-functions>`_ and +`ES.33 <https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#es33-if-you-must-use-macros-give-them-unique-names>`_. Index: docs/ReleaseNotes.rst =================================================================== --- docs/ReleaseNotes.rst +++ docs/ReleaseNotes.rst @@ -57,6 +57,12 @@ Improvements to clang-tidy -------------------------- +- New `cppcoreguidelines-macro-usage + <http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-macro-usage.html>`_ check + + Find macro usage that is considered problematic because better language + constructs exist for the task. + - New `fuchsia-statically-constructed-objects <http://clang.llvm.org/extra/clang-tidy/checks/fuchsia-statically-constructed-objects.html>`_ check Index: clang-tidy/cppcoreguidelines/MacroUsageCheck.h =================================================================== --- /dev/null +++ clang-tidy/cppcoreguidelines/MacroUsageCheck.h @@ -0,0 +1,45 @@ +//===--- MacroUsageCheck.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_MACROUSAGECHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_MACROUSAGECHECK_H + +#include "../ClangTidy.h" +#include "clang/Lex/Preprocessor.h" +#include <string> + +namespace clang { +namespace tidy { +namespace cppcoreguidelines { + +enum class MacroUsageMode { Constant, Function, Variadic }; +/// Find macro usage that is considered problematic because better language +/// constructs exist for the task. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-macro-usage.html +class MacroUsageCheck : public ClangTidyCheck { +public: + MacroUsageCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + AllowedRegexp(Options.get("AllowedRegexp", "^DEBUG_*")) {} + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + void registerPPCallbacks(CompilerInstance &Compiler) override; + void warnMacro(const MacroDirective *MD); + +private: + /// A regular expression that defines how allowed macros must look like. + std::string AllowedRegexp; +}; + +} // namespace cppcoreguidelines +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_MACROUSAGECHECK_H Index: clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp =================================================================== --- /dev/null +++ clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp @@ -0,0 +1,71 @@ +//===--- MacroUsageCheck.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 "MacroUsageCheck.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/PPCallbacks.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Regex.h" + +namespace clang { +namespace tidy { +namespace cppcoreguidelines { + +namespace { +class MacroUsageCallbacks : public PPCallbacks { +public: + MacroUsageCallbacks(MacroUsageCheck *Check, StringRef RegExp) + : Check(Check), RegExp(RegExp) {} + void MacroDefined(const Token &MacroNameTok, + const MacroDirective *MD) override { + if (MD->getMacroInfo()->isUsedForHeaderGuard() || + MD->getMacroInfo()->getNumTokens() == 0) + return; + + StringRef MacroName = MacroNameTok.getIdentifierInfo()->getName(); + if (!llvm::Regex(RegExp).match(MacroName)) + Check->warnMacro(MD); + } + +private: + MacroUsageCheck *Check; + StringRef RegExp; +}; +} // namespace + +void MacroUsageCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "AllowedRegexp", AllowedRegexp); +} + +void MacroUsageCheck::registerPPCallbacks(CompilerInstance &Compiler) { + if (!getLangOpts().CPlusPlus11) + return; + + Compiler.getPreprocessor().addPPCallbacks( + llvm::make_unique<MacroUsageCallbacks>(this, AllowedRegexp)); +} + +void MacroUsageCheck::warnMacro(const MacroDirective *MD) { + std::string DiagnosticMessage = + "macro used to declare a constant; consider using a 'constexpr' constant"; + + const MacroInfo *Info = MD->getMacroInfo(); + if (Info->isFunctionLike()) + DiagnosticMessage = + "function like macro used; consider a (constexpr) template function"; + if (Info->isVariadic()) + DiagnosticMessage = + "variadic macro used; consider using a variadic template"; + + diag(MD->getLocation(), DiagnosticMessage); +} + +} // namespace cppcoreguidelines +} // namespace tidy +} // namespace clang Index: clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp =================================================================== --- clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp +++ clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp @@ -12,6 +12,7 @@ #include "../ClangTidyModuleRegistry.h" #include "../misc/UnconventionalAssignOperatorCheck.h" #include "InterfacesGlobalInitCheck.h" +#include "MacroUsageCheck.h" #include "NoMallocCheck.h" #include "OwningMemoryCheck.h" #include "ProBoundsArrayToPointerDecayCheck.h" @@ -37,6 +38,8 @@ void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck<InterfacesGlobalInitCheck>( "cppcoreguidelines-interfaces-global-init"); + CheckFactories.registerCheck<MacroUsageCheck>( + "cppcoreguidelines-macro-usage"); CheckFactories.registerCheck<NoMallocCheck>("cppcoreguidelines-no-malloc"); CheckFactories.registerCheck<OwningMemoryCheck>( "cppcoreguidelines-owning-memory"); Index: clang-tidy/cppcoreguidelines/CMakeLists.txt =================================================================== --- clang-tidy/cppcoreguidelines/CMakeLists.txt +++ clang-tidy/cppcoreguidelines/CMakeLists.txt @@ -3,6 +3,7 @@ add_clang_library(clangTidyCppCoreGuidelinesModule CppCoreGuidelinesTidyModule.cpp InterfacesGlobalInitCheck.cpp + MacroUsageCheck.cpp NoMallocCheck.cpp OwningMemoryCheck.cpp ProBoundsArrayToPointerDecayCheck.cpp
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits