blob: 79195a38500113f441111c55934f68a7180462f7 [file] [log] [blame]
Ted Kremenek97f75312007-08-21 21:42:03 +00001//===--- CFG.cpp - Classes for representing and building CFGs----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Ted Kremenek and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the CFG and CFGBuilder classes for representing and
11// building Control-Flow Graphs (CFGs) from ASTs.
12//
13//===----------------------------------------------------------------------===//
14
15#include "clang/AST/CFG.h"
16#include "clang/AST/Expr.h"
Ted Kremenek95e854d2007-08-21 22:06:14 +000017#include "clang/AST/StmtVisitor.h"
Ted Kremenekc5de2222007-08-21 23:26:17 +000018#include "llvm/ADT/DenseMap.h"
Ted Kremenek0edd3a92007-08-28 19:26:49 +000019#include "llvm/ADT/SmallPtrSet.h"
Ted Kremenek97f75312007-08-21 21:42:03 +000020#include <iostream>
21#include <iomanip>
22#include <algorithm>
23using namespace clang;
24
25namespace {
26
Ted Kremenekd6e50602007-08-23 21:26:19 +000027// SaveAndRestore - A utility class that uses RIIA to save and restore
28// the value of a variable.
29template<typename T>
30struct SaveAndRestore {
31 SaveAndRestore(T& x) : X(x), old_value(x) {}
32 ~SaveAndRestore() { X = old_value; }
33
34 T& X;
35 T old_value;
36};
Ted Kremenek97f75312007-08-21 21:42:03 +000037
38/// CFGBuilder - This class is implements CFG construction from an AST.
39/// The builder is stateful: an instance of the builder should be used to only
40/// construct a single CFG.
41///
42/// Example usage:
43///
44/// CFGBuilder builder;
45/// CFG* cfg = builder.BuildAST(stmt1);
46///
Ted Kremenek95e854d2007-08-21 22:06:14 +000047/// CFG construction is done via a recursive walk of an AST.
48/// We actually parse the AST in reverse order so that the successor
49/// of a basic block is constructed prior to its predecessor. This
50/// allows us to nicely capture implicit fall-throughs without extra
51/// basic blocks.
52///
53class CFGBuilder : public StmtVisitor<CFGBuilder,CFGBlock*> {
Ted Kremenek97f75312007-08-21 21:42:03 +000054 CFG* cfg;
55 CFGBlock* Block;
Ted Kremenek97f75312007-08-21 21:42:03 +000056 CFGBlock* Succ;
Ted Kremenekf511d672007-08-22 21:36:54 +000057 CFGBlock* ContinueTargetBlock;
Ted Kremenekf308d372007-08-22 21:51:58 +000058 CFGBlock* BreakTargetBlock;
Ted Kremeneke809ebf2007-08-23 18:43:24 +000059 CFGBlock* SwitchTerminatedBlock;
Ted Kremenek97f75312007-08-21 21:42:03 +000060 unsigned NumBlocks;
61
Ted Kremenek0edd3a92007-08-28 19:26:49 +000062 // LabelMap records the mapping from Label expressions to their blocks.
Ted Kremenekc5de2222007-08-21 23:26:17 +000063 typedef llvm::DenseMap<LabelStmt*,CFGBlock*> LabelMapTy;
64 LabelMapTy LabelMap;
65
Ted Kremenek0edd3a92007-08-28 19:26:49 +000066 // A list of blocks that end with a "goto" that must be backpatched to
67 // their resolved targets upon completion of CFG construction.
Ted Kremenekf5392b72007-08-22 15:40:58 +000068 typedef std::vector<CFGBlock*> BackpatchBlocksTy;
Ted Kremenekc5de2222007-08-21 23:26:17 +000069 BackpatchBlocksTy BackpatchBlocks;
70
Ted Kremenek0edd3a92007-08-28 19:26:49 +000071 // A list of labels whose address has been taken (for indirect gotos).
72 typedef llvm::SmallPtrSet<LabelStmt*,5> LabelSetTy;
73 LabelSetTy AddressTakenLabels;
74
Ted Kremenek97f75312007-08-21 21:42:03 +000075public:
Ted Kremenek4db5b452007-08-23 16:51:22 +000076 explicit CFGBuilder() : cfg(NULL), Block(NULL), Succ(NULL),
Ted Kremenekf308d372007-08-22 21:51:58 +000077 ContinueTargetBlock(NULL), BreakTargetBlock(NULL),
Ted Kremeneke809ebf2007-08-23 18:43:24 +000078 SwitchTerminatedBlock(NULL),
Ted Kremenek97f75312007-08-21 21:42:03 +000079 NumBlocks(0) {
80 // Create an empty CFG.
81 cfg = new CFG();
82 }
83
84 ~CFGBuilder() { delete cfg; }
Ted Kremenek97f75312007-08-21 21:42:03 +000085
Ted Kremenek73543912007-08-23 21:42:29 +000086 // buildCFG - Used by external clients to construct the CFG.
87 CFG* buildCFG(Stmt* Statement);
Ted Kremenek95e854d2007-08-21 22:06:14 +000088
Ted Kremenek73543912007-08-23 21:42:29 +000089 // Visitors to walk an AST and construct the CFG. Called by
90 // buildCFG. Do not call directly!
Ted Kremenekd8313202007-08-22 18:22:34 +000091
Ted Kremenek73543912007-08-23 21:42:29 +000092 CFGBlock* VisitStmt(Stmt* Statement);
93 CFGBlock* VisitNullStmt(NullStmt* Statement);
94 CFGBlock* VisitCompoundStmt(CompoundStmt* C);
95 CFGBlock* VisitIfStmt(IfStmt* I);
96 CFGBlock* VisitReturnStmt(ReturnStmt* R);
97 CFGBlock* VisitLabelStmt(LabelStmt* L);
98 CFGBlock* VisitGotoStmt(GotoStmt* G);
99 CFGBlock* VisitForStmt(ForStmt* F);
100 CFGBlock* VisitWhileStmt(WhileStmt* W);
101 CFGBlock* VisitDoStmt(DoStmt* D);
102 CFGBlock* VisitContinueStmt(ContinueStmt* C);
103 CFGBlock* VisitBreakStmt(BreakStmt* B);
104 CFGBlock* VisitSwitchStmt(SwitchStmt* S);
105 CFGBlock* VisitSwitchCase(SwitchCase* S);
Ted Kremenek0edd3a92007-08-28 19:26:49 +0000106 CFGBlock* VisitIndirectGotoStmt(IndirectGotoStmt* I);
Ted Kremenek97f75312007-08-21 21:42:03 +0000107
Ted Kremenek73543912007-08-23 21:42:29 +0000108private:
109 CFGBlock* createBlock(bool add_successor = true);
Ted Kremenek65cfa562007-08-27 21:27:44 +0000110 CFGBlock* addStmt(Stmt* S);
111 CFGBlock* WalkAST(Stmt* S, bool AlwaysAddStmt);
112 CFGBlock* WalkAST_VisitChildren(Stmt* S);
Ted Kremeneke822b622007-08-28 18:14:37 +0000113 CFGBlock* WalkAST_VisitVarDecl(VarDecl* D);
Ted Kremenek6fca3e02007-08-28 18:30:10 +0000114 CFGBlock* WalkAST_VisitStmtExpr(StmtExpr* S);
Ted Kremenek73543912007-08-23 21:42:29 +0000115 void FinishBlock(CFGBlock* B);
Ted Kremenekd8313202007-08-22 18:22:34 +0000116
Ted Kremenek97f75312007-08-21 21:42:03 +0000117};
Ted Kremenek73543912007-08-23 21:42:29 +0000118
119/// BuildCFG - Constructs a CFG from an AST (a Stmt*). The AST can
120/// represent an arbitrary statement. Examples include a single expression
121/// or a function body (compound statement). The ownership of the returned
122/// CFG is transferred to the caller. If CFG construction fails, this method
123/// returns NULL.
124CFG* CFGBuilder::buildCFG(Stmt* Statement) {
Ted Kremenek0edd3a92007-08-28 19:26:49 +0000125 assert (cfg);
Ted Kremenek73543912007-08-23 21:42:29 +0000126 if (!Statement) return NULL;
127
128 // Create an empty block that will serve as the exit block for the CFG.
129 // Since this is the first block added to the CFG, it will be implicitly
130 // registered as the exit block.
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000131 Succ = createBlock();
132 assert (Succ == &cfg->getExit());
133 Block = NULL; // the EXIT block is empty. Create all other blocks lazily.
Ted Kremenek73543912007-08-23 21:42:29 +0000134
135 // Visit the statements and create the CFG.
136 if (CFGBlock* B = Visit(Statement)) {
137 // Finalize the last constructed block. This usually involves
138 // reversing the order of the statements in the block.
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000139 if (Block) FinishBlock(B);
Ted Kremenek73543912007-08-23 21:42:29 +0000140
141 // Backpatch the gotos whose label -> block mappings we didn't know
142 // when we encountered them.
143 for (BackpatchBlocksTy::iterator I = BackpatchBlocks.begin(),
144 E = BackpatchBlocks.end(); I != E; ++I ) {
145
146 CFGBlock* B = *I;
147 GotoStmt* G = cast<GotoStmt>(B->getTerminator());
148 LabelMapTy::iterator LI = LabelMap.find(G->getLabel());
149
150 // If there is no target for the goto, then we are looking at an
151 // incomplete AST. Handle this by not registering a successor.
152 if (LI == LabelMap.end()) continue;
153
154 B->addSuccessor(LI->second);
Ted Kremenek0edd3a92007-08-28 19:26:49 +0000155 }
Ted Kremenek73543912007-08-23 21:42:29 +0000156
Ted Kremenek0edd3a92007-08-28 19:26:49 +0000157 // Add successors to the Indirect Goto Dispatch block (if we have one).
158 if (CFGBlock* B = cfg->getIndirectGotoBlock())
159 for (LabelSetTy::iterator I = AddressTakenLabels.begin(),
160 E = AddressTakenLabels.end(); I != E; ++I ) {
161
162 // Lookup the target block.
163 LabelMapTy::iterator LI = LabelMap.find(*I);
164
165 // If there is no target block that contains label, then we are looking
166 // at an incomplete AST. Handle this by not registering a successor.
167 if (LI == LabelMap.end()) continue;
168
169 B->addSuccessor(LI->second);
170 }
171
172 // Create an empty entry block that has no predecessors.
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000173 if (B->pred_size() > 0) {
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000174 Succ = B;
175 cfg->setEntry(createBlock());
176 }
177 else cfg->setEntry(B);
178
Ted Kremenek0edd3a92007-08-28 19:26:49 +0000179 // NULL out cfg so that repeated calls to the builder will fail and that
180 // the ownership of the constructed CFG is passed to the caller.
Ted Kremenek73543912007-08-23 21:42:29 +0000181 CFG* t = cfg;
182 cfg = NULL;
183 return t;
184 }
185 else return NULL;
186}
187
188/// createBlock - Used to lazily create blocks that are connected
189/// to the current (global) succcessor.
190CFGBlock* CFGBuilder::createBlock(bool add_successor) {
191 CFGBlock* B = cfg->createBlock(NumBlocks++);
192 if (add_successor && Succ) B->addSuccessor(Succ);
193 return B;
194}
195
196/// FinishBlock - When the last statement has been added to the block,
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000197/// we must reverse the statements because they have been inserted
198/// in reverse order.
Ted Kremenek73543912007-08-23 21:42:29 +0000199void CFGBuilder::FinishBlock(CFGBlock* B) {
200 assert (B);
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000201 B->reverseStmts();
Ted Kremenek73543912007-08-23 21:42:29 +0000202}
203
Ted Kremenek65cfa562007-08-27 21:27:44 +0000204/// addStmt - Used to add statements/expressions to the current CFGBlock
205/// "Block". This method calls WalkAST on the passed statement to see if it
206/// contains any short-circuit expressions. If so, it recursively creates
207/// the necessary blocks for such expressions. It returns the "topmost" block
208/// of the created blocks, or the original value of "Block" when this method
209/// was called if no additional blocks are created.
210CFGBlock* CFGBuilder::addStmt(Stmt* S) {
211 assert (Block);
212 return WalkAST(S,true);
213}
214
215/// WalkAST - Used by addStmt to walk the subtree of a statement and
Ted Kremeneke822b622007-08-28 18:14:37 +0000216/// add extra blocks for ternary operators, &&, and ||. We also
217/// process "," and DeclStmts (which may contain nested control-flow).
Ted Kremenek65cfa562007-08-27 21:27:44 +0000218CFGBlock* CFGBuilder::WalkAST(Stmt* S, bool AlwaysAddStmt = false) {
219 switch (S->getStmtClass()) {
220 case Stmt::ConditionalOperatorClass: {
221 ConditionalOperator* C = cast<ConditionalOperator>(S);
222
223 CFGBlock* ConfluenceBlock = (Block) ? Block : createBlock();
224 ConfluenceBlock->appendStmt(C);
225 FinishBlock(ConfluenceBlock);
226
227 Succ = ConfluenceBlock;
228 Block = NULL;
229 CFGBlock* LHSBlock = Visit(C->getLHS());
230
231 Succ = ConfluenceBlock;
232 Block = NULL;
233 CFGBlock* RHSBlock = Visit(C->getRHS());
234
235 Block = createBlock(false);
236 Block->addSuccessor(LHSBlock);
237 Block->addSuccessor(RHSBlock);
238 Block->setTerminator(C);
239 return addStmt(C->getCond());
240 }
Ted Kremenek666a6af2007-08-28 16:18:58 +0000241
Ted Kremeneke822b622007-08-28 18:14:37 +0000242 case Stmt::DeclStmtClass:
243 if (VarDecl* V = dyn_cast<VarDecl>(cast<DeclStmt>(S)->getDecl())) {
244 Block->appendStmt(S);
245 return WalkAST_VisitVarDecl(V);
246 }
247 else return Block;
Ted Kremenek6fca3e02007-08-28 18:30:10 +0000248
Ted Kremenek0edd3a92007-08-28 19:26:49 +0000249 case Stmt::AddrLabelExprClass: {
250 AddrLabelExpr* A = cast<AddrLabelExpr>(S);
251 AddressTakenLabels.insert(A->getLabel());
252
253 if (AlwaysAddStmt) Block->appendStmt(S);
254 return Block;
255 }
256
Ted Kremenek6fca3e02007-08-28 18:30:10 +0000257 case Stmt::StmtExprClass:
258 return WalkAST_VisitStmtExpr(cast<StmtExpr>(S));
Ted Kremeneke822b622007-08-28 18:14:37 +0000259
Ted Kremenekcfaae762007-08-27 21:54:41 +0000260 case Stmt::BinaryOperatorClass: {
261 BinaryOperator* B = cast<BinaryOperator>(S);
262
263 if (B->isLogicalOp()) { // && or ||
264 CFGBlock* ConfluenceBlock = (Block) ? Block : createBlock();
265 ConfluenceBlock->appendStmt(B);
266 FinishBlock(ConfluenceBlock);
267
268 // create the block evaluating the LHS
269 CFGBlock* LHSBlock = createBlock(false);
270 LHSBlock->addSuccessor(ConfluenceBlock);
271 LHSBlock->setTerminator(B);
272
273 // create the block evaluating the RHS
274 Succ = ConfluenceBlock;
275 Block = NULL;
276 CFGBlock* RHSBlock = Visit(B->getRHS());
277 LHSBlock->addSuccessor(RHSBlock);
278
279 // Generate the blocks for evaluating the LHS.
280 Block = LHSBlock;
281 return addStmt(B->getLHS());
Ted Kremeneke822b622007-08-28 18:14:37 +0000282 }
283 else if (B->getOpcode() == BinaryOperator::Comma) { // ,
284 Block->appendStmt(B);
285 addStmt(B->getRHS());
286 return addStmt(B->getLHS());
Ted Kremenekcfaae762007-08-27 21:54:41 +0000287 }
288
289 // Fall through to the default case.
290 }
291
Ted Kremenek65cfa562007-08-27 21:27:44 +0000292 default:
293 if (AlwaysAddStmt) Block->appendStmt(S);
294 return WalkAST_VisitChildren(S);
295 };
296}
297
Ted Kremeneke822b622007-08-28 18:14:37 +0000298/// WalkAST_VisitVarDecl - Utility method to handle VarDecls contained in
299/// DeclStmts. Because the initialization code for declarations can
300/// contain arbitrary expressions, we must linearize declarations
301/// to handle arbitrary control-flow induced by those expressions.
302CFGBlock* CFGBuilder::WalkAST_VisitVarDecl(VarDecl* V) {
303 // We actually must parse the LAST declaration in a chain of
304 // declarations first, because we are building the CFG in reverse
305 // order.
306 if (Decl* D = V->getNextDeclarator())
307 if (VarDecl* Next = cast<VarDecl>(D))
308 Block = WalkAST_VisitVarDecl(Next);
309
310 if (Expr* E = V->getInit())
311 return addStmt(E);
312
313 assert (Block);
314 return Block;
315}
316
Ted Kremenek65cfa562007-08-27 21:27:44 +0000317/// WalkAST_VisitChildren - Utility method to call WalkAST on the
318/// children of a Stmt.
Ted Kremenekcfaae762007-08-27 21:54:41 +0000319CFGBlock* CFGBuilder::WalkAST_VisitChildren(Stmt* S) {
Ted Kremenek65cfa562007-08-27 21:27:44 +0000320 CFGBlock* B = Block;
321 for (Stmt::child_iterator I = S->child_begin(), E = S->child_end() ;
322 I != E; ++I)
323 B = WalkAST(*I);
324
325 return B;
326}
327
Ted Kremenek6fca3e02007-08-28 18:30:10 +0000328/// WalkAST_VisitStmtExpr - Utility method to handle (nested) statement
329/// expressions (a GCC extension).
330CFGBlock* CFGBuilder::WalkAST_VisitStmtExpr(StmtExpr* S) {
331 Block->appendStmt(S);
332 return VisitCompoundStmt(S->getSubStmt());
333}
334
Ted Kremenek73543912007-08-23 21:42:29 +0000335/// VisitStmt - Handle statements with no branching control flow.
336CFGBlock* CFGBuilder::VisitStmt(Stmt* Statement) {
337 // We cannot assume that we are in the middle of a basic block, since
338 // the CFG might only be constructed for this single statement. If
339 // we have no current basic block, just create one lazily.
340 if (!Block) Block = createBlock();
341
342 // Simply add the statement to the current block. We actually
343 // insert statements in reverse order; this order is reversed later
344 // when processing the containing element in the AST.
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000345 addStmt(Statement);
346
Ted Kremenek73543912007-08-23 21:42:29 +0000347 return Block;
348}
349
350CFGBlock* CFGBuilder::VisitNullStmt(NullStmt* Statement) {
351 return Block;
352}
353
354CFGBlock* CFGBuilder::VisitCompoundStmt(CompoundStmt* C) {
355 // The value returned from this function is the last created CFGBlock
356 // that represents the "entry" point for the translated AST node.
357 CFGBlock* LastBlock;
358
359 for (CompoundStmt::reverse_body_iterator I = C->body_rbegin(),
360 E = C->body_rend(); I != E; ++I )
361 // Add the statement to the current block.
362 if (!(LastBlock=Visit(*I)))
363 return NULL;
364
365 return LastBlock;
366}
367
368CFGBlock* CFGBuilder::VisitIfStmt(IfStmt* I) {
369 // We may see an if statement in the middle of a basic block, or
370 // it may be the first statement we are processing. In either case,
371 // we create a new basic block. First, we create the blocks for
372 // the then...else statements, and then we create the block containing
373 // the if statement. If we were in the middle of a block, we
374 // stop processing that block and reverse its statements. That block
375 // is then the implicit successor for the "then" and "else" clauses.
376
377 // The block we were proccessing is now finished. Make it the
378 // successor block.
379 if (Block) {
380 Succ = Block;
381 FinishBlock(Block);
382 }
383
384 // Process the false branch. NULL out Block so that the recursive
385 // call to Visit will create a new basic block.
386 // Null out Block so that all successor
387 CFGBlock* ElseBlock = Succ;
388
389 if (Stmt* Else = I->getElse()) {
390 SaveAndRestore<CFGBlock*> sv(Succ);
391
392 // NULL out Block so that the recursive call to Visit will
393 // create a new basic block.
394 Block = NULL;
395 ElseBlock = Visit(Else);
396 if (!ElseBlock) return NULL;
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000397 if (Block) FinishBlock(ElseBlock);
Ted Kremenek73543912007-08-23 21:42:29 +0000398 }
399
400 // Process the true branch. NULL out Block so that the recursive
401 // call to Visit will create a new basic block.
402 // Null out Block so that all successor
403 CFGBlock* ThenBlock;
404 {
405 Stmt* Then = I->getThen();
406 assert (Then);
407 SaveAndRestore<CFGBlock*> sv(Succ);
408 Block = NULL;
409 ThenBlock = Visit(Then);
410 if (!ThenBlock) return NULL;
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000411 if (Block) FinishBlock(ThenBlock);
Ted Kremenek73543912007-08-23 21:42:29 +0000412 }
413
414 // Now create a new block containing the if statement.
415 Block = createBlock(false);
Ted Kremenek73543912007-08-23 21:42:29 +0000416
417 // Set the terminator of the new block to the If statement.
418 Block->setTerminator(I);
419
420 // Now add the successors.
421 Block->addSuccessor(ThenBlock);
422 Block->addSuccessor(ElseBlock);
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000423
424 // Add the condition as the last statement in the new block. This
425 // may create new blocks as the condition may contain control-flow. Any
426 // newly created blocks will be pointed to be "Block".
427 return addStmt(I->getCond());
Ted Kremenek73543912007-08-23 21:42:29 +0000428}
429
430CFGBlock* CFGBuilder::VisitReturnStmt(ReturnStmt* R) {
431 // If we were in the middle of a block we stop processing that block
432 // and reverse its statements.
433 //
434 // NOTE: If a "return" appears in the middle of a block, this means
435 // that the code afterwards is DEAD (unreachable). We still
436 // keep a basic block for that code; a simple "mark-and-sweep"
437 // from the entry block will be able to report such dead
438 // blocks.
439 if (Block) FinishBlock(Block);
440
441 // Create the new block.
442 Block = createBlock(false);
443
444 // The Exit block is the only successor.
445 Block->addSuccessor(&cfg->getExit());
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000446
447 // Add the return statement to the block. This may create new blocks
448 // if R contains control-flow (short-circuit operations).
449 return addStmt(R);
Ted Kremenek73543912007-08-23 21:42:29 +0000450}
451
452CFGBlock* CFGBuilder::VisitLabelStmt(LabelStmt* L) {
453 // Get the block of the labeled statement. Add it to our map.
454 CFGBlock* LabelBlock = Visit(L->getSubStmt());
455 assert (LabelBlock);
456
457 assert (LabelMap.find(L) == LabelMap.end() && "label already in map");
458 LabelMap[ L ] = LabelBlock;
459
460 // Labels partition blocks, so this is the end of the basic block
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000461 // we were processing (the label is the first statement). Add the label
462 // the to end (really the beginning) of the block. Because this is
463 // label (and we have already processed the substatement) there is no
464 // extra control-flow to worry about.
Ted Kremenek73543912007-08-23 21:42:29 +0000465 LabelBlock->appendStmt(L);
466 FinishBlock(LabelBlock);
467
468 // We set Block to NULL to allow lazy creation of a new block
469 // (if necessary);
470 Block = NULL;
471
472 // This block is now the implicit successor of other blocks.
473 Succ = LabelBlock;
474
475 return LabelBlock;
476}
477
478CFGBlock* CFGBuilder::VisitGotoStmt(GotoStmt* G) {
479 // Goto is a control-flow statement. Thus we stop processing the
480 // current block and create a new one.
481 if (Block) FinishBlock(Block);
482 Block = createBlock(false);
483 Block->setTerminator(G);
484
485 // If we already know the mapping to the label block add the
486 // successor now.
487 LabelMapTy::iterator I = LabelMap.find(G->getLabel());
488
489 if (I == LabelMap.end())
490 // We will need to backpatch this block later.
491 BackpatchBlocks.push_back(Block);
492 else
493 Block->addSuccessor(I->second);
494
495 return Block;
496}
497
498CFGBlock* CFGBuilder::VisitForStmt(ForStmt* F) {
499 // "for" is a control-flow statement. Thus we stop processing the
500 // current block.
501
502 CFGBlock* LoopSuccessor = NULL;
503
504 if (Block) {
505 FinishBlock(Block);
506 LoopSuccessor = Block;
507 }
508 else LoopSuccessor = Succ;
509
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000510 // Because of short-circuit evaluation, the condition of the loop
511 // can span multiple basic blocks. Thus we need the "Entry" and "Exit"
512 // blocks that evaluate the condition.
513 CFGBlock* ExitConditionBlock = createBlock(false);
514 CFGBlock* EntryConditionBlock = ExitConditionBlock;
515
516 // Set the terminator for the "exit" condition block.
517 ExitConditionBlock->setTerminator(F);
518
519 // Now add the actual condition to the condition block. Because the
520 // condition itself may contain control-flow, new blocks may be created.
521 if (Stmt* C = F->getCond()) {
522 Block = ExitConditionBlock;
523 EntryConditionBlock = addStmt(C);
524 if (Block) FinishBlock(EntryConditionBlock);
525 }
Ted Kremenek73543912007-08-23 21:42:29 +0000526
527 // The condition block is the implicit successor for the loop body as
528 // well as any code above the loop.
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000529 Succ = EntryConditionBlock;
Ted Kremenek73543912007-08-23 21:42:29 +0000530
531 // Now create the loop body.
532 {
533 assert (F->getBody());
534
535 // Save the current values for Block, Succ, and continue and break targets
536 SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),
537 save_continue(ContinueTargetBlock),
538 save_break(BreakTargetBlock);
539
540 // All continues within this loop should go to the condition block
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000541 ContinueTargetBlock = EntryConditionBlock;
Ted Kremenek73543912007-08-23 21:42:29 +0000542
543 // All breaks should go to the code following the loop.
544 BreakTargetBlock = LoopSuccessor;
545
546 // Create a new block to contain the (bottom) of the loop body.
547 Block = createBlock();
548
549 // If we have increment code, insert it at the end of the body block.
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000550 if (Stmt* I = F->getInc()) Block = addStmt(I);
Ted Kremenek73543912007-08-23 21:42:29 +0000551
552 // Now populate the body block, and in the process create new blocks
553 // as we walk the body of the loop.
554 CFGBlock* BodyBlock = Visit(F->getBody());
555 assert (BodyBlock);
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000556 if (Block) FinishBlock(BodyBlock);
Ted Kremenek73543912007-08-23 21:42:29 +0000557
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000558 // This new body block is a successor to our "exit" condition block.
559 ExitConditionBlock->addSuccessor(BodyBlock);
Ted Kremenek73543912007-08-23 21:42:29 +0000560 }
561
562 // Link up the condition block with the code that follows the loop.
563 // (the false branch).
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000564 ExitConditionBlock->addSuccessor(LoopSuccessor);
565
Ted Kremenek73543912007-08-23 21:42:29 +0000566 // If the loop contains initialization, create a new block for those
567 // statements. This block can also contain statements that precede
568 // the loop.
569 if (Stmt* I = F->getInit()) {
570 Block = createBlock();
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000571 return addStmt(I);
Ted Kremenek73543912007-08-23 21:42:29 +0000572 }
573 else {
574 // There is no loop initialization. We are thus basically a while
575 // loop. NULL out Block to force lazy block construction.
576 Block = NULL;
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000577 return EntryConditionBlock;
Ted Kremenek73543912007-08-23 21:42:29 +0000578 }
579}
580
581CFGBlock* CFGBuilder::VisitWhileStmt(WhileStmt* W) {
582 // "while" is a control-flow statement. Thus we stop processing the
583 // current block.
584
585 CFGBlock* LoopSuccessor = NULL;
586
587 if (Block) {
588 FinishBlock(Block);
589 LoopSuccessor = Block;
590 }
591 else LoopSuccessor = Succ;
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000592
593 // Because of short-circuit evaluation, the condition of the loop
594 // can span multiple basic blocks. Thus we need the "Entry" and "Exit"
595 // blocks that evaluate the condition.
596 CFGBlock* ExitConditionBlock = createBlock(false);
597 CFGBlock* EntryConditionBlock = ExitConditionBlock;
598
599 // Set the terminator for the "exit" condition block.
600 ExitConditionBlock->setTerminator(W);
601
602 // Now add the actual condition to the condition block. Because the
603 // condition itself may contain control-flow, new blocks may be created.
604 // Thus we update "Succ" after adding the condition.
605 if (Stmt* C = W->getCond()) {
606 Block = ExitConditionBlock;
607 EntryConditionBlock = addStmt(C);
608 if (Block) FinishBlock(EntryConditionBlock);
609 }
Ted Kremenek73543912007-08-23 21:42:29 +0000610
611 // The condition block is the implicit successor for the loop body as
612 // well as any code above the loop.
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000613 Succ = EntryConditionBlock;
Ted Kremenek73543912007-08-23 21:42:29 +0000614
615 // Process the loop body.
616 {
617 assert (W->getBody());
618
619 // Save the current values for Block, Succ, and continue and break targets
620 SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),
621 save_continue(ContinueTargetBlock),
622 save_break(BreakTargetBlock);
623
624 // All continues within this loop should go to the condition block
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000625 ContinueTargetBlock = EntryConditionBlock;
Ted Kremenek73543912007-08-23 21:42:29 +0000626
627 // All breaks should go to the code following the loop.
628 BreakTargetBlock = LoopSuccessor;
629
630 // NULL out Block to force lazy instantiation of blocks for the body.
631 Block = NULL;
632
633 // Create the body. The returned block is the entry to the loop body.
634 CFGBlock* BodyBlock = Visit(W->getBody());
635 assert (BodyBlock);
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000636 if (Block) FinishBlock(BodyBlock);
Ted Kremenek73543912007-08-23 21:42:29 +0000637
638 // Add the loop body entry as a successor to the condition.
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000639 ExitConditionBlock->addSuccessor(BodyBlock);
Ted Kremenek73543912007-08-23 21:42:29 +0000640 }
641
642 // Link up the condition block with the code that follows the loop.
643 // (the false branch).
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000644 ExitConditionBlock->addSuccessor(LoopSuccessor);
Ted Kremenek73543912007-08-23 21:42:29 +0000645
646 // There can be no more statements in the condition block
647 // since we loop back to this block. NULL out Block to force
648 // lazy creation of another block.
649 Block = NULL;
650
651 // Return the condition block, which is the dominating block for the loop.
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000652 return EntryConditionBlock;
Ted Kremenek73543912007-08-23 21:42:29 +0000653}
654
655CFGBlock* CFGBuilder::VisitDoStmt(DoStmt* D) {
656 // "do...while" is a control-flow statement. Thus we stop processing the
657 // current block.
658
659 CFGBlock* LoopSuccessor = NULL;
660
661 if (Block) {
662 FinishBlock(Block);
663 LoopSuccessor = Block;
664 }
665 else LoopSuccessor = Succ;
666
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000667 // Because of short-circuit evaluation, the condition of the loop
668 // can span multiple basic blocks. Thus we need the "Entry" and "Exit"
669 // blocks that evaluate the condition.
670 CFGBlock* ExitConditionBlock = createBlock(false);
671 CFGBlock* EntryConditionBlock = ExitConditionBlock;
672
673 // Set the terminator for the "exit" condition block.
674 ExitConditionBlock->setTerminator(D);
Ted Kremenek73543912007-08-23 21:42:29 +0000675
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000676 // Now add the actual condition to the condition block. Because the
677 // condition itself may contain control-flow, new blocks may be created.
678 if (Stmt* C = D->getCond()) {
679 Block = ExitConditionBlock;
680 EntryConditionBlock = addStmt(C);
681 if (Block) FinishBlock(EntryConditionBlock);
682 }
Ted Kremenek73543912007-08-23 21:42:29 +0000683
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000684 // The condition block is the implicit successor for the loop body as
685 // well as any code above the loop.
686 Succ = EntryConditionBlock;
687
688
Ted Kremenek73543912007-08-23 21:42:29 +0000689 // Process the loop body.
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000690 CFGBlock* BodyBlock = NULL;
Ted Kremenek73543912007-08-23 21:42:29 +0000691 {
692 assert (D->getBody());
693
694 // Save the current values for Block, Succ, and continue and break targets
695 SaveAndRestore<CFGBlock*> save_Block(Block), save_Succ(Succ),
696 save_continue(ContinueTargetBlock),
697 save_break(BreakTargetBlock);
698
699 // All continues within this loop should go to the condition block
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000700 ContinueTargetBlock = EntryConditionBlock;
Ted Kremenek73543912007-08-23 21:42:29 +0000701
702 // All breaks should go to the code following the loop.
703 BreakTargetBlock = LoopSuccessor;
704
705 // NULL out Block to force lazy instantiation of blocks for the body.
706 Block = NULL;
707
708 // Create the body. The returned block is the entry to the loop body.
709 BodyBlock = Visit(D->getBody());
710 assert (BodyBlock);
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000711 if (Block) FinishBlock(BodyBlock);
Ted Kremenek73543912007-08-23 21:42:29 +0000712
713 // Add the loop body entry as a successor to the condition.
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000714 ExitConditionBlock->addSuccessor(BodyBlock);
Ted Kremenek73543912007-08-23 21:42:29 +0000715 }
716
717 // Link up the condition block with the code that follows the loop.
718 // (the false branch).
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000719 ExitConditionBlock->addSuccessor(LoopSuccessor);
Ted Kremenek73543912007-08-23 21:42:29 +0000720
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000721 // There can be no more statements in the body block(s)
722 // since we loop back to the body. NULL out Block to force
Ted Kremenek73543912007-08-23 21:42:29 +0000723 // lazy creation of another block.
724 Block = NULL;
725
726 // Return the loop body, which is the dominating block for the loop.
727 return BodyBlock;
728}
729
730CFGBlock* CFGBuilder::VisitContinueStmt(ContinueStmt* C) {
731 // "continue" is a control-flow statement. Thus we stop processing the
732 // current block.
733 if (Block) FinishBlock(Block);
734
735 // Now create a new block that ends with the continue statement.
736 Block = createBlock(false);
737 Block->setTerminator(C);
738
739 // If there is no target for the continue, then we are looking at an
740 // incomplete AST. Handle this by not registering a successor.
741 if (ContinueTargetBlock) Block->addSuccessor(ContinueTargetBlock);
742
743 return Block;
744}
745
746CFGBlock* CFGBuilder::VisitBreakStmt(BreakStmt* B) {
747 // "break" is a control-flow statement. Thus we stop processing the
748 // current block.
749 if (Block) FinishBlock(Block);
750
751 // Now create a new block that ends with the continue statement.
752 Block = createBlock(false);
753 Block->setTerminator(B);
754
755 // If there is no target for the break, then we are looking at an
756 // incomplete AST. Handle this by not registering a successor.
757 if (BreakTargetBlock) Block->addSuccessor(BreakTargetBlock);
758
759 return Block;
760}
761
762CFGBlock* CFGBuilder::VisitSwitchStmt(SwitchStmt* S) {
763 // "switch" is a control-flow statement. Thus we stop processing the
764 // current block.
765 CFGBlock* SwitchSuccessor = NULL;
766
767 if (Block) {
768 FinishBlock(Block);
769 SwitchSuccessor = Block;
770 }
771 else SwitchSuccessor = Succ;
772
773 // Save the current "switch" context.
774 SaveAndRestore<CFGBlock*> save_switch(SwitchTerminatedBlock),
775 save_break(BreakTargetBlock);
776
777 // Create a new block that will contain the switch statement.
778 SwitchTerminatedBlock = createBlock(false);
779
Ted Kremenek73543912007-08-23 21:42:29 +0000780 // Now process the switch body. The code after the switch is the implicit
781 // successor.
782 Succ = SwitchSuccessor;
783 BreakTargetBlock = SwitchSuccessor;
Ted Kremenek73543912007-08-23 21:42:29 +0000784
785 // When visiting the body, the case statements should automatically get
786 // linked up to the switch. We also don't keep a pointer to the body,
787 // since all control-flow from the switch goes to case/default statements.
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000788 assert (S->getBody() && "switch must contain a non-NULL body");
789 Block = NULL;
790 CFGBlock *BodyBlock = Visit(S->getBody());
791 if (Block) FinishBlock(BodyBlock);
792
793 // Add the terminator and condition in the switch block.
794 SwitchTerminatedBlock->setTerminator(S);
795 assert (S->getCond() && "switch condition must be non-NULL");
Ted Kremenek73543912007-08-23 21:42:29 +0000796 Block = SwitchTerminatedBlock;
Ted Kremenekcfee50c2007-08-27 19:46:09 +0000797 return addStmt(S->getCond());
Ted Kremenek73543912007-08-23 21:42:29 +0000798}
799
800CFGBlock* CFGBuilder::VisitSwitchCase(SwitchCase* S) {
801 // A SwitchCase is either a "default" or "case" statement. We handle
802 // both in the same way. They are essentially labels, so they are the
803 // first statement in a block.
804 CFGBlock* CaseBlock = Visit(S->getSubStmt());
805 assert (CaseBlock);
806
807 // Cases/Default statements parition block, so this is the top of
808 // the basic block we were processing (the case/default is the first stmt).
809 CaseBlock->appendStmt(S);
810 FinishBlock(CaseBlock);
811
812 // Add this block to the list of successors for the block with the
813 // switch statement.
814 if (SwitchTerminatedBlock) SwitchTerminatedBlock->addSuccessor(CaseBlock);
815
816 // We set Block to NULL to allow lazy creation of a new block (if necessary)
817 Block = NULL;
818
819 // This block is now the implicit successor of other blocks.
820 Succ = CaseBlock;
821
822 return CaseBlock;
823}
824
Ted Kremenek0edd3a92007-08-28 19:26:49 +0000825CFGBlock* CFGBuilder::VisitIndirectGotoStmt(IndirectGotoStmt* I) {
826 // Lazily create the indirect-goto dispatch block if there isn't one
827 // already.
828 CFGBlock* IBlock = cfg->getIndirectGotoBlock();
829
830 if (!IBlock) {
831 IBlock = createBlock(false);
832 cfg->setIndirectGotoBlock(IBlock);
833 }
834
835 // IndirectGoto is a control-flow statement. Thus we stop processing the
836 // current block and create a new one.
837 if (Block) FinishBlock(Block);
838 Block = createBlock(false);
839 Block->setTerminator(I);
840 Block->addSuccessor(IBlock);
841 return addStmt(I->getTarget());
842}
843
Ted Kremenek73543912007-08-23 21:42:29 +0000844
Ted Kremenekd6e50602007-08-23 21:26:19 +0000845} // end anonymous namespace
Ted Kremenek4db5b452007-08-23 16:51:22 +0000846
847/// createBlock - Constructs and adds a new CFGBlock to the CFG. The
848/// block has no successors or predecessors. If this is the first block
849/// created in the CFG, it is automatically set to be the Entry and Exit
850/// of the CFG.
851CFGBlock* CFG::createBlock(unsigned blockID) {
852 bool first_block = begin() == end();
853
854 // Create the block.
855 Blocks.push_front(CFGBlock(blockID));
856
857 // If this is the first block, set it as the Entry and Exit.
858 if (first_block) Entry = Exit = &front();
859
860 // Return the block.
861 return &front();
Ted Kremenek97f75312007-08-21 21:42:03 +0000862}
863
Ted Kremenek4db5b452007-08-23 16:51:22 +0000864/// buildCFG - Constructs a CFG from an AST. Ownership of the returned
865/// CFG is returned to the caller.
866CFG* CFG::buildCFG(Stmt* Statement) {
867 CFGBuilder Builder;
868 return Builder.buildCFG(Statement);
869}
870
871/// reverseStmts - Reverses the orders of statements within a CFGBlock.
Ted Kremenek97f75312007-08-21 21:42:03 +0000872void CFGBlock::reverseStmts() { std::reverse(Stmts.begin(),Stmts.end()); }
873
Ted Kremenek4db5b452007-08-23 16:51:22 +0000874/// dump - A simple pretty printer of a CFG that outputs to stderr.
Ted Kremenek97f75312007-08-21 21:42:03 +0000875void CFG::dump() { print(std::cerr); }
876
Ted Kremenek4db5b452007-08-23 16:51:22 +0000877/// print - A simple pretty printer of a CFG that outputs to an ostream.
Ted Kremenek97f75312007-08-21 21:42:03 +0000878void CFG::print(std::ostream& OS) {
Ted Kremenek4db5b452007-08-23 16:51:22 +0000879 // Print the Entry block.
Ted Kremenekbec06e82007-08-22 21:05:42 +0000880 if (begin() != end()) {
881 CFGBlock& Entry = getEntry();
882 OS << "\n [ B" << Entry.getBlockID() << " (ENTRY) ]\n";
883 Entry.print(OS);
884 }
885
Ted Kremenek4db5b452007-08-23 16:51:22 +0000886 // Iterate through the CFGBlocks and print them one by one.
Ted Kremenek97f75312007-08-21 21:42:03 +0000887 for (iterator I = Blocks.begin(), E = Blocks.end() ; I != E ; ++I) {
Ted Kremenekbec06e82007-08-22 21:05:42 +0000888 // Skip the entry block, because we already printed it.
Ted Kremenek4db5b452007-08-23 16:51:22 +0000889 if (&(*I) == &getEntry() || &(*I) == &getExit()) continue;
Ted Kremenekbec06e82007-08-22 21:05:42 +0000890
Ted Kremenek0edd3a92007-08-28 19:26:49 +0000891 OS << "\n [ B" << I->getBlockID();
892
893 if (&(*I) == getIndirectGotoBlock())
894 OS << " (INDIRECT GOTO DISPATCH) ]\n";
895 else
896 OS << " ]\n";
897
Ted Kremenek97f75312007-08-21 21:42:03 +0000898 I->print(OS);
899 }
Ted Kremenek73543912007-08-23 21:42:29 +0000900
Ted Kremenek4db5b452007-08-23 16:51:22 +0000901 // Print the Exit Block.
902 if (begin() != end()) {
903 CFGBlock& Exit = getExit();
904 OS << "\n [ B" << Exit.getBlockID() << " (EXIT) ]\n";
905 Exit.print(OS);
906 }
Ted Kremenek73543912007-08-23 21:42:29 +0000907
Ted Kremenek97f75312007-08-21 21:42:03 +0000908 OS << "\n";
909}
910
Ted Kremenekd8313202007-08-22 18:22:34 +0000911
912namespace {
913
Ted Kremenek73543912007-08-23 21:42:29 +0000914class CFGBlockTerminatorPrint : public StmtVisitor<CFGBlockTerminatorPrint,
915 void > {
916 std::ostream& OS;
917public:
918 CFGBlockTerminatorPrint(std::ostream& os) : OS(os) {}
919
920 void VisitIfStmt(IfStmt* I) {
921 OS << "if ";
922 I->getCond()->printPretty(std::cerr);
923 OS << "\n";
924 }
925
926 // Default case.
927 void VisitStmt(Stmt* S) { S->printPretty(OS); }
928
929 void VisitForStmt(ForStmt* F) {
930 OS << "for (" ;
931 if (Stmt* I = F->getInit()) I->printPretty(OS);
932 OS << " ; ";
933 if (Stmt* C = F->getCond()) C->printPretty(OS);
934 OS << " ; ";
935 if (Stmt* I = F->getInc()) I->printPretty(OS);
936 OS << ")\n";
937 }
938
939 void VisitWhileStmt(WhileStmt* W) {
940 OS << "while " ;
941 if (Stmt* C = W->getCond()) C->printPretty(OS);
942 OS << "\n";
943 }
944
945 void VisitDoStmt(DoStmt* D) {
946 OS << "do ... while ";
947 if (Stmt* C = D->getCond()) C->printPretty(OS);
Ted Kremenek65cfa562007-08-27 21:27:44 +0000948 OS << '\n';
949 }
950
951 void VisitSwitchStmt(SwitchStmt* S) {
952 OS << "switch ";
953 S->getCond()->printPretty(OS);
954 OS << '\n';
955 }
956
Ted Kremenekcfaae762007-08-27 21:54:41 +0000957 void VisitExpr(Expr* E) {
958 E->printPretty(OS);
Ted Kremenek65cfa562007-08-27 21:27:44 +0000959 OS << '\n';
Ted Kremenekcfaae762007-08-27 21:54:41 +0000960 }
Ted Kremenek73543912007-08-23 21:42:29 +0000961};
962} // end anonymous namespace
Ted Kremenekd8313202007-08-22 18:22:34 +0000963
Ted Kremenek4db5b452007-08-23 16:51:22 +0000964/// dump - A simply pretty printer of a CFGBlock that outputs to stderr.
Ted Kremenek97f75312007-08-21 21:42:03 +0000965void CFGBlock::dump() { print(std::cerr); }
966
Ted Kremenek4db5b452007-08-23 16:51:22 +0000967/// print - A simple pretty printer of a CFGBlock that outputs to an ostream.
968/// Generally this will only be called from CFG::print.
Ted Kremenek97f75312007-08-21 21:42:03 +0000969void CFGBlock::print(std::ostream& OS) {
970
971 // Iterate through the statements in the block and print them.
972 OS << " ------------------------\n";
973 unsigned j = 1;
974 for (iterator I = Stmts.begin(), E = Stmts.end() ; I != E ; ++I, ++j ) {
Ted Kremenekc5de2222007-08-21 23:26:17 +0000975 // Print the statement # in the basic block.
976 OS << " " << std::setw(3) << j << ": ";
977
978 // Print the statement/expression.
979 Stmt* S = *I;
980
981 if (LabelStmt* L = dyn_cast<LabelStmt>(S))
982 OS << L->getName() << ": (LABEL)\n";
983 else
984 (*I)->printPretty(OS);
985
986 // Expressions need a newline.
Ted Kremenek97f75312007-08-21 21:42:03 +0000987 if (isa<Expr>(*I)) OS << '\n';
988 }
989 OS << " ------------------------\n";
990
991 // Print the predecessors of this block.
992 OS << " Predecessors (" << pred_size() << "):";
993 unsigned i = 0;
994 for (pred_iterator I = pred_begin(), E = pred_end(); I != E; ++I, ++i ) {
995 if (i == 8 || (i-8) == 0) {
996 OS << "\n ";
997 }
998 OS << " B" << (*I)->getBlockID();
999 }
1000
1001 // Print the terminator of this block.
1002 OS << "\n Terminator: ";
Ted Kremenekd8313202007-08-22 18:22:34 +00001003 if (ControlFlowStmt)
1004 CFGBlockTerminatorPrint(OS).Visit(ControlFlowStmt);
1005 else
1006 OS << "<NULL>\n";
Ted Kremenek97f75312007-08-21 21:42:03 +00001007
1008 // Print the successors of this block.
1009 OS << " Successors (" << succ_size() << "):";
1010 i = 0;
1011 for (succ_iterator I = succ_begin(), E = succ_end(); I != E; ++I, ++i ) {
1012 if (i == 8 || (i-8) % 10 == 0) {
1013 OS << "\n ";
1014 }
1015 OS << " B" << (*I)->getBlockID();
1016 }
1017 OS << '\n';
Ted Kremenek4db5b452007-08-23 16:51:22 +00001018}