diff options
| author | Ted Kremenek <kremenek@apple.com> | 2007-10-01 19:33:33 +0000 |
|---|---|---|
| committer | Ted Kremenek <kremenek@apple.com> | 2007-10-01 19:33:33 +0000 |
| commit | f2d4372ba950cc85e41f624bd569b575e81fc11b (patch) | |
| tree | 965701ace88478a610d1cc64512834de24003d5a | |
| parent | 67391b8a54bbc836d9b09465006bd5abf278a3da (diff) | |
| download | bcm5719-llvm-f2d4372ba950cc85e41f624bd569b575e81fc11b.tar.gz bcm5719-llvm-f2d4372ba950cc85e41f624bd569b575e81fc11b.zip | |
CFG objects now internally store a (lazily created) map from block-level
expressions to IDs. This is used by various dataflow analyses, but is
also useful for anyone querying a CFG to determine where an expression
is evaluated.
llvm-svn: 42495
| -rw-r--r-- | clang/AST/CFG.cpp | 50 | ||||
| -rw-r--r-- | clang/include/clang/AST/CFG.h | 25 |
2 files changed, 71 insertions, 4 deletions
diff --git a/clang/AST/CFG.cpp b/clang/AST/CFG.cpp index acda71ef42c..3755fa6369c 100644 --- a/clang/AST/CFG.cpp +++ b/clang/AST/CFG.cpp @@ -315,7 +315,7 @@ CFGBlock* CFGBuilder::WalkAST(Stmt* S, bool AlwaysAddStmt = false) { Block->appendStmt(B); addStmt(B->getRHS()); return addStmt(B->getLHS()); - } + } // Fall through to the default case. } @@ -929,7 +929,55 @@ CFG* CFG::buildCFG(Stmt* Statement) { /// reverseStmts - Reverses the orders of statements within a CFGBlock. void CFGBlock::reverseStmts() { std::reverse(Stmts.begin(),Stmts.end()); } +//===----------------------------------------------------------------------===// +// CFG: Queries for BlkExprs. +//===----------------------------------------------------------------------===// + +namespace { + typedef llvm::DenseMap<const Expr*,unsigned> BlkExprMapTy; +} + +static BlkExprMapTy* PopulateBlkExprMap(CFG& cfg) { + BlkExprMapTy* M = new BlkExprMapTy(); + + for (CFG::iterator I=cfg.begin(), E=cfg.end(); I != E; ++I) + for (CFGBlock::iterator BI=I->begin(), EI=I->end(); BI != EI; ++BI) + if (const Expr* E = dyn_cast<Expr>(*BI)) + (*M)[E] = M->size(); + + return M; +} + +bool CFG::isBlkExpr(const Stmt* S) { + if (const Expr* E = dyn_cast<Expr>(S)) return getBlkExprNum(E); + else return true; // Statements are by default "block-level expressions." +} + +CFG::BlkExprNumTy CFG::getBlkExprNum(const Expr* E) { + if (!BlkExprMap) { BlkExprMap = (void*) PopulateBlkExprMap(*this); } + + BlkExprMapTy* M = reinterpret_cast<BlkExprMapTy*>(BlkExprMap); + BlkExprMapTy::iterator I = M->find(E); + + if (I == M->end()) return CFG::BlkExprNumTy(); + else return CFG::BlkExprNumTy(I->second); +} +unsigned CFG::getNumBlkExprs() { + if (const BlkExprMapTy* M = reinterpret_cast<const BlkExprMapTy*>(BlkExprMap)) + return M->size(); + else { + // We assume callers interested in the number of BlkExprs will want + // the map constructed if it doesn't already exist. + BlkExprMap = (void*) PopulateBlkExprMap(*this); + return reinterpret_cast<BlkExprMapTy*>(BlkExprMap)->size(); + } +} + +CFG::~CFG() { + delete reinterpret_cast<const BlkExprMapTy*>(BlkExprMap); +} + //===----------------------------------------------------------------------===// // CFG pretty printing //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/AST/CFG.h b/clang/include/clang/AST/CFG.h index e50c3cc906a..113ee876137 100644 --- a/clang/include/clang/AST/CFG.h +++ b/clang/include/clang/AST/CFG.h @@ -23,6 +23,7 @@ namespace clang { class Stmt; + class Expr; class CFG; class PrinterHelper; @@ -263,6 +264,19 @@ public: // CFG Introspection. //===--------------------------------------------------------------------===// + struct BlkExprNumTy { + const signed Idx; + explicit BlkExprNumTy(signed idx) : Idx(idx) {} + explicit BlkExprNumTy() : Idx(-1) {} + operator bool() const { return Idx >= 0; } + operator unsigned() const { assert(Idx >=0); return (unsigned) Idx; } + }; + + bool isBlkExpr(const Stmt* S); + bool isBlkExpr(const Expr* E) { return getBlkExprNum(E); } + BlkExprNumTy getBlkExprNum(const Expr* E); + unsigned getNumBlkExprs(); + unsigned getNumBlockIDs() const { return NumBlockIDs; } //===--------------------------------------------------------------------===// @@ -277,8 +291,10 @@ public: // Internal: constructors and data. //===--------------------------------------------------------------------===// - CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0) {}; - ~CFG() {}; + CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0), + BlkExprMap(NULL) {}; + + ~CFG(); private: CFGBlock* Entry; @@ -286,7 +302,10 @@ private: CFGBlock* IndirectGotoBlock; // Special block to contain collective dispatch // for indirect gotos CFGBlockListTy Blocks; - unsigned NumBlockIDs; + unsigned NumBlockIDs; + // opaque pointer to prevent inclusion of DenseMap.h. Map from expressions + // to integers to record block-level expressions. + void* BlkExprMap; }; } // end namespace clang |

