Home | History | Annotate | Download | only in Support
      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