1 //===--- CFGStmtMap.h - Map from Stmt* to CFGBlock* -----------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file defines the CFGStmtMap class, which defines a mapping from
12 //===----------------------------------------------------------------------===//
14 #include "llvm/ADT/DenseMap.h"
15 #include "clang/AST/ParentMap.h"
16 #include "clang/Analysis/CFG.h"
17 #include "clang/Analysis/CFGStmtMap.h"
20 using namespace clang
;
22 typedef llvm::DenseMap
<const Stmt
*, CFGBlock
*> SMap
;
23 static SMap
*AsMap(void *m
) { return (SMap
*) m
; }
25 CFGStmtMap::~CFGStmtMap() { delete AsMap(M
); }
27 CFGBlock
*CFGStmtMap::getBlock(Stmt
*S
) {
31 // If 'S' isn't in the map, walk the ParentMap to see if one of its ancestors
34 SMap::iterator I
= SM
->find(X
);
36 CFGBlock
*B
= I
->second
;
37 // Memoize this lookup.
43 X
= PM
->getParentIgnoreParens(X
);
49 static void Accumulate(SMap
&SM
, CFGBlock
*B
) {
50 // First walk the block-level expressions.
51 for (CFGBlock::iterator I
= B
->begin(), E
= B
->end(); I
!= E
; ++I
) {
52 const CFGElement
&CE
= *I
;
53 std::optional
<CFGStmt
> CS
= CE
.getAs
<CFGStmt
>();
57 CFGBlock
*&Entry
= SM
[CS
->getStmt()];
58 // If 'Entry' is already initialized (e.g., a terminator was already),
67 // Look at the label of the block.
68 if (Stmt
*Label
= B
->getLabel())
71 // Finally, look at the terminator. If the terminator was already added
72 // because it is a block-level expression in another block, overwrite
74 if (Stmt
*Term
= B
->getTerminatorStmt())
78 CFGStmtMap
*CFGStmtMap::Build(CFG
*C
, ParentMap
*PM
) {
82 SMap
*SM
= new SMap();
84 // Walk all blocks, accumulating the block-level expressions, labels,
86 for (CFG::iterator I
= C
->begin(), E
= C
->end(); I
!= E
; ++I
)
89 return new CFGStmtMap(PM
, SM
);