//===--- NoRecursionCheck.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 "NoRecursionCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Analysis/CallGraph.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/SCCIterator.h"

using namespace clang::ast_matchers;

namespace clang::tidy::misc {

namespace {

/// Much like SmallSet, with two differences:
/// 1. It can *only* be constructed from an ArrayRef<>. If the element count
///    is small, there is no copy and said storage *must* outlive us.
/// 2. it is immutable, the way it was constructed it will stay.
template <typename T, unsigned SmallSize> class ImmutableSmallSet {
  ArrayRef<T> Vector;
  llvm::DenseSet<T> Set;

  static_assert(SmallSize <= 32, "N should be small");

  bool isSmall() const { return Set.empty(); }

public:
  using size_type = size_t;

  ImmutableSmallSet() = delete;
  ImmutableSmallSet(const ImmutableSmallSet &) = delete;
  ImmutableSmallSet(ImmutableSmallSet &&) = delete;
  T &operator=(const ImmutableSmallSet &) = delete;
  T &operator=(ImmutableSmallSet &&) = delete;

  // WARNING: Storage *must* outlive us if we decide that the size is small.
  ImmutableSmallSet(ArrayRef<T> Storage) {
    // Is size small-enough to just keep using the existing storage?
    if (Storage.size() <= SmallSize) {
      Vector = Storage;
      return;
    }

    // We've decided that it isn't performant to keep using vector.
    // Let's migrate the data into Set.
    Set.reserve(Storage.size());
    Set.insert(Storage.begin(), Storage.end());
  }

  /// count - Return 1 if the element is in the set, 0 otherwise.
  size_type count(const T &V) const {
    if (isSmall()) {
      // Since the collection is small, just do a linear search.
      return llvm::is_contained(Vector, V) ? 1 : 0;
    }

    return Set.count(V);
  }
};

/// Much like SmallSetVector, but with one difference:
/// when the size is \p SmallSize or less, when checking whether an element is
/// already in the set or not, we perform linear search over the vector,
/// but if the size is larger than \p SmallSize, we look in set.
/// FIXME: upstream this into SetVector/SmallSetVector itself.
template <typename T, unsigned SmallSize> class SmartSmallSetVector {
public:
  using size_type = size_t;

private:
  SmallVector<T, SmallSize> Vector;
  llvm::DenseSet<T> Set;

  static_assert(SmallSize <= 32, "N should be small");

  // Are we still using Vector for uniqness tracking?
  bool isSmall() const { return Set.empty(); }

  // Will one more entry cause Vector to switch away from small-size storage?
  bool entiretyOfVectorSmallSizeIsOccupied() const {
    assert(isSmall() && Vector.size() <= SmallSize &&
           "Shouldn't ask if we have already [should have] migrated into Set.");
    return Vector.size() == SmallSize;
  }

  void populateSet() {
    assert(Set.empty() && "Should not have already utilized the Set.");
    // Magical growth factor prediction - to how many elements do we expect to
    // sanely grow after switching away from small-size storage?
    const size_t NewMaxElts = 4 * Vector.size();
    Vector.reserve(NewMaxElts);
    Set.reserve(NewMaxElts);
    Set.insert(Vector.begin(), Vector.end());
  }

  /// count - Return 1 if the element is in the set, 0 otherwise.
  size_type count(const T &V) const {
    if (isSmall()) {
      // Since the collection is small, just do a linear search.
      return llvm::is_contained(Vector, V) ? 1 : 0;
    }
    // Look-up in the Set.
    return Set.count(V);
  }

  bool setInsert(const T &V) {
    if (count(V) != 0)
      return false; // Already exists.
    // Does not exist, Can/need to record it.
    if (isSmall()) { // Are we still using Vector for uniqness tracking?
      // Will one more entry fit within small-sized Vector?
      if (!entiretyOfVectorSmallSizeIsOccupied())
        return true; // We'll insert into vector right afterwards anyway.
      // Time to switch to Set.
      populateSet();
    }
    // Set time!
    // Note that this must be after `populateSet()` might have been called.
    bool SetInsertionSucceeded = Set.insert(V).second;
    (void)SetInsertionSucceeded;
    assert(SetInsertionSucceeded && "We did check that no such value existed");
    return true;
  }

public:
  /// Insert a new element into the SmartSmallSetVector.
  /// \returns true if the element was inserted into the SmartSmallSetVector.
  bool insert(const T &X) {
    bool Result = setInsert(X);
    if (Result)
      Vector.push_back(X);
    return Result;
  }

  /// Clear the SmartSmallSetVector and return the underlying vector.
  decltype(Vector) takeVector() {
    Set.clear();
    return std::move(Vector);
  }
};

constexpr unsigned SmallCallStackSize = 16;
constexpr unsigned SmallSCCSize = 32;

using CallStackTy =
    llvm::SmallVector<CallGraphNode::CallRecord, SmallCallStackSize>;

// In given SCC, find *some* call stack that will be cyclic.
// This will only find *one* such stack, it might not be the smallest one,
// and there may be other loops.
CallStackTy pathfindSomeCycle(ArrayRef<CallGraphNode *> SCC) {
  // We'll need to be able to performantly look up whether some CallGraphNode
  // is in SCC or not, so cache all the SCC elements in a set.
  const ImmutableSmallSet<CallGraphNode *, SmallSCCSize> SCCElts(SCC);

  // Is node N part if the current SCC?
  auto NodeIsPartOfSCC = [&SCCElts](CallGraphNode *N) {
    return SCCElts.count(N) != 0;
  };

  // Track the call stack that will cause a cycle.
  SmartSmallSetVector<CallGraphNode::CallRecord, SmallCallStackSize>
      CallStackSet;

  // Arbitrarily take the first element of SCC as entry point.
  CallGraphNode::CallRecord EntryNode(SCC.front(), /*CallExpr=*/nullptr);
  // Continue recursing into subsequent callees that are part of this SCC,
  // and are thus known to be part of the call graph loop, until loop forms.
  CallGraphNode::CallRecord *Node = &EntryNode;
  while (true) {
    // Did we see this node before?
    if (!CallStackSet.insert(*Node))
      break; // Cycle completed! Note that didn't insert the node into stack!
    // Else, perform depth-first traversal: out of all callees, pick first one
    // that is part of this SCC. This is not guaranteed to yield shortest cycle.
    Node = llvm::find_if(Node->Callee->callees(), NodeIsPartOfSCC);
  }

  // Note that we failed to insert the last node, that completes the cycle.
  // But we really want to have it. So insert it manually into stack only.
  CallStackTy CallStack = CallStackSet.takeVector();
  CallStack.emplace_back(*Node);

  return CallStack;
}

} // namespace

void NoRecursionCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(translationUnitDecl().bind("TUDecl"), this);
}

void NoRecursionCheck::handleSCC(ArrayRef<CallGraphNode *> SCC) {
  assert(!SCC.empty() && "Empty SCC does not make sense.");

  // First of all, call out every strongly connected function.
  for (CallGraphNode *N : SCC) {
    FunctionDecl *D = N->getDefinition();
    diag(D->getLocation(), "function %0 is within a recursive call chain") << D;
  }

  // Now, SCC only tells us about strongly connected function declarations in
  // the call graph. It doesn't *really* tell us about the cycles they form.
  // And there may be more than one cycle in SCC.
  // So let's form a call stack that eventually exposes *some* cycle.
  const CallStackTy EventuallyCyclicCallStack = pathfindSomeCycle(SCC);
  assert(!EventuallyCyclicCallStack.empty() && "We should've found the cycle");

  // While last node of the call stack does cause a loop, due to the way we
  // pathfind the cycle, the loop does not necessarily begin at the first node
  // of the call stack, so drop front nodes of the call stack until it does.
  const auto CyclicCallStack =
      ArrayRef<CallGraphNode::CallRecord>(EventuallyCyclicCallStack)
          .drop_until([LastNode = EventuallyCyclicCallStack.back()](
                          CallGraphNode::CallRecord FrontNode) {
            return FrontNode == LastNode;
          });
  assert(CyclicCallStack.size() >= 2 && "Cycle requires at least 2 frames");

  // Which function we decided to be the entry point that lead to the recursion?
  FunctionDecl *CycleEntryFn = CyclicCallStack.front().Callee->getDefinition();
  // And now, for ease of understanding, let's print the call sequence that
  // forms the cycle in question.
  diag(CycleEntryFn->getLocation(),
       "example recursive call chain, starting from function %0",
       DiagnosticIDs::Note)
      << CycleEntryFn;
  for (int CurFrame = 1, NumFrames = CyclicCallStack.size();
       CurFrame != NumFrames; ++CurFrame) {
    CallGraphNode::CallRecord PrevNode = CyclicCallStack[CurFrame - 1];
    CallGraphNode::CallRecord CurrNode = CyclicCallStack[CurFrame];

    Decl *PrevDecl = PrevNode.Callee->getDecl();
    Decl *CurrDecl = CurrNode.Callee->getDecl();

    diag(CurrNode.CallExpr->getBeginLoc(),
         "Frame #%0: function %1 calls function %2 here:", DiagnosticIDs::Note)
        << CurFrame << cast<NamedDecl>(PrevDecl) << cast<NamedDecl>(CurrDecl);
  }

  diag(CyclicCallStack.back().CallExpr->getBeginLoc(),
       "... which was the starting point of the recursive call chain; there "
       "may be other cycles",
       DiagnosticIDs::Note);
}

void NoRecursionCheck::check(const MatchFinder::MatchResult &Result) {
  // Build call graph for the entire translation unit.
  const auto *TU = Result.Nodes.getNodeAs<TranslationUnitDecl>("TUDecl");
  CallGraph CG;
  CG.addToCallGraph(const_cast<TranslationUnitDecl *>(TU));

  // Look for cycles in call graph,
  // by looking for Strongly Connected Components (SCC's)
  for (llvm::scc_iterator<CallGraph *> SCCI = llvm::scc_begin(&CG),
                                       SCCE = llvm::scc_end(&CG);
       SCCI != SCCE; ++SCCI) {
    if (!SCCI.hasCycle()) // We only care about cycles, not standalone nodes.
      continue;
    handleSCC(*SCCI);
  }
}

} // namespace clang::tidy::misc
