[clang-tools-extra] r344940 - [clang-tidy] implement cppcoreguidelines macro rules

Jonas Toth via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 22 12:20:01 PDT 2018


Author: jonastoth
Date: Mon Oct 22 12:20:01 2018
New Revision: 344940

URL: http://llvm.org/viewvc/llvm-project?rev=344940&view=rev
Log:
[clang-tidy] implement cppcoreguidelines macro rules

Summary:
In short macros are discouraged by multiple rules (and sometimes reference randomly). [Enum.1], [ES.30], [ES.31]
This check allows only headerguards and empty macros for annotation.

Reviewers: aaron.ballman, hokein

Reviewed By: aaron.ballman

Subscribers: jbcoe, Eugene.Zelenko, klimek, nemanjai, mgorny, xazax.hun, kbarton, cfe-commits

Differential Revision: https://reviews.llvm.org/D41648

Added:
    clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp
    clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/MacroUsageCheck.h
    clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-macro-usage.rst
    clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-macro-usage-caps-only.cpp
    clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-macro-usage-custom.cpp
    clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-macro-usage.cpp
Modified:
    clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
    clang-tools-extra/trunk/docs/ReleaseNotes.rst
    clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst

Modified: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt?rev=344940&r1=344939&r2=344940&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt Mon Oct 22 12:20:01 2018
@@ -4,6 +4,7 @@ add_clang_library(clangTidyCppCoreGuidel
   AvoidGotoCheck.cpp
   CppCoreGuidelinesTidyModule.cpp
   InterfacesGlobalInitCheck.cpp
+  MacroUsageCheck.cpp
   NarrowingConversionsCheck.cpp
   NoMallocCheck.cpp
   OwningMemoryCheck.cpp

Modified: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp?rev=344940&r1=344939&r2=344940&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp Mon Oct 22 12:20:01 2018
@@ -15,6 +15,7 @@
 #include "../readability/MagicNumbersCheck.h"
 #include "AvoidGotoCheck.h"
 #include "InterfacesGlobalInitCheck.h"
+#include "MacroUsageCheck.h"
 #include "NarrowingConversionsCheck.h"
 #include "NoMallocCheck.h"
 #include "OwningMemoryCheck.h"
@@ -45,6 +46,8 @@ public:
         "cppcoreguidelines-avoid-magic-numbers");
     CheckFactories.registerCheck<InterfacesGlobalInitCheck>(
         "cppcoreguidelines-interfaces-global-init");
+    CheckFactories.registerCheck<MacroUsageCheck>(
+        "cppcoreguidelines-macro-usage");
     CheckFactories.registerCheck<NarrowingConversionsCheck>(
         "cppcoreguidelines-narrowing-conversions");
     CheckFactories.registerCheck<NoMallocCheck>("cppcoreguidelines-no-malloc");

Added: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp?rev=344940&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp Mon Oct 22 12:20:01 2018
@@ -0,0 +1,95 @@
+//===--- 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"
+#include <algorithm>
+
+namespace clang {
+namespace tidy {
+namespace cppcoreguidelines {
+
+namespace {
+
+bool isCapsOnly(StringRef Name) {
+  return std::all_of(Name.begin(), Name.end(), [](const char c) {
+    if (std::isupper(c) || std::isdigit(c) || c == '_')
+      return true;
+    return false;
+  });
+}
+
+class MacroUsageCallbacks : public PPCallbacks {
+public:
+  MacroUsageCallbacks(MacroUsageCheck *Check, StringRef RegExp, bool CapsOnly)
+      : Check(Check), RegExp(RegExp), CheckCapsOnly(CapsOnly) {}
+  void MacroDefined(const Token &MacroNameTok,
+                    const MacroDirective *MD) override {
+    if (MD->getMacroInfo()->isUsedForHeaderGuard() ||
+        MD->getMacroInfo()->getNumTokens() == 0)
+      return;
+
+    StringRef MacroName = MacroNameTok.getIdentifierInfo()->getName();
+    if (!CheckCapsOnly && !llvm::Regex(RegExp).match(MacroName))
+      Check->warnMacro(MD);
+
+    if (CheckCapsOnly && !isCapsOnly(MacroName))
+      Check->warnNaming(MD);
+  }
+
+private:
+  MacroUsageCheck *Check;
+  StringRef RegExp;
+  bool CheckCapsOnly;
+};
+} // namespace
+
+void MacroUsageCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "AllowedRegexp", AllowedRegexp);
+  Options.store(Opts, "CheckCapsOnly", CheckCapsOnly);
+}
+
+void MacroUsageCheck::registerPPCallbacks(CompilerInstance &Compiler) {
+  if (!getLangOpts().CPlusPlus11)
+    return;
+
+  Compiler.getPreprocessor().addPPCallbacks(
+      llvm::make_unique<MacroUsageCallbacks>(this, AllowedRegexp,
+                                             CheckCapsOnly));
+}
+
+void MacroUsageCheck::warnMacro(const MacroDirective *MD) {
+  StringRef Message =
+      "macro used to declare a constant; consider using a 'constexpr' "
+      "constant";
+
+  /// A variadic macro is function-like at the same time. Therefore variadic
+  /// macros are checked first and will be excluded for the function-like
+  /// diagnostic.
+  if (MD->getMacroInfo()->isVariadic())
+    Message = "variadic macro used; consider using a 'constexpr' "
+              "variadic template function";
+  else if (MD->getMacroInfo()->isFunctionLike())
+    Message = "function-like macro used; consider a 'constexpr' template "
+              "function";
+
+  diag(MD->getLocation(), Message);
+}
+
+void MacroUsageCheck::warnNaming(const MacroDirective *MD) {
+  diag(MD->getLocation(), "macro definition does not define the macro name "
+                          "using all uppercase characters");
+}
+
+} // namespace cppcoreguidelines
+} // namespace tidy
+} // namespace clang

Added: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/MacroUsageCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/MacroUsageCheck.h?rev=344940&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/MacroUsageCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/MacroUsageCheck.h Mon Oct 22 12:20:01 2018
@@ -0,0 +1,48 @@
+//===--- 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 {
+
+/// 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_*")),
+        CheckCapsOnly(Options.get("CheckCapsOnly", 0)) {}
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void warnMacro(const MacroDirective *MD);
+  void warnNaming(const MacroDirective *MD);
+
+private:
+  /// A regular expression that defines how allowed macros must look like.
+  std::string AllowedRegexp;
+  /// Control if only the check shall only test on CAPS_ONLY macros.
+  bool CheckCapsOnly;
+};
+
+} // namespace cppcoreguidelines
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_MACROUSAGECHECK_H

Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=344940&r1=344939&r2=344940&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original)
+++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Mon Oct 22 12:20:01 2018
@@ -103,6 +103,12 @@ Improvements to clang-tidy
   Flags uses of ``absl::StrCat()`` to append to a ``std::string``. Suggests
   ``absl::StrAppend()`` should be used instead.
 
+- New :doc:`cppcoreguidelines-macro-usage
+  <clang-tidy/checks/cppcoreguidelines-macro-usage>` check.
+
+  Find macro usage that is considered problematic because better language
+  constructs exist for the task.
+
 - New :doc:`misc-non-private-member-variables-in-classes
   <clang-tidy/checks/misc-non-private-member-variables-in-classes>` check.
 

Added: clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-macro-usage.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-macro-usage.rst?rev=344940&view=auto
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-macro-usage.rst (added)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-macro-usage.rst Mon Oct 22 12:20:01 2018
@@ -0,0 +1,28 @@
+.. 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>`_.
+
+Options
+-------
+
+.. option:: AllowedRegexp
+
+    A regular expression to filter allowed macros. For example 
+    `DEBUG*|LIBTORRENT*|TORRENT*|UNI*` could be applied to filter `libtorrent`.
+    Default value is `^DEBUG_*`.
+
+.. option:: CheckCapsOnly
+
+    Boolean flag to warn on all macros except those with CAPS_ONLY names.
+    This option is intended to ease introduction of this check into older
+    code bases. Default value is `0`/`false`.

Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst?rev=344940&r1=344939&r2=344940&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Mon Oct 22 12:20:01 2018
@@ -89,6 +89,7 @@ Clang-Tidy Checks
    cppcoreguidelines-avoid-magic-numbers (redirects to readability-magic-numbers) <cppcoreguidelines-avoid-magic-numbers>
    cppcoreguidelines-c-copy-assignment-signature (redirects to misc-unconventional-assign-operator) <cppcoreguidelines-c-copy-assignment-signature>
    cppcoreguidelines-interfaces-global-init
+   cppcoreguidelines-macro-usage
    cppcoreguidelines-narrowing-conversions
    cppcoreguidelines-no-malloc
    cppcoreguidelines-non-private-member-variables-in-classes (redirects to misc-non-private-member-variables-in-classes) <cppcoreguidelines-non-private-member-variables-in-classes>

Added: clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-macro-usage-caps-only.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-macro-usage-caps-only.cpp?rev=344940&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-macro-usage-caps-only.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-macro-usage-caps-only.cpp Mon Oct 22 12:20:01 2018
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-macro-usage %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: cppcoreguidelines-macro-usage.CheckCapsOnly, value: 1}]}' --
+
+#ifndef INCLUDE_GUARD
+#define INCLUDE_GUARD
+
+#define problematic_constant 0
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro definition does not define the macro name using all uppercase characters
+
+#define problematic_function(x, y) ((a) > (b) ? (a) : (b))
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro definition does not define the macro name using all uppercase characters
+
+#define problematic_variadic(...) (__VA_ARGS__)
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro definition does not define the macro name using all uppercase characters
+//
+#define problematic_variadic2(x, ...) (__VA_ARGS__)
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro definition does not define the macro name using all uppercase characters
+
+#define OKISH_CONSTANT 42
+#define OKISH_FUNCTION(x, y) ((a) > (b) ? (a) : (b))
+#define OKISH_VARIADIC(...) (__VA_ARGS__)
+
+#endif

Added: clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-macro-usage-custom.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-macro-usage-custom.cpp?rev=344940&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-macro-usage-custom.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-macro-usage-custom.cpp Mon Oct 22 12:20:01 2018
@@ -0,0 +1,28 @@
+// 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 'constexpr' variadic template function
+
+#define PROBLEMATIC_VARIADIC2(x, ...) (__VA_ARGS__)
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: variadic macro used; consider using a 'constexpr' variadic template function
+
+#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__)
+#define TEST_VARIADIC2(x, ...) (__VA_ARGS__)
+
+#endif

Added: clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-macro-usage.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-macro-usage.cpp?rev=344940&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-macro-usage.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-macro-usage.cpp Mon Oct 22 12:20:01 2018
@@ -0,0 +1,18 @@
+// 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 'constexpr' variadic template function
+
+#define PROBLEMATIC_VARIADIC2(x, ...) (__VA_ARGS__)
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: variadic macro used; consider using a 'constexpr' variadic template function
+
+#endif




More information about the cfe-commits mailing list