From: Ted Kremenek Date: Fri, 28 Sep 2007 20:12:10 +0000 (+0000) Subject: Refactored ExprDeclBitVector into two classes: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ca64cef65c2fcc3d22908b121bc101993604c286;p=clang Refactored ExprDeclBitVector into two classes: DeclBitVector ExprDeclBitVector (which subclasses the former) DeclBitVector is for analyses that just want to track bitvector state for declarations. ExprDeclBitVector is for analyses that want to track bitvector state for both both declarations and CFGBlock-level expressions. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42445 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Analysis/ExprDeclBitVector.h b/include/clang/Analysis/ExprDeclBitVector.h index d1cdc03762..8cda9538a8 100644 --- a/include/clang/Analysis/ExprDeclBitVector.h +++ b/include/clang/Analysis/ExprDeclBitVector.h @@ -24,111 +24,189 @@ namespace clang { class Expr; class ScopedDecl; - -struct ExprDeclBitVector_Types { + +struct DeclBitVector_Types { //===--------------------------------------------------------------------===// // AnalysisDataTy - Whole-function meta data. //===--------------------------------------------------------------------===// - + class AnalysisDataTy { public: typedef llvm::DenseMap DMapTy; - typedef llvm::DenseMap EMapTy; typedef DMapTy::const_iterator decl_iterator; - typedef EMapTy::const_iterator expr_iterator; - + protected: - EMapTy EMap; DMapTy DMap; unsigned NDecls; - unsigned NExprs; - + public: - AnalysisDataTy() : NDecls(0), NExprs(0) {} + AnalysisDataTy() : NDecls(0) {} virtual ~AnalysisDataTy() {} bool isTracked(const ScopedDecl* SD) { return DMap.find(SD) != DMap.end(); } - bool isTracked(const Expr* E) { return EMap.find(E) != EMap.end(); } - - unsigned operator[](const ScopedDecl* SD) const { + + unsigned getIdx(const ScopedDecl* SD) const { DMapTy::const_iterator I = DMap.find(SD); assert (I != DMap.end()); return I->second; } - - unsigned operator[](const Expr* E) const { - EMapTy::const_iterator I = EMap.find(E); - assert (I != EMap.end()); - return I->second; - } - + unsigned getNumDecls() const { return NDecls; } - unsigned getNumExprs() const { return NExprs; } void Register(const ScopedDecl* SD) { if (!isTracked(SD)) DMap[SD] = NDecls++; } - - void Register(const Expr* E) { - if (!isTracked(E)) EMap[E] = NExprs++; - } - + decl_iterator begin_decl() const { return DMap.begin(); } decl_iterator end_decl() const { return DMap.end(); } - expr_iterator begin_expr() const { return EMap.begin(); } - expr_iterator end_expr() const { return EMap.end(); } }; - + //===--------------------------------------------------------------------===// // ValTy - Dataflow value. //===--------------------------------------------------------------------===// - + class ValTy { llvm::BitVector DeclBV; - llvm::BitVector ExprBV; public: void resetValues(AnalysisDataTy& AD) { DeclBV.resize(AD.getNumDecls()); DeclBV.reset(); - ExprBV.resize(AD.getNumExprs()); - ExprBV.reset(); } bool operator==(const ValTy& RHS) const { assert (sizesEqual(RHS)); - return DeclBV == RHS.DeclBV && ExprBV == RHS.ExprBV; + return DeclBV == RHS.DeclBV; } - void copyValues(const ValTy& RHS) { - DeclBV = RHS.DeclBV; - ExprBV = RHS.ExprBV; - } + void copyValues(const ValTy& RHS) { DeclBV = RHS.DeclBV; } llvm::BitVector::reference operator()(const ScopedDecl* SD, const AnalysisDataTy& AD) { - return DeclBV[AD[SD]]; + return DeclBV[AD.getIdx(SD)]; } const llvm::BitVector::reference operator()(const ScopedDecl* SD, const AnalysisDataTy& AD) const { return const_cast(*this)(SD,AD); } + llvm::BitVector::reference getDeclBit(unsigned i) { return DeclBV[i]; } + const llvm::BitVector::reference getDeclBit(unsigned i) const { + return const_cast(DeclBV)[i]; + } + + ValTy& operator|=(const ValTy& RHS) { + assert (sizesEqual(RHS)); + DeclBV |= RHS.DeclBV; + return *this; + } + + ValTy& operator&=(const ValTy& RHS) { + assert (sizesEqual(RHS)); + DeclBV &= RHS.DeclBV; + return *this; + } + + bool sizesEqual(const ValTy& RHS) const { + return DeclBV.size() == RHS.DeclBV.size(); + } + }; + + //===--------------------------------------------------------------------===// + // Some useful merge operations. + //===--------------------------------------------------------------------===// + + struct Union { void operator()(ValTy& Dst, ValTy& Src) { Dst |= Src; } }; + struct Intersect { void operator()(ValTy& Dst, ValTy& Src) { Dst &= Src; } }; +}; + + +struct ExprDeclBitVector_Types { + + //===--------------------------------------------------------------------===// + // AnalysisDataTy - Whole-function meta data. + //===--------------------------------------------------------------------===// + + class AnalysisDataTy : public DeclBitVector_Types::AnalysisDataTy { + public: + typedef llvm::DenseMap EMapTy; + typedef EMapTy::const_iterator expr_iterator; + + protected: + EMapTy EMap; + unsigned NExprs; + + public: + + AnalysisDataTy() : NExprs(0) {} + virtual ~AnalysisDataTy() {} + + bool isTracked(const Expr* E) { return EMap.find(E) != EMap.end(); } + using DeclBitVector_Types::AnalysisDataTy::isTracked; + + unsigned getIdx(const Expr* E) const { + EMapTy::const_iterator I = EMap.find(E); + assert (I != EMap.end()); + return I->second; + } + using DeclBitVector_Types::AnalysisDataTy::getIdx; + + unsigned getNumExprs() const { return NExprs; } + + void Register(const Expr* E) { if (!isTracked(E)) EMap[E] = NExprs++; } + using DeclBitVector_Types::AnalysisDataTy::Register; + + expr_iterator begin_expr() const { return EMap.begin(); } + expr_iterator end_expr() const { return EMap.end(); } + }; + + //===--------------------------------------------------------------------===// + // ValTy - Dataflow value. + //===--------------------------------------------------------------------===// + + class ValTy : public DeclBitVector_Types::ValTy { + llvm::BitVector ExprBV; + typedef DeclBitVector_Types::ValTy ParentTy; + + static inline ParentTy& ParentRef(ValTy& X) { + return static_cast(X); + } + + static inline const ParentTy& ParentRef(const ValTy& X) { + return static_cast(X); + } + + public: + + void resetValues(AnalysisDataTy& AD) { + ParentRef(*this).resetValues(AD); + ExprBV.resize(AD.getNumExprs()); + ExprBV.reset(); + } + + bool operator==(const ValTy& RHS) const { + return ParentRef(*this) == ParentRef(RHS) + && ExprBV == RHS.ExprBV; + } + + void copyValues(const ValTy& RHS) { + ParentRef(*this).copyValues(ParentRef(RHS)); + ExprBV = RHS.ExprBV; + } + llvm::BitVector::reference operator()(const Expr* E, const AnalysisDataTy& AD) { - return ExprBV[AD[E]]; + return ExprBV[AD.getIdx(E)]; } const llvm::BitVector::reference operator()(const Expr* E, const AnalysisDataTy& AD) const { return const_cast(*this)(E,AD); } - llvm::BitVector::reference getDeclBit(unsigned i) { return DeclBV[i]; } - const llvm::BitVector::reference getDeclBit(unsigned i) const { - return const_cast(DeclBV)[i]; - } + using DeclBitVector_Types::ValTy::operator(); + llvm::BitVector::reference getExprBit(unsigned i) { return ExprBV[i]; } const llvm::BitVector::reference getExprBit(unsigned i) const { @@ -137,20 +215,20 @@ struct ExprDeclBitVector_Types { ValTy& operator|=(const ValTy& RHS) { assert (sizesEqual(RHS)); - DeclBV |= RHS.DeclBV; + ParentRef(*this) |= ParentRef(RHS); ExprBV |= RHS.ExprBV; return *this; } ValTy& operator&=(const ValTy& RHS) { assert (sizesEqual(RHS)); - DeclBV &= RHS.DeclBV; + ParentRef(*this) &= ParentRef(RHS); ExprBV &= RHS.ExprBV; return *this; } bool sizesEqual(const ValTy& RHS) const { - return DeclBV.size() == RHS.DeclBV.size() + return ParentRef(*this).sizesEqual(ParentRef(RHS)) && ExprBV.size() == RHS.ExprBV.size(); } };