clang API Documentation

PostOrderCFGView.h
Go to the documentation of this file.
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_POSTORDER_CFGVIEW
00015 #define LLVM_CLANG_POSTORDER_CFGVIEW
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 == 0)
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 
00081   PostOrderCFGView(const CFG *cfg);
00082 
00083   iterator begin() { return Blocks.rbegin(); }
00084   iterator end()   { return Blocks.rend(); }
00085 
00086   bool empty() { return begin() == end(); }
00087 
00088   struct BlockOrderCompare;
00089   friend struct BlockOrderCompare;
00090 
00091   struct BlockOrderCompare {
00092     const PostOrderCFGView &POV;
00093   public:
00094     BlockOrderCompare(const PostOrderCFGView &pov) : POV(pov) {}
00095     bool operator()(const CFGBlock *b1, const CFGBlock *b2) const;
00096   };
00097 
00098   BlockOrderCompare getComparator() const {
00099     return BlockOrderCompare(*this);
00100   }
00101 
00102   // Used by AnalyisContext to construct this object.
00103   static const void *getTag();
00104 
00105   static PostOrderCFGView *create(AnalysisDeclContext &analysisContext);
00106 };
00107 
00108 } // end clang namespace
00109 
00110 #endif
00111