blob: f7728013b6f69acc7fa6d4f1f90cc41930ebcde2 [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(
27 has(integerLiteral().bind("literal")),
28 hasImplicitDestinationType(qualType(booleanType())),
29 unless(isInTemplateInstantiation()),
30 anyOf(hasParent(explicitCastExpr().bind("cast")), anything())),
31 this);
32}
33
34void UseBoolLiteralsCheck::check(const MatchFinder::MatchResult &Result) {
35 const auto *Literal = Result.Nodes.getNodeAs<IntegerLiteral>("literal");
36 const auto *Cast = Result.Nodes.getNodeAs<Expr>("cast");
37 bool LiteralBooleanValue = Literal->getValue().getBoolValue();
38
39 if (Literal->isInstantiationDependent())
40 return;
41
42 const Expr *Expression = Cast ? Cast : Literal;
43
44 auto Diag =
45 diag(Expression->getExprLoc(),
46 "converting integer literal to bool, use bool literal instead");
47
48 if (!Expression->getLocStart().isMacroID())
49 Diag << FixItHint::CreateReplacement(
50 Expression->getSourceRange(), LiteralBooleanValue ? "true" : "false");
51}
52
53} // namespace modernize
54} // namespace tidy
55} // namespace clang