Add hooks into the CFG builder to force that specific expressions are always CFGElements.

llvm-svn: 135479
This commit is contained in:
Ted Kremenek 2011-07-19 14:18:43 +00:00
parent bf904773bb
commit 8b46c00b5f
3 changed files with 32 additions and 9 deletions

View File

@ -81,6 +81,15 @@ public:
idx::TranslationUnit *getTranslationUnit() const { return TU; }
/// Return the build options used to construct the CFG.
CFG::BuildOptions &getCFGBuildOptions() {
return cfgBuildOptions;
}
const CFG::BuildOptions &getCFGBuildOptions() const {
return cfgBuildOptions;
}
/// getAddEHEdges - Return true iff we are adding exceptional edges from
/// callExprs. If this is false, then try/catch statements and blocks
/// reachable from them can appear to be dead in the CFG, analysis passes must

View File

@ -21,6 +21,8 @@
#include "llvm/Support/Casting.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/BitVector.h"
#include "clang/AST/Stmt.h"
#include "clang/Analysis/Support/BumpVector.h"
#include "clang/Basic/SourceLocation.h"
#include <cassert>
@ -533,6 +535,7 @@ public:
//===--------------------------------------------------------------------===//
class BuildOptions {
llvm::BitVector alwaysAddMask;
public:
typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs;
ForcedBlkExprs **forcedBlkExprs;
@ -541,12 +544,21 @@ public:
bool AddEHEdges:1;
bool AddInitializers:1;
bool AddImplicitDtors:1;
bool alwaysAdd(const Stmt *stmt) const {
return alwaysAddMask[stmt->getStmtClass()];
}
void setAlwaysAdd(Stmt::StmtClass stmtClass) {
alwaysAddMask[stmtClass] = true;
}
BuildOptions()
: forcedBlkExprs(0), PruneTriviallyFalseEdges(true)
, AddEHEdges(false)
, AddInitializers(false)
, AddImplicitDtors(false) {}
: alwaysAddMask(Stmt::lastStmtConstant, false)
,forcedBlkExprs(0), PruneTriviallyFalseEdges(true)
,AddEHEdges(false)
,AddInitializers(false)
,AddImplicitDtors(false) {}
};
/// buildCFG - Builds a CFG from an AST. The responsibility to free the

View File

@ -394,7 +394,7 @@ private:
// Interface to CFGBlock - adding CFGElements.
void appendStmt(CFGBlock *B, const Stmt *S) {
if (alwaysAdd(S))
if (alwaysAdd(S) && cachedEntry)
cachedEntry->second = B;
// All block-level expressions should have already been IgnoreParens()ed.
@ -461,15 +461,17 @@ inline bool AddStmtChoice::alwaysAdd(CFGBuilder &builder,
}
bool CFGBuilder::alwaysAdd(const Stmt *stmt) {
bool shouldAdd = BuildOpts.alwaysAdd(stmt);
if (!BuildOpts.forcedBlkExprs)
return false;
return shouldAdd;
if (lastLookup == stmt) {
if (cachedEntry) {
assert(cachedEntry->first == stmt);
return true;
}
return false;
return shouldAdd;
}
lastLookup = stmt;
@ -480,13 +482,13 @@ bool CFGBuilder::alwaysAdd(const Stmt *stmt) {
if (!fb) {
// No need to update 'cachedEntry', since it will always be null.
assert(cachedEntry == 0);
return false;
return shouldAdd;
}
CFG::BuildOptions::ForcedBlkExprs::iterator itr = fb->find(stmt);
if (itr == fb->end()) {
cachedEntry = 0;
return false;
return shouldAdd;
}
cachedEntry = &*itr;