75 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "UseBoolLiteralsCheck.h"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 18UseBoolLiteralsCheck::UseBoolLiteralsCheck(StringRef Name,19 ClangTidyContext *Context)20 : ClangTidyCheck(Name, Context),21 IgnoreMacros(Options.get("IgnoreMacros", true)) {}22 23void UseBoolLiteralsCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {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 const bool LiteralBooleanValue = Literal->getValue().getBoolValue();54 55 if (Literal->isInstantiationDependent())56 return;57 58 const Expr *Expression = Cast ? Cast : Literal;59 60 const 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::modernize75