clang API Documentation
00001 // BlkExprDeclBitVector.h - Dataflow types for Bitvector Analysis --*- C++ --*-- 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file provides definition of dataflow types used by analyses such 00011 // as LiveVariables and UninitializedValues. The underlying dataflow values 00012 // are implemented as bitvectors, but the definitions in this file include 00013 // the necessary boilerplate to use with our dataflow framework. 00014 // 00015 //===----------------------------------------------------------------------===// 00016 00017 #ifndef LLVM_CLANG_STMTDECLBVDVAL_H 00018 #define LLVM_CLANG_STMTDECLBVDVAL_H 00019 00020 #include "clang/Analysis/CFG.h" 00021 #include "clang/AST/Decl.h" // for Decl* -> NamedDecl* conversion 00022 #include "llvm/ADT/BitVector.h" 00023 #include "llvm/ADT/DenseMap.h" 00024 00025 namespace clang { 00026 00027 class Stmt; 00028 class ASTContext; 00029 00030 struct DeclBitVector_Types { 00031 00032 class Idx { 00033 unsigned I; 00034 public: 00035 explicit Idx(unsigned i) : I(i) {} 00036 Idx() : I(~0U) {} 00037 00038 bool isValid() const { 00039 return I != ~0U; 00040 } 00041 operator unsigned() const { 00042 assert (isValid()); 00043 return I; 00044 } 00045 }; 00046 00047 //===--------------------------------------------------------------------===// 00048 // AnalysisDataTy - Whole-function meta data. 00049 //===--------------------------------------------------------------------===// 00050 00051 class AnalysisDataTy { 00052 public: 00053 typedef llvm::DenseMap<const NamedDecl*, unsigned > DMapTy; 00054 typedef DMapTy::const_iterator decl_iterator; 00055 00056 protected: 00057 DMapTy DMap; 00058 unsigned NDecls; 00059 00060 public: 00061 00062 AnalysisDataTy() : NDecls(0) {} 00063 virtual ~AnalysisDataTy() {} 00064 00065 bool isTracked(const NamedDecl *SD) { return DMap.find(SD) != DMap.end(); } 00066 00067 Idx getIdx(const NamedDecl *SD) const { 00068 DMapTy::const_iterator I = DMap.find(SD); 00069 return I == DMap.end() ? Idx() : Idx(I->second); 00070 } 00071 00072 unsigned getNumDecls() const { return NDecls; } 00073 00074 void Register(const NamedDecl *SD) { 00075 if (!isTracked(SD)) DMap[SD] = NDecls++; 00076 } 00077 00078 decl_iterator begin_decl() const { return DMap.begin(); } 00079 decl_iterator end_decl() const { return DMap.end(); } 00080 }; 00081 00082 //===--------------------------------------------------------------------===// 00083 // ValTy - Dataflow value. 00084 //===--------------------------------------------------------------------===// 00085 00086 class ValTy { 00087 llvm::BitVector DeclBV; 00088 public: 00089 00090 void resetDeclValues(AnalysisDataTy& AD) { 00091 DeclBV.resize(AD.getNumDecls()); 00092 DeclBV.reset(); 00093 } 00094 00095 void setDeclValues(AnalysisDataTy& AD) { 00096 DeclBV.resize(AD.getNumDecls()); 00097 DeclBV.set(); 00098 } 00099 00100 void resetValues(AnalysisDataTy& AD) { 00101 resetDeclValues(AD); 00102 } 00103 00104 bool operator==(const ValTy& RHS) const { 00105 assert (sizesEqual(RHS)); 00106 return DeclBV == RHS.DeclBV; 00107 } 00108 00109 void copyValues(const ValTy& RHS) { DeclBV = RHS.DeclBV; } 00110 00111 llvm::BitVector::reference getBit(unsigned i) { 00112 return DeclBV[i]; 00113 } 00114 00115 bool getBit(unsigned i) const { 00116 return DeclBV[i]; 00117 } 00118 00119 llvm::BitVector::reference 00120 operator()(const NamedDecl *ND, const AnalysisDataTy& AD) { 00121 return getBit(AD.getIdx(ND)); 00122 } 00123 00124 bool operator()(const NamedDecl *ND, const AnalysisDataTy& AD) const { 00125 return getBit(AD.getIdx(ND)); 00126 } 00127 00128 llvm::BitVector::reference getDeclBit(unsigned i) { return DeclBV[i]; } 00129 const llvm::BitVector::reference getDeclBit(unsigned i) const { 00130 return const_cast<llvm::BitVector&>(DeclBV)[i]; 00131 } 00132 00133 ValTy& operator|=(const ValTy& RHS) { 00134 assert (sizesEqual(RHS)); 00135 DeclBV |= RHS.DeclBV; 00136 return *this; 00137 } 00138 00139 ValTy& operator&=(const ValTy& RHS) { 00140 assert (sizesEqual(RHS)); 00141 DeclBV &= RHS.DeclBV; 00142 return *this; 00143 } 00144 00145 ValTy& OrDeclBits(const ValTy& RHS) { 00146 return operator|=(RHS); 00147 } 00148 00149 ValTy& AndDeclBits(const ValTy& RHS) { 00150 return operator&=(RHS); 00151 } 00152 00153 bool sizesEqual(const ValTy& RHS) const { 00154 return DeclBV.size() == RHS.DeclBV.size(); 00155 } 00156 }; 00157 00158 //===--------------------------------------------------------------------===// 00159 // Some useful merge operations. 00160 //===--------------------------------------------------------------------===// 00161 00162 struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } }; 00163 struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } }; 00164 }; 00165 00166 00167 struct StmtDeclBitVector_Types { 00168 00169 //===--------------------------------------------------------------------===// 00170 // AnalysisDataTy - Whole-function meta data. 00171 //===--------------------------------------------------------------------===// 00172 00173 class AnalysisDataTy : public DeclBitVector_Types::AnalysisDataTy { 00174 ASTContext *ctx; 00175 CFG* cfg; 00176 public: 00177 AnalysisDataTy() : ctx(0), cfg(0) {} 00178 virtual ~AnalysisDataTy() {} 00179 00180 void setContext(ASTContext &c) { ctx = &c; } 00181 ASTContext &getContext() { 00182 assert(ctx && "ASTContext should not be NULL."); 00183 return *ctx; 00184 } 00185 00186 void setCFG(CFG& c) { cfg = &c; } 00187 CFG& getCFG() { assert(cfg && "CFG should not be NULL."); return *cfg; } 00188 00189 bool isTracked(const Stmt *S) { return cfg->isBlkExpr(S); } 00190 using DeclBitVector_Types::AnalysisDataTy::isTracked; 00191 00192 unsigned getIdx(const Stmt *S) const { 00193 CFG::BlkExprNumTy I = cfg->getBlkExprNum(S); 00194 assert(I && "Stmtession not tracked for bitvector."); 00195 return I; 00196 } 00197 using DeclBitVector_Types::AnalysisDataTy::getIdx; 00198 00199 unsigned getNumBlkExprs() const { return cfg->getNumBlkExprs(); } 00200 }; 00201 00202 //===--------------------------------------------------------------------===// 00203 // ValTy - Dataflow value. 00204 //===--------------------------------------------------------------------===// 00205 00206 class ValTy : public DeclBitVector_Types::ValTy { 00207 llvm::BitVector BlkExprBV; 00208 typedef DeclBitVector_Types::ValTy ParentTy; 00209 00210 static inline ParentTy& ParentRef(ValTy& X) { 00211 return static_cast<ParentTy&>(X); 00212 } 00213 00214 static inline const ParentTy& ParentRef(const ValTy& X) { 00215 return static_cast<const ParentTy&>(X); 00216 } 00217 00218 public: 00219 00220 void resetBlkExprValues(AnalysisDataTy& AD) { 00221 BlkExprBV.resize(AD.getNumBlkExprs()); 00222 BlkExprBV.reset(); 00223 } 00224 00225 void setBlkExprValues(AnalysisDataTy& AD) { 00226 BlkExprBV.resize(AD.getNumBlkExprs()); 00227 BlkExprBV.set(); 00228 } 00229 00230 void resetValues(AnalysisDataTy& AD) { 00231 resetDeclValues(AD); 00232 resetBlkExprValues(AD); 00233 } 00234 00235 void setValues(AnalysisDataTy& AD) { 00236 setDeclValues(AD); 00237 setBlkExprValues(AD); 00238 } 00239 00240 bool operator==(const ValTy& RHS) const { 00241 return ParentRef(*this) == ParentRef(RHS) 00242 && BlkExprBV == RHS.BlkExprBV; 00243 } 00244 00245 void copyValues(const ValTy& RHS) { 00246 ParentRef(*this).copyValues(ParentRef(RHS)); 00247 BlkExprBV = RHS.BlkExprBV; 00248 } 00249 00250 llvm::BitVector::reference 00251 operator()(const Stmt *S, const AnalysisDataTy& AD) { 00252 return BlkExprBV[AD.getIdx(S)]; 00253 } 00254 const llvm::BitVector::reference 00255 operator()(const Stmt *S, const AnalysisDataTy& AD) const { 00256 return const_cast<ValTy&>(*this)(S,AD); 00257 } 00258 00259 using DeclBitVector_Types::ValTy::operator(); 00260 00261 00262 llvm::BitVector::reference getStmtBit(unsigned i) { return BlkExprBV[i]; } 00263 const llvm::BitVector::reference getStmtBit(unsigned i) const { 00264 return const_cast<llvm::BitVector&>(BlkExprBV)[i]; 00265 } 00266 00267 ValTy& OrBlkExprBits(const ValTy& RHS) { 00268 BlkExprBV |= RHS.BlkExprBV; 00269 return *this; 00270 } 00271 00272 ValTy& AndBlkExprBits(const ValTy& RHS) { 00273 BlkExprBV &= RHS.BlkExprBV; 00274 return *this; 00275 } 00276 00277 ValTy& operator|=(const ValTy& RHS) { 00278 assert (sizesEqual(RHS)); 00279 ParentRef(*this) |= ParentRef(RHS); 00280 BlkExprBV |= RHS.BlkExprBV; 00281 return *this; 00282 } 00283 00284 ValTy& operator&=(const ValTy& RHS) { 00285 assert (sizesEqual(RHS)); 00286 ParentRef(*this) &= ParentRef(RHS); 00287 BlkExprBV &= RHS.BlkExprBV; 00288 return *this; 00289 } 00290 00291 bool sizesEqual(const ValTy& RHS) const { 00292 return ParentRef(*this).sizesEqual(ParentRef(RHS)) 00293 && BlkExprBV.size() == RHS.BlkExprBV.size(); 00294 } 00295 }; 00296 00297 //===--------------------------------------------------------------------===// 00298 // Some useful merge operations. 00299 //===--------------------------------------------------------------------===// 00300 00301 struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } }; 00302 struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } }; 00303 00304 }; 00305 } // end namespace clang 00306 00307 #endif