1193326Sed//===--- DataflowValues.h - Data structure for dataflow values --*- C++ -*-===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file defines a skeleton data structure for encapsulating the dataflow 11193326Sed// values for a CFG. Typically this is subclassed to provide methods for 12193326Sed// computing these values from a CFG. 13193326Sed// 14193326Sed//===----------------------------------------------------------------------===// 15193326Sed 16193326Sed#ifndef LLVM_CLANG_ANALYSES_DATAFLOW_VALUES 17193326Sed#define LLVM_CLANG_ANALYSES_DATAFLOW_VALUES 18193326Sed 19198092Srdivacky#include "clang/Analysis/CFG.h" 20193326Sed#include "clang/Analysis/ProgramPoint.h" 21193326Sed#include "llvm/ADT/DenseMap.h" 22193326Sed 23193326Sed//===----------------------------------------------------------------------===// 24193326Sed/// Dataflow Directional Tag Classes. These are used for tag dispatching 25193326Sed/// within the dataflow solver/transfer functions to determine what direction 26193326Sed/// a dataflow analysis flows. 27198092Srdivacky//===----------------------------------------------------------------------===// 28193326Sed 29193326Sednamespace clang { 30193326Sednamespace dataflow { 31193326Sed struct forward_analysis_tag {}; 32193326Sed struct backward_analysis_tag {}; 33193326Sed} // end namespace dataflow 34193326Sed 35193326Sed//===----------------------------------------------------------------------===// 36193326Sed/// DataflowValues. Container class to store dataflow values for a CFG. 37198092Srdivacky//===----------------------------------------------------------------------===// 38198092Srdivacky 39193326Sedtemplate <typename ValueTypes, 40193326Sed typename _AnalysisDirTag = dataflow::forward_analysis_tag > 41193326Sedclass DataflowValues { 42193326Sed 43193326Sed //===--------------------------------------------------------------------===// 44193326Sed // Type declarations. 45198092Srdivacky //===--------------------------------------------------------------------===// 46193326Sed 47193326Sedpublic: 48193326Sed typedef typename ValueTypes::ValTy ValTy; 49198092Srdivacky typedef typename ValueTypes::AnalysisDataTy AnalysisDataTy; 50193326Sed typedef _AnalysisDirTag AnalysisDirTag; 51193326Sed typedef llvm::DenseMap<ProgramPoint, ValTy> EdgeDataMapTy; 52193326Sed typedef llvm::DenseMap<const CFGBlock*, ValTy> BlockDataMapTy; 53193326Sed typedef llvm::DenseMap<const Stmt*, ValTy> StmtDataMapTy; 54193326Sed 55193326Sed //===--------------------------------------------------------------------===// 56193326Sed // Predicates. 57193326Sed //===--------------------------------------------------------------------===// 58193326Sed 59193326Sedpublic: 60193326Sed /// isForwardAnalysis - Returns true if the dataflow values are computed 61193326Sed /// from a forward analysis. 62193326Sed bool isForwardAnalysis() { return isForwardAnalysis(AnalysisDirTag()); } 63198092Srdivacky 64193326Sed /// isBackwardAnalysis - Returns true if the dataflow values are computed 65193326Sed /// from a backward analysis. 66193326Sed bool isBackwardAnalysis() { return !isForwardAnalysis(); } 67198092Srdivacky 68193326Sedprivate: 69193326Sed bool isForwardAnalysis(dataflow::forward_analysis_tag) { return true; } 70198092Srdivacky bool isForwardAnalysis(dataflow::backward_analysis_tag) { return false; } 71198092Srdivacky 72193326Sed //===--------------------------------------------------------------------===// 73193326Sed // Initialization and accessors methods. 74193326Sed //===--------------------------------------------------------------------===// 75193326Sed 76193326Sedpublic: 77193326Sed DataflowValues() : StmtDataMap(NULL) {} 78193326Sed ~DataflowValues() { delete StmtDataMap; } 79198092Srdivacky 80193326Sed /// InitializeValues - Invoked by the solver to initialize state needed for 81193326Sed /// dataflow analysis. This method is usually specialized by subclasses. 82201361Srdivacky void InitializeValues(const CFG& cfg) {} 83193326Sed 84193326Sed 85193326Sed /// getEdgeData - Retrieves the dataflow values associated with a 86193326Sed /// CFG edge. 87226633Sdim ValTy& getEdgeData(const BlockEdge &E) { 88193326Sed typename EdgeDataMapTy::iterator I = EdgeDataMap.find(E); 89193326Sed assert (I != EdgeDataMap.end() && "No data associated with Edge."); 90193326Sed return I->second; 91193326Sed } 92198092Srdivacky 93226633Sdim const ValTy& getEdgeData(const BlockEdge &E) const { 94193326Sed return reinterpret_cast<DataflowValues*>(this)->getEdgeData(E); 95198092Srdivacky } 96193326Sed 97198092Srdivacky /// getBlockData - Retrieves the dataflow values associated with a 98193326Sed /// specified CFGBlock. If the dataflow analysis is a forward analysis, 99193326Sed /// this data is associated with the END of the block. If the analysis 100198092Srdivacky /// is a backwards analysis, it is associated with the ENTRY of the block. 101226633Sdim ValTy& getBlockData(const CFGBlock *B) { 102193326Sed typename BlockDataMapTy::iterator I = BlockDataMap.find(B); 103193326Sed assert (I != BlockDataMap.end() && "No data associated with block."); 104193326Sed return I->second; 105193326Sed } 106198092Srdivacky 107226633Sdim const ValTy& getBlockData(const CFGBlock *B) const { 108193326Sed return const_cast<DataflowValues*>(this)->getBlockData(B); 109193326Sed } 110198092Srdivacky 111198092Srdivacky /// getStmtData - Retrieves the dataflow values associated with a 112193326Sed /// specified Stmt. If the dataflow analysis is a forward analysis, 113198092Srdivacky /// this data corresponds to the point immediately before a Stmt. 114193326Sed /// If the analysis is a backwards analysis, it is associated with 115193326Sed /// the point after a Stmt. This data is only computed for block-level 116193326Sed /// expressions, and only when requested when the analysis is executed. 117226633Sdim ValTy& getStmtData(const Stmt *S) { 118193326Sed assert (StmtDataMap && "Dataflow values were not computed for statements."); 119193326Sed typename StmtDataMapTy::iterator I = StmtDataMap->find(S); 120193326Sed assert (I != StmtDataMap->end() && "No data associated with statement."); 121193326Sed return I->second; 122193326Sed } 123198092Srdivacky 124226633Sdim const ValTy& getStmtData(const Stmt *S) const { 125193326Sed return const_cast<DataflowValues*>(this)->getStmtData(S); 126193326Sed } 127198092Srdivacky 128193326Sed /// getEdgeDataMap - Retrieves the internal map between CFG edges and 129193326Sed /// dataflow values. Usually used by a dataflow solver to compute 130193326Sed /// values for blocks. 131193326Sed EdgeDataMapTy& getEdgeDataMap() { return EdgeDataMap; } 132193326Sed const EdgeDataMapTy& getEdgeDataMap() const { return EdgeDataMap; } 133193326Sed 134193326Sed /// getBlockDataMap - Retrieves the internal map between CFGBlocks and 135193326Sed /// dataflow values. If the dataflow analysis operates in the forward 136193326Sed /// direction, the values correspond to the dataflow values at the start 137193326Sed /// of the block. Otherwise, for a backward analysis, the values correpsond 138193326Sed /// to the dataflow values at the end of the block. 139193326Sed BlockDataMapTy& getBlockDataMap() { return BlockDataMap; } 140193326Sed const BlockDataMapTy& getBlockDataMap() const { return BlockDataMap; } 141198092Srdivacky 142193326Sed /// getStmtDataMap - Retrieves the internal map between Stmts and 143193326Sed /// dataflow values. 144193326Sed StmtDataMapTy& getStmtDataMap() { 145193326Sed if (!StmtDataMap) StmtDataMap = new StmtDataMapTy(); 146193326Sed return *StmtDataMap; 147193326Sed } 148198092Srdivacky 149193326Sed const StmtDataMapTy& getStmtDataMap() const { 150193326Sed return const_cast<DataflowValues*>(this)->getStmtDataMap(); 151193326Sed } 152193326Sed 153198092Srdivacky /// getAnalysisData - Retrieves the meta data associated with a 154198092Srdivacky /// dataflow analysis for analyzing a particular CFG. 155193326Sed /// This is typically consumed by transfer function code (via the solver). 156193326Sed /// This can also be used by subclasses to interpret the dataflow values. 157193326Sed AnalysisDataTy& getAnalysisData() { return AnalysisData; } 158193326Sed const AnalysisDataTy& getAnalysisData() const { return AnalysisData; } 159198092Srdivacky 160193326Sed //===--------------------------------------------------------------------===// 161193326Sed // Internal data. 162193326Sed //===--------------------------------------------------------------------===// 163198092Srdivacky 164193326Sedprotected: 165193326Sed EdgeDataMapTy EdgeDataMap; 166193326Sed BlockDataMapTy BlockDataMap; 167193326Sed StmtDataMapTy* StmtDataMap; 168193326Sed AnalysisDataTy AnalysisData; 169198092Srdivacky}; 170193326Sed 171193326Sed} // end namespace clang 172193326Sed#endif 173