//===--- 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 {

using namespace ::clang::ast_matchers;
using llvm::SmallPtrSet;

namespace {

template <typename S> bool isSetDifferenceEmpty(const S &S1, const S &S2) {
  for (auto E : S1)
    if (S2.count(E) == 0)
      return false;
  return true;
}

// 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) {
  for (const auto &Match : Matches)
    Nodes.insert(Match.getNodeAs<Node>(ID));
}

// 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) {
  // We walk up the parents of the DeclRefExpr recursively until we end up on a
  // parent that cannot modify the underlying object. There are a few kinds of
  // expressions:
  //  - Those that cannot be used to mutate the underlying object. We can stop
  //    recursion there.
  //  - Those that can be used to mutate the underlying object in analyzable
  //    ways (such as taking the address or accessing a subobject). We have to
  //    examine the parents.
  //  - Those that we don't know how to analyze. In that case we stop there and
  //    we assume that they can mutate the underlying expression.

  struct StackEntry {
    StackEntry(const Expr *E, int Indirections)
        : E(E), Indirections(Indirections) {}
    // The expression to analyze.
    const Expr *E;
    // The number of pointer indirections of the object being tracked (how
    // many times an address was taken).
    int Indirections;
  };

  llvm::SmallVector<StackEntry, 4> Stack;
  Stack.emplace_back(&Node, Indirections);
  ASTContext &Ctx = Finder->getASTContext();

  while (!Stack.empty()) {
    const StackEntry Entry = Stack.back();
    Stack.pop_back();

    // If the expression type is const-qualified at the appropriate indirection
    // level then we can not mutate the object.
    QualType Ty = Entry.E->getType().getCanonicalType();
    for (int I = 0; I < Entry.Indirections; ++I) {
      assert(Ty->isPointerType());
      Ty = Ty->getPointeeType().getCanonicalType();
    }
    if (Ty.isConstQualified())
      continue;

    // Otherwise we have to look at the parents to see how the expression is
    // used.
    const DynTypedNodeList Parents = Ctx.getParents(*Entry.E);
    // Note: most nodes have a single parents, but there exist nodes that have
    // several parents, such as `InitListExpr` that have semantic and syntactic
    // forms.
    for (const auto &Parent : Parents) {
      if (Parent.get<CompoundStmt>()) {
        // Unused block-scope statement.
        continue;
      }
      const Expr *const P = Parent.get<Expr>();
      if (P == nullptr) {
        // `Parent` is not an expr (e.g. a `VarDecl`).
        // The case of binding to a `const&` or `const*` variable is handled by
        // the fact that there is going to be a `NoOp` cast to const below the
        // `VarDecl`, so we're not even going to get there.
        // The case of copying into a value-typed variable is handled by the
        // rvalue cast.
        // This triggers only when binding to a mutable reference/ptr variable.
        // FIXME: When we take a mutable reference we could keep checking the
        // new variable for const usage only.
        return false;
      }
      // Cosmetic nodes.
      if (isa<ParenExpr>(P) || isa<MaterializeTemporaryExpr>(P)) {
        Stack.emplace_back(P, Entry.Indirections);
        continue;
      }
      if (const auto *const Cast = dyn_cast<CastExpr>(P)) {
        switch (Cast->getCastKind()) {
        // NoOp casts are used to add `const`. We'll check whether adding that
        // const prevents modification when we process the cast.
        case CK_NoOp:
        // These do nothing w.r.t. to mutability.
        case CK_BaseToDerived:
        case CK_DerivedToBase:
        case CK_UncheckedDerivedToBase:
        case CK_Dynamic:
        case CK_BaseToDerivedMemberPointer:
        case CK_DerivedToBaseMemberPointer:
          Stack.emplace_back(Cast, Entry.Indirections);
          continue;
        case CK_ToVoid:
        case CK_PointerToBoolean:
          // These do not mutate the underlying variable.
          continue;
        case CK_LValueToRValue: {
          // An rvalue is immutable.
          if (Entry.Indirections == 0)
            continue;
          Stack.emplace_back(Cast, Entry.Indirections);
          continue;
        }
        default:
          // Bail out on casts that we cannot analyze.
          return false;
        }
      }
      if (const auto *const Member = dyn_cast<MemberExpr>(P)) {
        if (const auto *const Method =
                dyn_cast<CXXMethodDecl>(Member->getMemberDecl())) {
          if (Method->isConst() || Method->isStatic()) {
            // The method call cannot mutate our variable.
            continue;
          }
          return false;
        }
        Stack.emplace_back(Member, 0);
        continue;
      }

      if (const auto *const Op = dyn_cast<UnaryOperator>(P)) {
        switch (Op->getOpcode()) {
        case UO_AddrOf:
          Stack.emplace_back(Op, Entry.Indirections + 1);
          continue;
        case UO_Deref:
          assert(Entry.Indirections > 0);
          Stack.emplace_back(Op, Entry.Indirections - 1);
          continue;
        default:
          // Bail out on unary operators that we cannot analyze.
          return false;
        }
      }

      // Assume any other expression can modify the underlying variable.
      return false;
    }
  }

  // No parent can modify the variable.
  return true;
}

} // namespace

SmallPtrSet<const DeclRefExpr *, 16>
constReferenceDeclRefExprs(const VarDecl &VarDecl, const Stmt &Stmt,
                           ASTContext &Context, int Indirections) {
  auto Matches = match(findAll(declRefExpr(to(varDecl(equalsNode(&VarDecl))),
                                           doesNotMutateObject(Indirections))
                                   .bind("declRef")),
                       Stmt, Context);
  SmallPtrSet<const DeclRefExpr *, 16> DeclRefs;
  extractNodesByIdTo(Matches, "declRef", DeclRefs);

  return DeclRefs;
}

bool isOnlyUsedAsConst(const VarDecl &Var, const Stmt &Stmt,
                       ASTContext &Context, int Indirections) {
  // Collect all DeclRefExprs to the loop variable and all CallExprs and
  // CXXConstructExprs where the loop variable is used as argument to a const
  // reference parameter.
  // If the difference is empty it is safe for the loop variable to be a const
  // reference.
  auto AllDeclRefs = allDeclRefExprs(Var, Stmt, Context);
  auto ConstReferenceDeclRefs =
      constReferenceDeclRefExprs(Var, Stmt, Context, Indirections);
  return isSetDifferenceEmpty(AllDeclRefs, ConstReferenceDeclRefs);
}

SmallPtrSet<const DeclRefExpr *, 16>
allDeclRefExprs(const VarDecl &VarDecl, const Stmt &Stmt, ASTContext &Context) {
  auto Matches = match(
      findAll(declRefExpr(to(varDecl(equalsNode(&VarDecl)))).bind("declRef")),
      Stmt, Context);
  SmallPtrSet<const DeclRefExpr *, 16> DeclRefs;
  extractNodesByIdTo(Matches, "declRef", DeclRefs);
  return DeclRefs;
}

SmallPtrSet<const DeclRefExpr *, 16>
allDeclRefExprs(const VarDecl &VarDecl, const Decl &Decl, ASTContext &Context) {
  auto Matches = match(
      decl(forEachDescendant(
          declRefExpr(to(varDecl(equalsNode(&VarDecl)))).bind("declRef"))),
      Decl, Context);
  SmallPtrSet<const DeclRefExpr *, 16> DeclRefs;
  extractNodesByIdTo(Matches, "declRef", DeclRefs);
  return DeclRefs;
}

bool isCopyConstructorArgument(const DeclRefExpr &DeclRef, const Decl &Decl,
                               ASTContext &Context) {
  auto UsedAsConstRefArg = forEachArgumentWithParam(
      declRefExpr(equalsNode(&DeclRef)),
      parmVarDecl(hasType(matchers::isReferenceToConst())));
  auto Matches = match(
      decl(hasDescendant(
          cxxConstructExpr(UsedAsConstRefArg, hasDeclaration(cxxConstructorDecl(
                                                  isCopyConstructor())))
              .bind("constructExpr"))),
      Decl, Context);
  return !Matches.empty();
}

bool isCopyAssignmentArgument(const DeclRefExpr &DeclRef, const Decl &Decl,
                              ASTContext &Context) {
  auto UsedAsConstRefArg = forEachArgumentWithParam(
      declRefExpr(equalsNode(&DeclRef)),
      parmVarDecl(hasType(matchers::isReferenceToConst())));
  auto Matches = match(
      decl(hasDescendant(
          cxxOperatorCallExpr(UsedAsConstRefArg, hasOverloadedOperatorName("="),
                              callee(cxxMethodDecl(isCopyAssignmentOperator())))
              .bind("operatorCallExpr"))),
      Decl, Context);
  return !Matches.empty();
}

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