clang API Documentation
00001 //===- PostOrderCFGView.h - Post order view of CFG blocks ---------*- 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 implements post order view of the blocks in a CFG. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_POSTORDERCFGVIEW_H 00015 #define LLVM_CLANG_ANALYSIS_ANALYSES_POSTORDERCFGVIEW_H 00016 00017 #include <vector> 00018 //#include <algorithm> 00019 00020 #include "llvm/ADT/PostOrderIterator.h" 00021 #include "llvm/ADT/DenseMap.h" 00022 #include "llvm/ADT/BitVector.h" 00023 00024 #include "clang/Analysis/AnalysisContext.h" 00025 #include "clang/Analysis/CFG.h" 00026 00027 namespace clang { 00028 00029 class PostOrderCFGView : public ManagedAnalysis { 00030 virtual void anchor(); 00031 public: 00032 /// \brief Implements a set of CFGBlocks using a BitVector. 00033 /// 00034 /// This class contains a minimal interface, primarily dictated by the SetType 00035 /// template parameter of the llvm::po_iterator template, as used with 00036 /// external storage. We also use this set to keep track of which CFGBlocks we 00037 /// visit during the analysis. 00038 class CFGBlockSet { 00039 llvm::BitVector VisitedBlockIDs; 00040 public: 00041 // po_iterator requires this iterator, but the only interface needed is the 00042 // value_type typedef. 00043 struct iterator { typedef const CFGBlock *value_type; }; 00044 00045 CFGBlockSet() {} 00046 CFGBlockSet(const CFG *G) : VisitedBlockIDs(G->getNumBlockIDs(), false) {} 00047 00048 /// \brief Set the bit associated with a particular CFGBlock. 00049 /// This is the important method for the SetType template parameter. 00050 bool insert(const CFGBlock *Block) { 00051 // Note that insert() is called by po_iterator, which doesn't check to 00052 // make sure that Block is non-null. Moreover, the CFGBlock iterator will 00053 // occasionally hand out null pointers for pruned edges, so we catch those 00054 // here. 00055 if (!Block) 00056 return false; // if an edge is trivially false. 00057 if (VisitedBlockIDs.test(Block->getBlockID())) 00058 return false; 00059 VisitedBlockIDs.set(Block->getBlockID()); 00060 return true; 00061 } 00062 00063 /// \brief Check if the bit for a CFGBlock has been already set. 00064 /// This method is for tracking visited blocks in the main threadsafety 00065 /// loop. Block must not be null. 00066 bool alreadySet(const CFGBlock *Block) { 00067 return VisitedBlockIDs.test(Block->getBlockID()); 00068 } 00069 }; 00070 00071 private: 00072 typedef llvm::po_iterator<const CFG*, CFGBlockSet, true> po_iterator; 00073 std::vector<const CFGBlock*> Blocks; 00074 00075 typedef llvm::DenseMap<const CFGBlock *, unsigned> BlockOrderTy; 00076 BlockOrderTy BlockOrder; 00077 00078 public: 00079 typedef std::vector<const CFGBlock *>::reverse_iterator iterator; 00080 typedef std::vector<const CFGBlock *>::const_reverse_iterator const_iterator; 00081 00082 PostOrderCFGView(const CFG *cfg); 00083 00084 iterator begin() { return Blocks.rbegin(); } 00085 iterator end() { return Blocks.rend(); } 00086 00087 const_iterator begin() const { return Blocks.rbegin(); } 00088 const_iterator end() const { return Blocks.rend(); } 00089 00090 bool empty() const { return begin() == end(); } 00091 00092 struct BlockOrderCompare; 00093 friend struct BlockOrderCompare; 00094 00095 struct BlockOrderCompare { 00096 const PostOrderCFGView &POV; 00097 public: 00098 BlockOrderCompare(const PostOrderCFGView &pov) : POV(pov) {} 00099 bool operator()(const CFGBlock *b1, const CFGBlock *b2) const; 00100 }; 00101 00102 BlockOrderCompare getComparator() const { 00103 return BlockOrderCompare(*this); 00104 } 00105 00106 // Used by AnalyisContext to construct this object. 00107 static const void *getTag(); 00108 00109 static PostOrderCFGView *create(AnalysisDeclContext &analysisContext); 00110 }; 00111 00112 } // end clang namespace 00113 00114 #endif 00115