[clang-tidy] Add readability-simplify-boolean-expr check to clang-tidy
This check looks for comparisons between boolean expressions and boolean
constants and simplifies them to just use the appropriate boolean expression
directly.
if (b == true) becomes if (b)
if (b == false) becomes if (!b)
if (b && true) becomes if (b)
if (b && false) becomes if (false)
if (b || true) becomes if (true)
if (b || false) becomes if (b)
e ? true : false becomes e
e ? false : true becomes !e
if (true) t(); else f(); becomes t();
if (false) t(); else f(); becomes f();
if (e) return true; else return false; becomes return (e);
if (e) return false; else return true; becomes return !(e);
if (e) b = true; else b = false; becomes b = e;
if (e) b = false; else b = true; becomes b = !(e);
http://reviews.llvm.org/D7648
Patch by Richard Thomson!
llvm-svn: 234626
diff --git a/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.h b/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.h
new file mode 100644
index 0000000..5bb67a4
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/SimplifyBooleanExprCheck.h
@@ -0,0 +1,101 @@
+//===--- SimplifyBooleanExpr.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_SIMPLIFY_BOOLEAN_EXPR_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_SIMPLIFY_BOOLEAN_EXPR_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+/// \brief Looks for boolean expressions involving boolean constants and
+// simplifies them to use the appropriate boolean expression directly.
+///
+/// Examples:
+/// `if (b == true)` becomes `if (b)`
+/// `if (b == false)` becomes `if (!b)`
+/// `if (b && true)` becomes `if (b)`
+/// `if (b && false)` becomes `if (false)`
+/// `if (b || true)` becomes `if (true)`
+/// `if (b || false)` becomes `if (b)`
+/// `e ? true : false` becomes `e`
+/// `e ? false : true` becomes `!e`
+/// `if (true) t(); else f();` becomes `t();`
+/// `if (false) t(); else f();` becomes `f();`
+/// `if (e) return true; else return false;` becomes `return (e);`
+/// `if (e) return false; else return true;` becomes `return !(e);`
+/// `if (e) b = true; else b = false;` becomes `b = e;`
+/// `if (e) b = false; else b = true;` becomes `b = !(e);`
+///
+class SimplifyBooleanExprCheck : public ClangTidyCheck {
+public:
+ SimplifyBooleanExprCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+ void matchBoolBinOpExpr(ast_matchers::MatchFinder *Finder, bool Value,
+ StringRef OperatorName, StringRef BooleanId);
+
+ void matchExprBinOpBool(ast_matchers::MatchFinder *Finder, bool Value,
+ StringRef OperatorName, StringRef BooleanId);
+
+ void matchBoolCompOpExpr(ast_matchers::MatchFinder *Finder, bool Value,
+ StringRef OperatorName, StringRef BooleanId);
+
+ void matchExprCompOpBool(ast_matchers::MatchFinder *Finder, bool Value,
+ StringRef OperatorName, StringRef BooleanId);
+
+ void matchBoolCondition(ast_matchers::MatchFinder *Finder, bool Value,
+ StringRef BooleanId);
+
+ void matchTernaryResult(ast_matchers::MatchFinder *Finder, bool Value,
+ StringRef TernaryId);
+
+ void matchIfReturnsBool(ast_matchers::MatchFinder *Finder, bool Value,
+ StringRef Id);
+
+ void matchIfAssignsBool(ast_matchers::MatchFinder *Finder, bool Value,
+ StringRef Id);
+
+ void
+ replaceWithExpression(const ast_matchers::MatchFinder::MatchResult &Result,
+ const CXXBoolLiteralExpr *BoolLiteral, bool UseLHS,
+ bool Negated = false);
+
+ void
+ replaceWithThenStatement(const ast_matchers::MatchFinder::MatchResult &Result,
+ const CXXBoolLiteralExpr *BoolLiteral);
+
+ void
+ replaceWithElseStatement(const ast_matchers::MatchFinder::MatchResult &Result,
+ const CXXBoolLiteralExpr *FalseConditionRemoved);
+
+ void
+ replaceWithCondition(const ast_matchers::MatchFinder::MatchResult &Result,
+ const ConditionalOperator *Ternary,
+ bool Negated = false);
+
+ void replaceWithReturnCondition(
+ const ast_matchers::MatchFinder::MatchResult &Result, const IfStmt *If,
+ bool Negated = false);
+
+ void
+ replaceWithAssignment(const ast_matchers::MatchFinder::MatchResult &Result,
+ const IfStmt *If, bool Negated = false);
+};
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_SIMPLIFY_BOOLEAN_EXPR_H