//===- ThreadSafetyCommon.h -------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Parts of thread safety analysis that are not specific to thread safety
// itself have been factored into classes here, where they can be potentially
// used by other analyses.  Currently these include:
//
// * Generalize clang CFG visitors.
// * Conversion of the clang CFG to SSA form.
// * Translation of clang Exprs to TIL SExprs
//
// UNDER CONSTRUCTION.  USE AT YOUR OWN RISK.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H

#include "clang/AST/Decl.h"
#include "clang/Analysis/Analyses/PostOrderCFGView.h"
#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
#include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
#include "clang/Analysis/Analyses/ThreadSafetyUtil.h"
#include "clang/Analysis/AnalysisDeclContext.h"
#include "clang/Analysis/CFG.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Casting.h"
#include <sstream>
#include <string>
#include <utility>
#include <vector>

namespace clang {

class AbstractConditionalOperator;
class ArraySubscriptExpr;
class BinaryOperator;
class CallExpr;
class CastExpr;
class CXXDestructorDecl;
class CXXMemberCallExpr;
class CXXOperatorCallExpr;
class CXXThisExpr;
class DeclRefExpr;
class DeclStmt;
class Expr;
class MemberExpr;
class Stmt;
class UnaryOperator;

namespace threadSafety {

// Various helper functions on til::SExpr
namespace sx {

inline bool equals(const til::SExpr *E1, const til::SExpr *E2) {
  return til::EqualsComparator::compareExprs(E1, E2);
}

inline bool matches(const til::SExpr *E1, const til::SExpr *E2) {
  // We treat a top-level wildcard as the "univsersal" lock.
  // It matches everything for the purpose of checking locks, but not
  // for unlocking them.
  if (isa<til::Wildcard>(E1))
    return isa<til::Wildcard>(E2);
  if (isa<til::Wildcard>(E2))
    return isa<til::Wildcard>(E1);

  return til::MatchComparator::compareExprs(E1, E2);
}

inline bool partiallyMatches(const til::SExpr *E1, const til::SExpr *E2) {
  const auto *PE1 = dyn_cast_or_null<til::Project>(E1);
  if (!PE1)
    return false;
  const auto *PE2 = dyn_cast_or_null<til::Project>(E2);
  if (!PE2)
    return false;
  return PE1->clangDecl() == PE2->clangDecl();
}

inline std::string toString(const til::SExpr *E) {
  std::stringstream ss;
  til::StdPrinter::print(E, ss);
  return ss.str();
}

}  // namespace sx

// This class defines the interface of a clang CFG Visitor.
// CFGWalker will invoke the following methods.
// Note that methods are not virtual; the visitor is templatized.
class CFGVisitor {
  // Enter the CFG for Decl D, and perform any initial setup operations.
  void enterCFG(CFG *Cfg, const NamedDecl *D, const CFGBlock *First) {}

  // Enter a CFGBlock.
  void enterCFGBlock(const CFGBlock *B) {}

  // Returns true if this visitor implements handlePredecessor
  bool visitPredecessors() { return true; }

  // Process a predecessor edge.
  void handlePredecessor(const CFGBlock *Pred) {}

  // Process a successor back edge to a previously visited block.
  void handlePredecessorBackEdge(const CFGBlock *Pred) {}

  // Called just before processing statements.
  void enterCFGBlockBody(const CFGBlock *B) {}

  // Process an ordinary statement.
  void handleStatement(const Stmt *S) {}

  // Process a destructor call
  void handleDestructorCall(const VarDecl *VD, const CXXDestructorDecl *DD) {}

  // Called after all statements have been handled.
  void exitCFGBlockBody(const CFGBlock *B) {}

  // Return true
  bool visitSuccessors() { return true; }

  // Process a successor edge.
  void handleSuccessor(const CFGBlock *Succ) {}

  // Process a successor back edge to a previously visited block.
  void handleSuccessorBackEdge(const CFGBlock *Succ) {}

  // Leave a CFGBlock.
  void exitCFGBlock(const CFGBlock *B) {}

  // Leave the CFG, and perform any final cleanup operations.
  void exitCFG(const CFGBlock *Last) {}
};

// Walks the clang CFG, and invokes methods on a given CFGVisitor.
class CFGWalker {
public:
  CFGWalker() = default;

  // Initialize the CFGWalker.  This setup only needs to be done once, even
  // if there are multiple passes over the CFG.
  bool init(AnalysisDeclContext &AC) {
    ACtx = &AC;
    CFGraph = AC.getCFG();
    if (!CFGraph)
      return false;

    // Ignore anonymous functions.
    if (!isa_and_nonnull<NamedDecl>(AC.getDecl()))
      return false;

    SortedGraph = AC.getAnalysis<PostOrderCFGView>();
    if (!SortedGraph)
      return false;

    return true;
  }

  // Traverse the CFG, calling methods on V as appropriate.
  template <class Visitor>
  void walk(Visitor &V) {
    PostOrderCFGView::CFGBlockSet VisitedBlocks(CFGraph);

    V.enterCFG(CFGraph, getDecl(), &CFGraph->getEntry());

    for (const auto *CurrBlock : *SortedGraph) {
      VisitedBlocks.insert(CurrBlock);

      V.enterCFGBlock(CurrBlock);

      // Process predecessors, handling back edges last
      if (V.visitPredecessors()) {
        SmallVector<CFGBlock*, 4> BackEdges;
        // Process successors
        for (CFGBlock::const_pred_iterator SI = CurrBlock->pred_begin(),
                                           SE = CurrBlock->pred_end();
             SI != SE; ++SI) {
          if (*SI == nullptr)
            continue;

          if (!VisitedBlocks.alreadySet(*SI)) {
            BackEdges.push_back(*SI);
            continue;
          }
          V.handlePredecessor(*SI);
        }

        for (auto *Blk : BackEdges)
          V.handlePredecessorBackEdge(Blk);
      }

      V.enterCFGBlockBody(CurrBlock);

      // Process statements
      for (const auto &BI : *CurrBlock) {
        switch (BI.getKind()) {
        case CFGElement::Statement:
          V.handleStatement(BI.castAs<CFGStmt>().getStmt());
          break;

        case CFGElement::AutomaticObjectDtor: {
          CFGAutomaticObjDtor AD = BI.castAs<CFGAutomaticObjDtor>();
          auto *DD = const_cast<CXXDestructorDecl *>(
              AD.getDestructorDecl(ACtx->getASTContext()));
          auto *VD = const_cast<VarDecl *>(AD.getVarDecl());
          V.handleDestructorCall(VD, DD);
          break;
        }
        default:
          break;
        }
      }

      V.exitCFGBlockBody(CurrBlock);

      // Process successors, handling back edges first.
      if (V.visitSuccessors()) {
        SmallVector<CFGBlock*, 8> ForwardEdges;

        // Process successors
        for (CFGBlock::const_succ_iterator SI = CurrBlock->succ_begin(),
                                           SE = CurrBlock->succ_end();
             SI != SE; ++SI) {
          if (*SI == nullptr)
            continue;

          if (!VisitedBlocks.alreadySet(*SI)) {
            ForwardEdges.push_back(*SI);
            continue;
          }
          V.handleSuccessorBackEdge(*SI);
        }

        for (auto *Blk : ForwardEdges)
          V.handleSuccessor(Blk);
      }

      V.exitCFGBlock(CurrBlock);
    }
    V.exitCFG(&CFGraph->getExit());
  }

  const CFG *getGraph() const { return CFGraph; }
  CFG *getGraph() { return CFGraph; }

  const NamedDecl *getDecl() const {
    return dyn_cast<NamedDecl>(ACtx->getDecl());
  }

  const PostOrderCFGView *getSortedGraph() const { return SortedGraph; }

private:
  CFG *CFGraph = nullptr;
  AnalysisDeclContext *ACtx = nullptr;
  PostOrderCFGView *SortedGraph = nullptr;
};

// TODO: move this back into ThreadSafety.cpp
// This is specific to thread safety.  It is here because
// translateAttrExpr needs it, but that should be moved too.
class CapabilityExpr {
private:
  /// The capability expression and whether it's negated.
  llvm::PointerIntPair<const til::SExpr *, 1, bool> CapExpr;

  /// The kind of capability as specified by @ref CapabilityAttr::getName.
  StringRef CapKind;

public:
  CapabilityExpr() : CapExpr(nullptr, false) {}
  CapabilityExpr(const til::SExpr *E, StringRef Kind, bool Neg)
      : CapExpr(E, Neg), CapKind(Kind) {}

  // Don't allow implicitly-constructed StringRefs since we'll capture them.
  template <typename T> CapabilityExpr(const til::SExpr *, T, bool) = delete;

  const til::SExpr *sexpr() const { return CapExpr.getPointer(); }
  StringRef getKind() const { return CapKind; }
  bool negative() const { return CapExpr.getInt(); }

  CapabilityExpr operator!() const {
    return CapabilityExpr(CapExpr.getPointer(), CapKind, !CapExpr.getInt());
  }

  bool equals(const CapabilityExpr &other) const {
    return (negative() == other.negative()) &&
           sx::equals(sexpr(), other.sexpr());
  }

  bool matches(const CapabilityExpr &other) const {
    return (negative() == other.negative()) &&
           sx::matches(sexpr(), other.sexpr());
  }

  bool matchesUniv(const CapabilityExpr &CapE) const {
    return isUniversal() || matches(CapE);
  }

  bool partiallyMatches(const CapabilityExpr &other) const {
    return (negative() == other.negative()) &&
           sx::partiallyMatches(sexpr(), other.sexpr());
  }

  const ValueDecl* valueDecl() const {
    if (negative() || sexpr() == nullptr)
      return nullptr;
    if (const auto *P = dyn_cast<til::Project>(sexpr()))
      return P->clangDecl();
    if (const auto *P = dyn_cast<til::LiteralPtr>(sexpr()))
      return P->clangDecl();
    return nullptr;
  }

  std::string toString() const {
    if (negative())
      return "!" + sx::toString(sexpr());
    return sx::toString(sexpr());
  }

  bool shouldIgnore() const { return sexpr() == nullptr; }

  bool isInvalid() const { return sexpr() && isa<til::Undefined>(sexpr()); }

  bool isUniversal() const { return sexpr() && isa<til::Wildcard>(sexpr()); }
};

// Translate clang::Expr to til::SExpr.
class SExprBuilder {
public:
  /// Encapsulates the lexical context of a function call.  The lexical
  /// context includes the arguments to the call, including the implicit object
  /// argument.  When an attribute containing a mutex expression is attached to
  /// a method, the expression may refer to formal parameters of the method.
  /// Actual arguments must be substituted for formal parameters to derive
  /// the appropriate mutex expression in the lexical context where the function
  /// is called.  PrevCtx holds the context in which the arguments themselves
  /// should be evaluated; multiple calling contexts can be chained together
  /// by the lock_returned attribute.
  struct CallingContext {
    // The previous context; or 0 if none.
    CallingContext  *Prev;

    // The decl to which the attr is attached.
    const NamedDecl *AttrDecl;

    // Implicit object argument -- e.g. 'this'
    llvm::PointerUnion<const Expr *, til::SExpr *> SelfArg = nullptr;

    // Number of funArgs
    unsigned NumArgs = 0;

    // Function arguments
    llvm::PointerUnion<const Expr *const *, til::SExpr *> FunArgs = nullptr;

    // is Self referred to with -> or .?
    bool SelfArrow = false;

    CallingContext(CallingContext *P, const NamedDecl *D = nullptr)
        : Prev(P), AttrDecl(D) {}
  };

  SExprBuilder(til::MemRegionRef A) : Arena(A) {
    // FIXME: we don't always have a self-variable.
    SelfVar = new (Arena) til::Variable(nullptr);
    SelfVar->setKind(til::Variable::VK_SFun);
  }

  // Translate a clang expression in an attribute to a til::SExpr.
  // Constructs the context from D, DeclExp, and SelfDecl.
  CapabilityExpr translateAttrExpr(const Expr *AttrExp, const NamedDecl *D,
                                   const Expr *DeclExp,
                                   til::SExpr *Self = nullptr);

  CapabilityExpr translateAttrExpr(const Expr *AttrExp, CallingContext *Ctx);

  // Translate a variable reference.
  til::LiteralPtr *createVariable(const VarDecl *VD);

  // Create placeholder for this: we don't know the VarDecl on construction yet.
  std::pair<til::LiteralPtr *, StringRef>
  createThisPlaceholder(const Expr *Exp);

  // Translate a clang statement or expression to a TIL expression.
  // Also performs substitution of variables; Ctx provides the context.
  // Dispatches on the type of S.
  til::SExpr *translate(const Stmt *S, CallingContext *Ctx);
  til::SCFG  *buildCFG(CFGWalker &Walker);

  til::SExpr *lookupStmt(const Stmt *S);

  til::BasicBlock *lookupBlock(const CFGBlock *B) {
    return BlockMap[B->getBlockID()];
  }

  const til::SCFG *getCFG() const { return Scfg; }
  til::SCFG *getCFG() { return Scfg; }

private:
  // We implement the CFGVisitor API
  friend class CFGWalker;

  til::SExpr *translateDeclRefExpr(const DeclRefExpr *DRE,
                                   CallingContext *Ctx) ;
  til::SExpr *translateCXXThisExpr(const CXXThisExpr *TE, CallingContext *Ctx);
  til::SExpr *translateMemberExpr(const MemberExpr *ME, CallingContext *Ctx);
  til::SExpr *translateObjCIVarRefExpr(const ObjCIvarRefExpr *IVRE,
                                       CallingContext *Ctx);
  til::SExpr *translateCallExpr(const CallExpr *CE, CallingContext *Ctx,
                                const Expr *SelfE = nullptr);
  til::SExpr *translateCXXMemberCallExpr(const CXXMemberCallExpr *ME,
                                         CallingContext *Ctx);
  til::SExpr *translateCXXOperatorCallExpr(const CXXOperatorCallExpr *OCE,
                                           CallingContext *Ctx);
  til::SExpr *translateUnaryOperator(const UnaryOperator *UO,
                                     CallingContext *Ctx);
  til::SExpr *translateBinOp(til::TIL_BinaryOpcode Op,
                             const BinaryOperator *BO,
                             CallingContext *Ctx, bool Reverse = false);
  til::SExpr *translateBinAssign(til::TIL_BinaryOpcode Op,
                                 const BinaryOperator *BO,
                                 CallingContext *Ctx, bool Assign = false);
  til::SExpr *translateBinaryOperator(const BinaryOperator *BO,
                                      CallingContext *Ctx);
  til::SExpr *translateCastExpr(const CastExpr *CE, CallingContext *Ctx);
  til::SExpr *translateArraySubscriptExpr(const ArraySubscriptExpr *E,
                                          CallingContext *Ctx);
  til::SExpr *translateAbstractConditionalOperator(
      const AbstractConditionalOperator *C, CallingContext *Ctx);

  til::SExpr *translateDeclStmt(const DeclStmt *S, CallingContext *Ctx);

  // Map from statements in the clang CFG to SExprs in the til::SCFG.
  using StatementMap = llvm::DenseMap<const Stmt *, til::SExpr *>;

  // Map from clang local variables to indices in a LVarDefinitionMap.
  using LVarIndexMap = llvm::DenseMap<const ValueDecl *, unsigned>;

  // Map from local variable indices to SSA variables (or constants).
  using NameVarPair = std::pair<const ValueDecl *, til::SExpr *>;
  using LVarDefinitionMap = CopyOnWriteVector<NameVarPair>;

  struct BlockInfo {
    LVarDefinitionMap ExitMap;
    bool HasBackEdges = false;

    // Successors yet to be processed
    unsigned UnprocessedSuccessors = 0;

    // Predecessors already processed
    unsigned ProcessedPredecessors = 0;

    BlockInfo() = default;
    BlockInfo(BlockInfo &&) = default;
    BlockInfo &operator=(BlockInfo &&) = default;
  };

  void enterCFG(CFG *Cfg, const NamedDecl *D, const CFGBlock *First);
  void enterCFGBlock(const CFGBlock *B);
  bool visitPredecessors() { return true; }
  void handlePredecessor(const CFGBlock *Pred);
  void handlePredecessorBackEdge(const CFGBlock *Pred);
  void enterCFGBlockBody(const CFGBlock *B);
  void handleStatement(const Stmt *S);
  void handleDestructorCall(const VarDecl *VD, const CXXDestructorDecl *DD);
  void exitCFGBlockBody(const CFGBlock *B);
  bool visitSuccessors() { return true; }
  void handleSuccessor(const CFGBlock *Succ);
  void handleSuccessorBackEdge(const CFGBlock *Succ);
  void exitCFGBlock(const CFGBlock *B);
  void exitCFG(const CFGBlock *Last);

  void insertStmt(const Stmt *S, til::SExpr *E) {
    SMap.insert(std::make_pair(S, E));
  }

  til::SExpr *addStatement(til::SExpr *E, const Stmt *S,
                           const ValueDecl *VD = nullptr);
  til::SExpr *lookupVarDecl(const ValueDecl *VD);
  til::SExpr *addVarDecl(const ValueDecl *VD, til::SExpr *E);
  til::SExpr *updateVarDecl(const ValueDecl *VD, til::SExpr *E);

  void makePhiNodeVar(unsigned i, unsigned NPreds, til::SExpr *E);
  void mergeEntryMap(LVarDefinitionMap Map);
  void mergeEntryMapBackEdge();
  void mergePhiNodesBackEdge(const CFGBlock *Blk);

private:
  // Set to true when parsing capability expressions, which get translated
  // inaccurately in order to hack around smart pointers etc.
  static const bool CapabilityExprMode = true;

  til::MemRegionRef Arena;

  // Variable to use for 'this'.  May be null.
  til::Variable *SelfVar = nullptr;

  til::SCFG *Scfg = nullptr;

  // Map from Stmt to TIL Variables
  StatementMap SMap;

  // Indices of clang local vars.
  LVarIndexMap LVarIdxMap;

  // Map from clang to til BBs.
  std::vector<til::BasicBlock *> BlockMap;

  // Extra information per BB. Indexed by clang BlockID.
  std::vector<BlockInfo> BBInfo;

  LVarDefinitionMap CurrentLVarMap;
  std::vector<til::Phi *> CurrentArguments;
  std::vector<til::SExpr *> CurrentInstructions;
  std::vector<til::Phi *> IncompleteArgs;
  til::BasicBlock *CurrentBB = nullptr;
  BlockInfo *CurrentBlockInfo = nullptr;
};

#ifndef NDEBUG
// Dump an SCFG to llvm::errs().
void printSCFG(CFGWalker &Walker);
#endif // NDEBUG

} // namespace threadSafety
} // namespace clang

#endif // LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
