[cfe-commits] r41547 - /cfe/trunk/AST/CFG.cpp
Ted Kremenek
kremenek at apple.com
Tue Aug 28 11:14:37 PDT 2007
Author: kremenek
Date: Tue Aug 28 13:14:37 2007
New Revision: 41547
URL: http://llvm.org/viewvc/llvm-project?rev=41547&view=rev
Log:
Added support for comma expressions and DeclStmts which may have
arbitrarily complex control-flow in their subexpressions.
Modified:
cfe/trunk/AST/CFG.cpp
Modified: cfe/trunk/AST/CFG.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/CFG.cpp?rev=41547&r1=41546&r2=41547&view=diff
==============================================================================
--- cfe/trunk/AST/CFG.cpp (original)
+++ cfe/trunk/AST/CFG.cpp Tue Aug 28 13:14:37 2007
@@ -101,6 +101,7 @@
CFGBlock* addStmt(Stmt* S);
CFGBlock* WalkAST(Stmt* S, bool AlwaysAddStmt);
CFGBlock* WalkAST_VisitChildren(Stmt* S);
+ CFGBlock* WalkAST_VisitVarDecl(VarDecl* D);
void FinishBlock(CFGBlock* B);
};
@@ -185,7 +186,8 @@
}
/// WalkAST - Used by addStmt to walk the subtree of a statement and
-/// add extra blocks for ternary operators, &&, and ||.
+/// add extra blocks for ternary operators, &&, and ||. We also
+/// process "," and DeclStmts (which may contain nested control-flow).
CFGBlock* CFGBuilder::WalkAST(Stmt* S, bool AlwaysAddStmt = false) {
switch (S->getStmtClass()) {
case Stmt::ConditionalOperatorClass: {
@@ -210,6 +212,13 @@
return addStmt(C->getCond());
}
+ case Stmt::DeclStmtClass:
+ if (VarDecl* V = dyn_cast<VarDecl>(cast<DeclStmt>(S)->getDecl())) {
+ Block->appendStmt(S);
+ return WalkAST_VisitVarDecl(V);
+ }
+ else return Block;
+
case Stmt::BinaryOperatorClass: {
BinaryOperator* B = cast<BinaryOperator>(S);
@@ -232,6 +241,11 @@
// Generate the blocks for evaluating the LHS.
Block = LHSBlock;
return addStmt(B->getLHS());
+ }
+ else if (B->getOpcode() == BinaryOperator::Comma) { // ,
+ Block->appendStmt(B);
+ addStmt(B->getRHS());
+ return addStmt(B->getLHS());
}
// Fall through to the default case.
@@ -243,6 +257,25 @@
};
}
+/// WalkAST_VisitVarDecl - Utility method to handle VarDecls contained in
+/// DeclStmts. Because the initialization code for declarations can
+/// contain arbitrary expressions, we must linearize declarations
+/// to handle arbitrary control-flow induced by those expressions.
+CFGBlock* CFGBuilder::WalkAST_VisitVarDecl(VarDecl* V) {
+ // We actually must parse the LAST declaration in a chain of
+ // declarations first, because we are building the CFG in reverse
+ // order.
+ if (Decl* D = V->getNextDeclarator())
+ if (VarDecl* Next = cast<VarDecl>(D))
+ Block = WalkAST_VisitVarDecl(Next);
+
+ if (Expr* E = V->getInit())
+ return addStmt(E);
+
+ assert (Block);
+ return Block;
+}
+
/// WalkAST_VisitChildren - Utility method to call WalkAST on the
/// children of a Stmt.
CFGBlock* CFGBuilder::WalkAST_VisitChildren(Stmt* S) {
@@ -365,9 +398,6 @@
// The Exit block is the only successor.
Block->addSuccessor(&cfg->getExit());
-
- // Also add the return statement as the terminator.
- Block->setTerminator(R);
// Add the return statement to the block. This may create new blocks
// if R contains control-flow (short-circuit operations).
More information about the cfe-commits
mailing list