Added method "printTerminator" to CFGBlock so that external clients can

pretty-print a block's terminator.

When building CFGs, for IfStmts ('if'), we no longer add the ParenExpr
that is the subexpression of the IfStmt to the CFG; instead we add its
first descendant subexpression that is not a ParenExpr.

llvm-svn: 46580
This commit is contained in:
Ted Kremenek 2008-01-30 23:02:42 +00:00
parent b9b740119d
commit 1564763b8e
2 changed files with 15 additions and 12 deletions

View File

@ -523,7 +523,7 @@ CFGBlock* CFGBuilder::VisitIfStmt(IfStmt* I) {
// Add the condition as the last statement in the new block. This // Add the condition as the last statement in the new block. This
// may create new blocks as the condition may contain control-flow. Any // may create new blocks as the condition may contain control-flow. Any
// newly created blocks will be pointed to be "Block". // newly created blocks will be pointed to be "Block".
return addStmt(I->getCond()); return addStmt(I->getCond()->IgnoreParens());
} }
@ -1142,7 +1142,6 @@ public:
void VisitIfStmt(IfStmt* I) { void VisitIfStmt(IfStmt* I) {
OS << "if "; OS << "if ";
I->getCond()->printPretty(OS,Helper); I->getCond()->printPretty(OS,Helper);
OS << "\n";
} }
// Default case. // Default case.
@ -1155,42 +1154,38 @@ public:
if (Stmt* C = F->getCond()) C->printPretty(OS,Helper); if (Stmt* C = F->getCond()) C->printPretty(OS,Helper);
OS << "; "; OS << "; ";
if (F->getInc()) OS << "..."; if (F->getInc()) OS << "...";
OS << ")\n"; OS << ")";
} }
void VisitWhileStmt(WhileStmt* W) { void VisitWhileStmt(WhileStmt* W) {
OS << "while " ; OS << "while " ;
if (Stmt* C = W->getCond()) C->printPretty(OS,Helper); if (Stmt* C = W->getCond()) C->printPretty(OS,Helper);
OS << "\n";
} }
void VisitDoStmt(DoStmt* D) { void VisitDoStmt(DoStmt* D) {
OS << "do ... while "; OS << "do ... while ";
if (Stmt* C = D->getCond()) C->printPretty(OS,Helper); if (Stmt* C = D->getCond()) C->printPretty(OS,Helper);
OS << '\n';
} }
void VisitSwitchStmt(SwitchStmt* S) { void VisitSwitchStmt(SwitchStmt* S) {
OS << "switch "; OS << "switch ";
S->getCond()->printPretty(OS,Helper); S->getCond()->printPretty(OS,Helper);
OS << '\n';
} }
void VisitConditionalOperator(ConditionalOperator* C) { void VisitConditionalOperator(ConditionalOperator* C) {
C->getCond()->printPretty(OS,Helper); C->getCond()->printPretty(OS,Helper);
OS << " ? ... : ...\n"; OS << " ? ... : ...";
} }
void VisitChooseExpr(ChooseExpr* C) { void VisitChooseExpr(ChooseExpr* C) {
OS << "__builtin_choose_expr( "; OS << "__builtin_choose_expr( ";
C->getCond()->printPretty(OS,Helper); C->getCond()->printPretty(OS,Helper);
OS << " )\n"; OS << " )";
} }
void VisitIndirectGotoStmt(IndirectGotoStmt* I) { void VisitIndirectGotoStmt(IndirectGotoStmt* I) {
OS << "goto *"; OS << "goto *";
I->getTarget()->printPretty(OS,Helper); I->getTarget()->printPretty(OS,Helper);
OS << '\n';
} }
void VisitBinaryOperator(BinaryOperator* B) { void VisitBinaryOperator(BinaryOperator* B) {
@ -1203,10 +1198,10 @@ public:
switch (B->getOpcode()) { switch (B->getOpcode()) {
case BinaryOperator::LOr: case BinaryOperator::LOr:
OS << " || ...\n"; OS << " || ...";
return; return;
case BinaryOperator::LAnd: case BinaryOperator::LAnd:
OS << " && ...\n"; OS << " && ...";
return; return;
default: default:
assert(false && "Invalid logical operator."); assert(false && "Invalid logical operator.");
@ -1215,7 +1210,6 @@ public:
void VisitExpr(Expr* E) { void VisitExpr(Expr* E) {
E->printPretty(OS,Helper); E->printPretty(OS,Helper);
OS << '\n';
} }
}; };
@ -1321,6 +1315,7 @@ void print_block(std::ostream& OS, const CFG* cfg, const CFGBlock& B,
CFGBlockTerminatorPrint TPrinter(OS,Helper); CFGBlockTerminatorPrint TPrinter(OS,Helper);
TPrinter.Visit(const_cast<Stmt*>(B.getTerminator())); TPrinter.Visit(const_cast<Stmt*>(B.getTerminator()));
OS << '\n';
} }
if (print_edges) { if (print_edges) {
@ -1392,6 +1387,13 @@ void CFGBlock::print(std::ostream& OS, const CFG* cfg) const {
print_block(OS, cfg, *this, &Helper, true); print_block(OS, cfg, *this, &Helper, true);
} }
/// printTerminator - A simple pretty printer of the terminator of a CFGBlock.
void CFGBlock::printTerminator(std::ostream& OS) const {
CFGBlockTerminatorPrint TPrinter(OS,NULL);
TPrinter.Visit(const_cast<Stmt*>(getTerminator()));
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// CFG Graphviz Visualization // CFG Graphviz Visualization
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -166,6 +166,7 @@ public:
void dump(const CFG* cfg) const; void dump(const CFG* cfg) const;
void print(std::ostream& OS, const CFG* cfg) const; void print(std::ostream& OS, const CFG* cfg) const;
void printTerminator(std::ostream& OS) const;
}; };