clang API Documentation

BlkExprDeclBitVector.h
Go to the documentation of this file.
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