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
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits