clang API Documentation

CFG.h
Go to the documentation of this file.
00001 //===--- CFG.h - Classes for representing and building CFGs------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file defines the CFG and CFGBuilder classes for representing and
00011 //  building Control-Flow Graphs (CFGs) from ASTs.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_CLANG_CFG_H
00016 #define LLVM_CLANG_CFG_H
00017 
00018 #include "llvm/ADT/PointerIntPair.h"
00019 #include "llvm/ADT/GraphTraits.h"
00020 #include "llvm/Support/Allocator.h"
00021 #include "llvm/Support/Casting.h"
00022 #include "llvm/ADT/OwningPtr.h"
00023 #include "llvm/ADT/DenseMap.h"
00024 #include "llvm/ADT/BitVector.h"
00025 #include "clang/AST/Stmt.h"
00026 #include "clang/Analysis/Support/BumpVector.h"
00027 #include "clang/Basic/SourceLocation.h"
00028 #include <cassert>
00029 #include <iterator>
00030 
00031 namespace clang {
00032   class CXXDestructorDecl;
00033   class Decl;
00034   class Stmt;
00035   class Expr;
00036   class FieldDecl;
00037   class VarDecl;
00038   class CXXCtorInitializer;
00039   class CXXBaseSpecifier;
00040   class CXXBindTemporaryExpr;
00041   class CFG;
00042   class PrinterHelper;
00043   class LangOptions;
00044   class ASTContext;
00045 
00046 /// CFGElement - Represents a top-level expression in a basic block.
00047 class CFGElement {
00048 public:
00049   enum Kind {
00050     // main kind
00051     Invalid,
00052     Statement,
00053     Initializer,
00054     // dtor kind
00055     AutomaticObjectDtor,
00056     BaseDtor,
00057     MemberDtor,
00058     TemporaryDtor,
00059     DTOR_BEGIN = AutomaticObjectDtor,
00060     DTOR_END = TemporaryDtor
00061   };
00062 
00063 protected:
00064   // The int bits are used to mark the kind.
00065   llvm::PointerIntPair<void *, 2> Data1;
00066   llvm::PointerIntPair<void *, 2> Data2;
00067 
00068   CFGElement(Kind kind, const void *Ptr1, const void *Ptr2 = 0)
00069     : Data1(const_cast<void*>(Ptr1), ((unsigned) kind) & 0x3),
00070       Data2(const_cast<void*>(Ptr2), (((unsigned) kind) >> 2) & 0x3) {}
00071 
00072 public:
00073   CFGElement() {}
00074 
00075   Kind getKind() const {
00076     unsigned x = Data2.getInt();
00077     x <<= 2;
00078     x |= Data1.getInt();
00079     return (Kind) x;
00080   }
00081 
00082   bool isValid() const { return getKind() != Invalid; }
00083 
00084   operator bool() const { return isValid(); }
00085 
00086   template<class ElemTy> const ElemTy *getAs() const {
00087     if (llvm::isa<ElemTy>(this))
00088       return static_cast<const ElemTy*>(this);
00089     return 0;
00090   }
00091 
00092   static bool classof(const CFGElement *E) { return true; }
00093 };
00094 
00095 class CFGStmt : public CFGElement {
00096 public:
00097   CFGStmt(Stmt *S) : CFGElement(Statement, S) {}
00098 
00099   const Stmt *getStmt() const {
00100     return static_cast<const Stmt *>(Data1.getPointer());
00101   }
00102 
00103   static bool classof(const CFGElement *E) {
00104     return E->getKind() == Statement;
00105   }
00106 };
00107 
00108 /// CFGInitializer - Represents C++ base or member initializer from
00109 /// constructor's initialization list.
00110 class CFGInitializer : public CFGElement {
00111 public:
00112   CFGInitializer(CXXCtorInitializer *initializer)
00113       : CFGElement(Initializer, initializer) {}
00114 
00115   CXXCtorInitializer* getInitializer() const {
00116     return static_cast<CXXCtorInitializer*>(Data1.getPointer());
00117   }
00118 
00119   static bool classof(const CFGElement *E) {
00120     return E->getKind() == Initializer;
00121   }
00122 };
00123 
00124 /// CFGImplicitDtor - Represents C++ object destructor implicitly generated
00125 /// by compiler on various occasions.
00126 class CFGImplicitDtor : public CFGElement {
00127 protected:
00128   CFGImplicitDtor(Kind kind, const void *data1, const void *data2 = 0)
00129     : CFGElement(kind, data1, data2) {
00130     assert(kind >= DTOR_BEGIN && kind <= DTOR_END);
00131   }
00132 
00133 public:
00134   const CXXDestructorDecl *getDestructorDecl(ASTContext &astContext) const;
00135   bool isNoReturn(ASTContext &astContext) const;
00136 
00137   static bool classof(const CFGElement *E) {
00138     Kind kind = E->getKind();
00139     return kind >= DTOR_BEGIN && kind <= DTOR_END;
00140   }
00141 };
00142 
00143 /// CFGAutomaticObjDtor - Represents C++ object destructor implicitly generated
00144 /// for automatic object or temporary bound to const reference at the point
00145 /// of leaving its local scope.
00146 class CFGAutomaticObjDtor: public CFGImplicitDtor {
00147 public:
00148   CFGAutomaticObjDtor(const VarDecl *var, const Stmt *stmt)
00149       : CFGImplicitDtor(AutomaticObjectDtor, var, stmt) {}
00150 
00151   const VarDecl *getVarDecl() const {
00152     return static_cast<VarDecl*>(Data1.getPointer());
00153   }
00154 
00155   // Get statement end of which triggered the destructor call.
00156   const Stmt *getTriggerStmt() const {
00157     return static_cast<Stmt*>(Data2.getPointer());
00158   }
00159 
00160   static bool classof(const CFGElement *elem) {
00161     return elem->getKind() == AutomaticObjectDtor;
00162   }
00163 };
00164 
00165 /// CFGBaseDtor - Represents C++ object destructor implicitly generated for
00166 /// base object in destructor.
00167 class CFGBaseDtor : public CFGImplicitDtor {
00168 public:
00169   CFGBaseDtor(const CXXBaseSpecifier *base)
00170       : CFGImplicitDtor(BaseDtor, base) {}
00171 
00172   const CXXBaseSpecifier *getBaseSpecifier() const {
00173     return static_cast<const CXXBaseSpecifier*>(Data1.getPointer());
00174   }
00175 
00176   static bool classof(const CFGElement *E) {
00177     return E->getKind() == BaseDtor;
00178   }
00179 };
00180 
00181 /// CFGMemberDtor - Represents C++ object destructor implicitly generated for
00182 /// member object in destructor.
00183 class CFGMemberDtor : public CFGImplicitDtor {
00184 public:
00185   CFGMemberDtor(const FieldDecl *field)
00186       : CFGImplicitDtor(MemberDtor, field, 0) {}
00187 
00188   const FieldDecl *getFieldDecl() const {
00189     return static_cast<const FieldDecl*>(Data1.getPointer());
00190   }
00191 
00192   static bool classof(const CFGElement *E) {
00193     return E->getKind() == MemberDtor;
00194   }
00195 };
00196 
00197 /// CFGTemporaryDtor - Represents C++ object destructor implicitly generated
00198 /// at the end of full expression for temporary object.
00199 class CFGTemporaryDtor : public CFGImplicitDtor {
00200 public:
00201   CFGTemporaryDtor(CXXBindTemporaryExpr *expr)
00202       : CFGImplicitDtor(TemporaryDtor, expr, 0) {}
00203 
00204   const CXXBindTemporaryExpr *getBindTemporaryExpr() const {
00205     return static_cast<const CXXBindTemporaryExpr *>(Data1.getPointer());
00206   }
00207 
00208   static bool classof(const CFGElement *E) {
00209     return E->getKind() == TemporaryDtor;
00210   }
00211 };
00212 
00213 /// CFGTerminator - Represents CFGBlock terminator statement.
00214 ///
00215 /// TemporaryDtorsBranch bit is set to true if the terminator marks a branch
00216 /// in control flow of destructors of temporaries. In this case terminator
00217 /// statement is the same statement that branches control flow in evaluation
00218 /// of matching full expression.
00219 class CFGTerminator {
00220   llvm::PointerIntPair<Stmt *, 1> Data;
00221 public:
00222   CFGTerminator() {}
00223   CFGTerminator(Stmt *S, bool TemporaryDtorsBranch = false)
00224       : Data(S, TemporaryDtorsBranch) {}
00225 
00226   Stmt *getStmt() { return Data.getPointer(); }
00227   const Stmt *getStmt() const { return Data.getPointer(); }
00228 
00229   bool isTemporaryDtorsBranch() const { return Data.getInt(); }
00230 
00231   operator Stmt *() { return getStmt(); }
00232   operator const Stmt *() const { return getStmt(); }
00233 
00234   Stmt *operator->() { return getStmt(); }
00235   const Stmt *operator->() const { return getStmt(); }
00236 
00237   Stmt &operator*() { return *getStmt(); }
00238   const Stmt &operator*() const { return *getStmt(); }
00239 
00240   operator bool() const { return getStmt(); }
00241 };
00242 
00243 /// CFGBlock - Represents a single basic block in a source-level CFG.
00244 ///  It consists of:
00245 ///
00246 ///  (1) A set of statements/expressions (which may contain subexpressions).
00247 ///  (2) A "terminator" statement (not in the set of statements).
00248 ///  (3) A list of successors and predecessors.
00249 ///
00250 /// Terminator: The terminator represents the type of control-flow that occurs
00251 /// at the end of the basic block.  The terminator is a Stmt* referring to an
00252 /// AST node that has control-flow: if-statements, breaks, loops, etc.
00253 /// If the control-flow is conditional, the condition expression will appear
00254 /// within the set of statements in the block (usually the last statement).
00255 ///
00256 /// Predecessors: the order in the set of predecessors is arbitrary.
00257 ///
00258 /// Successors: the order in the set of successors is NOT arbitrary.  We
00259 ///  currently have the following orderings based on the terminator:
00260 ///
00261 ///     Terminator       Successor Ordering
00262 ///  -----------------------------------------------------
00263 ///       if            Then Block;  Else Block
00264 ///     ? operator      LHS expression;  RHS expression
00265 ///     &&, ||          expression that uses result of && or ||, RHS
00266 ///
00267 /// But note that any of that may be NULL in case of optimized-out edges.
00268 ///
00269 class CFGBlock {
00270   class ElementList {
00271     typedef BumpVector<CFGElement> ImplTy;
00272     ImplTy Impl;
00273   public:
00274     ElementList(BumpVectorContext &C) : Impl(C, 4) {}
00275 
00276     typedef std::reverse_iterator<ImplTy::iterator>       iterator;
00277     typedef std::reverse_iterator<ImplTy::const_iterator> const_iterator;
00278     typedef ImplTy::iterator                              reverse_iterator;
00279     typedef ImplTy::const_iterator                       const_reverse_iterator;
00280     typedef ImplTy::const_reference                       const_reference;
00281 
00282     void push_back(CFGElement e, BumpVectorContext &C) { Impl.push_back(e, C); }
00283     reverse_iterator insert(reverse_iterator I, size_t Cnt, CFGElement E,
00284         BumpVectorContext &C) {
00285       return Impl.insert(I, Cnt, E, C);
00286     }
00287 
00288     const_reference front() const { return Impl.back(); }
00289     const_reference back() const { return Impl.front(); }
00290 
00291     iterator begin() { return Impl.rbegin(); }
00292     iterator end() { return Impl.rend(); }
00293     const_iterator begin() const { return Impl.rbegin(); }
00294     const_iterator end() const { return Impl.rend(); }
00295     reverse_iterator rbegin() { return Impl.begin(); }
00296     reverse_iterator rend() { return Impl.end(); }
00297     const_reverse_iterator rbegin() const { return Impl.begin(); }
00298     const_reverse_iterator rend() const { return Impl.end(); }
00299 
00300    CFGElement operator[](size_t i) const  {
00301      assert(i < Impl.size());
00302      return Impl[Impl.size() - 1 - i];
00303    }
00304 
00305     size_t size() const { return Impl.size(); }
00306     bool empty() const { return Impl.empty(); }
00307   };
00308 
00309   /// Stmts - The set of statements in the basic block.
00310   ElementList Elements;
00311 
00312   /// Label - An (optional) label that prefixes the executable
00313   ///  statements in the block.  When this variable is non-NULL, it is
00314   ///  either an instance of LabelStmt, SwitchCase or CXXCatchStmt.
00315   Stmt *Label;
00316 
00317   /// Terminator - The terminator for a basic block that
00318   ///  indicates the type of control-flow that occurs between a block
00319   ///  and its successors.
00320   CFGTerminator Terminator;
00321 
00322   /// LoopTarget - Some blocks are used to represent the "loop edge" to
00323   ///  the start of a loop from within the loop body.  This Stmt* will be
00324   ///  refer to the loop statement for such blocks (and be null otherwise).
00325   const Stmt *LoopTarget;
00326 
00327   /// BlockID - A numerical ID assigned to a CFGBlock during construction
00328   ///   of the CFG.
00329   unsigned BlockID;
00330 
00331   /// Predecessors/Successors - Keep track of the predecessor / successor
00332   /// CFG blocks.
00333   typedef BumpVector<CFGBlock*> AdjacentBlocks;
00334   AdjacentBlocks Preds;
00335   AdjacentBlocks Succs;
00336 
00337   /// NoReturn - This bit is set when the basic block contains a function call
00338   /// or implicit destructor that is attributed as 'noreturn'. In that case,
00339   /// control cannot technically ever proceed past this block. All such blocks
00340   /// will have a single immediate successor: the exit block. This allows them
00341   /// to be easily reached from the exit block and using this bit quickly
00342   /// recognized without scanning the contents of the block.
00343   ///
00344   /// Optimization Note: This bit could be profitably folded with Terminator's
00345   /// storage if the memory usage of CFGBlock becomes an issue.
00346   unsigned HasNoReturnElement : 1;
00347 
00348   /// Parent - The parent CFG that owns this CFGBlock.
00349   CFG *Parent;
00350 
00351 public:
00352   explicit CFGBlock(unsigned blockid, BumpVectorContext &C, CFG *parent)
00353     : Elements(C), Label(NULL), Terminator(NULL), LoopTarget(NULL), 
00354       BlockID(blockid), Preds(C, 1), Succs(C, 1), HasNoReturnElement(false),
00355       Parent(parent) {}
00356   ~CFGBlock() {}
00357 
00358   // Statement iterators
00359   typedef ElementList::iterator                      iterator;
00360   typedef ElementList::const_iterator                const_iterator;
00361   typedef ElementList::reverse_iterator              reverse_iterator;
00362   typedef ElementList::const_reverse_iterator        const_reverse_iterator;
00363 
00364   CFGElement                 front()       const { return Elements.front();   }
00365   CFGElement                 back()        const { return Elements.back();    }
00366 
00367   iterator                   begin()             { return Elements.begin();   }
00368   iterator                   end()               { return Elements.end();     }
00369   const_iterator             begin()       const { return Elements.begin();   }
00370   const_iterator             end()         const { return Elements.end();     }
00371 
00372   reverse_iterator           rbegin()            { return Elements.rbegin();  }
00373   reverse_iterator           rend()              { return Elements.rend();    }
00374   const_reverse_iterator     rbegin()      const { return Elements.rbegin();  }
00375   const_reverse_iterator     rend()        const { return Elements.rend();    }
00376 
00377   unsigned                   size()        const { return Elements.size();    }
00378   bool                       empty()       const { return Elements.empty();   }
00379 
00380   CFGElement operator[](size_t i) const  { return Elements[i]; }
00381 
00382   // CFG iterators
00383   typedef AdjacentBlocks::iterator                              pred_iterator;
00384   typedef AdjacentBlocks::const_iterator                  const_pred_iterator;
00385   typedef AdjacentBlocks::reverse_iterator              pred_reverse_iterator;
00386   typedef AdjacentBlocks::const_reverse_iterator  const_pred_reverse_iterator;
00387 
00388   typedef AdjacentBlocks::iterator                              succ_iterator;
00389   typedef AdjacentBlocks::const_iterator                  const_succ_iterator;
00390   typedef AdjacentBlocks::reverse_iterator              succ_reverse_iterator;
00391   typedef AdjacentBlocks::const_reverse_iterator  const_succ_reverse_iterator;
00392 
00393   pred_iterator                pred_begin()        { return Preds.begin();   }
00394   pred_iterator                pred_end()          { return Preds.end();     }
00395   const_pred_iterator          pred_begin()  const { return Preds.begin();   }
00396   const_pred_iterator          pred_end()    const { return Preds.end();     }
00397 
00398   pred_reverse_iterator        pred_rbegin()       { return Preds.rbegin();  }
00399   pred_reverse_iterator        pred_rend()         { return Preds.rend();    }
00400   const_pred_reverse_iterator  pred_rbegin() const { return Preds.rbegin();  }
00401   const_pred_reverse_iterator  pred_rend()   const { return Preds.rend();    }
00402 
00403   succ_iterator                succ_begin()        { return Succs.begin();   }
00404   succ_iterator                succ_end()          { return Succs.end();     }
00405   const_succ_iterator          succ_begin()  const { return Succs.begin();   }
00406   const_succ_iterator          succ_end()    const { return Succs.end();     }
00407 
00408   succ_reverse_iterator        succ_rbegin()       { return Succs.rbegin();  }
00409   succ_reverse_iterator        succ_rend()         { return Succs.rend();    }
00410   const_succ_reverse_iterator  succ_rbegin() const { return Succs.rbegin();  }
00411   const_succ_reverse_iterator  succ_rend()   const { return Succs.rend();    }
00412 
00413   unsigned                     succ_size()   const { return Succs.size();    }
00414   bool                         succ_empty()  const { return Succs.empty();   }
00415 
00416   unsigned                     pred_size()   const { return Preds.size();    }
00417   bool                         pred_empty()  const { return Preds.empty();   }
00418 
00419 
00420   class FilterOptions {
00421   public:
00422     FilterOptions() {
00423       IgnoreDefaultsWithCoveredEnums = 0;
00424     }
00425 
00426     unsigned IgnoreDefaultsWithCoveredEnums : 1;
00427   };
00428 
00429   static bool FilterEdge(const FilterOptions &F, const CFGBlock *Src,
00430        const CFGBlock *Dst);
00431 
00432   template <typename IMPL, bool IsPred>
00433   class FilteredCFGBlockIterator {
00434   private:
00435     IMPL I, E;
00436     const FilterOptions F;
00437     const CFGBlock *From;
00438    public:
00439     explicit FilteredCFGBlockIterator(const IMPL &i, const IMPL &e,
00440               const CFGBlock *from,
00441               const FilterOptions &f)
00442       : I(i), E(e), F(f), From(from) {}
00443 
00444     bool hasMore() const { return I != E; }
00445 
00446     FilteredCFGBlockIterator &operator++() {
00447       do { ++I; } while (hasMore() && Filter(*I));
00448       return *this;
00449     }
00450 
00451     const CFGBlock *operator*() const { return *I; }
00452   private:
00453     bool Filter(const CFGBlock *To) {
00454       return IsPred ? FilterEdge(F, To, From) : FilterEdge(F, From, To);
00455     }
00456   };
00457 
00458   typedef FilteredCFGBlockIterator<const_pred_iterator, true>
00459           filtered_pred_iterator;
00460 
00461   typedef FilteredCFGBlockIterator<const_succ_iterator, false>
00462           filtered_succ_iterator;
00463 
00464   filtered_pred_iterator filtered_pred_start_end(const FilterOptions &f) const {
00465     return filtered_pred_iterator(pred_begin(), pred_end(), this, f);
00466   }
00467 
00468   filtered_succ_iterator filtered_succ_start_end(const FilterOptions &f) const {
00469     return filtered_succ_iterator(succ_begin(), succ_end(), this, f);
00470   }
00471 
00472   // Manipulation of block contents
00473 
00474   void setTerminator(Stmt *Statement) { Terminator = Statement; }
00475   void setLabel(Stmt *Statement) { Label = Statement; }
00476   void setLoopTarget(const Stmt *loopTarget) { LoopTarget = loopTarget; }
00477   void setHasNoReturnElement() { HasNoReturnElement = true; }
00478 
00479   CFGTerminator getTerminator() { return Terminator; }
00480   const CFGTerminator getTerminator() const { return Terminator; }
00481 
00482   Stmt *getTerminatorCondition();
00483 
00484   const Stmt *getTerminatorCondition() const {
00485     return const_cast<CFGBlock*>(this)->getTerminatorCondition();
00486   }
00487 
00488   const Stmt *getLoopTarget() const { return LoopTarget; }
00489 
00490   Stmt *getLabel() { return Label; }
00491   const Stmt *getLabel() const { return Label; }
00492 
00493   bool hasNoReturnElement() const { return HasNoReturnElement; }
00494 
00495   unsigned getBlockID() const { return BlockID; }
00496 
00497   CFG *getParent() const { return Parent; }
00498 
00499   void dump(const CFG *cfg, const LangOptions &LO, bool ShowColors = false) const;
00500   void print(raw_ostream &OS, const CFG* cfg, const LangOptions &LO,
00501              bool ShowColors) const;
00502   void printTerminator(raw_ostream &OS, const LangOptions &LO) const;
00503 
00504   void addSuccessor(CFGBlock *Block, BumpVectorContext &C) {
00505     if (Block)
00506       Block->Preds.push_back(this, C);
00507     Succs.push_back(Block, C);
00508   }
00509 
00510   void appendStmt(Stmt *statement, BumpVectorContext &C) {
00511     Elements.push_back(CFGStmt(statement), C);
00512   }
00513 
00514   void appendInitializer(CXXCtorInitializer *initializer,
00515                         BumpVectorContext &C) {
00516     Elements.push_back(CFGInitializer(initializer), C);
00517   }
00518 
00519   void appendBaseDtor(const CXXBaseSpecifier *BS, BumpVectorContext &C) {
00520     Elements.push_back(CFGBaseDtor(BS), C);
00521   }
00522 
00523   void appendMemberDtor(FieldDecl *FD, BumpVectorContext &C) {
00524     Elements.push_back(CFGMemberDtor(FD), C);
00525   }
00526 
00527   void appendTemporaryDtor(CXXBindTemporaryExpr *E, BumpVectorContext &C) {
00528     Elements.push_back(CFGTemporaryDtor(E), C);
00529   }
00530 
00531   void appendAutomaticObjDtor(VarDecl *VD, Stmt *S, BumpVectorContext &C) {
00532     Elements.push_back(CFGAutomaticObjDtor(VD, S), C);
00533   }
00534 
00535   // Destructors must be inserted in reversed order. So insertion is in two
00536   // steps. First we prepare space for some number of elements, then we insert
00537   // the elements beginning at the last position in prepared space.
00538   iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt,
00539       BumpVectorContext &C) {
00540     return iterator(Elements.insert(I.base(), Cnt, CFGElement(), C));
00541   }
00542   iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S) {
00543     *I = CFGAutomaticObjDtor(VD, S);
00544     return ++I;
00545   }
00546 };
00547 
00548 /// CFG - Represents a source-level, intra-procedural CFG that represents the
00549 ///  control-flow of a Stmt.  The Stmt can represent an entire function body,
00550 ///  or a single expression.  A CFG will always contain one empty block that
00551 ///  represents the Exit point of the CFG.  A CFG will also contain a designated
00552 ///  Entry block.  The CFG solely represents control-flow; it consists of
00553 ///  CFGBlocks which are simply containers of Stmt*'s in the AST the CFG
00554 ///  was constructed from.
00555 class CFG {
00556 public:
00557   //===--------------------------------------------------------------------===//
00558   // CFG Construction & Manipulation.
00559   //===--------------------------------------------------------------------===//
00560 
00561   class BuildOptions {
00562     llvm::BitVector alwaysAddMask;
00563   public:
00564     typedef llvm::DenseMap<const Stmt *, const CFGBlock*> ForcedBlkExprs;
00565     ForcedBlkExprs **forcedBlkExprs;
00566 
00567     bool PruneTriviallyFalseEdges;
00568     bool AddEHEdges;
00569     bool AddInitializers;
00570     bool AddImplicitDtors;
00571 
00572     bool alwaysAdd(const Stmt *stmt) const {
00573       return alwaysAddMask[stmt->getStmtClass()];
00574     }
00575 
00576     BuildOptions &setAlwaysAdd(Stmt::StmtClass stmtClass, bool val = true) {
00577       alwaysAddMask[stmtClass] = val;
00578       return *this;
00579     }
00580 
00581     BuildOptions &setAllAlwaysAdd() {
00582       alwaysAddMask.set();
00583       return *this;
00584     }
00585 
00586     BuildOptions()
00587     : alwaysAddMask(Stmt::lastStmtConstant, false)
00588       ,forcedBlkExprs(0), PruneTriviallyFalseEdges(true)
00589       ,AddEHEdges(false)
00590       ,AddInitializers(false)
00591       ,AddImplicitDtors(false) {}
00592   };
00593 
00594   /// \brief Provides a custom implementation of the iterator class to have the
00595   /// same interface as Function::iterator - iterator returns CFGBlock
00596   /// (not a pointer to CFGBlock).
00597   class graph_iterator {
00598   public:
00599     typedef const CFGBlock                  value_type;
00600     typedef value_type&                     reference;
00601     typedef value_type*                     pointer;
00602     typedef BumpVector<CFGBlock*>::iterator ImplTy;
00603 
00604     graph_iterator(const ImplTy &i) : I(i) {}
00605 
00606     bool operator==(const graph_iterator &X) const { return I == X.I; }
00607     bool operator!=(const graph_iterator &X) const { return I != X.I; }
00608 
00609     reference operator*()    const { return **I; }
00610     pointer operator->()     const { return  *I; }
00611     operator CFGBlock* ()          { return  *I; }
00612 
00613     graph_iterator &operator++() { ++I; return *this; }
00614     graph_iterator &operator--() { --I; return *this; }
00615 
00616   private:
00617     ImplTy I;
00618   };
00619 
00620   class const_graph_iterator {
00621   public:
00622     typedef const CFGBlock                  value_type;
00623     typedef value_type&                     reference;
00624     typedef value_type*                     pointer;
00625     typedef BumpVector<CFGBlock*>::const_iterator ImplTy;
00626 
00627     const_graph_iterator(const ImplTy &i) : I(i) {}
00628 
00629     bool operator==(const const_graph_iterator &X) const { return I == X.I; }
00630     bool operator!=(const const_graph_iterator &X) const { return I != X.I; }
00631 
00632     reference operator*() const { return **I; }
00633     pointer operator->()  const { return  *I; }
00634     operator CFGBlock* () const { return  *I; }
00635 
00636     const_graph_iterator &operator++() { ++I; return *this; }
00637     const_graph_iterator &operator--() { --I; return *this; }
00638 
00639   private:
00640     ImplTy I;
00641   };
00642 
00643   /// buildCFG - Builds a CFG from an AST.  The responsibility to free the
00644   ///   constructed CFG belongs to the caller.
00645   static CFG* buildCFG(const Decl *D, Stmt *AST, ASTContext *C,
00646                        const BuildOptions &BO);
00647 
00648   /// createBlock - Create a new block in the CFG.  The CFG owns the block;
00649   ///  the caller should not directly free it.
00650   CFGBlock *createBlock();
00651 
00652   /// setEntry - Set the entry block of the CFG.  This is typically used
00653   ///  only during CFG construction.  Most CFG clients expect that the
00654   ///  entry block has no predecessors and contains no statements.
00655   void setEntry(CFGBlock *B) { Entry = B; }
00656 
00657   /// setIndirectGotoBlock - Set the block used for indirect goto jumps.
00658   ///  This is typically used only during CFG construction.
00659   void setIndirectGotoBlock(CFGBlock *B) { IndirectGotoBlock = B; }
00660 
00661   //===--------------------------------------------------------------------===//
00662   // Block Iterators
00663   //===--------------------------------------------------------------------===//
00664 
00665   typedef BumpVector<CFGBlock*>                    CFGBlockListTy;
00666   typedef CFGBlockListTy::iterator                 iterator;
00667   typedef CFGBlockListTy::const_iterator           const_iterator;
00668   typedef std::reverse_iterator<iterator>          reverse_iterator;
00669   typedef std::reverse_iterator<const_iterator>    const_reverse_iterator;
00670 
00671   CFGBlock &                front()                { return *Blocks.front(); }
00672   CFGBlock &                back()                 { return *Blocks.back(); }
00673 
00674   iterator                  begin()                { return Blocks.begin(); }
00675   iterator                  end()                  { return Blocks.end(); }
00676   const_iterator            begin()       const    { return Blocks.begin(); }
00677   const_iterator            end()         const    { return Blocks.end(); }
00678 
00679   graph_iterator nodes_begin() { return graph_iterator(Blocks.begin()); }
00680   graph_iterator nodes_end() { return graph_iterator(Blocks.end()); }
00681   const_graph_iterator nodes_begin() const {
00682     return const_graph_iterator(Blocks.begin());
00683   }
00684   const_graph_iterator nodes_end() const {
00685     return const_graph_iterator(Blocks.end());
00686   }
00687 
00688   reverse_iterator          rbegin()               { return Blocks.rbegin(); }
00689   reverse_iterator          rend()                 { return Blocks.rend(); }
00690   const_reverse_iterator    rbegin()      const    { return Blocks.rbegin(); }
00691   const_reverse_iterator    rend()        const    { return Blocks.rend(); }
00692 
00693   CFGBlock &                getEntry()             { return *Entry; }
00694   const CFGBlock &          getEntry()    const    { return *Entry; }
00695   CFGBlock &                getExit()              { return *Exit; }
00696   const CFGBlock &          getExit()     const    { return *Exit; }
00697 
00698   CFGBlock *       getIndirectGotoBlock() { return IndirectGotoBlock; }
00699   const CFGBlock * getIndirectGotoBlock() const { return IndirectGotoBlock; }
00700 
00701   typedef std::vector<const CFGBlock*>::const_iterator try_block_iterator;
00702   try_block_iterator try_blocks_begin() const {
00703     return TryDispatchBlocks.begin();
00704   }
00705   try_block_iterator try_blocks_end() const {
00706     return TryDispatchBlocks.end();
00707   }
00708 
00709   void addTryDispatchBlock(const CFGBlock *block) {
00710     TryDispatchBlocks.push_back(block);
00711   }
00712 
00713   //===--------------------------------------------------------------------===//
00714   // Member templates useful for various batch operations over CFGs.
00715   //===--------------------------------------------------------------------===//
00716 
00717   template <typename CALLBACK>
00718   void VisitBlockStmts(CALLBACK& O) const {
00719     for (const_iterator I=begin(), E=end(); I != E; ++I)
00720       for (CFGBlock::const_iterator BI=(*I)->begin(), BE=(*I)->end();
00721            BI != BE; ++BI) {
00722         if (const CFGStmt *stmt = BI->getAs<CFGStmt>())
00723           O(const_cast<Stmt*>(stmt->getStmt()));
00724       }
00725   }
00726 
00727   //===--------------------------------------------------------------------===//
00728   // CFG Introspection.
00729   //===--------------------------------------------------------------------===//
00730 
00731   struct   BlkExprNumTy {
00732     const signed Idx;
00733     explicit BlkExprNumTy(signed idx) : Idx(idx) {}
00734     explicit BlkExprNumTy() : Idx(-1) {}
00735     operator bool() const { return Idx >= 0; }
00736     operator unsigned() const { assert(Idx >=0); return (unsigned) Idx; }
00737   };
00738 
00739   bool isBlkExpr(const Stmt *S) { return getBlkExprNum(S); }
00740   bool isBlkExpr(const Stmt *S) const {
00741     return const_cast<CFG*>(this)->isBlkExpr(S);
00742   }
00743   BlkExprNumTy  getBlkExprNum(const Stmt *S);
00744   unsigned      getNumBlkExprs();
00745 
00746   /// getNumBlockIDs - Returns the total number of BlockIDs allocated (which
00747   /// start at 0).
00748   unsigned getNumBlockIDs() const { return NumBlockIDs; }
00749 
00750   /// size - Return the total number of CFGBlocks within the CFG
00751   /// This is simply a renaming of the getNumBlockIDs(). This is necessary 
00752   /// because the dominator implementation needs such an interface.
00753   unsigned size() const { return NumBlockIDs; }
00754 
00755   //===--------------------------------------------------------------------===//
00756   // CFG Debugging: Pretty-Printing and Visualization.
00757   //===--------------------------------------------------------------------===//
00758 
00759   void viewCFG(const LangOptions &LO) const;
00760   void print(raw_ostream &OS, const LangOptions &LO, bool ShowColors) const;
00761   void dump(const LangOptions &LO, bool ShowColors) const;
00762 
00763   //===--------------------------------------------------------------------===//
00764   // Internal: constructors and data.
00765   //===--------------------------------------------------------------------===//
00766 
00767   CFG() : Entry(NULL), Exit(NULL), IndirectGotoBlock(NULL), NumBlockIDs(0),
00768           BlkExprMap(NULL), Blocks(BlkBVC, 10) {}
00769 
00770   ~CFG();
00771 
00772   llvm::BumpPtrAllocator& getAllocator() {
00773     return BlkBVC.getAllocator();
00774   }
00775 
00776   BumpVectorContext &getBumpVectorContext() {
00777     return BlkBVC;
00778   }
00779 
00780 private:
00781   CFGBlock *Entry;
00782   CFGBlock *Exit;
00783   CFGBlock* IndirectGotoBlock;  // Special block to contain collective dispatch
00784                                 // for indirect gotos
00785   unsigned  NumBlockIDs;
00786 
00787   // BlkExprMap - An opaque pointer to prevent inclusion of DenseMap.h.
00788   //  It represents a map from Expr* to integers to record the set of
00789   //  block-level expressions and their "statement number" in the CFG.
00790   void *    BlkExprMap;
00791 
00792   BumpVectorContext BlkBVC;
00793 
00794   CFGBlockListTy Blocks;
00795 
00796   /// C++ 'try' statements are modeled with an indirect dispatch block.
00797   /// This is the collection of such blocks present in the CFG.
00798   std::vector<const CFGBlock *> TryDispatchBlocks;
00799 
00800 };
00801 } // end namespace clang
00802 
00803 //===----------------------------------------------------------------------===//
00804 // GraphTraits specializations for CFG basic block graphs (source-level CFGs)
00805 //===----------------------------------------------------------------------===//
00806 
00807 namespace llvm {
00808 
00809 /// Implement simplify_type for CFGTerminator, so that we can dyn_cast from
00810 /// CFGTerminator to a specific Stmt class.
00811 template <> struct simplify_type<const ::clang::CFGTerminator> {
00812   typedef const ::clang::Stmt *SimpleType;
00813   static SimpleType getSimplifiedValue(const ::clang::CFGTerminator &Val) {
00814     return Val.getStmt();
00815   }
00816 };
00817 
00818 template <> struct simplify_type< ::clang::CFGTerminator> {
00819   typedef ::clang::Stmt *SimpleType;
00820   static SimpleType getSimplifiedValue(const ::clang::CFGTerminator &Val) {
00821     return const_cast<SimpleType>(Val.getStmt());
00822   }
00823 };
00824 
00825 // Traits for: CFGBlock
00826 
00827 template <> struct GraphTraits< ::clang::CFGBlock *> {
00828   typedef ::clang::CFGBlock NodeType;
00829   typedef ::clang::CFGBlock::succ_iterator ChildIteratorType;
00830 
00831   static NodeType* getEntryNode(::clang::CFGBlock *BB)
00832   { return BB; }
00833 
00834   static inline ChildIteratorType child_begin(NodeType* N)
00835   { return N->succ_begin(); }
00836 
00837   static inline ChildIteratorType child_end(NodeType* N)
00838   { return N->succ_end(); }
00839 };
00840 
00841 template <> struct GraphTraits< const ::clang::CFGBlock *> {
00842   typedef const ::clang::CFGBlock NodeType;
00843   typedef ::clang::CFGBlock::const_succ_iterator ChildIteratorType;
00844 
00845   static NodeType* getEntryNode(const clang::CFGBlock *BB)
00846   { return BB; }
00847 
00848   static inline ChildIteratorType child_begin(NodeType* N)
00849   { return N->succ_begin(); }
00850 
00851   static inline ChildIteratorType child_end(NodeType* N)
00852   { return N->succ_end(); }
00853 };
00854 
00855 template <> struct GraphTraits<Inverse< ::clang::CFGBlock*> > {
00856   typedef ::clang::CFGBlock NodeType;
00857   typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
00858 
00859   static NodeType *getEntryNode(Inverse< ::clang::CFGBlock*> G)
00860   { return G.Graph; }
00861 
00862   static inline ChildIteratorType child_begin(NodeType* N)
00863   { return N->pred_begin(); }
00864 
00865   static inline ChildIteratorType child_end(NodeType* N)
00866   { return N->pred_end(); }
00867 };
00868 
00869 template <> struct GraphTraits<Inverse<const ::clang::CFGBlock*> > {
00870   typedef const ::clang::CFGBlock NodeType;
00871   typedef ::clang::CFGBlock::const_pred_iterator ChildIteratorType;
00872 
00873   static NodeType *getEntryNode(Inverse<const ::clang::CFGBlock*> G)
00874   { return G.Graph; }
00875 
00876   static inline ChildIteratorType child_begin(NodeType* N)
00877   { return N->pred_begin(); }
00878 
00879   static inline ChildIteratorType child_end(NodeType* N)
00880   { return N->pred_end(); }
00881 };
00882 
00883 // Traits for: CFG
00884 
00885 template <> struct GraphTraits< ::clang::CFG* >
00886     : public GraphTraits< ::clang::CFGBlock *>  {
00887 
00888   typedef ::clang::CFG::graph_iterator nodes_iterator;
00889 
00890   static NodeType     *getEntryNode(::clang::CFG* F) { return &F->getEntry(); }
00891   static nodes_iterator nodes_begin(::clang::CFG* F) { return F->nodes_begin();}
00892   static nodes_iterator   nodes_end(::clang::CFG* F) { return F->nodes_end(); }
00893   static unsigned              size(::clang::CFG* F) { return F->size(); }
00894 };
00895 
00896 template <> struct GraphTraits<const ::clang::CFG* >
00897     : public GraphTraits<const ::clang::CFGBlock *>  {
00898 
00899   typedef ::clang::CFG::const_graph_iterator nodes_iterator;
00900 
00901   static NodeType *getEntryNode( const ::clang::CFG* F) {
00902     return &F->getEntry();
00903   }
00904   static nodes_iterator nodes_begin( const ::clang::CFG* F) {
00905     return F->nodes_begin();
00906   }
00907   static nodes_iterator nodes_end( const ::clang::CFG* F) {
00908     return F->nodes_end();
00909   }
00910   static unsigned size(const ::clang::CFG* F) {
00911     return F->size();
00912   }
00913 };
00914 
00915 template <> struct GraphTraits<Inverse< ::clang::CFG*> >
00916   : public GraphTraits<Inverse< ::clang::CFGBlock*> > {
00917 
00918   typedef ::clang::CFG::graph_iterator nodes_iterator;
00919 
00920   static NodeType *getEntryNode( ::clang::CFG* F) { return &F->getExit(); }
00921   static nodes_iterator nodes_begin( ::clang::CFG* F) {return F->nodes_begin();}
00922   static nodes_iterator nodes_end( ::clang::CFG* F) { return F->nodes_end(); }
00923 };
00924 
00925 template <> struct GraphTraits<Inverse<const ::clang::CFG*> >
00926   : public GraphTraits<Inverse<const ::clang::CFGBlock*> > {
00927 
00928   typedef ::clang::CFG::const_graph_iterator nodes_iterator;
00929 
00930   static NodeType *getEntryNode(const ::clang::CFG* F) { return &F->getExit(); }
00931   static nodes_iterator nodes_begin(const ::clang::CFG* F) {
00932     return F->nodes_begin();
00933   }
00934   static nodes_iterator nodes_end(const ::clang::CFG* F) {
00935     return F->nodes_end();
00936   }
00937 };
00938 } // end llvm namespace
00939 #endif