clang API Documentation
00001 //===--- CFGStmtMap.h - Map from Stmt* to CFGBlock* -----------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines the CFGStmtMap class, which defines a mapping from 00011 // Stmt* to CFGBlock* 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "llvm/ADT/DenseMap.h" 00016 #include "clang/AST/ParentMap.h" 00017 #include "clang/Analysis/CFG.h" 00018 #include "clang/Analysis/CFGStmtMap.h" 00019 00020 using namespace clang; 00021 00022 typedef llvm::DenseMap<const Stmt*, CFGBlock*> SMap; 00023 static SMap *AsMap(void *m) { return (SMap*) m; } 00024 00025 CFGStmtMap::~CFGStmtMap() { delete AsMap(M); } 00026 00027 CFGBlock *CFGStmtMap::getBlock(Stmt *S) { 00028 SMap *SM = AsMap(M); 00029 Stmt *X = S; 00030 00031 // If 'S' isn't in the map, walk the ParentMap to see if one of its ancestors 00032 // is in the map. 00033 while (X) { 00034 SMap::iterator I = SM->find(X); 00035 if (I != SM->end()) { 00036 CFGBlock *B = I->second; 00037 // Memoize this lookup. 00038 if (X != S) 00039 (*SM)[X] = B; 00040 return B; 00041 } 00042 00043 X = PM->getParentIgnoreParens(X); 00044 } 00045 00046 return nullptr; 00047 } 00048 00049 static void Accumulate(SMap &SM, CFGBlock *B) { 00050 // First walk the block-level expressions. 00051 for (CFGBlock::iterator I = B->begin(), E = B->end(); I != E; ++I) { 00052 const CFGElement &CE = *I; 00053 Optional<CFGStmt> CS = CE.getAs<CFGStmt>(); 00054 if (!CS) 00055 continue; 00056 00057 CFGBlock *&Entry = SM[CS->getStmt()]; 00058 // If 'Entry' is already initialized (e.g., a terminator was already), 00059 // skip. 00060 if (Entry) 00061 continue; 00062 00063 Entry = B; 00064 00065 } 00066 00067 // Look at the label of the block. 00068 if (Stmt *Label = B->getLabel()) 00069 SM[Label] = B; 00070 00071 // Finally, look at the terminator. If the terminator was already added 00072 // because it is a block-level expression in another block, overwrite 00073 // that mapping. 00074 if (Stmt *Term = B->getTerminator()) 00075 SM[Term] = B; 00076 } 00077 00078 CFGStmtMap *CFGStmtMap::Build(CFG *C, ParentMap *PM) { 00079 if (!C || !PM) 00080 return nullptr; 00081 00082 SMap *SM = new SMap(); 00083 00084 // Walk all blocks, accumulating the block-level expressions, labels, 00085 // and terminators. 00086 for (CFG::iterator I = C->begin(), E = C->end(); I != E; ++I) 00087 Accumulate(*SM, *I); 00088 00089 return new CFGStmtMap(PM, SM); 00090 } 00091