1 // BlkExprDeclBitVector.h - Dataflow types for Bitvector Analysis --*- C++ --*-- 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 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. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #ifndef LLVM_CLANG_STMTDECLBVDVAL_H 18 #define LLVM_CLANG_STMTDECLBVDVAL_H 19 20 #include "clang/Analysis/CFG.h" 21 #include "clang/AST/Decl.h" // for Decl* -> NamedDecl* conversion 22 #include "llvm/ADT/BitVector.h" 23 #include "llvm/ADT/DenseMap.h" 24 25 namespace clang { 26 27 class Stmt; 28 class ASTContext; 29 30 struct DeclBitVector_Types { 31 32 class Idx { 33 unsigned I; 34 public: 35 explicit Idx(unsigned i) : I(i) {} 36 Idx() : I(~0U) {} 37 38 bool isValid() const { 39 return I != ~0U; 40 } 41 operator unsigned() const { 42 assert (isValid()); 43 return I; 44 } 45 }; 46 47 //===--------------------------------------------------------------------===// 48 // AnalysisDataTy - Whole-function meta data. 49 //===--------------------------------------------------------------------===// 50 51 class AnalysisDataTy { 52 public: 53 typedef llvm::DenseMap<const NamedDecl*, unsigned > DMapTy; 54 typedef DMapTy::const_iterator decl_iterator; 55 56 protected: 57 DMapTy DMap; 58 unsigned NDecls; 59 60 public: 61 62 AnalysisDataTy() : NDecls(0) {} 63 virtual ~AnalysisDataTy() {} 64 65 bool isTracked(const NamedDecl* SD) { return DMap.find(SD) != DMap.end(); } 66 67 Idx getIdx(const NamedDecl* SD) const { 68 DMapTy::const_iterator I = DMap.find(SD); 69 return I == DMap.end() ? Idx() : Idx(I->second); 70 } 71 72 unsigned getNumDecls() const { return NDecls; } 73 74 void Register(const NamedDecl* SD) { 75 if (!isTracked(SD)) DMap[SD] = NDecls++; 76 } 77 78 decl_iterator begin_decl() const { return DMap.begin(); } 79 decl_iterator end_decl() const { return DMap.end(); } 80 }; 81 82 //===--------------------------------------------------------------------===// 83 // ValTy - Dataflow value. 84 //===--------------------------------------------------------------------===// 85 86 class ValTy { 87 llvm::BitVector DeclBV; 88 public: 89 90 void resetDeclValues(AnalysisDataTy& AD) { 91 DeclBV.resize(AD.getNumDecls()); 92 DeclBV.reset(); 93 } 94 95 void setDeclValues(AnalysisDataTy& AD) { 96 DeclBV.resize(AD.getNumDecls()); 97 DeclBV.set(); 98 } 99 100 void resetValues(AnalysisDataTy& AD) { 101 resetDeclValues(AD); 102 } 103 104 bool operator==(const ValTy& RHS) const { 105 assert (sizesEqual(RHS)); 106 return DeclBV == RHS.DeclBV; 107 } 108 109 void copyValues(const ValTy& RHS) { DeclBV = RHS.DeclBV; } 110 111 llvm::BitVector::reference getBit(unsigned i) { 112 return DeclBV[i]; 113 } 114 115 bool getBit(unsigned i) const { 116 return DeclBV[i]; 117 } 118 119 llvm::BitVector::reference 120 operator()(const NamedDecl* ND, const AnalysisDataTy& AD) { 121 return getBit(AD.getIdx(ND)); 122 } 123 124 bool operator()(const NamedDecl* ND, const AnalysisDataTy& AD) const { 125 return getBit(AD.getIdx(ND)); 126 } 127 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]; 131 } 132 133 ValTy& operator|=(const ValTy& RHS) { 134 assert (sizesEqual(RHS)); 135 DeclBV |= RHS.DeclBV; 136 return *this; 137 } 138 139 ValTy& operator&=(const ValTy& RHS) { 140 assert (sizesEqual(RHS)); 141 DeclBV &= RHS.DeclBV; 142 return *this; 143 } 144 145 ValTy& OrDeclBits(const ValTy& RHS) { 146 return operator|=(RHS); 147 } 148 149 ValTy& AndDeclBits(const ValTy& RHS) { 150 return operator&=(RHS); 151 } 152 153 bool sizesEqual(const ValTy& RHS) const { 154 return DeclBV.size() == RHS.DeclBV.size(); 155 } 156 }; 157 158 //===--------------------------------------------------------------------===// 159 // Some useful merge operations. 160 //===--------------------------------------------------------------------===// 161 162 struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } }; 163 struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } }; 164 }; 165 166 167 struct StmtDeclBitVector_Types { 168 169 //===--------------------------------------------------------------------===// 170 // AnalysisDataTy - Whole-function meta data. 171 //===--------------------------------------------------------------------===// 172 173 class AnalysisDataTy : public DeclBitVector_Types::AnalysisDataTy { 174 ASTContext* ctx; 175 CFG* cfg; 176 public: 177 AnalysisDataTy() : ctx(0), cfg(0) {} 178 virtual ~AnalysisDataTy() {} 179 180 void setContext(ASTContext& c) { ctx = &c; } 181 ASTContext& getContext() { 182 assert(ctx && "ASTContext should not be NULL."); 183 return *ctx; 184 } 185 186 void setCFG(CFG& c) { cfg = &c; } 187 CFG& getCFG() { assert(cfg && "CFG should not be NULL."); return *cfg; } 188 189 bool isTracked(const Stmt* S) { return cfg->isBlkExpr(S); } 190 using DeclBitVector_Types::AnalysisDataTy::isTracked; 191 192 unsigned getIdx(const Stmt* S) const { 193 CFG::BlkExprNumTy I = cfg->getBlkExprNum(S); 194 assert(I && "Stmtession not tracked for bitvector."); 195 return I; 196 } 197 using DeclBitVector_Types::AnalysisDataTy::getIdx; 198 199 unsigned getNumBlkExprs() const { return cfg->getNumBlkExprs(); } 200 }; 201 202 //===--------------------------------------------------------------------===// 203 // ValTy - Dataflow value. 204 //===--------------------------------------------------------------------===// 205 206 class ValTy : public DeclBitVector_Types::ValTy { 207 llvm::BitVector BlkExprBV; 208 typedef DeclBitVector_Types::ValTy ParentTy; 209 210 static inline ParentTy& ParentRef(ValTy& X) { 211 return static_cast<ParentTy&>(X); 212 } 213 214 static inline const ParentTy& ParentRef(const ValTy& X) { 215 return static_cast<const ParentTy&>(X); 216 } 217 218 public: 219 220 void resetBlkExprValues(AnalysisDataTy& AD) { 221 BlkExprBV.resize(AD.getNumBlkExprs()); 222 BlkExprBV.reset(); 223 } 224 225 void setBlkExprValues(AnalysisDataTy& AD) { 226 BlkExprBV.resize(AD.getNumBlkExprs()); 227 BlkExprBV.set(); 228 } 229 230 void resetValues(AnalysisDataTy& AD) { 231 resetDeclValues(AD); 232 resetBlkExprValues(AD); 233 } 234 235 void setValues(AnalysisDataTy& AD) { 236 setDeclValues(AD); 237 setBlkExprValues(AD); 238 } 239 240 bool operator==(const ValTy& RHS) const { 241 return ParentRef(*this) == ParentRef(RHS) 242 && BlkExprBV == RHS.BlkExprBV; 243 } 244 245 void copyValues(const ValTy& RHS) { 246 ParentRef(*this).copyValues(ParentRef(RHS)); 247 BlkExprBV = RHS.BlkExprBV; 248 } 249 250 llvm::BitVector::reference 251 operator()(const Stmt* S, const AnalysisDataTy& AD) { 252 return BlkExprBV[AD.getIdx(S)]; 253 } 254 const llvm::BitVector::reference 255 operator()(const Stmt* S, const AnalysisDataTy& AD) const { 256 return const_cast<ValTy&>(*this)(S,AD); 257 } 258 259 using DeclBitVector_Types::ValTy::operator(); 260 261 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]; 265 } 266 267 ValTy& OrBlkExprBits(const ValTy& RHS) { 268 BlkExprBV |= RHS.BlkExprBV; 269 return *this; 270 } 271 272 ValTy& AndBlkExprBits(const ValTy& RHS) { 273 BlkExprBV &= RHS.BlkExprBV; 274 return *this; 275 } 276 277 ValTy& operator|=(const ValTy& RHS) { 278 assert (sizesEqual(RHS)); 279 ParentRef(*this) |= ParentRef(RHS); 280 BlkExprBV |= RHS.BlkExprBV; 281 return *this; 282 } 283 284 ValTy& operator&=(const ValTy& RHS) { 285 assert (sizesEqual(RHS)); 286 ParentRef(*this) &= ParentRef(RHS); 287 BlkExprBV &= RHS.BlkExprBV; 288 return *this; 289 } 290 291 bool sizesEqual(const ValTy& RHS) const { 292 return ParentRef(*this).sizesEqual(ParentRef(RHS)) 293 && BlkExprBV.size() == RHS.BlkExprBV.size(); 294 } 295 }; 296 297 //===--------------------------------------------------------------------===// 298 // Some useful merge operations. 299 //===--------------------------------------------------------------------===// 300 301 struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } }; 302 struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } }; 303 304 }; 305 } // end namespace clang 306 307 #endif 308