mgehre created this revision.
Herald added a subscriber: mgorny.

Flags (and replaces) the alternative tokens for binary and unary
operators, such as ``not`` (for ``!``), ``bitand`` (for ``&``), ``or`` (for 
``||``)
or ``not_eq`` (for ``!=``).


https://reviews.llvm.org/D31308

Files:
  clang-tidy/readability/CMakeLists.txt
  clang-tidy/readability/NoAlternativeTokensCheck.cpp
  clang-tidy/readability/NoAlternativeTokensCheck.h
  clang-tidy/readability/ReadabilityTidyModule.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/readability-no-alternative-tokens.rst
  test/clang-tidy/readability-no-alternative-tokens.cpp

Index: test/clang-tidy/readability-no-alternative-tokens.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/readability-no-alternative-tokens.cpp
@@ -0,0 +1,54 @@
+// RUN: %check_clang_tidy %s readability-no-alternative-tokens %t
+
+void f() {
+  bool a, b, c;
+
+  c = a and b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: operator uses alternative spelling [readability-no-alternative-tokens]
+  // CHECK-FIXES: c = a && b;
+  c and_eq a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: operator
+  // CHECK-FIXES: c &= a;
+  c = a bitand b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: operator
+  // CHECK-FIXES: c = a & b;
+  c = a bitor b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: operator
+  // CHECK-FIXES: c = a | b;
+  c = compl a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: operator
+  // CHECK-FIXES: c = ~ a;
+  c = not a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: operator
+  // CHECK-FIXES: c = ! a;
+  c = a not_eq b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: operator
+  // CHECK-FIXES: c = a != b;
+  c = a or b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: operator
+  // CHECK-FIXES: c = a || b;
+  c or_eq a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: operator
+  // CHECK-FIXES: c |= a;
+  c = a xor b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: operator
+  // CHECK-FIXES: c = a ^ b;
+  c xor_eq a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: operator
+  // CHECK-FIXES: c ^= a;
+
+#define M a xor
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: operator
+  // 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
+}
Index: docs/clang-tidy/checks/readability-no-alternative-tokens.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/readability-no-alternative-tokens.rst
@@ -0,0 +1,8 @@
+.. title:: clang-tidy - readability-no-alternative-tokens
+
+readability-no-alternative-tokens
+=================================
+
+Flags (and replaces) the alternative tokens for binary and unary operators,
+such as ``not`` (for ``!``), ``bitand`` (for ``&``), ``or`` (for ``||``) or ``not_eq``
+(for ``!=``).
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -144,6 +144,7 @@
    readability-misleading-indentation
    readability-misplaced-array-index
    readability-named-parameter
+   readability-no-alternative-tokens
    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-no-alternative-tokens
+  <http://clang.llvm.org/extra/clang-tidy/checks/readability-no-alternative-tokens.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
@@ -23,6 +23,7 @@
 #include "MisleadingIndentationCheck.h"
 #include "MisplacedArrayIndexCheck.h"
 #include "NamedParameterCheck.h"
+#include "NoAlternativeTokensCheck.h"
 #include "NonConstParameterCheck.h"
 #include "RedundantControlFlowCheck.h"
 #include "RedundantDeclarationCheck.h"
@@ -66,6 +67,8 @@
         "readability-misleading-indentation");
     CheckFactories.registerCheck<MisplacedArrayIndexCheck>(
         "readability-misplaced-array-index");
+    CheckFactories.registerCheck<NoAlternativeTokensCheck>(
+        "readability-no-alternative-tokens");
     CheckFactories.registerCheck<RedundantFunctionPtrDereferenceCheck>(
         "readability-redundant-function-ptr-dereference");
     CheckFactories.registerCheck<RedundantMemberInitCheck>(
Index: clang-tidy/readability/NoAlternativeTokensCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/readability/NoAlternativeTokensCheck.h
@@ -0,0 +1,35 @@
+//===--- NoAlternativeTokensCheck.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_NO_ALTERNATIVE_TOKENS_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_NO_ALTERNATIVE_TOKENS_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-no-alternative-tokens.html
+class NoAlternativeTokensCheck : public ClangTidyCheck {
+public:
+  NoAlternativeTokensCheck(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_NO_ALTERNATIVE_TOKENS_H
Index: clang-tidy/readability/NoAlternativeTokensCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/readability/NoAlternativeTokensCheck.cpp
@@ -0,0 +1,75 @@
+//===--- NoAlternativeTokensCheck.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 "NoAlternativeTokensCheck.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 {
+
+void NoAlternativeTokensCheck::registerMatchers(MatchFinder *Finder) {
+  // We ignore implicit != operators in C++11 range-based for loops.
+  Finder->addMatcher(binaryOperator(unless(hasLHS(ignoringImpCasts(
+                                        declRefExpr(to(isImplicit()))))))
+                         .bind("binary"),
+                     this);
+  Finder->addMatcher(unaryOperator().bind("unary"), this);
+}
+
+void NoAlternativeTokensCheck::check(const MatchFinder::MatchResult &Result) {
+  StringRef PrimarySpelling;
+  SourceLocation OpLoc;
+
+  if (const auto *B = Result.Nodes.getNodeAs<BinaryOperator>("binary")) {
+    switch (B->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:
+      break;
+    default:
+      return;
+    }
+    PrimarySpelling = B->getOpcodeStr();
+    OpLoc = B->getOperatorLoc();
+  }
+
+  if (const auto *U = Result.Nodes.getNodeAs<UnaryOperator>("unary")) {
+    auto OpCode = U->getOpcode();
+    if (OpCode != UO_Not && OpCode != UO_LNot)
+      return;
+    PrimarySpelling = UnaryOperator::getOpcodeStr(OpCode);
+    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, "operator uses alternative spelling")
+        << 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
+  NoAlternativeTokensCheck.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