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