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:
Ted Kremenek 2007-10-30 21:48:34 +00:00
parent 73721a12ca
commit 4c0ef37fbb
1 changed files with 21 additions and 23 deletions

View File

@ -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);
else return Block; return WalkAST_VisitDeclSubExprs(I);
}
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;
} }