llvm/clang-tools-extra/clang-tidy/utils/DeclRefExprUtils.cpp

//===--- DeclRefExprUtils.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 "DeclRefExprUtils.h"
#include "Matchers.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/ExprCXX.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include <cassert>

namespace clang::tidy::utils::decl_ref_expr {

usingnamespace::clang::ast_matchers;
SmallPtrSet;

namespace {

template <typename S> bool isSetDifferenceEmpty(const S &S1, const S &S2) {}

// Extracts all Nodes keyed by ID from Matches and inserts them into Nodes.
template <typename Node>
void extractNodesByIdTo(ArrayRef<BoundNodes> Matches, StringRef ID,
                        SmallPtrSet<const Node *, 16> &Nodes) {}

// Returns true if both types refer to the same type,
// ignoring the const-qualifier.
bool isSameTypeIgnoringConst(QualType A, QualType B) {}

// Returns true if `D` and `O` have the same parameter types.
bool hasSameParameterTypes(const CXXMethodDecl &D, const CXXMethodDecl &O) {}

// If `D` has a const-qualified overload with otherwise identical
// ref-qualifiers and parameter types, returns that overload.
const CXXMethodDecl *findConstOverload(const CXXMethodDecl &D) {}

// Returns true if both types are pointers or reference to the same type,
// ignoring the const-qualifier.
bool pointsToSameTypeIgnoringConst(QualType A, QualType B) {}

// Return true if non-const member function `M` likely does not mutate `*this`.
//
// Note that if the member call selects a method/operator `f` that
// is not const-qualified, then we also consider that the object is
// not mutated if:
//  - (A) there is a const-qualified overload `cf` of `f` that has
//  the
//    same ref-qualifiers;
//  - (B) * `f` returns a value, or
//        * if `f` returns a `T&`, `cf` returns a `const T&` (up to
//          possible aliases such as `reference` and
//          `const_reference`), or
//        * if `f` returns a `T*`, `cf` returns a `const T*` (up to
//          possible aliases).
//  - (C) the result of the call is not mutated.
//
// The assumption that `cf` has the same semantics as `f`.
// For example:
//   - In `std::vector<T> v; const T t = v[...];`, we consider that
//     expression `v[...]` does not mutate `v` as
//    `T& std::vector<T>::operator[]` has a const overload
//     `const T& std::vector<T>::operator[] const`, and the
//     result expression of type `T&` is only used as a `const T&`;
//   - In `std::map<K, V> m; V v = m.at(...);`, we consider
//     `m.at(...)` to be an immutable access for the same reason.
// However:
//   - In `std::map<K, V> m; const V v = m[...];`, We consider that
//     `m[...]` mutates `m` as `V& std::map<K, V>::operator[]` does
//     not have a const overload.
//   - In `std::vector<T> v; T& t = v[...];`, we consider that
//     expression `v[...]` mutates `v` as the result is kept as a
//     mutable reference.
//
// This function checks (A) ad (B), but the caller should make sure that the
// object is not mutated through the return value.
bool isLikelyShallowConst(const CXXMethodDecl &M) {}

// A matcher that matches DeclRefExprs that are used in ways such that the
// underlying declaration is not modified.
// If the declaration is of pointer type, `Indirections` specifies the level
// of indirection of the object whose mutations we are tracking.
//
// For example, given:
//   ```
//   int i;
//   int* p;
//   p = &i;  // (A)
//   *p = 3;  // (B)
//   ```
//
//  `declRefExpr(to(varDecl(hasName("p"))), doesNotMutateObject(0))` matches
//  (B), but `declRefExpr(to(varDecl(hasName("p"))), doesNotMutateObject(1))`
//  matches (A).
//
AST_MATCHER_P(DeclRefExpr, doesNotMutateObject, int, Indirections) {}

} // namespace

SmallPtrSet<const DeclRefExpr *, 16>
constReferenceDeclRefExprs(const VarDecl &VarDecl, const Stmt &Stmt,
                           ASTContext &Context, int Indirections) {}

bool isOnlyUsedAsConst(const VarDecl &Var, const Stmt &Stmt,
                       ASTContext &Context, int Indirections) {}

SmallPtrSet<const DeclRefExpr *, 16>
allDeclRefExprs(const VarDecl &VarDecl, const Stmt &Stmt, ASTContext &Context) {}

SmallPtrSet<const DeclRefExpr *, 16>
allDeclRefExprs(const VarDecl &VarDecl, const Decl &Decl, ASTContext &Context) {}

bool isCopyConstructorArgument(const DeclRefExpr &DeclRef, const Decl &Decl,
                               ASTContext &Context) {}

bool isCopyAssignmentArgument(const DeclRefExpr &DeclRef, const Decl &Decl,
                              ASTContext &Context) {}

} // namespace clang::tidy::utils::decl_ref_expr