Add CFG::BuildOptions class to pass in CFG builder options under on parameter. Patch by Marcin Świderski!
llvm-svn: 113898
This commit is contained in:
parent
058fc820d7
commit
e97b1ebef1
|
@ -311,11 +311,24 @@ public:
|
|||
// CFG Construction & Manipulation.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
class BuildOptions {
|
||||
public:
|
||||
bool PruneTriviallyFalseEdges:1;
|
||||
bool AddEHEdges:1;
|
||||
bool AddInitializers:1;
|
||||
bool AddImplicitDtors:1;
|
||||
|
||||
BuildOptions()
|
||||
: PruneTriviallyFalseEdges(true)
|
||||
, AddEHEdges(false)
|
||||
, AddInitializers(false)
|
||||
, AddImplicitDtors(false) {}
|
||||
};
|
||||
|
||||
/// buildCFG - Builds a CFG from an AST. The responsibility to free the
|
||||
/// constructed CFG belongs to the caller.
|
||||
static CFG* buildCFG(const Decl *D, Stmt* AST, ASTContext *C,
|
||||
bool pruneTriviallyFalseEdges = true,
|
||||
bool AddEHEdges = false);
|
||||
BuildOptions BO = BuildOptions());
|
||||
|
||||
/// createBlock - Create a new block in the CFG. The CFG owns the block;
|
||||
/// the caller should not directly free it.
|
||||
|
|
|
@ -59,7 +59,9 @@ CFG *AnalysisContext::getCFG() {
|
|||
return getUnoptimizedCFG();
|
||||
|
||||
if (!builtCFG) {
|
||||
cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), true, AddEHEdges);
|
||||
CFG::BuildOptions B;
|
||||
B.AddEHEdges = AddEHEdges;
|
||||
cfg = CFG::buildCFG(D, getBody(), &D->getASTContext(), B);
|
||||
// Even when the cfg is not successfully built, we don't
|
||||
// want to try building it again.
|
||||
builtCFG = true;
|
||||
|
@ -69,8 +71,10 @@ CFG *AnalysisContext::getCFG() {
|
|||
|
||||
CFG *AnalysisContext::getUnoptimizedCFG() {
|
||||
if (!builtCompleteCFG) {
|
||||
completeCFG = CFG::buildCFG(D, getBody(), &D->getASTContext(),
|
||||
false, AddEHEdges);
|
||||
CFG::BuildOptions B;
|
||||
B.PruneTriviallyFalseEdges = false;
|
||||
B.AddEHEdges = AddEHEdges;
|
||||
completeCFG = CFG::buildCFG(D, getBody(), &D->getASTContext(), B);
|
||||
// Even when the cfg is not successfully built, we don't
|
||||
// want to try building it again.
|
||||
builtCompleteCFG = true;
|
||||
|
|
|
@ -100,7 +100,7 @@ public:
|
|||
|
||||
// buildCFG - Used by external clients to construct the CFG.
|
||||
CFG* buildCFG(const Decl *D, Stmt *Statement, ASTContext *C,
|
||||
bool pruneTriviallyFalseEdges, bool AddEHEdges);
|
||||
CFG::BuildOptions BO);
|
||||
|
||||
private:
|
||||
// Visitors to walk an AST and construct the CFG.
|
||||
|
@ -187,7 +187,7 @@ private:
|
|||
/// TryEvaluateBool - Try and evaluate the Stmt and return 0 or 1
|
||||
/// if we can evaluate to a known value, otherwise return -1.
|
||||
TryResult TryEvaluateBool(Expr *S) {
|
||||
if (!PruneTriviallyFalseEdges)
|
||||
if (!BuildOpts.PruneTriviallyFalseEdges)
|
||||
return TryResult();
|
||||
|
||||
Expr::EvalResult Result;
|
||||
|
@ -199,12 +199,7 @@ private:
|
|||
}
|
||||
|
||||
bool badCFG;
|
||||
|
||||
// True iff trivially false edges should be pruned from the CFG.
|
||||
bool PruneTriviallyFalseEdges;
|
||||
|
||||
// True iff EH edges on CallExprs should be added to the CFG.
|
||||
bool AddEHEdges;
|
||||
CFG::BuildOptions BuildOpts;
|
||||
};
|
||||
|
||||
// FIXME: Add support for dependent-sized array types in C++?
|
||||
|
@ -227,11 +222,7 @@ static VariableArrayType* FindVA(Type* t) {
|
|||
/// transferred to the caller. If CFG construction fails, this method returns
|
||||
/// NULL.
|
||||
CFG* CFGBuilder::buildCFG(const Decl *D, Stmt* Statement, ASTContext* C,
|
||||
bool pruneTriviallyFalseEdges,
|
||||
bool addehedges) {
|
||||
|
||||
AddEHEdges = addehedges;
|
||||
PruneTriviallyFalseEdges = pruneTriviallyFalseEdges;
|
||||
CFG::BuildOptions BO) {
|
||||
|
||||
Context = C;
|
||||
assert(cfg.get());
|
||||
|
@ -239,6 +230,9 @@ CFG* CFGBuilder::buildCFG(const Decl *D, Stmt* Statement, ASTContext* C,
|
|||
return NULL;
|
||||
|
||||
badCFG = false;
|
||||
BuildOpts = BO;
|
||||
if (!C->getLangOptions().CPlusPlus)
|
||||
BuildOpts.AddImplicitDtors = false;
|
||||
|
||||
// Create an empty block that will serve as the exit block for the CFG. Since
|
||||
// this is the first block added to the CFG, it will be implicitly registered
|
||||
|
@ -592,7 +586,7 @@ CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) {
|
|||
|
||||
// Languages without exceptions are assumed to not throw.
|
||||
if (Context->getLangOptions().Exceptions) {
|
||||
if (AddEHEdges)
|
||||
if (BuildOpts.AddEHEdges)
|
||||
AddEHEdge = true;
|
||||
}
|
||||
|
||||
|
@ -1810,11 +1804,9 @@ CFGBlock* CFG::createBlock() {
|
|||
/// buildCFG - Constructs a CFG from an AST. Ownership of the returned
|
||||
/// CFG is returned to the caller.
|
||||
CFG* CFG::buildCFG(const Decl *D, Stmt* Statement, ASTContext *C,
|
||||
bool PruneTriviallyFalse,
|
||||
bool AddEHEdges) {
|
||||
BuildOptions BO) {
|
||||
CFGBuilder Builder;
|
||||
return Builder.buildCFG(D, Statement, C, PruneTriviallyFalse,
|
||||
AddEHEdges);
|
||||
return Builder.buildCFG(D, Statement, C, BO);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
Loading…
Reference in New Issue