1 // BlkExprDeclBitVector.h - Dataflow types for Bitvector Analysis --*- C++ --*--
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file provides definition of dataflow types used by analyses such
11 // as LiveVariables and UninitializedValues. The underlying dataflow values
12 // are implemented as bitvectors, but the definitions in this file include
13 // the necessary boilerplate to use with our dataflow framework.
15 //===----------------------------------------------------------------------===//
17 #ifndef LLVM_CLANG_STMTDECLBVDVAL_H
18 #define LLVM_CLANG_STMTDECLBVDVAL_H
20 #include "clang/AST/Decl.h" // for Decl* -> NamedDecl* conversion
21 #include "clang/Analysis/CFG.h"
22 #include "llvm/ADT/BitVector.h"
23 #include "llvm/ADT/DenseMap.h"
30 struct DeclBitVector_Types {
35 explicit Idx(unsigned i) : I(i) {}
38 bool isValid() const {
41 operator unsigned() const {
47 //===--------------------------------------------------------------------===//
48 // AnalysisDataTy - Whole-function meta data.
49 //===--------------------------------------------------------------------===//
51 class AnalysisDataTy {
53 typedef llvm::DenseMap<const NamedDecl*, unsigned > DMapTy;
54 typedef DMapTy::const_iterator decl_iterator;
62 AnalysisDataTy() : NDecls(0) {}
63 virtual ~AnalysisDataTy() {}
65 bool isTracked(const NamedDecl *SD) { return DMap.find(SD) != DMap.end(); }
67 Idx getIdx(const NamedDecl *SD) const {
68 DMapTy::const_iterator I = DMap.find(SD);
69 return I == DMap.end() ? Idx() : Idx(I->second);
72 unsigned getNumDecls() const { return NDecls; }
74 void Register(const NamedDecl *SD) {
75 if (!isTracked(SD)) DMap[SD] = NDecls++;
78 decl_iterator begin_decl() const { return DMap.begin(); }
79 decl_iterator end_decl() const { return DMap.end(); }
82 //===--------------------------------------------------------------------===//
83 // ValTy - Dataflow value.
84 //===--------------------------------------------------------------------===//
87 llvm::BitVector DeclBV;
90 void resetDeclValues(AnalysisDataTy& AD) {
91 DeclBV.resize(AD.getNumDecls());
95 void setDeclValues(AnalysisDataTy& AD) {
96 DeclBV.resize(AD.getNumDecls());
100 void resetValues(AnalysisDataTy& AD) {
104 bool operator==(const ValTy& RHS) const {
105 assert (sizesEqual(RHS));
106 return DeclBV == RHS.DeclBV;
109 void copyValues(const ValTy& RHS) { DeclBV = RHS.DeclBV; }
111 llvm::BitVector::reference getBit(unsigned i) {
115 bool getBit(unsigned i) const {
119 llvm::BitVector::reference
120 operator()(const NamedDecl *ND, const AnalysisDataTy& AD) {
121 return getBit(AD.getIdx(ND));
124 bool operator()(const NamedDecl *ND, const AnalysisDataTy& AD) const {
125 return getBit(AD.getIdx(ND));
128 llvm::BitVector::reference getDeclBit(unsigned i) { return DeclBV[i]; }
129 const llvm::BitVector::reference getDeclBit(unsigned i) const {
130 return const_cast<llvm::BitVector&>(DeclBV)[i];
133 ValTy& operator|=(const ValTy& RHS) {
134 assert (sizesEqual(RHS));
135 DeclBV |= RHS.DeclBV;
139 ValTy& operator&=(const ValTy& RHS) {
140 assert (sizesEqual(RHS));
141 DeclBV &= RHS.DeclBV;
145 ValTy& OrDeclBits(const ValTy& RHS) {
146 return operator|=(RHS);
149 ValTy& AndDeclBits(const ValTy& RHS) {
150 return operator&=(RHS);
153 bool sizesEqual(const ValTy& RHS) const {
154 return DeclBV.size() == RHS.DeclBV.size();
158 //===--------------------------------------------------------------------===//
159 // Some useful merge operations.
160 //===--------------------------------------------------------------------===//
162 struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } };
163 struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } };
167 struct StmtDeclBitVector_Types {
169 //===--------------------------------------------------------------------===//
170 // AnalysisDataTy - Whole-function meta data.
171 //===--------------------------------------------------------------------===//
173 class AnalysisDataTy : public DeclBitVector_Types::AnalysisDataTy {
177 AnalysisDataTy() : ctx(0), cfg(0) {}
178 virtual ~AnalysisDataTy() {}
180 void setContext(ASTContext &c) { ctx = &c; }
181 ASTContext &getContext() {
182 assert(ctx && "ASTContext should not be NULL.");
186 void setCFG(CFG& c) { cfg = &c; }
187 CFG& getCFG() { assert(cfg && "CFG should not be NULL."); return *cfg; }
189 bool isTracked(const Stmt *S) { return cfg->isBlkExpr(S); }
190 using DeclBitVector_Types::AnalysisDataTy::isTracked;
192 unsigned getIdx(const Stmt *S) const {
193 CFG::BlkExprNumTy I = cfg->getBlkExprNum(S);
194 assert(I && "Stmtession not tracked for bitvector.");
197 using DeclBitVector_Types::AnalysisDataTy::getIdx;
199 unsigned getNumBlkExprs() const { return cfg->getNumBlkExprs(); }
202 //===--------------------------------------------------------------------===//
203 // ValTy - Dataflow value.
204 //===--------------------------------------------------------------------===//
206 class ValTy : public DeclBitVector_Types::ValTy {
207 llvm::BitVector BlkExprBV;
208 typedef DeclBitVector_Types::ValTy ParentTy;
210 static inline ParentTy& ParentRef(ValTy& X) {
211 return static_cast<ParentTy&>(X);
214 static inline const ParentTy& ParentRef(const ValTy& X) {
215 return static_cast<const ParentTy&>(X);
220 void resetBlkExprValues(AnalysisDataTy& AD) {
221 BlkExprBV.resize(AD.getNumBlkExprs());
225 void setBlkExprValues(AnalysisDataTy& AD) {
226 BlkExprBV.resize(AD.getNumBlkExprs());
230 void resetValues(AnalysisDataTy& AD) {
232 resetBlkExprValues(AD);
235 void setValues(AnalysisDataTy& AD) {
237 setBlkExprValues(AD);
240 bool operator==(const ValTy& RHS) const {
241 return ParentRef(*this) == ParentRef(RHS)
242 && BlkExprBV == RHS.BlkExprBV;
245 void copyValues(const ValTy& RHS) {
246 ParentRef(*this).copyValues(ParentRef(RHS));
247 BlkExprBV = RHS.BlkExprBV;
250 llvm::BitVector::reference
251 operator()(const Stmt *S, const AnalysisDataTy& AD) {
252 return BlkExprBV[AD.getIdx(S)];
254 const llvm::BitVector::reference
255 operator()(const Stmt *S, const AnalysisDataTy& AD) const {
256 return const_cast<ValTy&>(*this)(S,AD);
259 using DeclBitVector_Types::ValTy::operator();
262 llvm::BitVector::reference getStmtBit(unsigned i) { return BlkExprBV[i]; }
263 const llvm::BitVector::reference getStmtBit(unsigned i) const {
264 return const_cast<llvm::BitVector&>(BlkExprBV)[i];
267 ValTy& OrBlkExprBits(const ValTy& RHS) {
268 BlkExprBV |= RHS.BlkExprBV;
272 ValTy& AndBlkExprBits(const ValTy& RHS) {
273 BlkExprBV &= RHS.BlkExprBV;
277 ValTy& operator|=(const ValTy& RHS) {
278 assert (sizesEqual(RHS));
279 ParentRef(*this) |= ParentRef(RHS);
280 BlkExprBV |= RHS.BlkExprBV;
284 ValTy& operator&=(const ValTy& RHS) {
285 assert (sizesEqual(RHS));
286 ParentRef(*this) &= ParentRef(RHS);
287 BlkExprBV &= RHS.BlkExprBV;
291 bool sizesEqual(const ValTy& RHS) const {
292 return ParentRef(*this).sizesEqual(ParentRef(RHS))
293 && BlkExprBV.size() == RHS.BlkExprBV.size();
297 //===--------------------------------------------------------------------===//
298 // Some useful merge operations.
299 //===--------------------------------------------------------------------===//
301 struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } };
302 struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } };
305 } // end namespace clang