1193326Sed// BlkExprDeclBitVector.h - Dataflow types for Bitvector Analysis --*- C++ --*-- 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file provides definition of dataflow types used by analyses such 11193326Sed// as LiveVariables and UninitializedValues. The underlying dataflow values 12193326Sed// are implemented as bitvectors, but the definitions in this file include 13193326Sed// the necessary boilerplate to use with our dataflow framework. 14193326Sed// 15193326Sed//===----------------------------------------------------------------------===// 16193326Sed 17193326Sed#ifndef LLVM_CLANG_STMTDECLBVDVAL_H 18193326Sed#define LLVM_CLANG_STMTDECLBVDVAL_H 19193326Sed 20249423Sdim#include "clang/AST/Decl.h" // for Decl* -> NamedDecl* conversion 21198092Srdivacky#include "clang/Analysis/CFG.h" 22193326Sed#include "llvm/ADT/BitVector.h" 23193326Sed#include "llvm/ADT/DenseMap.h" 24193326Sed 25193326Sednamespace clang { 26198092Srdivacky 27193326Sed class Stmt; 28193326Sed class ASTContext; 29193326Sed 30193326Sedstruct DeclBitVector_Types { 31198092Srdivacky 32193326Sed class Idx { 33193326Sed unsigned I; 34193326Sed public: 35193326Sed explicit Idx(unsigned i) : I(i) {} 36193326Sed Idx() : I(~0U) {} 37198092Srdivacky 38193326Sed bool isValid() const { 39193326Sed return I != ~0U; 40193326Sed } 41193326Sed operator unsigned() const { 42193326Sed assert (isValid()); 43193326Sed return I; 44193326Sed } 45198092Srdivacky }; 46198092Srdivacky 47193326Sed //===--------------------------------------------------------------------===// 48193326Sed // AnalysisDataTy - Whole-function meta data. 49193326Sed //===--------------------------------------------------------------------===// 50198092Srdivacky 51193326Sed class AnalysisDataTy { 52193326Sed public: 53193326Sed typedef llvm::DenseMap<const NamedDecl*, unsigned > DMapTy; 54193326Sed typedef DMapTy::const_iterator decl_iterator; 55198092Srdivacky 56193326Sed protected: 57198092Srdivacky DMapTy DMap; 58193326Sed unsigned NDecls; 59198092Srdivacky 60193326Sed public: 61198092Srdivacky 62193326Sed AnalysisDataTy() : NDecls(0) {} 63193326Sed virtual ~AnalysisDataTy() {} 64198092Srdivacky 65226633Sdim bool isTracked(const NamedDecl *SD) { return DMap.find(SD) != DMap.end(); } 66198092Srdivacky 67226633Sdim Idx getIdx(const NamedDecl *SD) const { 68193326Sed DMapTy::const_iterator I = DMap.find(SD); 69193326Sed return I == DMap.end() ? Idx() : Idx(I->second); 70193326Sed } 71193326Sed 72193326Sed unsigned getNumDecls() const { return NDecls; } 73198092Srdivacky 74226633Sdim void Register(const NamedDecl *SD) { 75193326Sed if (!isTracked(SD)) DMap[SD] = NDecls++; 76193326Sed } 77193326Sed 78193326Sed decl_iterator begin_decl() const { return DMap.begin(); } 79193326Sed decl_iterator end_decl() const { return DMap.end(); } 80193326Sed }; 81198092Srdivacky 82193326Sed //===--------------------------------------------------------------------===// 83193326Sed // ValTy - Dataflow value. 84193326Sed //===--------------------------------------------------------------------===// 85198092Srdivacky 86193326Sed class ValTy { 87193326Sed llvm::BitVector DeclBV; 88193326Sed public: 89198092Srdivacky 90193326Sed void resetDeclValues(AnalysisDataTy& AD) { 91198092Srdivacky DeclBV.resize(AD.getNumDecls()); 92193326Sed DeclBV.reset(); 93193326Sed } 94193326Sed 95193326Sed void setDeclValues(AnalysisDataTy& AD) { 96198092Srdivacky DeclBV.resize(AD.getNumDecls()); 97193326Sed DeclBV.set(); 98193326Sed } 99198092Srdivacky 100193326Sed void resetValues(AnalysisDataTy& AD) { 101193326Sed resetDeclValues(AD); 102198092Srdivacky } 103198092Srdivacky 104198092Srdivacky bool operator==(const ValTy& RHS) const { 105193326Sed assert (sizesEqual(RHS)); 106193326Sed return DeclBV == RHS.DeclBV; 107193326Sed } 108198092Srdivacky 109193326Sed void copyValues(const ValTy& RHS) { DeclBV = RHS.DeclBV; } 110198092Srdivacky 111193326Sed llvm::BitVector::reference getBit(unsigned i) { 112193326Sed return DeclBV[i]; 113193326Sed } 114198092Srdivacky 115193326Sed bool getBit(unsigned i) const { 116193326Sed return DeclBV[i]; 117193326Sed } 118198092Srdivacky 119193326Sed llvm::BitVector::reference 120226633Sdim operator()(const NamedDecl *ND, const AnalysisDataTy& AD) { 121193326Sed return getBit(AD.getIdx(ND)); 122193326Sed } 123193326Sed 124226633Sdim bool operator()(const NamedDecl *ND, const AnalysisDataTy& AD) const { 125193326Sed return getBit(AD.getIdx(ND)); 126193326Sed } 127198092Srdivacky 128198092Srdivacky llvm::BitVector::reference getDeclBit(unsigned i) { return DeclBV[i]; } 129193326Sed const llvm::BitVector::reference getDeclBit(unsigned i) const { 130193326Sed return const_cast<llvm::BitVector&>(DeclBV)[i]; 131193326Sed } 132198092Srdivacky 133193326Sed ValTy& operator|=(const ValTy& RHS) { 134193326Sed assert (sizesEqual(RHS)); 135193326Sed DeclBV |= RHS.DeclBV; 136193326Sed return *this; 137193326Sed } 138198092Srdivacky 139193326Sed ValTy& operator&=(const ValTy& RHS) { 140193326Sed assert (sizesEqual(RHS)); 141193326Sed DeclBV &= RHS.DeclBV; 142193326Sed return *this; 143193326Sed } 144198092Srdivacky 145193326Sed ValTy& OrDeclBits(const ValTy& RHS) { 146193326Sed return operator|=(RHS); 147193326Sed } 148198092Srdivacky 149193326Sed ValTy& AndDeclBits(const ValTy& RHS) { 150193326Sed return operator&=(RHS); 151193326Sed } 152198092Srdivacky 153193326Sed bool sizesEqual(const ValTy& RHS) const { 154193326Sed return DeclBV.size() == RHS.DeclBV.size(); 155193326Sed } 156193326Sed }; 157198092Srdivacky 158193326Sed //===--------------------------------------------------------------------===// 159193326Sed // Some useful merge operations. 160193326Sed //===--------------------------------------------------------------------===// 161198092Srdivacky 162193326Sed struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } }; 163193326Sed struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } }; 164193326Sed}; 165193326Sed 166193326Sed 167193326Sedstruct StmtDeclBitVector_Types { 168198092Srdivacky 169193326Sed //===--------------------------------------------------------------------===// 170193326Sed // AnalysisDataTy - Whole-function meta data. 171193326Sed //===--------------------------------------------------------------------===// 172193326Sed 173193326Sed class AnalysisDataTy : public DeclBitVector_Types::AnalysisDataTy { 174226633Sdim ASTContext *ctx; 175193326Sed CFG* cfg; 176193326Sed public: 177193326Sed AnalysisDataTy() : ctx(0), cfg(0) {} 178193326Sed virtual ~AnalysisDataTy() {} 179193326Sed 180226633Sdim void setContext(ASTContext &c) { ctx = &c; } 181226633Sdim ASTContext &getContext() { 182198092Srdivacky assert(ctx && "ASTContext should not be NULL."); 183193326Sed return *ctx; 184193326Sed } 185193326Sed 186193326Sed void setCFG(CFG& c) { cfg = &c; } 187193326Sed CFG& getCFG() { assert(cfg && "CFG should not be NULL."); return *cfg; } 188198092Srdivacky 189226633Sdim bool isTracked(const Stmt *S) { return cfg->isBlkExpr(S); } 190193326Sed using DeclBitVector_Types::AnalysisDataTy::isTracked; 191193326Sed 192226633Sdim unsigned getIdx(const Stmt *S) const { 193193326Sed CFG::BlkExprNumTy I = cfg->getBlkExprNum(S); 194193326Sed assert(I && "Stmtession not tracked for bitvector."); 195193326Sed return I; 196193326Sed } 197193326Sed using DeclBitVector_Types::AnalysisDataTy::getIdx; 198198092Srdivacky 199193326Sed unsigned getNumBlkExprs() const { return cfg->getNumBlkExprs(); } 200193326Sed }; 201193326Sed 202193326Sed //===--------------------------------------------------------------------===// 203193326Sed // ValTy - Dataflow value. 204193326Sed //===--------------------------------------------------------------------===// 205193326Sed 206193326Sed class ValTy : public DeclBitVector_Types::ValTy { 207193326Sed llvm::BitVector BlkExprBV; 208193326Sed typedef DeclBitVector_Types::ValTy ParentTy; 209198092Srdivacky 210193326Sed static inline ParentTy& ParentRef(ValTy& X) { 211193326Sed return static_cast<ParentTy&>(X); 212193326Sed } 213198092Srdivacky 214193326Sed static inline const ParentTy& ParentRef(const ValTy& X) { 215193326Sed return static_cast<const ParentTy&>(X); 216193326Sed } 217198092Srdivacky 218193326Sed public: 219193326Sed 220193326Sed void resetBlkExprValues(AnalysisDataTy& AD) { 221193326Sed BlkExprBV.resize(AD.getNumBlkExprs()); 222193326Sed BlkExprBV.reset(); 223193326Sed } 224198092Srdivacky 225193326Sed void setBlkExprValues(AnalysisDataTy& AD) { 226193326Sed BlkExprBV.resize(AD.getNumBlkExprs()); 227193326Sed BlkExprBV.set(); 228193326Sed } 229198092Srdivacky 230193326Sed void resetValues(AnalysisDataTy& AD) { 231193326Sed resetDeclValues(AD); 232193326Sed resetBlkExprValues(AD); 233193326Sed } 234198092Srdivacky 235193326Sed void setValues(AnalysisDataTy& AD) { 236193326Sed setDeclValues(AD); 237193326Sed setBlkExprValues(AD); 238193326Sed } 239198092Srdivacky 240198092Srdivacky bool operator==(const ValTy& RHS) const { 241198092Srdivacky return ParentRef(*this) == ParentRef(RHS) 242193326Sed && BlkExprBV == RHS.BlkExprBV; 243193326Sed } 244198092Srdivacky 245193326Sed void copyValues(const ValTy& RHS) { 246193326Sed ParentRef(*this).copyValues(ParentRef(RHS)); 247193326Sed BlkExprBV = RHS.BlkExprBV; 248193326Sed } 249198092Srdivacky 250193326Sed llvm::BitVector::reference 251226633Sdim operator()(const Stmt *S, const AnalysisDataTy& AD) { 252198092Srdivacky return BlkExprBV[AD.getIdx(S)]; 253198092Srdivacky } 254193326Sed const llvm::BitVector::reference 255226633Sdim operator()(const Stmt *S, const AnalysisDataTy& AD) const { 256193326Sed return const_cast<ValTy&>(*this)(S,AD); 257193326Sed } 258198092Srdivacky 259193326Sed using DeclBitVector_Types::ValTy::operator(); 260193326Sed 261198092Srdivacky 262198092Srdivacky llvm::BitVector::reference getStmtBit(unsigned i) { return BlkExprBV[i]; } 263193326Sed const llvm::BitVector::reference getStmtBit(unsigned i) const { 264193326Sed return const_cast<llvm::BitVector&>(BlkExprBV)[i]; 265193326Sed } 266198092Srdivacky 267193326Sed ValTy& OrBlkExprBits(const ValTy& RHS) { 268193326Sed BlkExprBV |= RHS.BlkExprBV; 269193326Sed return *this; 270193326Sed } 271198092Srdivacky 272193326Sed ValTy& AndBlkExprBits(const ValTy& RHS) { 273193326Sed BlkExprBV &= RHS.BlkExprBV; 274193326Sed return *this; 275193326Sed } 276198092Srdivacky 277193326Sed ValTy& operator|=(const ValTy& RHS) { 278193326Sed assert (sizesEqual(RHS)); 279193326Sed ParentRef(*this) |= ParentRef(RHS); 280193326Sed BlkExprBV |= RHS.BlkExprBV; 281193326Sed return *this; 282193326Sed } 283198092Srdivacky 284193326Sed ValTy& operator&=(const ValTy& RHS) { 285193326Sed assert (sizesEqual(RHS)); 286193326Sed ParentRef(*this) &= ParentRef(RHS); 287193326Sed BlkExprBV &= RHS.BlkExprBV; 288193326Sed return *this; 289193326Sed } 290198092Srdivacky 291193326Sed bool sizesEqual(const ValTy& RHS) const { 292193326Sed return ParentRef(*this).sizesEqual(ParentRef(RHS)) 293193326Sed && BlkExprBV.size() == RHS.BlkExprBV.size(); 294193326Sed } 295193326Sed }; 296198092Srdivacky 297193326Sed //===--------------------------------------------------------------------===// 298193326Sed // Some useful merge operations. 299193326Sed //===--------------------------------------------------------------------===// 300198092Srdivacky 301193326Sed struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } }; 302193326Sed struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } }; 303198092Srdivacky 304193326Sed}; 305193326Sed} // end namespace clang 306193326Sed 307193326Sed#endif 308