clang-tools 22.0.0git
UseBoolLiteralsCheck.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
10#include "clang/AST/ASTContext.h"
11#include "clang/ASTMatchers/ASTMatchFinder.h"
12#include "clang/Lex/Lexer.h"
13
14using namespace clang::ast_matchers;
15
16namespace clang::tidy::modernize {
17
19 ClangTidyContext *Context)
20 : ClangTidyCheck(Name, Context),
21 IgnoreMacros(Options.get("IgnoreMacros", true)) {}
22
24 Options.store(Opts, "IgnoreMacros", IgnoreMacros);
25}
26
27void UseBoolLiteralsCheck::registerMatchers(MatchFinder *Finder) {
28 Finder->addMatcher(
29 traverse(TK_AsIs,
30 implicitCastExpr(
31 has(ignoringParenImpCasts(integerLiteral().bind("literal"))),
32 hasImplicitDestinationType(qualType(booleanType())),
33 unless(isInTemplateInstantiation()),
34 optionally(hasParent(explicitCastExpr().bind("cast"))))),
35 this);
36
37 Finder->addMatcher(
38 traverse(TK_AsIs,
39 conditionalOperator(
40 hasParent(implicitCastExpr(
41 hasImplicitDestinationType(qualType(booleanType())),
42 unless(isInTemplateInstantiation()))),
43 eachOf(hasTrueExpression(ignoringParenImpCasts(
44 integerLiteral().bind("literal"))),
45 hasFalseExpression(ignoringParenImpCasts(
46 integerLiteral().bind("literal")))))),
47 this);
48}
49
50void UseBoolLiteralsCheck::check(const MatchFinder::MatchResult &Result) {
51 const auto *Literal = Result.Nodes.getNodeAs<IntegerLiteral>("literal");
52 const auto *Cast = Result.Nodes.getNodeAs<Expr>("cast");
53 bool LiteralBooleanValue = Literal->getValue().getBoolValue();
54
55 if (Literal->isInstantiationDependent())
56 return;
57
58 const Expr *Expression = Cast ? Cast : Literal;
59
60 bool InMacro = Expression->getBeginLoc().isMacroID();
61
62 if (InMacro && IgnoreMacros)
63 return;
64
65 auto Diag =
66 diag(Expression->getExprLoc(),
67 "converting integer literal to bool, use bool literal instead");
68
69 if (!InMacro)
70 Diag << FixItHint::CreateReplacement(
71 Expression->getSourceRange(), LiteralBooleanValue ? "true" : "false");
72}
73
74} // namespace clang::tidy::modernize
Every ClangTidyCheck reports errors through a DiagnosticsEngine provided by this context.
void registerMatchers(ast_matchers::MatchFinder *Finder) override
void storeOptions(ClangTidyOptions::OptionMap &Opts) override
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
UseBoolLiteralsCheck(StringRef Name, ClangTidyContext *Context)
llvm::StringMap< ClangTidyValue > OptionMap