clang-tools 3.8.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

SimplifyBooleanExprCheck.h
Go to the documentation of this file.
1 //===--- 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
15 namespace clang {
16 namespace tidy {
17 namespace readability {
18
19 /// Looks for boolean expressions involving boolean constants and simplifies
20 /// them to use the appropriate boolean expression directly.
21 ///
22 /// Examples:
23 ///
24 /// =========================================== ================
25 /// Initial expression Result
26 /// ------------------------------------------- ----------------
27 /// `if (b == true)` `if (b)`
28 /// `if (b == false)` `if (!b)`
29 /// `if (b && true)` `if (b)`
30 /// `if (b && false)` `if (false)`
31 /// `if (b || true)` `if (true)`
32 /// `if (b || false)` `if (b)`
33 /// `e ? true : false` `e`
34 /// `e ? false : true` `!e`
35 /// `if (true) t(); else f();` `t();`
36 /// `if (false) t(); else f();` `f();`
37 /// `if (e) return true; else return false;` `return e;`
38 /// `if (e) return false; else return true;` `return !e;`
39 /// `if (e) b = true; else b = false;` `b = e;`
40 /// `if (e) b = false; else b = true;` `b = !e;`
41 /// `if (e) return true; return false;` `return e;`
42 /// `if (e) return false; return true;` `return !e;`
43 /// =========================================== ================
44 ///
45 /// The resulting expression `e` is modified as follows:
46 /// 1. Unnecessary parentheses around the expression are removed.
47 /// 2. Negated applications of `!` are eliminated.
48 /// 3. Negated applications of comparison operators are changed to use the
49 /// opposite condition.
50 /// 4. Implicit conversions of pointer to `bool` are replaced with explicit
51 /// comparisons to `nullptr`.
52 /// 5. Implicit casts to `bool` are replaced with explicit casts to `bool`.
53 /// 6. Object expressions with `explicit operator bool` conversion operators
54 /// are replaced with explicit casts to `bool`.
55 ///
56 /// Examples:
57 /// 1. The ternary assignment `bool b = (i < 0) ? true : false;` has redundant
58 /// parentheses and becomes `bool b = i < 0;`.
59 ///
60 /// 2. The conditional return `if (!b) return false; return true;` has an
61 /// implied double negation and becomes `return b;`.
62 ///
63 /// 3. The conditional return `if (i < 0) return false; return true;` becomes
64 /// `return i >= 0;`.
65 ///
66 /// The conditional return `if (i != 0) return false; return true;` becomes
67 /// `return i == 0;`.
68 ///
69 /// 4. The conditional return `if (p) return true; return false;` has an
70 /// implicit conversion of a pointer to `bool` and becomes
71 /// `return p != nullptr;`.
72 ///
73 /// The ternary assignment `bool b = (i & 1) ? true : false;` has an
74 /// implicit conversion of `i & 1` to `bool` and becomes
75 /// `bool b = static_cast<bool>(i & 1);`.
76 ///
77 /// 5. The conditional return `if (i & 1) return true; else return false;` has
78 /// an implicit conversion of an integer quantity `i & 1` to `bool` and
79 /// becomes `return static_cast<bool>(i & 1);`
80 ///
81 /// 6. Given `struct X { explicit operator bool(); };`, and an instance `x` of
82 /// `struct X`, the conditional return `if (x) return true; return false;`
83 /// becomes `return static_cast<bool>(x);`
84 ///
85 /// When a conditional boolean return or assignment appears at the end of a
86 /// chain of `if`, `else if` statements, the conditional statement is left
87 /// unchanged unless the option `ChainedConditionalReturn` or
88 /// `ChainedConditionalAssignment`, respectively, is specified as non-zero.
89 /// The default value for both options is zero.
90 ///
91 class SimplifyBooleanExprCheck : public ClangTidyCheck {
92 public:
93 SimplifyBooleanExprCheck(StringRef Name, ClangTidyContext *Context);
94
95 void storeOptions(ClangTidyOptions::OptionMap &Options) override;
96 void registerMatchers(ast_matchers::MatchFinder *Finder) override;
97 void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
98
99 private:
100 void matchBoolBinOpExpr(ast_matchers::MatchFinder *Finder, bool Value,
101 StringRef OperatorName, StringRef BooleanId);
102
103 void matchExprBinOpBool(ast_matchers::MatchFinder *Finder, bool Value,
104 StringRef OperatorName, StringRef BooleanId);
105
106 void matchBoolCompOpExpr(ast_matchers::MatchFinder *Finder, bool Value,
107 StringRef OperatorName, StringRef BooleanId);
108
109 void matchExprCompOpBool(ast_matchers::MatchFinder *Finder, bool Value,
110 StringRef OperatorName, StringRef BooleanId);
111
112 void matchBoolCondition(ast_matchers::MatchFinder *Finder, bool Value,
113 StringRef BooleanId);
114
115 void matchTernaryResult(ast_matchers::MatchFinder *Finder, bool Value,
116 StringRef TernaryId);
117
118 void matchIfReturnsBool(ast_matchers::MatchFinder *Finder, bool Value,
119 StringRef Id);
120
121 void matchIfAssignsBool(ast_matchers::MatchFinder *Finder, bool Value,
122 StringRef Id);
123
124 void matchCompoundIfReturnsBool(ast_matchers::MatchFinder *Finder, bool Value,
125 StringRef Id);
126
127 void
128 replaceWithExpression(const ast_matchers::MatchFinder::MatchResult &Result,
129 const CXXBoolLiteralExpr *BoolLiteral, bool UseLHS,
130 bool Negated = false);
131
132 void
133 replaceWithThenStatement(const ast_matchers::MatchFinder::MatchResult &Result,
134 const CXXBoolLiteralExpr *BoolLiteral);
135
136 void
137 replaceWithElseStatement(const ast_matchers::MatchFinder::MatchResult &Result,
138 const CXXBoolLiteralExpr *FalseConditionRemoved);
139
140 void
141 replaceWithCondition(const ast_matchers::MatchFinder::MatchResult &Result,
142 const ConditionalOperator *Ternary,
143 bool Negated = false);
144
145 void replaceWithReturnCondition(
146 const ast_matchers::MatchFinder::MatchResult &Result, const IfStmt *If,
147 bool Negated = false);
148
149 void
150 replaceWithAssignment(const ast_matchers::MatchFinder::MatchResult &Result,
151 const IfStmt *If, bool Negated = false);
152
153 void replaceCompoundReturnWithCondition(
154 const ast_matchers::MatchFinder::MatchResult &Result,
155 const CompoundStmt *Compound, bool Negated = false);
156
157 void issueDiag(const ast_matchers::MatchFinder::MatchResult &Result,
158 SourceLocation Loc, StringRef Description,
159 SourceRange ReplacementRange, StringRef Replacement);
160
161 const bool ChainedConditionalReturn;
162 const bool ChainedConditionalAssignment;
163 };
164
165 } // namespace readability
166 } // namespace tidy
167 } // namespace clang
168
169 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_SIMPLIFY_BOOLEAN_EXPR_H
Loc
SourceLocation Loc
'#' location in the include directive
Definition: IncludeOrderCheck.cpp:34
Name
StringHandle Name
Definition: PreprocessorTracker.cpp:525
Finder
std::unique_ptr< ast_matchers::MatchFinder > Finder
Definition: ClangTidy.cpp:188
clang::tidy::readability::SimplifyBooleanExprCheck::storeOptions
void storeOptions(ClangTidyOptions::OptionMap &Options) override
Should store all options supported by this check with their current values or default values for opti...
Definition: SimplifyBooleanExprCheck.cpp:402
clang::tidy::readability::SimplifyBooleanExprCheck
Looks for boolean expressions involving boolean constants and simplifies them to use the appropriate ...
Definition: SimplifyBooleanExprCheck.h:91
clang::tidy::ClangTidyCheck
Base class for all clang-tidy checks.
Definition: ClangTidy.h:102
clang::tidy::ClangTidyCheck::Options
OptionsView Options
Definition: ClangTidy.h:158
clang::tidy::readability::SimplifyBooleanExprCheck::check
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
ClangTidyChecks that register ASTMatchers should do the actual work in here.
Definition: SimplifyBooleanExprCheck.cpp:445
clang::tidy::readability::SimplifyBooleanExprCheck::SimplifyBooleanExprCheck
SimplifyBooleanExprCheck(StringRef Name, ClangTidyContext *Context)
Definition: SimplifyBooleanExprCheck.cpp:263
clang::tidy::ClangTidyOptions::OptionMap
std::map< std::string, std::string > OptionMap
Definition: ClangTidyOptions.h:82
clang::tidy::readability::SimplifyBooleanExprCheck::registerMatchers
void registerMatchers(ast_matchers::MatchFinder *Finder) override
Override this to register ASTMatchers with Finder.
Definition: SimplifyBooleanExprCheck.cpp:408
Context
ClangTidyContext & Context
Definition: ClangTidy.cpp:93
clang::tidy::ClangTidyContext
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
Definition: ClangTidyDiagnosticConsumer.h:124
Result
const NamedDecl * Result
Definition: USRFinder.cpp:121