Refactored CFG construction code that processes DeclStmts to use StmtIterator.
Now CFG construction transparently supports Variable Length Array declarations with expressions for their sizes, and typedefs that include VLAs. llvm-svn: 43520
This commit is contained in:
parent
73721a12ca
commit
4c0ef37fbb
|
@ -113,7 +113,7 @@ private:
|
||||||
CFGBlock* addStmt(Stmt* S);
|
CFGBlock* addStmt(Stmt* S);
|
||||||
CFGBlock* WalkAST(Stmt* S, bool AlwaysAddStmt);
|
CFGBlock* WalkAST(Stmt* S, bool AlwaysAddStmt);
|
||||||
CFGBlock* WalkAST_VisitChildren(Stmt* S);
|
CFGBlock* WalkAST_VisitChildren(Stmt* S);
|
||||||
CFGBlock* WalkAST_VisitVarDecl(VarDecl* D);
|
CFGBlock* WalkAST_VisitDeclSubExprs(StmtIterator& I);
|
||||||
CFGBlock* WalkAST_VisitStmtExpr(StmtExpr* S);
|
CFGBlock* WalkAST_VisitStmtExpr(StmtExpr* S);
|
||||||
CFGBlock* WalkAST_VisitCallExpr(CallExpr* C);
|
CFGBlock* WalkAST_VisitCallExpr(CallExpr* C);
|
||||||
void FinishBlock(CFGBlock* B);
|
void FinishBlock(CFGBlock* B);
|
||||||
|
@ -266,12 +266,13 @@ CFGBlock* CFGBuilder::WalkAST(Stmt* S, bool AlwaysAddStmt = false) {
|
||||||
return addStmt(C->getCond());
|
return addStmt(C->getCond());
|
||||||
}
|
}
|
||||||
|
|
||||||
case Stmt::DeclStmtClass:
|
case Stmt::DeclStmtClass: {
|
||||||
if (VarDecl* V = dyn_cast<VarDecl>(cast<DeclStmt>(S)->getDecl())) {
|
ScopedDecl* D = cast<DeclStmt>(S)->getDecl();
|
||||||
Block->appendStmt(S);
|
Block->appendStmt(S);
|
||||||
return WalkAST_VisitVarDecl(V);
|
|
||||||
|
StmtIterator I(D);
|
||||||
|
return WalkAST_VisitDeclSubExprs(I);
|
||||||
}
|
}
|
||||||
else return Block;
|
|
||||||
|
|
||||||
case Stmt::AddrLabelExprClass: {
|
case Stmt::AddrLabelExprClass: {
|
||||||
AddrLabelExpr* A = cast<AddrLabelExpr>(S);
|
AddrLabelExpr* A = cast<AddrLabelExpr>(S);
|
||||||
|
@ -325,22 +326,19 @@ CFGBlock* CFGBuilder::WalkAST(Stmt* S, bool AlwaysAddStmt = false) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// WalkAST_VisitVarDecl - Utility method to handle VarDecls contained in
|
/// WalkAST_VisitDeclSubExprs - Utility method to handle Decls contained in
|
||||||
/// DeclStmts. Because the initialization code for declarations can
|
/// DeclStmts. Because the initialization code (and sometimes the
|
||||||
/// contain arbitrary expressions, we must linearize declarations
|
/// the type declarations) for DeclStmts can contain arbitrary expressions,
|
||||||
/// to handle arbitrary control-flow induced by those expressions.
|
/// we must linearize declarations to handle arbitrary control-flow induced by
|
||||||
CFGBlock* CFGBuilder::WalkAST_VisitVarDecl(VarDecl* V) {
|
/// those expressions.
|
||||||
// We actually must parse the LAST declaration in a chain of
|
CFGBlock* CFGBuilder::WalkAST_VisitDeclSubExprs(StmtIterator& I) {
|
||||||
// declarations first, because we are building the CFG in reverse
|
Stmt* S = *I;
|
||||||
// order.
|
++I;
|
||||||
if (Decl* D = V->getNextDeclarator())
|
|
||||||
if (VarDecl* Next = cast<VarDecl>(D))
|
|
||||||
Block = WalkAST_VisitVarDecl(Next);
|
|
||||||
|
|
||||||
if (Expr* E = V->getInit())
|
if (I != StmtIterator())
|
||||||
return addStmt(E);
|
WalkAST_VisitDeclSubExprs(I);
|
||||||
|
|
||||||
assert (Block);
|
Block = addStmt(S);
|
||||||
return Block;
|
return Block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue