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