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