mgehre updated this revision to Diff 93519.
mgehre added a comment.

only check C++ code; only match operators that can have alternative 
representations


https://reviews.llvm.org/D31308

Files:
  clang-tidy/readability/CMakeLists.txt
  clang-tidy/readability/OperatorsRepresentationCheck.cpp
  clang-tidy/readability/OperatorsRepresentationCheck.h
  clang-tidy/readability/ReadabilityTidyModule.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/readability-operators-representation.rst
  test/clang-tidy/readability-operators-representation.cpp

Index: test/clang-tidy/readability-operators-representation.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/readability-operators-representation.cpp
@@ -0,0 +1,63 @@
+// RUN: %check_clang_tidy %s readability-operators-representation %t
+
+void f() {
+  bool a, b, c;
+
+  c = a and b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: 'and' is an alternative token spelling; consider using '&&' [readability-operators-representation]
+  // CHECK-FIXES: c = a && b;
+  c and_eq a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'and_eq' is an alternative
+  // CHECK-FIXES: c &= a;
+  c = a bitand b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: 'bitand' is an alternative
+  // CHECK-FIXES: c = a & b;
+  c = a bitor b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: 'bitor' is an alternative
+  // CHECK-FIXES: c = a | b;
+  c = compl a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'compl' is an alternative
+  // CHECK-FIXES: c = ~ a;
+  c = not a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: 'not' is an alternative
+  // CHECK-FIXES: c = ! a;
+  c = a not_eq b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: 'not_eq' is an alternative
+  // CHECK-FIXES: c = a != b;
+  c = a or b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: 'or' is an alternative
+  // CHECK-FIXES: c = a || b;
+  c or_eq a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'or_eq' is an alternative
+  // CHECK-FIXES: c |= a;
+  c = a xor b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: 'xor' is an alternative
+  // CHECK-FIXES: c = a ^ b;
+  c xor_eq a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'xor_eq' is an alternative
+  // CHECK-FIXES: c ^= a;
+
+#define M a xor
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: 'xor' is an alternative
+  // CHECK-FIXES: #define M a ^
+  c = M b;
+
+  int arr[2];
+  for (int i : arr) // OK (Here is an implicit != operator.)
+    ;
+
+  auto ptr = &c; // OK
+  auto i = -1;   // OK
+  c = a && b;    // OK
+  c &= a;        // OK
+  c = !a;        // OK
+}
+
+struct S {
+  friend S &operator and(const S &, const S &);
+};
+
+int g() {
+  S s1, s2;
+  S s3 = s1 and s2; // OK
+}
Index: docs/clang-tidy/checks/readability-operators-representation.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/readability-operators-representation.rst
@@ -0,0 +1,23 @@
+.. title:: clang-tidy - readability-operators-representation
+
+readability-operators-representation
+====================================
+
+Flags (and replaces) the alternative tokens for binary and unary operators by
+their primary ones for consistency.
+
+======= ===========
+Primary Alternative
+======= ===========
+``&&``  ``and``
+``&=``  ``and_eq``
+``&``   ``bitand``
+``|``   ``bitor``
+``~``   ``compl``
+``!``   ``not``
+``!=``  ``not_eq``
+``||``  ``or``
+``|=``  ``or_eq``
+``^``   ``xor``
+``^=``  ``xor_eq``
+======= ===========
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -145,6 +145,7 @@
    readability-misleading-indentation
    readability-misplaced-array-index
    readability-named-parameter
+   readability-operators-representation
    readability-non-const-parameter
    readability-redundant-control-flow
    readability-redundant-declaration
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -72,6 +72,12 @@
 
   Finds misleading indentation where braces should be introduced or the code should be reformatted.
 
+- New `readability-operators-representation
+  <http://clang.llvm.org/extra/clang-tidy/checks/readability-operators-representation.html>`_ check
+
+  Flags (and replaces) the alternative tokens for binary and unary operators,
+  such as ``not`` (for ``!``) and ``or`` (for ``||``).
+
 - Added `ParameterThreshold` to `readability-function-size`.
 
   Finds functions that have more then `ParameterThreshold` parameters and emits a warning.
Index: clang-tidy/readability/ReadabilityTidyModule.cpp
===================================================================
--- clang-tidy/readability/ReadabilityTidyModule.cpp
+++ clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -24,6 +24,7 @@
 #include "MisplacedArrayIndexCheck.h"
 #include "NamedParameterCheck.h"
 #include "NonConstParameterCheck.h"
+#include "OperatorsRepresentationCheck.h"
 #include "RedundantControlFlowCheck.h"
 #include "RedundantDeclarationCheck.h"
 #include "RedundantFunctionPtrDereferenceCheck.h"
@@ -66,6 +67,8 @@
         "readability-misleading-indentation");
     CheckFactories.registerCheck<MisplacedArrayIndexCheck>(
         "readability-misplaced-array-index");
+    CheckFactories.registerCheck<OperatorsRepresentationCheck>(
+        "readability-operators-representation");
     CheckFactories.registerCheck<RedundantFunctionPtrDereferenceCheck>(
         "readability-redundant-function-ptr-dereference");
     CheckFactories.registerCheck<RedundantMemberInitCheck>(
Index: clang-tidy/readability/OperatorsRepresentationCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/readability/OperatorsRepresentationCheck.h
@@ -0,0 +1,35 @@
+//===--- OperatorsRepresentationCheck.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_OPERATORS_REPRESENTATION_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_OPERATORS_REPRESENTATION_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+/// Flags alternative tokens for operators, such as 'compl', 'not' and 'or'.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/readability-operators-representation.html
+class OperatorsRepresentationCheck : public ClangTidyCheck {
+public:
+  OperatorsRepresentationCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_OPERATORS_REPRESENTATION_H
Index: clang-tidy/readability/OperatorsRepresentationCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/readability/OperatorsRepresentationCheck.cpp
@@ -0,0 +1,92 @@
+//===--- OperatorsRepresentationCheck.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 "OperatorsRepresentationCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+AST_MATCHER(BinaryOperator, binaryHasAlternativeRepr) {
+  switch (Node.getOpcode()) {
+  case BO_NE:
+  case BO_And:
+  case BO_Xor:
+  case BO_Or:
+  case BO_LAnd:
+  case BO_LOr:
+  case BO_AndAssign:
+  case BO_OrAssign:
+  case BO_XorAssign:
+    return true;
+  default:
+    return false;
+  }
+}
+
+AST_MATCHER(UnaryOperator, unaryHasAlternativeRepr) {
+  switch (Node.getOpcode()) {
+  case UO_Not:
+  case UO_LNot:
+    return true;
+  default:
+    return false;
+  }
+}
+
+void OperatorsRepresentationCheck::registerMatchers(MatchFinder *Finder) {
+  if (!getLangOpts().CPlusPlus)
+    return;
+
+  // We ignore implicit != operators in C++11 range-based for loops.
+  Finder->addMatcher(binaryOperator(binaryHasAlternativeRepr(),
+                                    unless(hasLHS(ignoringImpCasts(
+                                        declRefExpr(to(isImplicit()))))))
+                         .bind("binary"),
+                     this);
+  Finder->addMatcher(unaryOperator(unaryHasAlternativeRepr()).bind("unary"),
+                     this);
+}
+
+void OperatorsRepresentationCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  StringRef PrimarySpelling;
+  SourceLocation OpLoc;
+
+  if (const auto *B = Result.Nodes.getNodeAs<BinaryOperator>("binary")) {
+    PrimarySpelling = B->getOpcodeStr();
+    OpLoc = B->getOperatorLoc();
+  }
+
+  if (const auto *U = Result.Nodes.getNodeAs<UnaryOperator>("unary")) {
+    PrimarySpelling = UnaryOperator::getOpcodeStr(U->getOpcode());
+    OpLoc = U->getOperatorLoc();
+  }
+
+  auto &SM = *Result.SourceManager;
+  OpLoc = SM.getSpellingLoc(OpLoc);
+
+  auto TokenRange = CharSourceRange::getTokenRange(OpLoc);
+  StringRef Spelling = Lexer::getSourceText(TokenRange, SM, getLangOpts());
+
+  if (PrimarySpelling != Spelling) {
+    diag(OpLoc, "'%0' is an alternative token spelling; consider using '%1'")
+        << Spelling << PrimarySpelling
+        << FixItHint::CreateReplacement(TokenRange, PrimarySpelling);
+  }
+}
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/readability/CMakeLists.txt
===================================================================
--- clang-tidy/readability/CMakeLists.txt
+++ clang-tidy/readability/CMakeLists.txt
@@ -15,6 +15,7 @@
   MisplacedArrayIndexCheck.cpp
   NamedParameterCheck.cpp
   NamespaceCommentCheck.cpp
+  OperatorsRepresentationCheck.cpp
   NonConstParameterCheck.cpp
   ReadabilityTidyModule.cpp
   RedundantControlFlowCheck.cpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to