//===- AnalysisDeclContext.h - Context for path sensitivity -----*- 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
//
//===----------------------------------------------------------------------===//
//
/// \file
/// This file defines AnalysisDeclContext, a class that manages the analysis
/// context data for context sensitive and path sensitive analysis.
/// It also defines the helper classes to model entering, leaving or inlining
/// function calls.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_ANALYSIS_ANALYSISDECLCONTEXT_H
#define LLVM_CLANG_ANALYSIS_ANALYSISDECLCONTEXT_H

#include "clang/AST/DeclBase.h"
#include "clang/Analysis/BodyFarm.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/CodeInjector.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Support/Allocator.h"
#include <functional>
#include <memory>

namespace clang {

class AnalysisDeclContextManager;
class ASTContext;
class BlockDecl;
class BlockInvocationContext;
class CFGReverseBlockReachabilityAnalysis;
class CFGStmtMap;
class ImplicitParamDecl;
class LocationContext;
class LocationContextManager;
class ParentMap;
class StackFrameContext;
class Stmt;
class VarDecl;

/// The base class of a hierarchy of objects representing analyses tied
/// to AnalysisDeclContext.
class ManagedAnalysis {
protected:
  ManagedAnalysis() = default;

public:
  virtual ~ManagedAnalysis();

  // Subclasses need to implement:
  //
  //  static const void *getTag();
  //
  // Which returns a fixed pointer address to distinguish classes of
  // analysis objects.  They also need to implement:
  //
  //  static [Derived*] create(AnalysisDeclContext &Ctx);
  //
  // which creates the analysis object given an AnalysisDeclContext.
};

/// AnalysisDeclContext contains the context data for the function, method
/// or block under analysis.
class AnalysisDeclContext {
  // Backpoint to the AnalysisManager object that created this
  // AnalysisDeclContext. This may be null.
  AnalysisDeclContextManager *ADCMgr;

  const Decl *const D;

  std::unique_ptr<CFG> cfg, completeCFG;
  std::unique_ptr<CFGStmtMap> cfgStmtMap;

  CFG::BuildOptions cfgBuildOptions;
  CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs = nullptr;

  bool builtCFG = false;
  bool builtCompleteCFG = false;
  std::unique_ptr<ParentMap> PM;
  std::unique_ptr<CFGReverseBlockReachabilityAnalysis> CFA;

  llvm::BumpPtrAllocator A;

  llvm::DenseMap<const BlockDecl *, void *> *ReferencedBlockVars = nullptr;

  void *ManagedAnalyses = nullptr;

public:
  AnalysisDeclContext(AnalysisDeclContextManager *Mgr, const Decl *D);

  AnalysisDeclContext(AnalysisDeclContextManager *Mgr, const Decl *D,
                      const CFG::BuildOptions &BuildOptions);

  ~AnalysisDeclContext();

  ASTContext &getASTContext() const { return D->getASTContext(); }

  const Decl *getDecl() const { return D; }

  AnalysisDeclContextManager *getManager() const { return ADCMgr; }

  CFG::BuildOptions &getCFGBuildOptions() { return cfgBuildOptions; }

  const CFG::BuildOptions &getCFGBuildOptions() const {
    return cfgBuildOptions;
  }

  /// \returns Whether we are adding exception handling edges from CallExprs.
  /// If this is false, then try/catch statements and blocks reachable from them
  /// can appear to be dead in the CFG, analysis passes must cope with that.
  bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; }
  bool getUseUnoptimizedCFG() const {
    return !cfgBuildOptions.PruneTriviallyFalseEdges;
  }
  bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; }
  bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; }

  void registerForcedBlockExpression(const Stmt *stmt);
  const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt);

  /// \returns The body of the stored Decl \c D.
  Stmt *getBody() const;

  /// \copydoc AnalysisDeclContext::getBody()
  /// \param[out] IsAutosynthesized Specifies if the body is auto-generated
  ///             by the BodyFarm.
  Stmt *getBody(bool &IsAutosynthesized) const;

  /// \returns Whether the body of the Decl \c D is generated by the BodyFarm.
  ///
  /// \note The lookup is not free. We are going to call getBody behind
  /// the scenes.
  /// \sa getBody
  bool isBodyAutosynthesized() const;

  /// \returns Whether the body of the Decl \c D is generated by the BodyFarm
  /// from a model file.
  ///
  /// \note The lookup is not free. We are going to call getBody behind
  /// the scenes.
  /// \sa getBody
  bool isBodyAutosynthesizedFromModelFile() const;

  CFG *getCFG();

  CFGStmtMap *getCFGStmtMap();

  CFGReverseBlockReachabilityAnalysis *getCFGReachablityAnalysis();

  /// \returns A version of the CFG without any edges pruned.
  CFG *getUnoptimizedCFG();

  void dumpCFG(bool ShowColors);

  /// \returns Whether we have built a CFG for this analysis context.
  ///
  /// \note This doesn't correspond to whether or not a valid CFG exists, it
  /// corresponds to whether we *attempted* to build one.
  bool isCFGBuilt() const { return builtCFG; }

  ParentMap &getParentMap();

  using referenced_decls_iterator = const VarDecl *const *;

  llvm::iterator_range<referenced_decls_iterator>
  getReferencedBlockVars(const BlockDecl *BD);

  /// \returns The ImplicitParamDecl associated with \c self if this
  /// AnalysisDeclContext wraps an ObjCMethodDecl or nullptr otherwise.
  const ImplicitParamDecl *getSelfDecl() const;

  /// \copydoc LocationContextManager::getStackFrame()
  const StackFrameContext *getStackFrame(LocationContext const *ParentLC,
                                         const Stmt *S, const CFGBlock *Blk,
                                         unsigned BlockCount, unsigned Index);

  /// \copydoc LocationContextManager::getBlockInvocationContext()
  const BlockInvocationContext *
  getBlockInvocationContext(const LocationContext *ParentLC,
                            const BlockDecl *BD, const void *Data);

  /// \returns The specified analysis object, lazily running the analysis if
  /// necessary or nullptr if the analysis could not run.
  template <typename T> T *getAnalysis() {
    const void *tag = T::getTag();
    std::unique_ptr<ManagedAnalysis> &data = getAnalysisImpl(tag);
    if (!data)
      data = T::create(*this);
    return static_cast<T *>(data.get());
  }

  /// \returns Whether the root namespace of \p D is the \c std C++ namespace.
  static bool isInStdNamespace(const Decl *D);

  static std::string getFunctionName(const Decl *D);

private:
  std::unique_ptr<ManagedAnalysis> &getAnalysisImpl(const void *tag);

  LocationContextManager &getLocationContextManager();
};

/// It wraps the AnalysisDeclContext to represent both the call stack with
/// the help of StackFrameContext and inside the function calls the
/// BlockInvocationContext. It is needed for context sensitive analysis to
/// model entering, leaving or inlining function calls.
class LocationContext : public llvm::FoldingSetNode {
public:
  enum ContextKind { StackFrame, Block };

private:
  ContextKind Kind;

  // AnalysisDeclContext can't be const since some methods may modify its
  // member.
  AnalysisDeclContext *Ctx;

  const LocationContext *Parent;
  int64_t ID;

protected:
  LocationContext(ContextKind k, AnalysisDeclContext *ctx,
                  const LocationContext *parent, int64_t ID)
      : Kind(k), Ctx(ctx), Parent(parent), ID(ID) {
    assert(ctx);
  }

public:
  virtual ~LocationContext();

  ContextKind getKind() const { return Kind; }

  int64_t getID() const { return ID; }

  LLVM_ATTRIBUTE_RETURNS_NONNULL
  AnalysisDeclContext *getAnalysisDeclContext() const { return Ctx; }

  /// It might return null.
  const LocationContext *getParent() const { return Parent; }

  bool isParentOf(const LocationContext *LC) const;

  const Decl *getDecl() const { return Ctx->getDecl(); }

  CFG *getCFG() const { return Ctx->getCFG(); }

  template <typename T> T *getAnalysis() const { return Ctx->getAnalysis<T>(); }

  const ParentMap &getParentMap() const { return Ctx->getParentMap(); }

  /// \copydoc AnalysisDeclContext::getSelfDecl()
  const ImplicitParamDecl *getSelfDecl() const { return Ctx->getSelfDecl(); }

  const StackFrameContext *getStackFrame() const;

  /// \returns Whether the current LocationContext has no caller context.
  virtual bool inTopFrame() const;

  virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;

  /// Prints out the call stack.
  ///
  /// \param Out The out stream.
  LLVM_DUMP_METHOD void dumpStack(raw_ostream &Out) const;

  /// Prints out the call stack in \c json format.
  ///
  /// \param Out   The out stream.
  /// \param NL    The newline.
  /// \param Space The space count for indentation.
  /// \param IsDot Whether the output format is \c dot.
  /// \param printMoreInfoPerContext
  /// A callback to print more information for each context, for example:
  /// \code
  ///   [&](const LocationContext *LC) { LC->dump(); }
  /// \endcode
  void printJson(
      raw_ostream &Out, const char *NL = "\n", unsigned int Space = 0,
      bool IsDot = false,
      std::function<void(const LocationContext *)> printMoreInfoPerContext =
          [](const LocationContext *) {}) const;

  LLVM_DUMP_METHOD void dump() const;

  static void ProfileCommon(llvm::FoldingSetNodeID &ID, ContextKind ck,
                            AnalysisDeclContext *ctx,
                            const LocationContext *parent, const void *data);
};

/// It represents a stack frame of the call stack (based on CallEvent).
class StackFrameContext : public LocationContext {
  friend class LocationContextManager;

  // The call site where this stack frame is established.
  const Stmt *CallSite;

  // The parent block of the call site.
  const CFGBlock *Block;

  // The number of times the 'Block' has been visited.
  // It allows discriminating between stack frames of the same call that is
  // called multiple times in a loop.
  const unsigned BlockCount;

  // The index of the call site in the CFGBlock.
  const unsigned Index;

  StackFrameContext(AnalysisDeclContext *ADC, const LocationContext *ParentLC,
                    const Stmt *S, const CFGBlock *Block, unsigned BlockCount,
                    unsigned Index, int64_t ID)
      : LocationContext(StackFrame, ADC, ParentLC, ID), CallSite(S),
        Block(Block), BlockCount(BlockCount), Index(Index) {}

public:
  ~StackFrameContext() override = default;

  const Stmt *getCallSite() const { return CallSite; }

  const CFGBlock *getCallSiteBlock() const { return Block; }

  bool inTopFrame() const override { return getParent() == nullptr; }

  unsigned getIndex() const { return Index; }

  CFGElement getCallSiteCFGElement() const { return (*Block)[Index]; }

  void Profile(llvm::FoldingSetNodeID &ID) override;

  static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ADC,
                      const LocationContext *ParentLC, const Stmt *S,
                      const CFGBlock *Block, unsigned BlockCount,
                      unsigned Index) {
    ProfileCommon(ID, StackFrame, ADC, ParentLC, S);
    ID.AddPointer(Block);
    ID.AddInteger(BlockCount);
    ID.AddInteger(Index);
  }

  static bool classof(const LocationContext *LC) {
    return LC->getKind() == StackFrame;
  }
};

/// It represents a block invocation (based on BlockCall).
class BlockInvocationContext : public LocationContext {
  friend class LocationContextManager;

  const BlockDecl *BD;

  // FIXME: Come up with a more type-safe way to model context-sensitivity.
  const void *Data;

  BlockInvocationContext(AnalysisDeclContext *ADC,
                         const LocationContext *ParentLC, const BlockDecl *BD,
                         const void *Data, int64_t ID)
      : LocationContext(Block, ADC, ParentLC, ID), BD(BD), Data(Data) {}

public:
  ~BlockInvocationContext() override = default;

  const BlockDecl *getBlockDecl() const { return BD; }

  const void *getData() const { return Data; }

  void Profile(llvm::FoldingSetNodeID &ID) override;

  static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ADC,
                      const LocationContext *ParentLC, const BlockDecl *BD,
                      const void *Data) {
    ProfileCommon(ID, Block, ADC, ParentLC, BD);
    ID.AddPointer(Data);
  }

  static bool classof(const LocationContext *LC) {
    return LC->getKind() == Block;
  }
};

class LocationContextManager {
  llvm::FoldingSet<LocationContext> Contexts;

  // ID used for generating a new location context.
  int64_t NewID = 0;

public:
  ~LocationContextManager();

  /// Obtain a context of the call stack using its parent context.
  ///
  /// \param ADC        The AnalysisDeclContext.
  /// \param ParentLC   The parent context of this newly created context.
  /// \param S          The call.
  /// \param Block      The basic block.
  /// \param BlockCount The current count of entering into \p Blk.
  /// \param Index      The index of \p Blk.
  /// \returns The context for \p D with parent context \p ParentLC.
  const StackFrameContext *getStackFrame(AnalysisDeclContext *ADC,
                                         const LocationContext *ParentLC,
                                         const Stmt *S, const CFGBlock *Block,
                                         unsigned BlockCount, unsigned Index);

  /// Obtain a context of the block invocation using its parent context.
  ///
  /// \param ADC      The AnalysisDeclContext.
  /// \param ParentLC The parent context of this newly created context.
  /// \param BD       The BlockDecl.
  /// \param Data     The raw data to store as part of the context.
  const BlockInvocationContext *
  getBlockInvocationContext(AnalysisDeclContext *ADC,
                            const LocationContext *ParentLC,
                            const BlockDecl *BD, const void *Data);

  /// Discard all previously created LocationContext objects.
  void clear();
};

class AnalysisDeclContextManager {
  using ContextMap =
      llvm::DenseMap<const Decl *, std::unique_ptr<AnalysisDeclContext>>;

  ContextMap Contexts;
  LocationContextManager LocCtxMgr;
  CFG::BuildOptions cfgBuildOptions;

  // Pointer to an interface that can provide function bodies for
  // declarations from external source.
  std::unique_ptr<CodeInjector> Injector;

  // A factory for creating and caching implementations for common
  // methods during the analysis.
  BodyFarm FunctionBodyFarm;

  // Flag to indicate whether or not bodies should be synthesized
  // for well-known functions.
  bool SynthesizeBodies;

public:
  AnalysisDeclContextManager(
      ASTContext &ASTCtx, bool useUnoptimizedCFG = false,
      bool addImplicitDtors = false, bool addInitializers = false,
      bool addTemporaryDtors = false, bool addLifetime = false,
      bool addLoopExit = false, bool addScopes = false,
      bool synthesizeBodies = false, bool addStaticInitBranches = false,
      bool addCXXNewAllocator = true, bool addRichCXXConstructors = true,
      bool markElidedCXXConstructors = true, bool addVirtualBaseBranches = true,
      CodeInjector *injector = nullptr);

  AnalysisDeclContext *getContext(const Decl *D);

  bool getUseUnoptimizedCFG() const {
    return !cfgBuildOptions.PruneTriviallyFalseEdges;
  }

  CFG::BuildOptions &getCFGBuildOptions() { return cfgBuildOptions; }

  /// \returns Whether faux bodies should be synthesized for known functions.
  bool synthesizeBodies() const { return SynthesizeBodies; }

  /// Obtain the beginning context of the analysis.
  ///
  /// \returns The top level stack frame for \p D.
  const StackFrameContext *getStackFrame(const Decl *D) {
    return LocCtxMgr.getStackFrame(getContext(D), nullptr, nullptr, nullptr, 0,
                                   0);
  }

  /// \copydoc LocationContextManager::getStackFrame()
  const StackFrameContext *getStackFrame(AnalysisDeclContext *ADC,
                                         const LocationContext *Parent,
                                         const Stmt *S, const CFGBlock *Block,
                                         unsigned BlockCount, unsigned Index) {
    return LocCtxMgr.getStackFrame(ADC, Parent, S, Block, BlockCount, Index);
  }

  BodyFarm &getBodyFarm();

  /// Discard all previously created AnalysisDeclContexts.
  void clear();

private:
  friend class AnalysisDeclContext;

  LocationContextManager &getLocationContextManager() { return LocCtxMgr; }
};

} // namespace clang

#endif // LLVM_CLANG_ANALYSIS_ANALYSISDECLCONTEXT_H
