CFG.h revision 6c2497248bc4f7fd8e5fb0a206d20abbf0e16645
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 {
606c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek  class StatementList {
616c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    typedef std::vector<Stmt*> ImplTy;
626c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    ImplTy Impl;
636c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek  public:
646c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    typedef std::reverse_iterator<ImplTy::iterator>       iterator;
656c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    typedef std::reverse_iterator<ImplTy::const_iterator> const_iterator;
666c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    typedef ImplTy::iterator                              reverse_iterator;
676c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    typedef ImplTy::const_iterator                        const_reverse_iterator;
686c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek
696c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    void push_back(Stmt *s) { Impl.push_back(s); }
706c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    Stmt *front() const { return Impl.back(); }
716c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    Stmt *back() const { return Impl.front(); }
726c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek
736c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    iterator begin() { return Impl.rbegin(); }
746c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    iterator end() { return Impl.rend(); }
756c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    const_iterator begin() const { return Impl.rbegin(); }
766c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    const_iterator end() const { return Impl.rend(); }
776c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    reverse_iterator rbegin() { return Impl.begin(); }
786c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    reverse_iterator rend() { return Impl.end(); }
796c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    const_reverse_iterator rbegin() const { return Impl.begin(); }
806c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    const_reverse_iterator rend() const { return Impl.end(); }
816c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek
826c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek   Stmt*  operator[](size_t i) const  {
836c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek     assert(i < Impl.size());
846c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek     return Impl[Impl.size() - 1 - i];
856c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek   }
866c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek
876c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    size_t size() const { return Impl.size(); }
886c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek    bool empty() const { return Impl.empty(); }
896c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek  };
906c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek
91fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  /// Stmts - The set of statements in the basic block.
926c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek  StatementList Stmts;
939cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek
949cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  /// Label - An (optional) label that prefixes the executable
959cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  ///  statements in the block.  When this variable is non-NULL, it is
969cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  ///  either an instance of LabelStmt or SwitchCase.
973575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek  Stmt *Label;
981eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
999cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  /// Terminator - The terminator for a basic block that
100fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  ///  indicates the type of control-flow that occurs between a block
101fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  ///  and its successors.
1023575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek  Stmt *Terminator;
1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1043575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek  /// LoopTarget - Some blocks are used to represent the "loop edge" to
1053575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek  ///  the start of a loop from within the loop body.  This Stmt* will be
1063575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek  ///  refer to the loop statement for such blocks (and be null otherwise).
1071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const Stmt *LoopTarget;
1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
109fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  /// BlockID - A numerical ID assigned to a CFGBlock during construction
110fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  ///   of the CFG.
111fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  unsigned BlockID;
1121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
113fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  /// Predecessors/Successors - Keep track of the predecessor / successor
114fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  /// CFG blocks.
115fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef std::vector<CFGBlock*> AdjacentBlocks;
116fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  AdjacentBlocks Preds;
117fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  AdjacentBlocks Succs;
1181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
119fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekpublic:
1209cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  explicit CFGBlock(unsigned blockid) : Label(NULL), Terminator(NULL),
1213575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek                                        LoopTarget(NULL), BlockID(blockid) {}
122fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  ~CFGBlock() {};
123fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
124fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  // Statement iterators
1256c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek  typedef StatementList::iterator                      iterator;
1266c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek  typedef StatementList::const_iterator                const_iterator;
1276c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek  typedef StatementList::reverse_iterator              reverse_iterator;
1286c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek  typedef StatementList::const_reverse_iterator        const_reverse_iterator;
1291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1305156ad8b2e64850a13d4e9d9ddeb3f9c6b9d3ebbTed Kremenek  Stmt*                        front()       const { return Stmts.front();   }
1315156ad8b2e64850a13d4e9d9ddeb3f9c6b9d3ebbTed Kremenek  Stmt*                        back()        const { return Stmts.back();    }
1321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
133fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  iterator                     begin()             { return Stmts.begin();   }
134fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  iterator                     end()               { return Stmts.end();     }
135fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_iterator               begin()       const { return Stmts.begin();   }
1361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const_iterator               end()         const { return Stmts.end();     }
137fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
138fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  reverse_iterator             rbegin()            { return Stmts.rbegin();  }
139fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  reverse_iterator             rend()              { return Stmts.rend();    }
140fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_reverse_iterator       rbegin()      const { return Stmts.rbegin();  }
141fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_reverse_iterator       rend()        const { return Stmts.rend();    }
1421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
143fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  unsigned                     size()        const { return Stmts.size();    }
144fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  bool                         empty()       const { return Stmts.empty();   }
145be7a7d6f2e5b86807afd08a568863df973baaa38Ted Kremenek
1466c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek  Stmt*  operator[](size_t i) const  { return Stmts[i]; }
1476c2497248bc4f7fd8e5fb0a206d20abbf0e16645Ted Kremenek
1481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
149fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  // CFG iterators
150fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef AdjacentBlocks::iterator                              pred_iterator;
151fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef AdjacentBlocks::const_iterator                  const_pred_iterator;
152fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef AdjacentBlocks::reverse_iterator              pred_reverse_iterator;
153fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef AdjacentBlocks::const_reverse_iterator  const_pred_reverse_iterator;
154fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
155fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef AdjacentBlocks::iterator                              succ_iterator;
156fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef AdjacentBlocks::const_iterator                  const_succ_iterator;
157fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef AdjacentBlocks::reverse_iterator              succ_reverse_iterator;
158fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  typedef AdjacentBlocks::const_reverse_iterator  const_succ_reverse_iterator;
1591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
160fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  pred_iterator                pred_begin()        { return Preds.begin();   }
161fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  pred_iterator                pred_end()          { return Preds.end();     }
162fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_pred_iterator          pred_begin()  const { return Preds.begin();   }
163fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_pred_iterator          pred_end()    const { return Preds.end();     }
1641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
165fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  pred_reverse_iterator        pred_rbegin()       { return Preds.rbegin();  }
1661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  pred_reverse_iterator        pred_rend()         { return Preds.rend();    }
167fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_pred_reverse_iterator  pred_rbegin() const { return Preds.rbegin();  }
168fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_pred_reverse_iterator  pred_rend()   const { return Preds.rend();    }
169fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
1701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  succ_iterator                succ_begin()        { return Succs.begin();   }
171fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  succ_iterator                succ_end()          { return Succs.end();     }
172fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_succ_iterator          succ_begin()  const { return Succs.begin();   }
1731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const_succ_iterator          succ_end()    const { return Succs.end();     }
1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
175fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  succ_reverse_iterator        succ_rbegin()       { return Succs.rbegin();  }
176fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  succ_reverse_iterator        succ_rend()         { return Succs.rend();    }
177fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_succ_reverse_iterator  succ_rbegin() const { return Succs.rbegin();  }
178fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  const_succ_reverse_iterator  succ_rend()   const { return Succs.rend();    }
179fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
180fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  unsigned                     succ_size()   const { return Succs.size();    }
181fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  bool                         succ_empty()  const { return Succs.empty();   }
182fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
183fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  unsigned                     pred_size()   const { return Preds.size();    }
184fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  bool                         pred_empty()  const { return Preds.empty();   }
1851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
186fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  // Manipulation of block contents
1871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
188fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  void appendStmt(Stmt* Statement) { Stmts.push_back(Statement); }
1899cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  void setTerminator(Stmt* Statement) { Terminator = Statement; }
1909cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  void setLabel(Stmt* Statement) { Label = Statement; }
1913575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek  void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; }
1929cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek
1939cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  Stmt* getTerminator() { return Terminator; }
1949cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  const Stmt* getTerminator() const { return Terminator; }
1951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
196390e48b15ad93f85bfd1e33b9992c198fa0db475Ted Kremenek  Stmt* getTerminatorCondition();
1971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
198390e48b15ad93f85bfd1e33b9992c198fa0db475Ted Kremenek  const Stmt* getTerminatorCondition() const {
199411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek    return const_cast<CFGBlock*>(this)->getTerminatorCondition();
200411cdee0b490f79428c9eb977f25199eb7d21cd8Ted Kremenek  }
2011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2023575f84e459033d6427b84b4b795b22c85c4d27dTed Kremenek  const Stmt *getLoopTarget() const { return LoopTarget; }
2031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2049c2535a35db35b3a821a0d0c36a01a16f52f1ad0Ted Kremenek  bool hasBinaryBranchTerminator() const;
2051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
2069cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  Stmt* getLabel() { return Label; }
2079cffe7366ea3beb33c2d58f43a8c3a04c1873e11Ted Kremenek  const Stmt* getLabel() const { return Label; }
2081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
209fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  void reverseStmts();
2101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
211fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  void addSuccessor(CFGBlock* Block) {
212e5af3ce53ec58995b09381ba645ab2117a46647bMike Stump    if (Block)
213e5af3ce53ec58995b09381ba645ab2117a46647bMike Stump      Block->Preds.push_back(this);
214fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek    Succs.push_back(Block);
215fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  }
2161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
217fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek  unsigned getBlockID() const { return BlockID; }
2181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
219e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  void dump(const CFG *cfg, const LangOptions &LO) const;
220e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  void print(llvm::raw_ostream &OS, const CFG* cfg, const LangOptions &LO) const;
221e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  void printTerminator(llvm::raw_ostream &OS, const LangOptions &LO) const;
222fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek};
2231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
224fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
225fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek/// CFG - Represents a source-level, intra-procedural CFG that represents the
226fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  control-flow of a Stmt.  The Stmt can represent an entire function body,
227fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  or a single expression.  A CFG will always contain one empty block that
228fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  represents the Exit point of the CFG.  A CFG will also contain a designated
229fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  Entry block.  The CFG solely represents control-flow; it consists of
230fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  CFGBlocks which are simply containers of Stmt*'s in the AST the CFG
231fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek///  was constructed from.
232fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekclass CFG {
233fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenekpublic:
234a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
235a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  // CFG Construction & Manipulation.
236a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
237a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek
238a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  /// buildCFG - Builds a CFG from an AST.  The responsibility to free the
2391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ///   constructed CFG belongs to the caller.
2401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static CFG* buildCFG(Stmt* AST, ASTContext *C);
2411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
242a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  /// createBlock - Create a new block in the CFG.  The CFG owns the block;
243a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  ///  the caller should not directly free it.
244a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  CFGBlock* createBlock();
2451eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
246a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  /// setEntry - Set the entry block of the CFG.  This is typically used
247a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  ///  only during CFG construction.  Most CFG clients expect that the
248a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  ///  entry block has no predecessors and contains no statements.
249a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  void setEntry(CFGBlock *B) { Entry = B; }
2501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
251e38158de9236dfcded7da56126134e5e3e49cb01Ted Kremenek  /// setIndirectGotoBlock - Set the block used for indirect goto jumps.
252e38158de9236dfcded7da56126134e5e3e49cb01Ted Kremenek  ///  This is typically used only during CFG construction.
253a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  void setIndirectGotoBlock(CFGBlock* B) { IndirectGotoBlock = B; }
2541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
255a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
256a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  // Block Iterators
257a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
258a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek
259a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  typedef std::list<CFGBlock>                      CFGBlockListTy;
2601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
261a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  typedef CFGBlockListTy::iterator                 iterator;
262a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  typedef CFGBlockListTy::const_iterator           const_iterator;
263a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  typedef std::reverse_iterator<iterator>          reverse_iterator;
264a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
265fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek
26619bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  CFGBlock&                 front()                { return Blocks.front(); }
26719bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  CFGBlock&                 back()                 { return Blocks.back(); }
2681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
26919bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  iterator                  begin()                { return Blocks.begin(); }
27019bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  iterator                  end()                  { return Blocks.end(); }
27119bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  const_iterator            begin()       const    { return Blocks.begin(); }
2721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  const_iterator            end()         const    { return Blocks.end(); }
2731eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
27419bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  reverse_iterator          rbegin()               { return Blocks.rbegin(); }
27519bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  reverse_iterator          rend()                 { return Blocks.rend(); }
27619bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  const_reverse_iterator    rbegin()      const    { return Blocks.rbegin(); }
27719bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  const_reverse_iterator    rend()        const    { return Blocks.rend(); }
2781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
27919bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  CFGBlock&                 getEntry()             { return *Entry; }
2807dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  const CFGBlock&           getEntry()    const    { return *Entry; }
28119bb356317952445b03ee341c02f6147083c9eeaTed Kremenek  CFGBlock&                 getExit()              { return *Exit; }
2827dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  const CFGBlock&           getExit()     const    { return *Exit; }
2837dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
2847dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  CFGBlock*        getIndirectGotoBlock() { return IndirectGotoBlock; }
2857dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  const CFGBlock*  getIndirectGotoBlock() const { return IndirectGotoBlock; }
2861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
287a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
288a90b0d1e585d993621a342d0b2874e61941372d5Ted Kremenek  // Member templates useful for various batch operations over CFGs.
289a90b0d1e585d993621a342d0b2874e61941372d5Ted Kremenek  //===--------------------------------------------------------------------===//
2901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
291a90b0d1e585d993621a342d0b2874e61941372d5Ted Kremenek  template <typename CALLBACK>
292a90b0d1e585d993621a342d0b2874e61941372d5Ted Kremenek  void VisitBlockStmts(CALLBACK& O) const {
293a90b0d1e585d993621a342d0b2874e61941372d5Ted Kremenek    for (const_iterator I=begin(), E=end(); I != E; ++I)
294a90b0d1e585d993621a342d0b2874e61941372d5Ted Kremenek      for (CFGBlock::const_iterator BI=I->begin(), BE=I->end(); BI != BE; ++BI)
295a90b0d1e585d993621a342d0b2874e61941372d5Ted Kremenek        O(*BI);
2961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
2971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
298a90b0d1e585d993621a342d0b2874e61941372d5Ted Kremenek  //===--------------------------------------------------------------------===//
299a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  // CFG Introspection.
300a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
301a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek
30263f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  struct   BlkExprNumTy {
30363f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek    const signed Idx;
30463f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek    explicit BlkExprNumTy(signed idx) : Idx(idx) {}
30563f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek    explicit BlkExprNumTy() : Idx(-1) {}
30663f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek    operator bool() const { return Idx >= 0; }
30763f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek    operator unsigned() const { assert(Idx >=0); return (unsigned) Idx; }
30863f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  };
3091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
31086946745225096243f6969dc745267b78fc211a6Ted Kremenek  bool          isBlkExpr(const Stmt* S) { return getBlkExprNum(S); }
31186946745225096243f6969dc745267b78fc211a6Ted Kremenek  BlkExprNumTy  getBlkExprNum(const Stmt* S);
31263f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  unsigned      getNumBlkExprs();
3131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3140c8c5365be0176e8399e97d7da3293c79bc9da24Mike Stump  /// getNumBlockIDs - Returns the total number of BlockIDs allocated (which
3150c8c5365be0176e8399e97d7da3293c79bc9da24Mike Stump  /// start at 0).
3169438252ad2ecae5338df565ca33c6969e4fbfa41Ted Kremenek  unsigned getNumBlockIDs() const { return NumBlockIDs; }
317a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek
318a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
319a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  // CFG Debugging: Pretty-Printing and Visualization.
320a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
321a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek
322e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  void viewCFG(const LangOptions &LO) const;
323e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  void print(llvm::raw_ostream& OS, const LangOptions &LO) const;
324e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner  void dump(const LangOptions &LO) const;
325a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek
326a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
327a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  // Internal: constructors and data.
328a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  //===--------------------------------------------------------------------===//
329a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek
3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0),
331d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek          BlkExprMap(NULL) {};
3321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
33363f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  ~CFG();
3341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
335ce1eb34bbea1e0408f1952776d7d52ccde1bd275Ted Kremenek  llvm::BumpPtrAllocator& getAllocator() {
336ce1eb34bbea1e0408f1952776d7d52ccde1bd275Ted Kremenek    return Alloc;
337ce1eb34bbea1e0408f1952776d7d52ccde1bd275Ted Kremenek  }
3381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
339a36c6540346266f570b2fc7457950dea45d89988Ted Kremenekprivate:
340a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  CFGBlock* Entry;
341a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  CFGBlock* Exit;
342a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  CFGBlock* IndirectGotoBlock;  // Special block to contain collective dispatch
343a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  // for indirect gotos
344a36c6540346266f570b2fc7457950dea45d89988Ted Kremenek  CFGBlockListTy Blocks;
34563f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  unsigned  NumBlockIDs;
3461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
34786d1777a6b7723865c1e67a7aafc797ec0a574ffTed Kremenek  // BlkExprMap - An opaque pointer to prevent inclusion of DenseMap.h.
3481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  //  It represents a map from Expr* to integers to record the set of
34986d1777a6b7723865c1e67a7aafc797ec0a574ffTed Kremenek  //  block-level expressions and their "statement number" in the CFG.
35063f5887f316fb52d243fcbb3631c039de6c4b993Ted Kremenek  void*     BlkExprMap;
3511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
352d452758bb6b59340528a26def9ecc24b329d4ecfTed Kremenek  /// Alloc - An internal allocator.
3531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  llvm::BumpPtrAllocator Alloc;
354fddd51853f8ccaa1df2476376e6fd74d2f315c73Ted Kremenek};
355fa2be43dbd6fdc4414e261db69aaf35dfb21a416Ted Kremenek} // end namespace clang
3567dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3577dba8607e59096014b7139ff20ef00870041d518Ted Kremenek//===----------------------------------------------------------------------===//
3587dba8607e59096014b7139ff20ef00870041d518Ted Kremenek// GraphTraits specializations for CFG basic block graphs (source-level CFGs)
3597dba8607e59096014b7139ff20ef00870041d518Ted Kremenek//===----------------------------------------------------------------------===//
3607dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3617dba8607e59096014b7139ff20ef00870041d518Ted Kremeneknamespace llvm {
3627dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3637dba8607e59096014b7139ff20ef00870041d518Ted Kremenek// Traits for: CFGBlock
3647dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3657dba8607e59096014b7139ff20ef00870041d518Ted Kremenektemplate <> struct GraphTraits<clang::CFGBlock* > {
3667dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  typedef clang::CFGBlock NodeType;
3677dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  typedef clang::CFGBlock::succ_iterator ChildIteratorType;
3681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3697dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static NodeType* getEntryNode(clang::CFGBlock* BB)
3707dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return BB; }
3717dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3727dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static inline ChildIteratorType child_begin(NodeType* N)
3737dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return N->succ_begin(); }
3741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3757dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static inline ChildIteratorType child_end(NodeType* N)
3767dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return N->succ_end(); }
3777dba8607e59096014b7139ff20ef00870041d518Ted Kremenek};
3787dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3797dba8607e59096014b7139ff20ef00870041d518Ted Kremenektemplate <> struct GraphTraits<const clang::CFGBlock* > {
3807dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  typedef const clang::CFGBlock NodeType;
3817dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  typedef clang::CFGBlock::const_succ_iterator ChildIteratorType;
3821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3837dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static NodeType* getEntryNode(const clang::CFGBlock* BB)
3847dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return BB; }
3851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3867dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static inline ChildIteratorType child_begin(NodeType* N)
3877dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return N->succ_begin(); }
3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
3897dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static inline ChildIteratorType child_end(NodeType* N)
3907dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return N->succ_end(); }
3917dba8607e59096014b7139ff20ef00870041d518Ted Kremenek};
3927dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3937dba8607e59096014b7139ff20ef00870041d518Ted Kremenektemplate <> struct GraphTraits<Inverse<const clang::CFGBlock*> > {
3947dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  typedef const clang::CFGBlock NodeType;
3957dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  typedef clang::CFGBlock::const_pred_iterator ChildIteratorType;
3967dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
3977dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static NodeType *getEntryNode(Inverse<const clang::CFGBlock*> G)
3987dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return G.Graph; }
3997dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
4007dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static inline ChildIteratorType child_begin(NodeType* N)
4017dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return N->pred_begin(); }
4021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4037dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static inline ChildIteratorType child_end(NodeType* N)
4047dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  { return N->pred_end(); }
4057dba8607e59096014b7139ff20ef00870041d518Ted Kremenek};
4067dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
4077dba8607e59096014b7139ff20ef00870041d518Ted Kremenek// Traits for: CFG
4087dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
4091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate <> struct GraphTraits<clang::CFG* >
4107dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            : public GraphTraits<clang::CFGBlock* >  {
4117dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
4127dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  typedef clang::CFG::iterator nodes_iterator;
4131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static NodeType *getEntryNode(clang::CFG* F) { return &F->getEntry(); }
4157dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static nodes_iterator nodes_begin(clang::CFG* F) { return F->begin(); }
4167dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static nodes_iterator nodes_end(clang::CFG* F) { return F->end(); }
4177dba8607e59096014b7139ff20ef00870041d518Ted Kremenek};
4187dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
4191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumptemplate <> struct GraphTraits< const clang::CFG* >
4207dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            : public GraphTraits< const clang::CFGBlock* >  {
4217dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
4221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  typedef clang::CFG::const_iterator nodes_iterator;
4237dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
4247dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static NodeType *getEntryNode( const clang::CFG* F) { return &F->getEntry(); }
4257dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static nodes_iterator nodes_begin( const clang::CFG* F) { return F->begin(); }
4267dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static nodes_iterator nodes_end( const clang::CFG* F) { return F->end(); }
4277dba8607e59096014b7139ff20ef00870041d518Ted Kremenek};
4287dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
4297dba8607e59096014b7139ff20ef00870041d518Ted Kremenektemplate <> struct GraphTraits<Inverse<const clang::CFG*> >
4307dba8607e59096014b7139ff20ef00870041d518Ted Kremenek            : public GraphTraits<Inverse<const clang::CFGBlock*> > {
4317dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
4327dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  typedef clang::CFG::const_iterator nodes_iterator;
4337dba8607e59096014b7139ff20ef00870041d518Ted Kremenek
4347dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static NodeType *getEntryNode(const clang::CFG* F) { return &F->getExit(); }
4357dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static nodes_iterator nodes_begin(const clang::CFG* F) { return F->begin();}
4367dba8607e59096014b7139ff20ef00870041d518Ted Kremenek  static nodes_iterator nodes_end(const clang::CFG* F) { return F->end(); }
4377dba8607e59096014b7139ff20ef00870041d518Ted Kremenek};
4381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4397dba8607e59096014b7139ff20ef00870041d518Ted Kremenek} // end llvm namespace
440cd881d534517f09a2fae10445f9b865f49ccc6c8Ted Kremenek
441cd881d534517f09a2fae10445f9b865f49ccc6c8Ted Kremenek#endif
442