/// &&, || expression that uses result of && or ||, RHS
///
class CFGBlock {
- typedef std::vector<Stmt*> StatementListTy;
+ class StatementList {
+ typedef std::vector<Stmt*> ImplTy;
+ ImplTy Impl;
+ public:
+ typedef std::reverse_iterator<ImplTy::iterator> iterator;
+ typedef std::reverse_iterator<ImplTy::const_iterator> const_iterator;
+ typedef ImplTy::iterator reverse_iterator;
+ typedef ImplTy::const_iterator const_reverse_iterator;
+
+ void push_back(Stmt *s) { Impl.push_back(s); }
+ Stmt *front() const { return Impl.back(); }
+ Stmt *back() const { return Impl.front(); }
+
+ iterator begin() { return Impl.rbegin(); }
+ iterator end() { return Impl.rend(); }
+ const_iterator begin() const { return Impl.rbegin(); }
+ const_iterator end() const { return Impl.rend(); }
+ reverse_iterator rbegin() { return Impl.begin(); }
+ reverse_iterator rend() { return Impl.end(); }
+ const_reverse_iterator rbegin() const { return Impl.begin(); }
+ const_reverse_iterator rend() const { return Impl.end(); }
+
+ Stmt* operator[](size_t i) const {
+ assert(i < Impl.size());
+ return Impl[Impl.size() - 1 - i];
+ }
+
+ size_t size() const { return Impl.size(); }
+ bool empty() const { return Impl.empty(); }
+ };
+
/// Stmts - The set of statements in the basic block.
- StatementListTy Stmts;
+ StatementList Stmts;
/// Label - An (optional) label that prefixes the executable
/// statements in the block. When this variable is non-NULL, it is
~CFGBlock() {};
// Statement iterators
- typedef StatementListTy::iterator iterator;
- typedef StatementListTy::const_iterator const_iterator;
- typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
- typedef std::reverse_iterator<iterator> reverse_iterator;
+ typedef StatementList::iterator iterator;
+ typedef StatementList::const_iterator const_iterator;
+ typedef StatementList::reverse_iterator reverse_iterator;
+ typedef StatementList::const_reverse_iterator const_reverse_iterator;
Stmt* front() const { return Stmts.front(); }
Stmt* back() const { return Stmts.back(); }
unsigned size() const { return Stmts.size(); }
bool empty() const { return Stmts.empty(); }
- Stmt* operator[](size_t i) const { assert (i < size()); return Stmts[i]; }
+ Stmt* operator[](size_t i) const { return Stmts[i]; }
+
// CFG iterators
typedef AdjacentBlocks::iterator pred_iterator;
return B;
}
-/// FinishBlock - When the last statement has been added to the block, we must
-/// reverse the statements because they have been inserted in reverse order.
+/// FinishBlock - "Finalize" the block by checking if we have a bad CFG.
bool CFGBuilder::FinishBlock(CFGBlock* B) {
if (badCFG)
return false;
assert(B);
- B->reverseStmts();
return true;
}
// first statement we are processing. In either case, we create a new basic
// block. First, we create the blocks for the then...else statements, and
// then we create the block containing the if statement. If we were in the
- // middle of a block, we stop processing that block and reverse its
- // statements. That block is then the implicit successor for the "then" and
- // "else" clauses.
+ // middle of a block, we stop processing that block. That block is then the
+ // implicit successor for the "then" and "else" clauses.
// The block we were proccessing is now finished. Make it the successor
// block.
CFGBlock* CFGBuilder::VisitReturnStmt(ReturnStmt* R) {
- // If we were in the middle of a block we stop processing that block and
- // reverse its statements.
+ // If we were in the middle of a block we stop processing that block.
//
// NOTE: If a "return" appears in the middle of a block, this means that the
// code afterwards is DEAD (unreachable). We still keep a basic block
// for that code; a simple "mark-and-sweep" from the entry block will be
// able to report such dead blocks.
- if (Block) FinishBlock(Block);
+ if (Block)
+ FinishBlock(Block);
// Create the new block.
Block = createBlock(false);
// FIXME: This isn't complete. We basically treat @throw like a return
// statement.
- // If we were in the middle of a block we stop processing that block and
- // reverse its statements.
+ // If we were in the middle of a block we stop processing that block.
if (Block && !FinishBlock(Block))
return 0;
}
CFGBlock* CFGBuilder::VisitCXXThrowExpr(CXXThrowExpr* T) {
- // If we were in the middle of a block we stop processing that block and
- // reverse its statements.
+ // If we were in the middle of a block we stop processing that block.
if (Block && !FinishBlock(Block))
return 0;
return Builder.buildCFG(Statement, C);
}
-/// reverseStmts - Reverses the orders of statements within a CFGBlock.
-void CFGBlock::reverseStmts() { std::reverse(Stmts.begin(),Stmts.end()); }
-
//===----------------------------------------------------------------------===//
// CFG: Queries for BlkExprs.
//===----------------------------------------------------------------------===//