blob: 193bb61f5b43ee714af18261df82c298a4c53c52 [file] [log] [blame]
Jakub Staronf7df7262016-05-11 11:33:16 +00001//===--- UseBoolLiteralsCheck.cpp - clang-tidy-----------------------------===//
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#include "UseBoolLiteralsCheck.h"
11#include "clang/AST/ASTContext.h"
12#include "clang/ASTMatchers/ASTMatchFinder.h"
13#include "clang/Lex/Lexer.h"
14
15using namespace clang::ast_matchers;
16
17namespace clang {
18namespace tidy {
19namespace modernize {
20
21void UseBoolLiteralsCheck::registerMatchers(MatchFinder *Finder) {
22 if (!getLangOpts().CPlusPlus)
23 return;
24
25 Finder->addMatcher(
26 implicitCastExpr(
Piotr Padlewskie93a73f2016-05-31 15:26:56 +000027 has(ignoringParenImpCasts(integerLiteral().bind("literal"))),
Jakub Staronf7df7262016-05-11 11:33:16 +000028 hasImplicitDestinationType(qualType(booleanType())),
29 unless(isInTemplateInstantiation()),
30 anyOf(hasParent(explicitCastExpr().bind("cast")), anything())),
31 this);
Kirill Bobyrev75de8962016-08-08 17:11:56 +000032
33 Finder->addMatcher(
34 conditionalOperator(
35 hasParent(implicitCastExpr(
36 hasImplicitDestinationType(qualType(booleanType())),
37 unless(isInTemplateInstantiation()))),
38 eachOf(hasTrueExpression(
39 ignoringParenImpCasts(integerLiteral().bind("literal"))),
40 hasFalseExpression(
41 ignoringParenImpCasts(integerLiteral().bind("literal"))))),
42 this);
Jakub Staronf7df7262016-05-11 11:33:16 +000043}
44
45void UseBoolLiteralsCheck::check(const MatchFinder::MatchResult &Result) {
46 const auto *Literal = Result.Nodes.getNodeAs<IntegerLiteral>("literal");
47 const auto *Cast = Result.Nodes.getNodeAs<Expr>("cast");
48 bool LiteralBooleanValue = Literal->getValue().getBoolValue();
49
50 if (Literal->isInstantiationDependent())
51 return;
52
53 const Expr *Expression = Cast ? Cast : Literal;
54
55 auto Diag =
56 diag(Expression->getExprLoc(),
57 "converting integer literal to bool, use bool literal instead");
58
59 if (!Expression->getLocStart().isMacroID())
60 Diag << FixItHint::CreateReplacement(
61 Expression->getSourceRange(), LiteralBooleanValue ? "true" : "false");
62}
63
64} // namespace modernize
65} // namespace tidy
66} // namespace clang