blob: 365d82113471abec8b43a9aea08e31ff2d37bd38 [file] [log] [blame]
Alexander Kornienkof5e72b02015-04-10 19:26:43 +00001//===--- SimplifyBooleanExpr.h clang-tidy -----------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_SIMPLIFY_BOOLEAN_EXPR_H
11#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_SIMPLIFY_BOOLEAN_EXPR_H
12
13#include "../ClangTidy.h"
14
15namespace clang {
16namespace tidy {
17namespace readability {
18
19/// \brief Looks for boolean expressions involving boolean constants and
20// simplifies them to use the appropriate boolean expression directly.
21///
22/// Examples:
23/// `if (b == true)` becomes `if (b)`
24/// `if (b == false)` becomes `if (!b)`
25/// `if (b && true)` becomes `if (b)`
26/// `if (b && false)` becomes `if (false)`
27/// `if (b || true)` becomes `if (true)`
28/// `if (b || false)` becomes `if (b)`
29/// `e ? true : false` becomes `e`
30/// `e ? false : true` becomes `!e`
31/// `if (true) t(); else f();` becomes `t();`
32/// `if (false) t(); else f();` becomes `f();`
Alexander Kornienkofb3e2cd2015-05-17 12:31:12 +000033/// `if (e) return true; else return false;` becomes `return e;`
34/// `if (e) return false; else return true;` becomes `return !e;`
Alexander Kornienkof5e72b02015-04-10 19:26:43 +000035/// `if (e) b = true; else b = false;` becomes `b = e;`
Alexander Kornienkofb3e2cd2015-05-17 12:31:12 +000036/// `if (e) b = false; else b = true;` becomes `b = !e;`
37///
38/// Parenthesis from the resulting expression `e` are removed whenever
39/// possible.
40///
41/// When a conditional boolean return or assignment appears at the end of a
42/// chain of `if`, `else if` statements, the conditional statement is left
43/// unchanged unless the option `ChainedConditionalReturn` or
44/// `ChainedConditionalAssignment`, respectively, is specified as non-zero.
45/// The default value for both options is zero.
Alexander Kornienkof5e72b02015-04-10 19:26:43 +000046///
47class SimplifyBooleanExprCheck : public ClangTidyCheck {
48public:
Alexander Kornienkofb3e2cd2015-05-17 12:31:12 +000049 SimplifyBooleanExprCheck(StringRef Name, ClangTidyContext *Context);
50
51 void storeOptions(ClangTidyOptions::OptionMap &Options) override;
Alexander Kornienkof5e72b02015-04-10 19:26:43 +000052 void registerMatchers(ast_matchers::MatchFinder *Finder) override;
53 void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
54
55private:
56 void matchBoolBinOpExpr(ast_matchers::MatchFinder *Finder, bool Value,
57 StringRef OperatorName, StringRef BooleanId);
58
59 void matchExprBinOpBool(ast_matchers::MatchFinder *Finder, bool Value,
60 StringRef OperatorName, StringRef BooleanId);
61
62 void matchBoolCompOpExpr(ast_matchers::MatchFinder *Finder, bool Value,
63 StringRef OperatorName, StringRef BooleanId);
64
65 void matchExprCompOpBool(ast_matchers::MatchFinder *Finder, bool Value,
66 StringRef OperatorName, StringRef BooleanId);
67
68 void matchBoolCondition(ast_matchers::MatchFinder *Finder, bool Value,
69 StringRef BooleanId);
70
71 void matchTernaryResult(ast_matchers::MatchFinder *Finder, bool Value,
72 StringRef TernaryId);
73
74 void matchIfReturnsBool(ast_matchers::MatchFinder *Finder, bool Value,
75 StringRef Id);
76
77 void matchIfAssignsBool(ast_matchers::MatchFinder *Finder, bool Value,
78 StringRef Id);
79
80 void
81 replaceWithExpression(const ast_matchers::MatchFinder::MatchResult &Result,
82 const CXXBoolLiteralExpr *BoolLiteral, bool UseLHS,
83 bool Negated = false);
84
85 void
86 replaceWithThenStatement(const ast_matchers::MatchFinder::MatchResult &Result,
87 const CXXBoolLiteralExpr *BoolLiteral);
88
89 void
90 replaceWithElseStatement(const ast_matchers::MatchFinder::MatchResult &Result,
91 const CXXBoolLiteralExpr *FalseConditionRemoved);
92
93 void
94 replaceWithCondition(const ast_matchers::MatchFinder::MatchResult &Result,
95 const ConditionalOperator *Ternary,
96 bool Negated = false);
97
98 void replaceWithReturnCondition(
99 const ast_matchers::MatchFinder::MatchResult &Result, const IfStmt *If,
100 bool Negated = false);
101
102 void
103 replaceWithAssignment(const ast_matchers::MatchFinder::MatchResult &Result,
104 const IfStmt *If, bool Negated = false);
Alexander Kornienkofb3e2cd2015-05-17 12:31:12 +0000105
106 const bool ChainedConditionalReturn;
107 const bool ChainedConditionalAssignment;
Alexander Kornienkof5e72b02015-04-10 19:26:43 +0000108};
109
110} // namespace readability
111} // namespace tidy
112} // namespace clang
113
114#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_SIMPLIFY_BOOLEAN_EXPR_H