xref: /aosp_15_r20/external/clang/lib/Analysis/CFGStmtMap.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===--- CFGStmtMap.h - Map from Stmt* to CFGBlock* -----------*- C++ -*-===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li //  This file defines the CFGStmtMap class, which defines a mapping from
11*67e74705SXin Li //  Stmt* to CFGBlock*
12*67e74705SXin Li //
13*67e74705SXin Li //===----------------------------------------------------------------------===//
14*67e74705SXin Li 
15*67e74705SXin Li #include "llvm/ADT/DenseMap.h"
16*67e74705SXin Li #include "clang/AST/ParentMap.h"
17*67e74705SXin Li #include "clang/Analysis/CFG.h"
18*67e74705SXin Li #include "clang/Analysis/CFGStmtMap.h"
19*67e74705SXin Li 
20*67e74705SXin Li using namespace clang;
21*67e74705SXin Li 
22*67e74705SXin Li typedef llvm::DenseMap<const Stmt*, CFGBlock*> SMap;
AsMap(void * m)23*67e74705SXin Li static SMap *AsMap(void *m) { return (SMap*) m; }
24*67e74705SXin Li 
~CFGStmtMap()25*67e74705SXin Li CFGStmtMap::~CFGStmtMap() { delete AsMap(M); }
26*67e74705SXin Li 
getBlock(Stmt * S)27*67e74705SXin Li CFGBlock *CFGStmtMap::getBlock(Stmt *S) {
28*67e74705SXin Li   SMap *SM = AsMap(M);
29*67e74705SXin Li   Stmt *X = S;
30*67e74705SXin Li 
31*67e74705SXin Li   // If 'S' isn't in the map, walk the ParentMap to see if one of its ancestors
32*67e74705SXin Li   // is in the map.
33*67e74705SXin Li   while (X) {
34*67e74705SXin Li     SMap::iterator I = SM->find(X);
35*67e74705SXin Li     if (I != SM->end()) {
36*67e74705SXin Li       CFGBlock *B = I->second;
37*67e74705SXin Li       // Memoize this lookup.
38*67e74705SXin Li       if (X != S)
39*67e74705SXin Li         (*SM)[X] = B;
40*67e74705SXin Li       return B;
41*67e74705SXin Li     }
42*67e74705SXin Li 
43*67e74705SXin Li     X = PM->getParentIgnoreParens(X);
44*67e74705SXin Li   }
45*67e74705SXin Li 
46*67e74705SXin Li   return nullptr;
47*67e74705SXin Li }
48*67e74705SXin Li 
Accumulate(SMap & SM,CFGBlock * B)49*67e74705SXin Li static void Accumulate(SMap &SM, CFGBlock *B) {
50*67e74705SXin Li   // First walk the block-level expressions.
51*67e74705SXin Li   for (CFGBlock::iterator I = B->begin(), E = B->end(); I != E; ++I) {
52*67e74705SXin Li     const CFGElement &CE = *I;
53*67e74705SXin Li     Optional<CFGStmt> CS = CE.getAs<CFGStmt>();
54*67e74705SXin Li     if (!CS)
55*67e74705SXin Li       continue;
56*67e74705SXin Li 
57*67e74705SXin Li     CFGBlock *&Entry = SM[CS->getStmt()];
58*67e74705SXin Li     // If 'Entry' is already initialized (e.g., a terminator was already),
59*67e74705SXin Li     // skip.
60*67e74705SXin Li     if (Entry)
61*67e74705SXin Li       continue;
62*67e74705SXin Li 
63*67e74705SXin Li     Entry = B;
64*67e74705SXin Li 
65*67e74705SXin Li   }
66*67e74705SXin Li 
67*67e74705SXin Li   // Look at the label of the block.
68*67e74705SXin Li   if (Stmt *Label = B->getLabel())
69*67e74705SXin Li     SM[Label] = B;
70*67e74705SXin Li 
71*67e74705SXin Li   // Finally, look at the terminator.  If the terminator was already added
72*67e74705SXin Li   // because it is a block-level expression in another block, overwrite
73*67e74705SXin Li   // that mapping.
74*67e74705SXin Li   if (Stmt *Term = B->getTerminator())
75*67e74705SXin Li     SM[Term] = B;
76*67e74705SXin Li }
77*67e74705SXin Li 
Build(CFG * C,ParentMap * PM)78*67e74705SXin Li CFGStmtMap *CFGStmtMap::Build(CFG *C, ParentMap *PM) {
79*67e74705SXin Li   if (!C || !PM)
80*67e74705SXin Li     return nullptr;
81*67e74705SXin Li 
82*67e74705SXin Li   SMap *SM = new SMap();
83*67e74705SXin Li 
84*67e74705SXin Li   // Walk all blocks, accumulating the block-level expressions, labels,
85*67e74705SXin Li   // and terminators.
86*67e74705SXin Li   for (CFG::iterator I = C->begin(), E = C->end(); I != E; ++I)
87*67e74705SXin Li     Accumulate(*SM, *I);
88*67e74705SXin Li 
89*67e74705SXin Li   return new CFGStmtMap(PM, SM);
90*67e74705SXin Li }
91*67e74705SXin Li 
92