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 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( "cppcoreguidelines-interfaces-global-init"); + CheckFactories.registerCheck( + "cppcoreguidelines-macro-usage"); CheckFactories.registerCheck("cppcoreguidelines-no-malloc"); CheckFactories.registerCheck( "cppcoreguidelines-owning-memory"); Index: clang-tidy/cppcoreguidelines/MacroUsageCheck.h =================================================================== --- /dev/null +++ clang-tidy/cppcoreguidelines/MacroUsageCheck.h @@ -0,0 +1,38 @@ +//===--- 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" + +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) {} + void registerPPCallbacks(CompilerInstance &Compiler) override; + void warnMacro(const MacroDirective *MD); +}; + +} // 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,57 @@ +//===--- 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 "STLExtras.h" +#include + +namespace clang { +namespace tidy { +namespace cppcoreguidelines { + +namespace { +class MacroUsageCallbacks : public PPCallbacks { +public: + MacroUsageCallbacks(MacroUsageCheck *Check) : Check(Check) {} + void MacroDefined(const Token &MacroNameTok, + const MacroDirective *MD) override { + if (MD->getMacroInfo()->isUsedForHeaderGuard() || + MD->getMacroInfo()->getNumTokens() == 0) + return; + + Check->warnMacro(MD); + } + +private: + MacroUsageCheck *Check; +}; +} // namespace + +void MacroUsageCheck::registerPPCallbacks(CompilerInstance &Compiler) { + Compiler.getPreprocessor().addPPCallbacks( + llvm::make_unique(this)); +} + +void MacroUsageCheck::warnMacro(const MacroDirective *MD) { + std::string DiagnosticMessage = "don't use macros to declare constants"; + + auto *Info = MD->getMacroInfo(); + if (Info->isFunctionLike()) + DiagnosticMessage = "don't use macros to simulate functions"; + if (Info->isVariadic()) + DiagnosticMessage = "don't use macros to simulate variadic templates"; + + diag(MD->getLocation(), DiagnosticMessage); +} + +} // namespace cppcoreguidelines +} // namespace tidy +} // namespace clang Index: docs/ReleaseNotes.rst =================================================================== --- docs/ReleaseNotes.rst +++ docs/ReleaseNotes.rst @@ -57,6 +57,12 @@ Improvements to clang-tidy -------------------------- +- New `cppcoreguidelines-macro-usage + `_ check + + Find macro usage that is considered problematic because better language + constructs exist for the task. + - New `fuchsia-statically-constructed-objects `_ check @@ -64,6 +70,7 @@ object is statically initialized with a ``constexpr`` constructor or has no explicit constructor. + Improvements to include-fixer ----------------------------- 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++ Coreguidelines are +`Enum.1 `_, +`ES.30 `_, +`ES.31 `_ and +`ES.33 `_. 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) cppcoreguidelines-c-copy-assignment-signature (redirects to misc-unconventional-assign-operator) cppcoreguidelines-interfaces-global-init + cppcoreguidelines-macro-usage cppcoreguidelines-no-malloc cppcoreguidelines-owning-memory cppcoreguidelines-pro-bounds-array-to-pointer-decay 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: don't use macros to declare constants + +#define PROBLEMATIC_FUNCTION(x,y) ((a) > (b) ? (a) : (b)) +// CHECK-MESSAGES: [[@LINE-1]]:9: warning: don't use macros to simulate functions + +#define PROBLEMATIC_VARIADIC(...) (__VA_ARGS__) +// CHECK-MESSAGES: [[@LINE-1]]:9: warning: don't use macros to simulate variadic templates + +#endif