Files
clang-r547379/include/clang/Analysis/FlowSensitive/AdornedCFG.h
Ryan Prichard 6024e5c395 Update prebuilt Clang to r547379 (20.0.0).
clang 20.0.0 (based on r547379) from build 12806354.

Bug: http://b/379133546
Test: N/A
Change-Id: I2eb8938af55d809de674be63cb30cf27e801862b

Upstream-Commit: ad834e67b1105d15ef907f6255d4c96e8e733f57
2025-11-26 14:59:46 -05:00

112 lines
4.0 KiB
C++

//===-- AdornedCFG.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
//
//===----------------------------------------------------------------------===//
//
// This file defines an AdornedCFG class that is used by dataflow analyses that
// run over Control-Flow Graphs (CFGs).
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ADORNEDCFG_H
#define LLVM_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 <memory>
#include <utility>
namespace clang {
namespace dataflow {
namespace internal {
class StmtToBlockMap {
public:
StmtToBlockMap(const CFG &Cfg);
const CFGBlock *lookup(const Stmt &S) const {
return StmtToBlock.lookup(&ignoreCFGOmittedNodes(S));
}
private:
llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock;
};
} // namespace internal
/// Holds CFG with additional information derived from it that is needed to
/// perform dataflow analysis.
class AdornedCFG {
public:
/// Builds an `AdornedCFG` from a `FunctionDecl`.
/// `Func.doesThisDeclarationHaveABody()` must be true, and
/// `Func.isTemplated()` must be false.
static llvm::Expected<AdornedCFG> build(const FunctionDecl &Func);
/// Builds an `AdornedCFG` from an AST node. `D` is the function in which
/// `S` resides. `D.isTemplated()` must be false.
static llvm::Expected<AdornedCFG> build(const Decl &D, Stmt &S,
ASTContext &C);
/// Returns the `Decl` containing the statement used to construct the CFG, if
/// available.
const Decl &getDecl() const { return ContainingDecl; }
/// Returns the CFG that is stored in this context.
const CFG &getCFG() const { return *Cfg; }
/// Returns the basic block that contains `S`, or null if no basic block
/// containing `S` is found.
const CFGBlock *blockForStmt(const Stmt &S) const {
return StmtToBlock.lookup(S);
}
/// Returns whether `B` is reachable from the entry block.
bool isBlockReachable(const CFGBlock &B) const {
return BlockReachable[B.getBlockID()];
}
/// Returns whether `B` contains an expression that is consumed in a
/// different block than `B` (i.e. the parent of the expression is in a
/// different block).
/// This happens if there is control flow within a full-expression (triggered
/// by `&&`, `||`, or the conditional operator). Note that the operands of
/// these operators are not the only expressions that can be consumed in a
/// different block. For example, in the function call
/// `f(&i, cond() ? 1 : 0)`, `&i` is in a different block than the `CallExpr`.
bool containsExprConsumedInDifferentBlock(const CFGBlock &B) const {
return ContainsExprConsumedInDifferentBlock.contains(&B);
}
private:
AdornedCFG(
const Decl &D, std::unique_ptr<CFG> Cfg,
internal::StmtToBlockMap StmtToBlock, llvm::BitVector BlockReachable,
llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock)
: ContainingDecl(D), Cfg(std::move(Cfg)),
StmtToBlock(std::move(StmtToBlock)),
BlockReachable(std::move(BlockReachable)),
ContainsExprConsumedInDifferentBlock(
std::move(ContainsExprConsumedInDifferentBlock)) {}
/// The `Decl` containing the statement used to construct the CFG.
const Decl &ContainingDecl;
std::unique_ptr<CFG> Cfg;
internal::StmtToBlockMap StmtToBlock;
llvm::BitVector BlockReachable;
llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock;
};
} // namespace dataflow
} // namespace clang
#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ADORNEDCFG_H