#include "RedundantExpressionCheck.h"
#include "../utils/Matchers.h"
#include "../utils/OptionsUtils.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ExprConcepts.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/FormatVariadic.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <optional>
#include <string>
#include <vector>
usingnamespaceclang::ast_matchers;
usingnamespaceclang::tidy::matchers;
namespace clang::tidy::misc {
namespace {
APSInt;
static constexpr llvm::StringLiteral KnownBannedMacroNames[] = …;
static bool incrementWithoutOverflow(const APSInt &Value, APSInt &Result) { … }
static bool areEquivalentNameSpecifier(const NestedNameSpecifier *Left,
const NestedNameSpecifier *Right) { … }
static bool areEquivalentExpr(const Expr *Left, const Expr *Right) { … }
static bool areEquivalentRanges(BinaryOperatorKind OpcodeLHS,
const APSInt &ValueLHS,
BinaryOperatorKind OpcodeRHS,
const APSInt &ValueRHS) { … }
static bool areExclusiveRanges(BinaryOperatorKind OpcodeLHS,
const APSInt &ValueLHS,
BinaryOperatorKind OpcodeRHS,
const APSInt &ValueRHS) { … }
static bool rangesFullyCoverDomain(BinaryOperatorKind OpcodeLHS,
const APSInt &ValueLHS,
BinaryOperatorKind OpcodeRHS,
const APSInt &ValueRHS) { … }
static bool rangeSubsumesRange(BinaryOperatorKind OpcodeLHS,
const APSInt &ValueLHS,
BinaryOperatorKind OpcodeRHS,
const APSInt &ValueRHS) { … }
static void transformSubToCanonicalAddExpr(BinaryOperatorKind &Opcode,
APSInt &Value) { … }
static OverloadedOperatorKind getOp(const BinaryOperator *Op) { … }
static OverloadedOperatorKind getOp(const CXXOperatorCallExpr *Op) { … }
static std::pair<const Expr *, const Expr *>
getOperands(const BinaryOperator *Op) { … }
static std::pair<const Expr *, const Expr *>
getOperands(const CXXOperatorCallExpr *Op) { … }
template <typename TExpr>
static const TExpr *checkOpKind(const Expr *TheExpr,
OverloadedOperatorKind OpKind) { … }
template <typename TExpr, unsigned N>
static bool collectOperands(const Expr *Part,
SmallVector<const Expr *, N> &AllOperands,
OverloadedOperatorKind OpKind) { … }
template <typename TExpr>
static bool hasSameOperatorParent(const Expr *TheExpr,
OverloadedOperatorKind OpKind,
ASTContext &Context) { … }
template <typename TExpr>
static bool
markDuplicateOperands(const TExpr *TheExpr,
ast_matchers::internal::BoundNodesTreeBuilder *Builder,
ASTContext &Context) { … }
AST_MATCHER(Expr, isIntegerConstantExpr) { … }
AST_MATCHER(BinaryOperator, operandsAreEquivalent) { … }
AST_MATCHER(BinaryOperator, nestedOperandsAreEquivalent) { … }
AST_MATCHER(ConditionalOperator, expressionsAreEquivalent) { … }
AST_MATCHER(CallExpr, parametersAreEquivalent) { … }
AST_MATCHER(CXXOperatorCallExpr, nestedParametersAreEquivalent) { … }
AST_MATCHER(BinaryOperator, binaryOperatorIsInMacro) { … }
AST_MATCHER(ConditionalOperator, conditionalOperatorIsInMacro) { … }
AST_MATCHER(Expr, isMacro) { … }
AST_MATCHER_P(Expr, expandedByMacro, ArrayRef<llvm::StringLiteral>, Names) { … }
static ast_matchers::internal::Matcher<Expr>
matchIntegerConstantExpr(StringRef Id) { … }
static bool retrieveIntegerConstantExpr(const MatchFinder::MatchResult &Result,
StringRef Id, APSInt &Value,
const Expr *&ConstExpr) { … }
static bool retrieveIntegerConstantExpr(const MatchFinder::MatchResult &Result,
StringRef Id, APSInt &Value) { … }
static ast_matchers::internal::Matcher<Expr> matchSymbolicExpr(StringRef Id) { … }
static bool retrieveSymbolicExpr(const MatchFinder::MatchResult &Result,
StringRef Id, const Expr *&SymExpr) { … }
static ast_matchers::internal::Matcher<Expr>
matchBinOpIntegerConstantExpr(StringRef Id) { … }
static bool
retrieveBinOpIntegerConstantExpr(const MatchFinder::MatchResult &Result,
StringRef Id, BinaryOperatorKind &Opcode,
const Expr *&Symbol, APSInt &Value) { … }
static ast_matchers::internal::Matcher<Expr>
matchRelationalIntegerConstantExpr(StringRef Id) { … }
static bool isNonConstReferenceType(QualType ParamType) { … }
static bool
canOverloadedOperatorArgsBeModified(const CXXOperatorCallExpr *OperatorCall,
bool CheckSecondParam) { … }
static bool retrieveRelationalIntegerConstantExpr(
const MatchFinder::MatchResult &Result, StringRef Id,
const Expr *&OperandExpr, BinaryOperatorKind &Opcode, const Expr *&Symbol,
APSInt &Value, const Expr *&ConstExpr) { … }
static bool areSidesBinaryConstExpressions(const BinaryOperator *&BinOp, const ASTContext *AstCtx) { … }
static bool retrieveConstExprFromBothSides(const BinaryOperator *&BinOp,
BinaryOperatorKind &MainOpcode,
BinaryOperatorKind &SideOpcode,
const Expr *&LhsConst,
const Expr *&RhsConst,
const ASTContext *AstCtx) { … }
static bool isSameRawIdentifierToken(const Token &T1, const Token &T2,
const SourceManager &SM) { … }
bool isTokAtEndOfExpr(SourceRange ExprSR, Token T, const SourceManager &SM) { … }
static bool areExprsFromDifferentMacros(const Expr *LhsExpr,
const Expr *RhsExpr,
const ASTContext *AstCtx) { … }
static bool areExprsMacroAndNonMacro(const Expr *&LhsExpr,
const Expr *&RhsExpr) { … }
}
void RedundantExpressionCheck::registerMatchers(MatchFinder *Finder) { … }
void RedundantExpressionCheck::checkArithmeticExpr(
const MatchFinder::MatchResult &Result) { … }
static bool exprEvaluatesToZero(BinaryOperatorKind Opcode, APSInt Value) { … }
static bool exprEvaluatesToBitwiseNegatedZero(BinaryOperatorKind Opcode,
APSInt Value) { … }
static bool exprEvaluatesToSymbolic(BinaryOperatorKind Opcode, APSInt Value) { … }
void RedundantExpressionCheck::checkBitwiseExpr(
const MatchFinder::MatchResult &Result) { … }
void RedundantExpressionCheck::checkRelationalExpr(
const MatchFinder::MatchResult &Result) { … }
void RedundantExpressionCheck::check(const MatchFinder::MatchResult &Result) { … }
}