CFG.h revision 1eb4433ac451dc16f4133a88af2d002ac26c58ef
1fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//===--- CFG.h - Classes for representing and building CFGs------*- C++ -*-===//
2fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//
3fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//                     The LLVM Compiler Infrastructure
4fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
7fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//
8fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//===----------------------------------------------------------------------===//
9fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//
10fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//  This file defines the CFG and CFGBuilder classes for representing and
11fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//  building Control-Flow Graphs (CFGs) from ASTs.
12fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//
13fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek//===----------------------------------------------------------------------===//
14fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
15cd881d534517f09a2fae10445f9b865f49ccc6c8Ted Kremenek#ifndef LLVM_CLANG_CFG_H
16cd881d534517f09a2fae10445f9b865f49ccc6c8Ted Kremenek#define LLVM_CLANG_CFG_H
17cd881d534517f09a2fae10445f9b865f49ccc6c8Ted Kremenek
187dba8607e59096014b7139ff20ef00870041d518Ted Kremenek#include "llvm/ADT/GraphTraits.h"
19ce1eb34bbea1e0408f1952776d7d52ccde1bd275Ted Kremenek#include "llvm/Support/Allocator.h"
20fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek#include <list>
21fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek#include <vector>
22c1581a0d64b0ee4f822ed2fca4442a111d03569aHartmut Kaiser#include <cassert>
23fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
24e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattnernamespace llvm {
25e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  class raw_ostream;
26e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner}
27fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremeneknamespace clang {
2842a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  class Stmt;
2963f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  class Expr;
3042a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  class CFG;
3142a509f6a4f71bb805cc4abbb26722a34dffdddeTed Kremenek  class PrinterHelper;
32e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  class LangOptions;
33e5af3ce53ec58995b09381ba645ab2117a46647bMike Stump  class ASTContext;
34e5af3ce53ec58995b09381ba645ab2117a46647bMike Stump
35fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// CFGBlock - Represents a single basic block in a source-level CFG.
36fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  It consists of:
37fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///
38fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  (1) A set of statements/expressions (which may contain subexpressions).
39fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  (2) A "terminator" statement (not in the set of statements).
40fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  (3) A list of successors and predecessors.
41fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///
42fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// Terminator: The terminator represents the type of control-flow that occurs
43fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// at the end of the basic block.  The terminator is a Stmt* referring to an
44fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// AST node that has control-flow: if-statements, breaks, loops, etc.
45fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// If the control-flow is conditional, the condition expression will appear
46fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// within the set of statements in the block (usually the last statement).
47fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///
48fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// Predecessors: the order in the set of predecessors is arbitrary.
49fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///
50fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// Successors: the order in the set of successors is NOT arbitrary.  We
51fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  currently have the following orderings based on the terminator:
52fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///
53fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///     Terminator       Successor Ordering
54fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  -----------------------------------------------------
55fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///       if            Then Block;  Else Block
569cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek///     ? operator      LHS expression;  RHS expression
579cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek///     &&, ||          expression that uses result of && or ||, RHS
58fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///
59fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekclass CFGBlock {
60fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef std::vector<Stmt*> StatementListTy;
61fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  /// Stmts - The set of statements in the basic block.
62fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  StatementListTy Stmts;
639cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek
649cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  /// Label - An (optional) label that prefixes the executable
659cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  ///  statements in the block.  When this variable is non-NULL, it is
669cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  ///  either an instance of LabelStmt or SwitchCase.
673575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek  Stmt *Label;
681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
699cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  /// Terminator - The terminator for a basic block that
70fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  ///  indicates the type of control-flow that occurs between a block
71fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  ///  and its successors.
723575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek  Stmt *Terminator;
731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
743575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek  /// LoopTarget - Some blocks are used to represent the "loop edge" to
753575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek  ///  the start of a loop from within the loop body.  This Stmt* will be
763575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek  ///  refer to the loop statement for such blocks (and be null otherwise).
771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const Stmt *LoopTarget;
781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
79fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  /// BlockID - A numerical ID assigned to a CFGBlock during construction
80fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  ///   of the CFG.
81fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  unsigned BlockID;
821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
83fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  /// Predecessors/Successors - Keep track of the predecessor / successor
84fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  /// CFG blocks.
85fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef std::vector<CFGBlock*> AdjacentBlocks;
86fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  AdjacentBlocks Preds;
87fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  AdjacentBlocks Succs;
881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
89fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekpublic:
909cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  explicit CFGBlock(unsigned blockid) : Label(NULL), Terminator(NULL),
913575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek                                        LoopTarget(NULL), BlockID(blockid) {}
92fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  ~CFGBlock() {};
93fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
94fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  // Statement iterators
95fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef StatementListTy::iterator                                  iterator;
96fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef StatementListTy::const_iterator                      const_iterator;
97fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef std::reverse_iterator<const_iterator>        const_reverse_iterator;
98fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef std::reverse_iterator<iterator>                    reverse_iterator;
991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1005156ad8b2e64850a13d4e9d9ddeb3f9c6b9d3ebbTed Kremenek  Stmt*                        front()       const { return Stmts.front();   }
1015156ad8b2e64850a13d4e9d9ddeb3f9c6b9d3ebbTed Kremenek  Stmt*                        back()        const { return Stmts.back();    }
1021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
103fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  iterator                     begin()             { return Stmts.begin();   }
104fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  iterator                     end()               { return Stmts.end();     }
105fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_iterator               begin()       const { return Stmts.begin();   }
1061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const_iterator               end()         const { return Stmts.end();     }
107fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
108fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  reverse_iterator             rbegin()            { return Stmts.rbegin();  }
109fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  reverse_iterator             rend()              { return Stmts.rend();    }
110fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_reverse_iterator       rbegin()      const { return Stmts.rbegin();  }
111fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_reverse_iterator       rend()        const { return Stmts.rend();    }
1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
113fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  unsigned                     size()        const { return Stmts.size();    }
114fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  bool                         empty()       const { return Stmts.empty();   }
115be7a7d6f2e5b86807afd08a568863df973baaa38Ted Kremenek
116be7a7d6f2e5b86807afd08a568863df973baaa38Ted Kremenek  Stmt*  operator[](size_t i) const  { assert (i < size()); return Stmts[i]; }
1171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
118fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  // CFG iterators
119fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef AdjacentBlocks::iterator                              pred_iterator;
120fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef AdjacentBlocks::const_iterator                  const_pred_iterator;
121fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef AdjacentBlocks::reverse_iterator              pred_reverse_iterator;
122fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef AdjacentBlocks::const_reverse_iterator  const_pred_reverse_iterator;
123fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
124fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef AdjacentBlocks::iterator                              succ_iterator;
125fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef AdjacentBlocks::const_iterator                  const_succ_iterator;
126fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef AdjacentBlocks::reverse_iterator              succ_reverse_iterator;
127fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef AdjacentBlocks::const_reverse_iterator  const_succ_reverse_iterator;
1281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
129fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  pred_iterator                pred_begin()        { return Preds.begin();   }
130fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  pred_iterator                pred_end()          { return Preds.end();     }
131fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_pred_iterator          pred_begin()  const { return Preds.begin();   }
132fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_pred_iterator          pred_end()    const { return Preds.end();     }
1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
134fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  pred_reverse_iterator        pred_rbegin()       { return Preds.rbegin();  }
1351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  pred_reverse_iterator        pred_rend()         { return Preds.rend();    }
136fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_pred_reverse_iterator  pred_rbegin() const { return Preds.rbegin();  }
137fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_pred_reverse_iterator  pred_rend()   const { return Preds.rend();    }
138fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
1391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  succ_iterator                succ_begin()        { return Succs.begin();   }
140fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  succ_iterator                succ_end()          { return Succs.end();     }
141fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_succ_iterator          succ_begin()  const { return Succs.begin();   }
1421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const_succ_iterator          succ_end()    const { return Succs.end();     }
1431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
144fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  succ_reverse_iterator        succ_rbegin()       { return Succs.rbegin();  }
145fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  succ_reverse_iterator        succ_rend()         { return Succs.rend();    }
146fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_succ_reverse_iterator  succ_rbegin() const { return Succs.rbegin();  }
147fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_succ_reverse_iterator  succ_rend()   const { return Succs.rend();    }
148fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
149fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  unsigned                     succ_size()   const { return Succs.size();    }
150fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  bool                         succ_empty()  const { return Succs.empty();   }
151fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
152fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  unsigned                     pred_size()   const { return Preds.size();    }
153fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  bool                         pred_empty()  const { return Preds.empty();   }
1541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
155fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  // Manipulation of block contents
1561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
157fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  void appendStmt(Stmt* Statement) { Stmts.push_back(Statement); }
1589cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  void setTerminator(Stmt* Statement) { Terminator = Statement; }
1599cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  void setLabel(Stmt* Statement) { Label = Statement; }
1603575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek  void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; }
1619cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek
1629cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  Stmt* getTerminator() { return Terminator; }
1639cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  const Stmt* getTerminator() const { return Terminator; }
1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
165390e48b15ad93f85bfd1e33b9992c198fa0db475Ted Kremenek  Stmt* getTerminatorCondition();
1661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
167390e48b15ad93f85bfd1e33b9992c198fa0db475Ted Kremenek  const Stmt* getTerminatorCondition() const {
168411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek    return const_cast<CFGBlock*>(this)->getTerminatorCondition();
169411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek  }
1701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1713575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek  const Stmt *getLoopTarget() const { return LoopTarget; }
1721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1739c2535a35db35b3a821a0d0c36a01a16f52f1ad0Ted Kremenek  bool hasBinaryBranchTerminator() const;
1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1759cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  Stmt* getLabel() { return Label; }
1769cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  const Stmt* getLabel() const { return Label; }
1771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
178fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  void reverseStmts();
1791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
180fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  void addSuccessor(CFGBlock* Block) {
181e5af3ce53ec58995b09381ba645ab2117a46647bMike Stump    if (Block)
182e5af3ce53ec58995b09381ba645ab2117a46647bMike Stump      Block->Preds.push_back(this);
183fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    Succs.push_back(Block);
184fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  }
1851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
186fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  unsigned getBlockID() const { return BlockID; }
1871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
188e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  void dump(const CFG *cfg, const LangOptions &LO) const;
189e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  void print(llvm::raw_ostream &OS, const CFG* cfg, const LangOptions &LO) const;
190e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  void printTerminator(llvm::raw_ostream &OS, const LangOptions &LO) const;
191fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek};
1921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
193fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
194fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// CFG - Represents a source-level, intra-procedural CFG that represents the
195fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  control-flow of a Stmt.  The Stmt can represent an entire function body,
196fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  or a single expression.  A CFG will always contain one empty block that
197fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  represents the Exit point of the CFG.  A CFG will also contain a designated
198fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  Entry block.  The CFG solely represents control-flow; it consists of
199fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  CFGBlocks which are simply containers of Stmt*'s in the AST the CFG
200fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  was constructed from.
201fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekclass CFG {
202fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekpublic:
203a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
204a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  // CFG Construction & Manipulation.
205a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
206a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek
207a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  /// buildCFG - Builds a CFG from an AST.  The responsibility to free the
2081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ///   constructed CFG belongs to the caller.
2091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static CFG* buildCFG(Stmt* AST, ASTContext *C);
2101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
211a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  /// createBlock - Create a new block in the CFG.  The CFG owns the block;
212a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  ///  the caller should not directly free it.
213a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  CFGBlock* createBlock();
2141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
215a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  /// setEntry - Set the entry block of the CFG.  This is typically used
216a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  ///  only during CFG construction.  Most CFG clients expect that the
217a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  ///  entry block has no predecessors and contains no statements.
218a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  void setEntry(CFGBlock *B) { Entry = B; }
2191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
220e38158de9236dfcded7da56126134e5e3e49cb01Ted Kremenek  /// setIndirectGotoBlock - Set the block used for indirect goto jumps.
221e38158de9236dfcded7da56126134e5e3e49cb01Ted Kremenek  ///  This is typically used only during CFG construction.
222a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  void setIndirectGotoBlock(CFGBlock* B) { IndirectGotoBlock = B; }
2231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
224a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
225a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  // Block Iterators
226a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
227a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek
228a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  typedef std::list<CFGBlock>                      CFGBlockListTy;
2291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
230a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  typedef CFGBlockListTy::iterator                 iterator;
231a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  typedef CFGBlockListTy::const_iterator           const_iterator;
232a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  typedef std::reverse_iterator<iterator>          reverse_iterator;
233a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
234fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
23519bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  CFGBlock&                 front()                { return Blocks.front(); }
23619bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  CFGBlock&                 back()                 { return Blocks.back(); }
2371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23819bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  iterator                  begin()                { return Blocks.begin(); }
23919bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  iterator                  end()                  { return Blocks.end(); }
24019bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  const_iterator            begin()       const    { return Blocks.begin(); }
2411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const_iterator            end()         const    { return Blocks.end(); }
2421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24319bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  reverse_iterator          rbegin()               { return Blocks.rbegin(); }
24419bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  reverse_iterator          rend()                 { return Blocks.rend(); }
24519bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  const_reverse_iterator    rbegin()      const    { return Blocks.rbegin(); }
24619bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  const_reverse_iterator    rend()        const    { return Blocks.rend(); }
2471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
24819bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  CFGBlock&                 getEntry()             { return *Entry; }
2497dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  const CFGBlock&           getEntry()    const    { return *Entry; }
25019bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  CFGBlock&                 getExit()              { return *Exit; }
2517dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  const CFGBlock&           getExit()     const    { return *Exit; }
2527dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
2537dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  CFGBlock*        getIndirectGotoBlock() { return IndirectGotoBlock; }
2547dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  const CFGBlock*  getIndirectGotoBlock() const { return IndirectGotoBlock; }
2551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
256a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
257a90b0d1e585d993621a342d0b2874e61941372d5Ted Kremenek  // Member templates useful for various batch operations over CFGs.
258a90b0d1e585d993621a342d0b2874e61941372d5Ted Kremenek  //===--------------------------------------------------------------------===//
2591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
260a90b0d1e585d993621a342d0b2874e61941372d5Ted Kremenek  template <typename CALLBACK>
261a90b0d1e585d993621a342d0b2874e61941372d5Ted Kremenek  void VisitBlockStmts(CALLBACK& O) const {
262a90b0d1e585d993621a342d0b2874e61941372d5Ted Kremenek    for (const_iterator I=begin(), E=end(); I != E; ++I)
263a90b0d1e585d993621a342d0b2874e61941372d5Ted Kremenek      for (CFGBlock::const_iterator BI=I->begin(), BE=I->end(); BI != BE; ++BI)
264a90b0d1e585d993621a342d0b2874e61941372d5Ted Kremenek        O(*BI);
2651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
2661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
267a90b0d1e585d993621a342d0b2874e61941372d5Ted Kremenek  //===--------------------------------------------------------------------===//
268a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  // CFG Introspection.
269a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
270a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek
27163f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  struct   BlkExprNumTy {
27263f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek    const signed Idx;
27363f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek    explicit BlkExprNumTy(signed idx) : Idx(idx) {}
27463f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek    explicit BlkExprNumTy() : Idx(-1) {}
27563f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek    operator bool() const { return Idx >= 0; }
27663f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek    operator unsigned() const { assert(Idx >=0); return (unsigned) Idx; }
27763f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  };
2781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
27986946745225096243f6969dc745267b78fc211a6Ted Kremenek  bool          isBlkExpr(const Stmt* S) { return getBlkExprNum(S); }
28086946745225096243f6969dc745267b78fc211a6Ted Kremenek  BlkExprNumTy  getBlkExprNum(const Stmt* S);
28163f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  unsigned      getNumBlkExprs();
2821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2830c8c5365be0176e8399e97d7da3293c79bc9da24Mike Stump  /// getNumBlockIDs - Returns the total number of BlockIDs allocated (which
2840c8c5365be0176e8399e97d7da3293c79bc9da24Mike Stump  /// start at 0).
2859438252ad2ecae5338df565ca33c6969e4fbfa41Ted Kremenek  unsigned getNumBlockIDs() const { return NumBlockIDs; }
286a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek
287a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
288a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  // CFG Debugging: Pretty-Printing and Visualization.
289a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
290a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek
291e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  void viewCFG(const LangOptions &LO) const;
292e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  void print(llvm::raw_ostream& OS, const LangOptions &LO) const;
293e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  void dump(const LangOptions &LO) const;
294a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek
295a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
296a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  // Internal: constructors and data.
297a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
298a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek
2991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0),
300d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek          BlkExprMap(NULL) {};
3011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
30263f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  ~CFG();
3031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
304ce1eb34bbea1e0408f1952776d7d52ccde1bd275Ted Kremenek  llvm::BumpPtrAllocator& getAllocator() {
305ce1eb34bbea1e0408f1952776d7d52ccde1bd275Ted Kremenek    return Alloc;
306ce1eb34bbea1e0408f1952776d7d52ccde1bd275Ted Kremenek  }
3071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
308a36c6540346266f570b2fc7457950dea45d89988Ted Kremenekprivate:
309a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  CFGBlock* Entry;
310a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  CFGBlock* Exit;
311a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  CFGBlock* IndirectGotoBlock;  // Special block to contain collective dispatch
312a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  // for indirect gotos
313a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  CFGBlockListTy Blocks;
31463f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  unsigned  NumBlockIDs;
3151eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
31686d1777a6b7723865c1e67a7aafc797ec0a574ffTed Kremenek  // BlkExprMap - An opaque pointer to prevent inclusion of DenseMap.h.
3171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  //  It represents a map from Expr* to integers to record the set of
31886d1777a6b7723865c1e67a7aafc797ec0a574ffTed Kremenek  //  block-level expressions and their "statement number" in the CFG.
31963f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  void*     BlkExprMap;
3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
321d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  /// Alloc - An internal allocator.
3221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::BumpPtrAllocator Alloc;
323fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek};
324fa2be43dbd6fdc4414e261db69aaf35dfb21a416Ted Kremenek} // end namespace clang
3257dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3267dba8607e59096014b7139ff20ef00870041d518Ted Kremenek//===----------------------------------------------------------------------===//
3277dba8607e59096014b7139ff20ef00870041d518Ted Kremenek// GraphTraits specializations for CFG basic block graphs (source-level CFGs)
3287dba8607e59096014b7139ff20ef00870041d518Ted Kremenek//===----------------------------------------------------------------------===//
3297dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3307dba8607e59096014b7139ff20ef00870041d518Ted Kremeneknamespace llvm {
3317dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3327dba8607e59096014b7139ff20ef00870041d518Ted Kremenek// Traits for: CFGBlock
3337dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3347dba8607e59096014b7139ff20ef00870041d518Ted Kremenektemplate <> struct GraphTraits<clang::CFGBlock* > {
3357dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  typedef clang::CFGBlock NodeType;
3367dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  typedef clang::CFGBlock::succ_iterator ChildIteratorType;
3371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3387dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static NodeType* getEntryNode(clang::CFGBlock* BB)
3397dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return BB; }
3407dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3417dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static inline ChildIteratorType child_begin(NodeType* N)
3427dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return N->succ_begin(); }
3431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3447dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static inline ChildIteratorType child_end(NodeType* N)
3457dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return N->succ_end(); }
3467dba8607e59096014b7139ff20ef00870041d518Ted Kremenek};
3477dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3487dba8607e59096014b7139ff20ef00870041d518Ted Kremenektemplate <> struct GraphTraits<const clang::CFGBlock* > {
3497dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  typedef const clang::CFGBlock NodeType;
3507dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  typedef clang::CFGBlock::const_succ_iterator ChildIteratorType;
3511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3527dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static NodeType* getEntryNode(const clang::CFGBlock* BB)
3537dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return BB; }
3541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3557dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static inline ChildIteratorType child_begin(NodeType* N)
3567dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return N->succ_begin(); }
3571eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3587dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static inline ChildIteratorType child_end(NodeType* N)
3597dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return N->succ_end(); }
3607dba8607e59096014b7139ff20ef00870041d518Ted Kremenek};
3617dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3627dba8607e59096014b7139ff20ef00870041d518Ted Kremenektemplate <> struct GraphTraits<Inverse<const clang::CFGBlock*> > {
3637dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  typedef const clang::CFGBlock NodeType;
3647dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  typedef clang::CFGBlock::const_pred_iterator ChildIteratorType;
3657dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3667dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static NodeType *getEntryNode(Inverse<const clang::CFGBlock*> G)
3677dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return G.Graph; }
3687dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3697dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static inline ChildIteratorType child_begin(NodeType* N)
3707dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return N->pred_begin(); }
3711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3727dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static inline ChildIteratorType child_end(NodeType* N)
3737dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return N->pred_end(); }
3747dba8607e59096014b7139ff20ef00870041d518Ted Kremenek};
3757dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3767dba8607e59096014b7139ff20ef00870041d518Ted Kremenek// Traits for: CFG
3777dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate <> struct GraphTraits<clang::CFG* >
3797dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            : public GraphTraits<clang::CFGBlock* >  {
3807dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3817dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  typedef clang::CFG::iterator nodes_iterator;
3821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static NodeType *getEntryNode(clang::CFG* F) { return &F->getEntry(); }
3847dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static nodes_iterator nodes_begin(clang::CFG* F) { return F->begin(); }
3857dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static nodes_iterator nodes_end(clang::CFG* F) { return F->end(); }
3867dba8607e59096014b7139ff20ef00870041d518Ted Kremenek};
3877dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate <> struct GraphTraits< const clang::CFG* >
3897dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            : public GraphTraits< const clang::CFGBlock* >  {
3907dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  typedef clang::CFG::const_iterator nodes_iterator;
3927dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3937dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static NodeType *getEntryNode( const clang::CFG* F) { return &F->getEntry(); }
3947dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static nodes_iterator nodes_begin( const clang::CFG* F) { return F->begin(); }
3957dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static nodes_iterator nodes_end( const clang::CFG* F) { return F->end(); }
3967dba8607e59096014b7139ff20ef00870041d518Ted Kremenek};
3977dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3987dba8607e59096014b7139ff20ef00870041d518Ted Kremenektemplate <> struct GraphTraits<Inverse<const clang::CFG*> >
3997dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            : public GraphTraits<Inverse<const clang::CFGBlock*> > {
4007dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
4017dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  typedef clang::CFG::const_iterator nodes_iterator;
4027dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
4037dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static NodeType *getEntryNode(const clang::CFG* F) { return &F->getExit(); }
4047dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static nodes_iterator nodes_begin(const clang::CFG* F) { return F->begin();}
4057dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static nodes_iterator nodes_end(const clang::CFG* F) { return F->end(); }
4067dba8607e59096014b7139ff20ef00870041d518Ted Kremenek};
4071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4087dba8607e59096014b7139ff20ef00870041d518Ted Kremenek} // end llvm namespace
409cd881d534517f09a2fae10445f9b865f49ccc6c8Ted Kremenek
410cd881d534517f09a2fae10445f9b865f49ccc6c8Ted Kremenek#endif
411