1 //===--- 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 15 using namespace clang::ast_matchers; 16 17 namespace clang { 18 namespace tidy { 19 namespace modernize { 20 21 UseBoolLiteralsCheck::UseBoolLiteralsCheck(StringRef Name, 22 ClangTidyContext *Context) 23 : ClangTidyCheck(Name, Context), 24 IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)) {} 25 26 void UseBoolLiteralsCheck::registerMatchers(MatchFinder *Finder) { 27 if (!getLangOpts().CPlusPlus) 28 return; 29 30 Finder->addMatcher( 31 implicitCastExpr( 32 has(ignoringParenImpCasts(integerLiteral().bind("literal"))), 33 hasImplicitDestinationType(qualType(booleanType())), 34 unless(isInTemplateInstantiation()), 35 anyOf(hasParent(explicitCastExpr().bind("cast")), anything())), 36 this); 37 38 Finder->addMatcher( 39 conditionalOperator( 40 hasParent(implicitCastExpr( 41 hasImplicitDestinationType(qualType(booleanType())), 42 unless(isInTemplateInstantiation()))), 43 eachOf(hasTrueExpression( 44 ignoringParenImpCasts(integerLiteral().bind("literal"))), 45 hasFalseExpression( 46 ignoringParenImpCasts(integerLiteral().bind("literal"))))), 47 this); 48 } 49 50 void 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->getLocStart().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 modernize 75 } // namespace tidy 76 } // namespace clang 77