llvm/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp

//===--- RedundantExpressionCheck.cpp - clang-tidy-------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#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) {}

// For a given expression 'x', returns whether the ranges covered by the
// relational operators are equivalent (i.e.  x <= 4 is equivalent to x < 5).
static bool areEquivalentRanges(BinaryOperatorKind OpcodeLHS,
                                const APSInt &ValueLHS,
                                BinaryOperatorKind OpcodeRHS,
                                const APSInt &ValueRHS) {}

// For a given expression 'x', returns whether the ranges covered by the
// relational operators are fully disjoint (i.e. x < 4  and  x > 7).
static bool areExclusiveRanges(BinaryOperatorKind OpcodeLHS,
                               const APSInt &ValueLHS,
                               BinaryOperatorKind OpcodeRHS,
                               const APSInt &ValueRHS) {}

// Returns whether the ranges covered by the union of both relational
// expressions cover the whole domain (i.e. x < 10  and  x > 0).
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) {}

// to use in the template below
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) {}

// returns true if a subexpression has two directly equivalent operands and
// is already handled by operands/parametersAreEquivalent
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) {}

// Returns a matcher for integer constant expressions.
static ast_matchers::internal::Matcher<Expr>
matchIntegerConstantExpr(StringRef Id) {}

// Retrieves the integer expression matched by 'matchIntegerConstantExpr' with
// name 'Id' and stores it into 'ConstExpr', the value of the expression is
// stored into `Value`.
static bool retrieveIntegerConstantExpr(const MatchFinder::MatchResult &Result,
                                        StringRef Id, APSInt &Value,
                                        const Expr *&ConstExpr) {}

// Overloaded `retrieveIntegerConstantExpr` for compatibility.
static bool retrieveIntegerConstantExpr(const MatchFinder::MatchResult &Result,
                                        StringRef Id, APSInt &Value) {}

// Returns a matcher for symbolic expressions (matches every expression except
// ingeter constant expressions).
static ast_matchers::internal::Matcher<Expr> matchSymbolicExpr(StringRef Id) {}

// Retrieves the expression matched by 'matchSymbolicExpr' with name 'Id' and
// stores it into 'SymExpr'.
static bool retrieveSymbolicExpr(const MatchFinder::MatchResult &Result,
                                 StringRef Id, const Expr *&SymExpr) {}

// Match a binary operator between a symbolic expression and an integer constant
// expression.
static ast_matchers::internal::Matcher<Expr>
matchBinOpIntegerConstantExpr(StringRef Id) {}

// Retrieves sub-expressions matched by 'matchBinOpIntegerConstantExpr' with
// name 'Id'.
static bool
retrieveBinOpIntegerConstantExpr(const MatchFinder::MatchResult &Result,
                                 StringRef Id, BinaryOperatorKind &Opcode,
                                 const Expr *&Symbol, APSInt &Value) {}

// Matches relational expressions: 'Expr <op> k' (i.e. x < 2, x != 3, 12 <= x).
static ast_matchers::internal::Matcher<Expr>
matchRelationalIntegerConstantExpr(StringRef Id) {}

// Checks whether a function param is non constant reference type, and may
// be modified in the function.
static bool isNonConstReferenceType(QualType ParamType) {}

// Checks whether the arguments of an overloaded operator can be modified in the
// function.
// For operators that take an instance and a constant as arguments, only the
// first argument (the instance) needs to be checked, since the constant itself
// is a temporary expression. Whether the second parameter is checked is
// controlled by the parameter `ParamsToCheckCount`.
static bool
canOverloadedOperatorArgsBeModified(const CXXOperatorCallExpr *OperatorCall,
                                    bool CheckSecondParam) {}

// Retrieves sub-expressions matched by 'matchRelationalIntegerConstantExpr'
// with name 'Id'.
static bool retrieveRelationalIntegerConstantExpr(
    const MatchFinder::MatchResult &Result, StringRef Id,
    const Expr *&OperandExpr, BinaryOperatorKind &Opcode, const Expr *&Symbol,
    APSInt &Value, const Expr *&ConstExpr) {}

// Checks for expressions like (X == 4) && (Y != 9)
static bool areSidesBinaryConstExpressions(const BinaryOperator *&BinOp, const ASTContext *AstCtx) {}

// Retrieves integer constant subexpressions from binary operator expressions
// that have two equivalent sides.
// E.g.: from (X == 5) && (X == 5) retrieves 5 and 5.
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) {}

/// Returns true if both LhsExpr and RhsExpr are
/// macro expressions and they are expanded
/// from different macros.
static bool areExprsFromDifferentMacros(const Expr *LhsExpr,
                                        const Expr *RhsExpr,
                                        const ASTContext *AstCtx) {}

static bool areExprsMacroAndNonMacro(const Expr *&LhsExpr,
                                     const Expr *&RhsExpr) {}
} // namespace

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) {}

} // namespace clang::tidy::misc