1193326Sed// BlkExprDeclBitVector.h - Dataflow types for Bitvector Analysis --*- 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 provides definition of dataflow types used by analyses such
11193326Sed// as LiveVariables and UninitializedValues.  The underlying dataflow values
12193326Sed// are implemented as bitvectors, but the definitions in this file include
13193326Sed// the necessary boilerplate to use with our dataflow framework.
14193326Sed//
15193326Sed//===----------------------------------------------------------------------===//
16193326Sed
17193326Sed#ifndef LLVM_CLANG_STMTDECLBVDVAL_H
18193326Sed#define LLVM_CLANG_STMTDECLBVDVAL_H
19193326Sed
20249423Sdim#include "clang/AST/Decl.h" // for Decl* -> NamedDecl* conversion
21198092Srdivacky#include "clang/Analysis/CFG.h"
22193326Sed#include "llvm/ADT/BitVector.h"
23193326Sed#include "llvm/ADT/DenseMap.h"
24193326Sed
25193326Sednamespace clang {
26198092Srdivacky
27193326Sed  class Stmt;
28193326Sed  class ASTContext;
29193326Sed
30193326Sedstruct DeclBitVector_Types {
31198092Srdivacky
32193326Sed  class Idx {
33193326Sed    unsigned I;
34193326Sed  public:
35193326Sed    explicit Idx(unsigned i) : I(i) {}
36193326Sed    Idx() : I(~0U) {}
37198092Srdivacky
38193326Sed    bool isValid() const {
39193326Sed      return I != ~0U;
40193326Sed    }
41193326Sed    operator unsigned() const {
42193326Sed      assert (isValid());
43193326Sed      return I;
44193326Sed    }
45198092Srdivacky  };
46198092Srdivacky
47193326Sed  //===--------------------------------------------------------------------===//
48193326Sed  // AnalysisDataTy - Whole-function meta data.
49193326Sed  //===--------------------------------------------------------------------===//
50198092Srdivacky
51193326Sed  class AnalysisDataTy {
52193326Sed  public:
53193326Sed    typedef llvm::DenseMap<const NamedDecl*, unsigned > DMapTy;
54193326Sed    typedef DMapTy::const_iterator decl_iterator;
55198092Srdivacky
56193326Sed  protected:
57198092Srdivacky    DMapTy DMap;
58193326Sed    unsigned NDecls;
59198092Srdivacky
60193326Sed  public:
61198092Srdivacky
62193326Sed    AnalysisDataTy() : NDecls(0) {}
63193326Sed    virtual ~AnalysisDataTy() {}
64198092Srdivacky
65226633Sdim    bool isTracked(const NamedDecl *SD) { return DMap.find(SD) != DMap.end(); }
66198092Srdivacky
67226633Sdim    Idx getIdx(const NamedDecl *SD) const {
68193326Sed      DMapTy::const_iterator I = DMap.find(SD);
69193326Sed      return I == DMap.end() ? Idx() : Idx(I->second);
70193326Sed    }
71193326Sed
72193326Sed    unsigned getNumDecls() const { return NDecls; }
73198092Srdivacky
74226633Sdim    void Register(const NamedDecl *SD) {
75193326Sed      if (!isTracked(SD)) DMap[SD] = NDecls++;
76193326Sed    }
77193326Sed
78193326Sed    decl_iterator begin_decl() const { return DMap.begin(); }
79193326Sed    decl_iterator end_decl() const { return DMap.end(); }
80193326Sed  };
81198092Srdivacky
82193326Sed  //===--------------------------------------------------------------------===//
83193326Sed  // ValTy - Dataflow value.
84193326Sed  //===--------------------------------------------------------------------===//
85198092Srdivacky
86193326Sed  class ValTy {
87193326Sed    llvm::BitVector DeclBV;
88193326Sed  public:
89198092Srdivacky
90193326Sed    void resetDeclValues(AnalysisDataTy& AD) {
91198092Srdivacky      DeclBV.resize(AD.getNumDecls());
92193326Sed      DeclBV.reset();
93193326Sed    }
94193326Sed
95193326Sed    void setDeclValues(AnalysisDataTy& AD) {
96198092Srdivacky      DeclBV.resize(AD.getNumDecls());
97193326Sed      DeclBV.set();
98193326Sed    }
99198092Srdivacky
100193326Sed    void resetValues(AnalysisDataTy& AD) {
101193326Sed      resetDeclValues(AD);
102198092Srdivacky    }
103198092Srdivacky
104198092Srdivacky    bool operator==(const ValTy& RHS) const {
105193326Sed      assert (sizesEqual(RHS));
106193326Sed      return DeclBV == RHS.DeclBV;
107193326Sed    }
108198092Srdivacky
109193326Sed    void copyValues(const ValTy& RHS) { DeclBV = RHS.DeclBV; }
110198092Srdivacky
111193326Sed    llvm::BitVector::reference getBit(unsigned i) {
112193326Sed      return DeclBV[i];
113193326Sed    }
114198092Srdivacky
115193326Sed    bool getBit(unsigned i) const {
116193326Sed      return DeclBV[i];
117193326Sed    }
118198092Srdivacky
119193326Sed    llvm::BitVector::reference
120226633Sdim    operator()(const NamedDecl *ND, const AnalysisDataTy& AD) {
121193326Sed      return getBit(AD.getIdx(ND));
122193326Sed    }
123193326Sed
124226633Sdim    bool operator()(const NamedDecl *ND, const AnalysisDataTy& AD) const {
125193326Sed      return getBit(AD.getIdx(ND));
126193326Sed    }
127198092Srdivacky
128198092Srdivacky    llvm::BitVector::reference getDeclBit(unsigned i) { return DeclBV[i]; }
129193326Sed    const llvm::BitVector::reference getDeclBit(unsigned i) const {
130193326Sed      return const_cast<llvm::BitVector&>(DeclBV)[i];
131193326Sed    }
132198092Srdivacky
133193326Sed    ValTy& operator|=(const ValTy& RHS) {
134193326Sed      assert (sizesEqual(RHS));
135193326Sed      DeclBV |= RHS.DeclBV;
136193326Sed      return *this;
137193326Sed    }
138198092Srdivacky
139193326Sed    ValTy& operator&=(const ValTy& RHS) {
140193326Sed      assert (sizesEqual(RHS));
141193326Sed      DeclBV &= RHS.DeclBV;
142193326Sed      return *this;
143193326Sed    }
144198092Srdivacky
145193326Sed    ValTy& OrDeclBits(const ValTy& RHS) {
146193326Sed      return operator|=(RHS);
147193326Sed    }
148198092Srdivacky
149193326Sed    ValTy& AndDeclBits(const ValTy& RHS) {
150193326Sed      return operator&=(RHS);
151193326Sed    }
152198092Srdivacky
153193326Sed    bool sizesEqual(const ValTy& RHS) const {
154193326Sed      return DeclBV.size() == RHS.DeclBV.size();
155193326Sed    }
156193326Sed  };
157198092Srdivacky
158193326Sed  //===--------------------------------------------------------------------===//
159193326Sed  // Some useful merge operations.
160193326Sed  //===--------------------------------------------------------------------===//
161198092Srdivacky
162193326Sed  struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } };
163193326Sed  struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } };
164193326Sed};
165193326Sed
166193326Sed
167193326Sedstruct StmtDeclBitVector_Types {
168198092Srdivacky
169193326Sed  //===--------------------------------------------------------------------===//
170193326Sed  // AnalysisDataTy - Whole-function meta data.
171193326Sed  //===--------------------------------------------------------------------===//
172193326Sed
173193326Sed  class AnalysisDataTy : public DeclBitVector_Types::AnalysisDataTy {
174226633Sdim    ASTContext *ctx;
175193326Sed    CFG* cfg;
176193326Sed  public:
177193326Sed    AnalysisDataTy() : ctx(0), cfg(0) {}
178193326Sed    virtual ~AnalysisDataTy() {}
179193326Sed
180226633Sdim    void setContext(ASTContext &c) { ctx = &c; }
181226633Sdim    ASTContext &getContext() {
182198092Srdivacky      assert(ctx && "ASTContext should not be NULL.");
183193326Sed      return *ctx;
184193326Sed    }
185193326Sed
186193326Sed    void setCFG(CFG& c) { cfg = &c; }
187193326Sed    CFG& getCFG() { assert(cfg && "CFG should not be NULL."); return *cfg; }
188198092Srdivacky
189226633Sdim    bool isTracked(const Stmt *S) { return cfg->isBlkExpr(S); }
190193326Sed    using DeclBitVector_Types::AnalysisDataTy::isTracked;
191193326Sed
192226633Sdim    unsigned getIdx(const Stmt *S) const {
193193326Sed      CFG::BlkExprNumTy I = cfg->getBlkExprNum(S);
194193326Sed      assert(I && "Stmtession not tracked for bitvector.");
195193326Sed      return I;
196193326Sed    }
197193326Sed    using DeclBitVector_Types::AnalysisDataTy::getIdx;
198198092Srdivacky
199193326Sed    unsigned getNumBlkExprs() const { return cfg->getNumBlkExprs(); }
200193326Sed  };
201193326Sed
202193326Sed  //===--------------------------------------------------------------------===//
203193326Sed  // ValTy - Dataflow value.
204193326Sed  //===--------------------------------------------------------------------===//
205193326Sed
206193326Sed  class ValTy : public DeclBitVector_Types::ValTy {
207193326Sed    llvm::BitVector BlkExprBV;
208193326Sed    typedef DeclBitVector_Types::ValTy ParentTy;
209198092Srdivacky
210193326Sed    static inline ParentTy& ParentRef(ValTy& X) {
211193326Sed      return static_cast<ParentTy&>(X);
212193326Sed    }
213198092Srdivacky
214193326Sed    static inline const ParentTy& ParentRef(const ValTy& X) {
215193326Sed      return static_cast<const ParentTy&>(X);
216193326Sed    }
217198092Srdivacky
218193326Sed  public:
219193326Sed
220193326Sed    void resetBlkExprValues(AnalysisDataTy& AD) {
221193326Sed      BlkExprBV.resize(AD.getNumBlkExprs());
222193326Sed      BlkExprBV.reset();
223193326Sed    }
224198092Srdivacky
225193326Sed    void setBlkExprValues(AnalysisDataTy& AD) {
226193326Sed      BlkExprBV.resize(AD.getNumBlkExprs());
227193326Sed      BlkExprBV.set();
228193326Sed    }
229198092Srdivacky
230193326Sed    void resetValues(AnalysisDataTy& AD) {
231193326Sed      resetDeclValues(AD);
232193326Sed      resetBlkExprValues(AD);
233193326Sed    }
234198092Srdivacky
235193326Sed    void setValues(AnalysisDataTy& AD) {
236193326Sed      setDeclValues(AD);
237193326Sed      setBlkExprValues(AD);
238193326Sed    }
239198092Srdivacky
240198092Srdivacky    bool operator==(const ValTy& RHS) const {
241198092Srdivacky      return ParentRef(*this) == ParentRef(RHS)
242193326Sed          && BlkExprBV == RHS.BlkExprBV;
243193326Sed    }
244198092Srdivacky
245193326Sed    void copyValues(const ValTy& RHS) {
246193326Sed      ParentRef(*this).copyValues(ParentRef(RHS));
247193326Sed      BlkExprBV = RHS.BlkExprBV;
248193326Sed    }
249198092Srdivacky
250193326Sed    llvm::BitVector::reference
251226633Sdim    operator()(const Stmt *S, const AnalysisDataTy& AD) {
252198092Srdivacky      return BlkExprBV[AD.getIdx(S)];
253198092Srdivacky    }
254193326Sed    const llvm::BitVector::reference
255226633Sdim    operator()(const Stmt *S, const AnalysisDataTy& AD) const {
256193326Sed      return const_cast<ValTy&>(*this)(S,AD);
257193326Sed    }
258198092Srdivacky
259193326Sed    using DeclBitVector_Types::ValTy::operator();
260193326Sed
261198092Srdivacky
262198092Srdivacky    llvm::BitVector::reference getStmtBit(unsigned i) { return BlkExprBV[i]; }
263193326Sed    const llvm::BitVector::reference getStmtBit(unsigned i) const {
264193326Sed      return const_cast<llvm::BitVector&>(BlkExprBV)[i];
265193326Sed    }
266198092Srdivacky
267193326Sed    ValTy& OrBlkExprBits(const ValTy& RHS) {
268193326Sed      BlkExprBV |= RHS.BlkExprBV;
269193326Sed      return *this;
270193326Sed    }
271198092Srdivacky
272193326Sed    ValTy& AndBlkExprBits(const ValTy& RHS) {
273193326Sed      BlkExprBV &= RHS.BlkExprBV;
274193326Sed      return *this;
275193326Sed    }
276198092Srdivacky
277193326Sed    ValTy& operator|=(const ValTy& RHS) {
278193326Sed      assert (sizesEqual(RHS));
279193326Sed      ParentRef(*this) |= ParentRef(RHS);
280193326Sed      BlkExprBV |= RHS.BlkExprBV;
281193326Sed      return *this;
282193326Sed    }
283198092Srdivacky
284193326Sed    ValTy& operator&=(const ValTy& RHS) {
285193326Sed      assert (sizesEqual(RHS));
286193326Sed      ParentRef(*this) &= ParentRef(RHS);
287193326Sed      BlkExprBV &= RHS.BlkExprBV;
288193326Sed      return *this;
289193326Sed    }
290198092Srdivacky
291193326Sed    bool sizesEqual(const ValTy& RHS) const {
292193326Sed      return ParentRef(*this).sizesEqual(ParentRef(RHS))
293193326Sed          && BlkExprBV.size() == RHS.BlkExprBV.size();
294193326Sed    }
295193326Sed  };
296198092Srdivacky
297193326Sed  //===--------------------------------------------------------------------===//
298193326Sed  // Some useful merge operations.
299193326Sed  //===--------------------------------------------------------------------===//
300198092Srdivacky
301193326Sed  struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } };
302193326Sed  struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } };
303198092Srdivacky
304193326Sed};
305193326Sed} // end namespace clang
306193326Sed
307193326Sed#endif
308