зеркало из https://github.com/microsoft/clang-1.git
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42495 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
980e508ca7
Коммит
63f5887f31
50
AST/CFG.cpp
50
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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче