//===- AdornedCFG.cpp ---------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
//  This file defines an `AdornedCFG` class that is used by dataflow analyses
//  that run over Control-Flow Graphs (CFGs).
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/FlowSensitive/AdornedCFG.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Stmt.h"
#include "clang/Analysis/CFG.h"
#include "clang/Analysis/FlowSensitive/ASTOps.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/Support/Error.h"
#include <utility>

namespace clang {
namespace dataflow {

/// Returns a map from statements to basic blocks that contain them.
static llvm::DenseMap<const Stmt *, const CFGBlock *>
buildStmtToBasicBlockMap(const CFG &Cfg) {
  llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock;
  for (const CFGBlock *Block : Cfg) {
    if (Block == nullptr)
      continue;

    for (const CFGElement &Element : *Block) {
      auto Stmt = Element.getAs<CFGStmt>();
      if (!Stmt)
        continue;

      StmtToBlock[Stmt->getStmt()] = Block;
    }
  }
  // Some terminator conditions don't appear as a `CFGElement` anywhere else -
  // for example, this is true if the terminator condition is a `&&` or `||`
  // operator.
  // We associate these conditions with the block the terminator appears in,
  // but only if the condition has not already appeared as a regular
  // `CFGElement`. (The `insert()` below does nothing if the key already exists
  // in the map.)
  for (const CFGBlock *Block : Cfg) {
    if (Block != nullptr)
      if (const Stmt *TerminatorCond = Block->getTerminatorCondition())
        StmtToBlock.insert({TerminatorCond, Block});
  }
  // Terminator statements typically don't appear as a `CFGElement` anywhere
  // else, so we want to associate them with the block that they terminate.
  // However, there are some important special cases:
  // -  The conditional operator is a type of terminator, but it also appears
  //    as a regular `CFGElement`, and we want to associate it with the block
  //    in which it appears as a `CFGElement`.
  // -  The `&&` and `||` operators are types of terminators, but like the
  //    conditional operator, they can appear as a regular `CFGElement` or
  //    as a terminator condition (see above).
  // We process terminators last to make sure that we only associate them with
  // the block they terminate if they haven't previously occurred as a regular
  // `CFGElement` or as a terminator condition.
  for (const CFGBlock *Block : Cfg) {
    if (Block != nullptr)
      if (const Stmt *TerminatorStmt = Block->getTerminatorStmt())
        StmtToBlock.insert({TerminatorStmt, Block});
  }
  return StmtToBlock;
}

static llvm::BitVector findReachableBlocks(const CFG &Cfg) {
  llvm::BitVector BlockReachable(Cfg.getNumBlockIDs(), false);

  llvm::SmallVector<const CFGBlock *> BlocksToVisit;
  BlocksToVisit.push_back(&Cfg.getEntry());
  while (!BlocksToVisit.empty()) {
    const CFGBlock *Block = BlocksToVisit.back();
    BlocksToVisit.pop_back();

    if (BlockReachable[Block->getBlockID()])
      continue;

    BlockReachable[Block->getBlockID()] = true;

    for (const CFGBlock *Succ : Block->succs())
      if (Succ)
        BlocksToVisit.push_back(Succ);
  }

  return BlockReachable;
}

static llvm::DenseSet<const CFGBlock *>
buildContainsExprConsumedInDifferentBlock(
    const CFG &Cfg, const internal::StmtToBlockMap &StmtToBlock) {
  llvm::DenseSet<const CFGBlock *> Result;

  auto CheckChildExprs = [&Result, &StmtToBlock](const Stmt *S,
                                                 const CFGBlock *Block) {
    for (const Stmt *Child : S->children()) {
      if (!isa_and_nonnull<Expr>(Child))
        continue;
      const CFGBlock *ChildBlock = StmtToBlock.lookup(*Child);
      if (ChildBlock != Block)
        Result.insert(ChildBlock);
    }
  };

  for (const CFGBlock *Block : Cfg) {
    if (Block == nullptr)
      continue;

    for (const CFGElement &Element : *Block)
      if (auto S = Element.getAs<CFGStmt>())
        CheckChildExprs(S->getStmt(), Block);

    if (const Stmt *TerminatorCond = Block->getTerminatorCondition())
      CheckChildExprs(TerminatorCond, Block);
  }

  return Result;
}

namespace internal {

StmtToBlockMap::StmtToBlockMap(const CFG &Cfg)
    : StmtToBlock(buildStmtToBasicBlockMap(Cfg)) {}

} // namespace internal

llvm::Expected<AdornedCFG> AdornedCFG::build(const FunctionDecl &Func) {
  if (!Func.doesThisDeclarationHaveABody())
    return llvm::createStringError(
        std::make_error_code(std::errc::invalid_argument),
        "Cannot analyze function without a body");

  return build(Func, *Func.getBody(), Func.getASTContext());
}

llvm::Expected<AdornedCFG> AdornedCFG::build(const Decl &D, Stmt &S,
                                             ASTContext &C) {
  if (D.isTemplated())
    return llvm::createStringError(
        std::make_error_code(std::errc::invalid_argument),
        "Cannot analyze templated declarations");

  // The shape of certain elements of the AST can vary depending on the
  // language. We currently only support C++.
  if (!C.getLangOpts().CPlusPlus || C.getLangOpts().ObjC)
    return llvm::createStringError(
        std::make_error_code(std::errc::invalid_argument),
        "Can only analyze C++");

  CFG::BuildOptions Options;
  Options.PruneTriviallyFalseEdges = true;
  Options.AddImplicitDtors = true;
  Options.AddTemporaryDtors = true;
  Options.AddInitializers = true;
  Options.AddCXXDefaultInitExprInCtors = true;
  Options.AddLifetime = true;

  // Ensure that all sub-expressions in basic blocks are evaluated.
  Options.setAllAlwaysAdd();

  auto Cfg = CFG::buildCFG(&D, &S, &C, Options);
  if (Cfg == nullptr)
    return llvm::createStringError(
        std::make_error_code(std::errc::invalid_argument),
        "CFG::buildCFG failed");

  internal::StmtToBlockMap StmtToBlock(*Cfg);

  llvm::BitVector BlockReachable = findReachableBlocks(*Cfg);

  llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock =
      buildContainsExprConsumedInDifferentBlock(*Cfg, StmtToBlock);

  return AdornedCFG(D, std::move(Cfg), std::move(StmtToBlock),
                    std::move(BlockReachable),
                    std::move(ContainsExprConsumedInDifferentBlock));
}

} // namespace dataflow
} // namespace clang
