clang API Documentation

DataflowValues.h
Go to the documentation of this file.
00001 //===--- DataflowValues.h - Data structure for dataflow values --*- 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 a skeleton data structure for encapsulating the dataflow
00011 // values for a CFG.  Typically this is subclassed to provide methods for
00012 // computing these values from a CFG.
00013 //
00014 //===----------------------------------------------------------------------===//
00015 
00016 #ifndef LLVM_CLANG_ANALYSES_DATAFLOW_VALUES
00017 #define LLVM_CLANG_ANALYSES_DATAFLOW_VALUES
00018 
00019 #include "clang/Analysis/CFG.h"
00020 #include "clang/Analysis/ProgramPoint.h"
00021 #include "llvm/ADT/DenseMap.h"
00022 
00023 //===----------------------------------------------------------------------===//
00024 /// Dataflow Directional Tag Classes.  These are used for tag dispatching
00025 ///  within the dataflow solver/transfer functions to determine what direction
00026 ///  a dataflow analysis flows.
00027 //===----------------------------------------------------------------------===//
00028 
00029 namespace clang {
00030 namespace dataflow {
00031   struct forward_analysis_tag {};
00032   struct backward_analysis_tag {};
00033 } // end namespace dataflow
00034 
00035 //===----------------------------------------------------------------------===//
00036 /// DataflowValues.  Container class to store dataflow values for a CFG.
00037 //===----------------------------------------------------------------------===//
00038 
00039 template <typename ValueTypes,
00040           typename _AnalysisDirTag = dataflow::forward_analysis_tag >
00041 class DataflowValues {
00042 
00043   //===--------------------------------------------------------------------===//
00044   // Type declarations.
00045   //===--------------------------------------------------------------------===//
00046 
00047 public:
00048   typedef typename ValueTypes::ValTy               ValTy;
00049   typedef typename ValueTypes::AnalysisDataTy      AnalysisDataTy;
00050   typedef _AnalysisDirTag                          AnalysisDirTag;
00051   typedef llvm::DenseMap<ProgramPoint, ValTy>      EdgeDataMapTy;
00052   typedef llvm::DenseMap<const CFGBlock*, ValTy>   BlockDataMapTy;
00053   typedef llvm::DenseMap<const Stmt*, ValTy>       StmtDataMapTy;
00054 
00055   //===--------------------------------------------------------------------===//
00056   // Predicates.
00057   //===--------------------------------------------------------------------===//
00058 
00059 public:
00060   /// isForwardAnalysis - Returns true if the dataflow values are computed
00061   ///  from a forward analysis.
00062   bool isForwardAnalysis() { return isForwardAnalysis(AnalysisDirTag()); }
00063 
00064   /// isBackwardAnalysis - Returns true if the dataflow values are computed
00065   ///  from a backward analysis.
00066   bool isBackwardAnalysis() { return !isForwardAnalysis(); }
00067 
00068 private:
00069   bool isForwardAnalysis(dataflow::forward_analysis_tag)  { return true; }
00070   bool isForwardAnalysis(dataflow::backward_analysis_tag) { return false; }
00071 
00072   //===--------------------------------------------------------------------===//
00073   // Initialization and accessors methods.
00074   //===--------------------------------------------------------------------===//
00075 
00076 public:
00077   DataflowValues() : StmtDataMap(NULL) {}
00078   ~DataflowValues() { delete StmtDataMap; }
00079 
00080   /// InitializeValues - Invoked by the solver to initialize state needed for
00081   ///  dataflow analysis.  This method is usually specialized by subclasses.
00082   void InitializeValues(const CFG& cfg) {}
00083 
00084 
00085   /// getEdgeData - Retrieves the dataflow values associated with a
00086   ///  CFG edge.
00087   ValTy& getEdgeData(const BlockEdge &E) {
00088     typename EdgeDataMapTy::iterator I = EdgeDataMap.find(E);
00089     assert (I != EdgeDataMap.end() && "No data associated with Edge.");
00090     return I->second;
00091   }
00092 
00093   const ValTy& getEdgeData(const BlockEdge &E) const {
00094     return reinterpret_cast<DataflowValues*>(this)->getEdgeData(E);
00095   }
00096 
00097   /// getBlockData - Retrieves the dataflow values associated with a
00098   ///  specified CFGBlock.  If the dataflow analysis is a forward analysis,
00099   ///  this data is associated with the END of the block.  If the analysis
00100   ///  is a backwards analysis, it is associated with the ENTRY of the block.
00101   ValTy& getBlockData(const CFGBlock *B) {
00102     typename BlockDataMapTy::iterator I = BlockDataMap.find(B);
00103     assert (I != BlockDataMap.end() && "No data associated with block.");
00104     return I->second;
00105   }
00106 
00107   const ValTy& getBlockData(const CFGBlock *B) const {
00108     return const_cast<DataflowValues*>(this)->getBlockData(B);
00109   }
00110 
00111   /// getStmtData - Retrieves the dataflow values associated with a
00112   ///  specified Stmt.  If the dataflow analysis is a forward analysis,
00113   ///  this data corresponds to the point immediately before a Stmt.
00114   ///  If the analysis is a backwards analysis, it is associated with
00115   ///  the point after a Stmt.  This data is only computed for block-level
00116   ///  expressions, and only when requested when the analysis is executed.
00117   ValTy& getStmtData(const Stmt *S) {
00118     assert (StmtDataMap && "Dataflow values were not computed for statements.");
00119     typename StmtDataMapTy::iterator I = StmtDataMap->find(S);
00120     assert (I != StmtDataMap->end() && "No data associated with statement.");
00121     return I->second;
00122   }
00123 
00124   const ValTy& getStmtData(const Stmt *S) const {
00125     return const_cast<DataflowValues*>(this)->getStmtData(S);
00126   }
00127 
00128   /// getEdgeDataMap - Retrieves the internal map between CFG edges and
00129   ///  dataflow values.  Usually used by a dataflow solver to compute
00130   ///  values for blocks.
00131   EdgeDataMapTy& getEdgeDataMap() { return EdgeDataMap; }
00132   const EdgeDataMapTy& getEdgeDataMap() const { return EdgeDataMap; }
00133 
00134   /// getBlockDataMap - Retrieves the internal map between CFGBlocks and
00135   /// dataflow values.  If the dataflow analysis operates in the forward
00136   /// direction, the values correspond to the dataflow values at the start
00137   /// of the block.  Otherwise, for a backward analysis, the values correpsond
00138   /// to the dataflow values at the end of the block.
00139   BlockDataMapTy& getBlockDataMap() { return BlockDataMap; }
00140   const BlockDataMapTy& getBlockDataMap() const { return BlockDataMap; }
00141 
00142   /// getStmtDataMap - Retrieves the internal map between Stmts and
00143   /// dataflow values.
00144   StmtDataMapTy& getStmtDataMap() {
00145     if (!StmtDataMap) StmtDataMap = new StmtDataMapTy();
00146     return *StmtDataMap;
00147   }
00148 
00149   const StmtDataMapTy& getStmtDataMap() const {
00150     return const_cast<DataflowValues*>(this)->getStmtDataMap();
00151   }
00152 
00153   /// getAnalysisData - Retrieves the meta data associated with a
00154   ///  dataflow analysis for analyzing a particular CFG.
00155   ///  This is typically consumed by transfer function code (via the solver).
00156   ///  This can also be used by subclasses to interpret the dataflow values.
00157   AnalysisDataTy& getAnalysisData() { return AnalysisData; }
00158   const AnalysisDataTy& getAnalysisData() const { return AnalysisData; }
00159 
00160   //===--------------------------------------------------------------------===//
00161   // Internal data.
00162   //===--------------------------------------------------------------------===//
00163 
00164 protected:
00165   EdgeDataMapTy      EdgeDataMap;
00166   BlockDataMapTy     BlockDataMap;
00167   StmtDataMapTy*     StmtDataMap;
00168   AnalysisDataTy     AnalysisData;
00169 };
00170 
00171 } // end namespace clang
00172 #endif