Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:24

0001 //===-- AdornedCFG.h ------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  This file defines an AdornedCFG class that is used by dataflow analyses that
0010 //  run over Control-Flow Graphs (CFGs).
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ADORNEDCFG_H
0015 #define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ADORNEDCFG_H
0016 
0017 #include "clang/AST/ASTContext.h"
0018 #include "clang/AST/Decl.h"
0019 #include "clang/AST/Stmt.h"
0020 #include "clang/Analysis/CFG.h"
0021 #include "clang/Analysis/FlowSensitive/ASTOps.h"
0022 #include "llvm/ADT/BitVector.h"
0023 #include "llvm/ADT/DenseMap.h"
0024 #include "llvm/Support/Error.h"
0025 #include <memory>
0026 #include <utility>
0027 
0028 namespace clang {
0029 namespace dataflow {
0030 
0031 namespace internal {
0032 class StmtToBlockMap {
0033 public:
0034   StmtToBlockMap(const CFG &Cfg);
0035 
0036   const CFGBlock *lookup(const Stmt &S) const {
0037     return StmtToBlock.lookup(&ignoreCFGOmittedNodes(S));
0038   }
0039 
0040 private:
0041   llvm::DenseMap<const Stmt *, const CFGBlock *> StmtToBlock;
0042 };
0043 } // namespace internal
0044 
0045 /// Holds CFG with additional information derived from it that is needed to
0046 /// perform dataflow analysis.
0047 class AdornedCFG {
0048 public:
0049   /// Builds an `AdornedCFG` from a `FunctionDecl`.
0050   /// `Func.doesThisDeclarationHaveABody()` must be true, and
0051   /// `Func.isTemplated()` must be false.
0052   static llvm::Expected<AdornedCFG> build(const FunctionDecl &Func);
0053 
0054   /// Builds an `AdornedCFG` from an AST node. `D` is the function in which
0055   /// `S` resides. `D.isTemplated()` must be false.
0056   static llvm::Expected<AdornedCFG> build(const Decl &D, Stmt &S,
0057                                           ASTContext &C);
0058 
0059   /// Returns the `Decl` containing the statement used to construct the CFG, if
0060   /// available.
0061   const Decl &getDecl() const { return ContainingDecl; }
0062 
0063   /// Returns the CFG that is stored in this context.
0064   const CFG &getCFG() const { return *Cfg; }
0065 
0066   /// Returns the basic block that contains `S`, or null if no basic block
0067   /// containing `S` is found.
0068   const CFGBlock *blockForStmt(const Stmt &S) const {
0069     return StmtToBlock.lookup(S);
0070   }
0071 
0072   /// Returns whether `B` is reachable from the entry block.
0073   bool isBlockReachable(const CFGBlock &B) const {
0074     return BlockReachable[B.getBlockID()];
0075   }
0076 
0077   /// Returns whether `B` contains an expression that is consumed in a
0078   /// different block than `B` (i.e. the parent of the expression is in a
0079   /// different block).
0080   /// This happens if there is control flow within a full-expression (triggered
0081   /// by `&&`, `||`, or the conditional operator). Note that the operands of
0082   /// these operators are not the only expressions that can be consumed in a
0083   /// different block. For example, in the function call
0084   /// `f(&i, cond() ? 1 : 0)`, `&i` is in a different block than the `CallExpr`.
0085   bool containsExprConsumedInDifferentBlock(const CFGBlock &B) const {
0086     return ContainsExprConsumedInDifferentBlock.contains(&B);
0087   }
0088 
0089 private:
0090   AdornedCFG(
0091       const Decl &D, std::unique_ptr<CFG> Cfg,
0092       internal::StmtToBlockMap StmtToBlock, llvm::BitVector BlockReachable,
0093       llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock)
0094       : ContainingDecl(D), Cfg(std::move(Cfg)),
0095         StmtToBlock(std::move(StmtToBlock)),
0096         BlockReachable(std::move(BlockReachable)),
0097         ContainsExprConsumedInDifferentBlock(
0098             std::move(ContainsExprConsumedInDifferentBlock)) {}
0099 
0100   /// The `Decl` containing the statement used to construct the CFG.
0101   const Decl &ContainingDecl;
0102   std::unique_ptr<CFG> Cfg;
0103   internal::StmtToBlockMap StmtToBlock;
0104   llvm::BitVector BlockReachable;
0105   llvm::DenseSet<const CFGBlock *> ContainsExprConsumedInDifferentBlock;
0106 };
0107 
0108 } // namespace dataflow
0109 } // namespace clang
0110 
0111 #endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_ADORNEDCFG_H