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:
parent
b9b740119d
commit
1564763b8e
|
@ -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
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue