diff options
Diffstat (limited to 'include/clang/Analysis/PathSensitive/SymbolManager.h')
| -rw-r--r-- | include/clang/Analysis/PathSensitive/SymbolManager.h | 179 |
1 files changed, 115 insertions, 64 deletions
diff --git a/include/clang/Analysis/PathSensitive/SymbolManager.h b/include/clang/Analysis/PathSensitive/SymbolManager.h index f32a7e3481dd..d3996c6330a2 100644 --- a/include/clang/Analysis/PathSensitive/SymbolManager.h +++ b/include/clang/Analysis/PathSensitive/SymbolManager.h @@ -21,66 +21,72 @@ #include "llvm/Support/DataTypes.h" #include "llvm/Support/Allocator.h" #include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/ImmutableSet.h" +#include "llvm/ADT/DenseSet.h" namespace llvm { class raw_ostream; } -namespace clang { +namespace clang { class MemRegion; + class TypedRegion; class ASTContext; class BasicValueFactory; } namespace clang { - + class SymExpr : public llvm::FoldingSetNode { public: - enum Kind { BEGIN_SYMBOLS, RegionValueKind, ConjuredKind, END_SYMBOLS, + enum Kind { BEGIN_SYMBOLS, + RegionValueKind, ConjuredKind, DerivedKind, + END_SYMBOLS, SymIntKind, SymSymKind }; private: Kind K; protected: - SymExpr(Kind k) : K(k) {} - + SymExpr(Kind k) : K(k) {} + public: virtual ~SymExpr() {} - - Kind getKind() const { return K; } - - virtual QualType getType(ASTContext&) const = 0; + + Kind getKind() const { return K; } + + void dump() const; + + virtual void dumpToStream(llvm::raw_ostream &os) const = 0; + + virtual QualType getType(ASTContext&) const = 0; virtual void Profile(llvm::FoldingSetNodeID& profile) = 0; - + // Implement isa<T> support. static inline bool classof(const SymExpr*) { return true; } }; - + typedef unsigned SymbolID; - + class SymbolData : public SymExpr { private: const SymbolID Sym; - + protected: - SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {} + SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {} public: virtual ~SymbolData() {} - + SymbolID getSymbolID() const { return Sym; } - + // Implement isa<T> support. - static inline bool classof(const SymExpr* SE) { + static inline bool classof(const SymExpr* SE) { Kind k = SE->getKind(); return k > BEGIN_SYMBOLS && k < END_SYMBOLS; } }; typedef const SymbolData* SymbolRef; - + class SymbolRegionValue : public SymbolData { const MemRegion *R; // We may cast the region to another type, so the expected type of the symbol @@ -90,7 +96,7 @@ class SymbolRegionValue : public SymbolData { public: SymbolRegionValue(SymbolID sym, const MemRegion *r, QualType t = QualType()) : SymbolData(RegionValueKind, sym), R(r), T(t) {} - + const MemRegion* getRegion() const { return R; } static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion* R, @@ -99,11 +105,13 @@ public: profile.AddPointer(R); T.Profile(profile); } - + virtual void Profile(llvm::FoldingSetNodeID& profile) { Profile(profile, R, T); } - + + void dumpToStream(llvm::raw_ostream &os) const; + QualType getType(ASTContext&) const; // Implement isa<T> support. @@ -123,15 +131,17 @@ public: const void* symbolTag) : SymbolData(ConjuredKind, sym), S(s), T(t), Count(count), SymbolTag(symbolTag) {} - + const Stmt* getStmt() const { return S; } unsigned getCount() const { return Count; } const void* getTag() const { return SymbolTag; } - + QualType getType(ASTContext&) const; - + + void dumpToStream(llvm::raw_ostream &os) const; + static void Profile(llvm::FoldingSetNodeID& profile, const Stmt* S, - QualType T, unsigned Count, const void* SymbolTag) { + QualType T, unsigned Count, const void* SymbolTag) { profile.AddInteger((unsigned) ConjuredKind); profile.AddPointer(S); profile.Add(T); @@ -146,7 +156,39 @@ public: // Implement isa<T> support. static inline bool classof(const SymExpr* SE) { return SE->getKind() == ConjuredKind; - } + } +}; + +class SymbolDerived : public SymbolData { + SymbolRef parentSymbol; + const TypedRegion *R; + +public: + SymbolDerived(SymbolID sym, SymbolRef parent, const TypedRegion *r) + : SymbolData(DerivedKind, sym), parentSymbol(parent), R(r) {} + + SymbolRef getParentSymbol() const { return parentSymbol; } + const TypedRegion *getRegion() const { return R; } + + QualType getType(ASTContext&) const; + + void dumpToStream(llvm::raw_ostream &os) const; + + static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent, + const TypedRegion *r) { + profile.AddInteger((unsigned) DerivedKind); + profile.AddPointer(r); + profile.AddPointer(parent); + } + + virtual void Profile(llvm::FoldingSetNodeID& profile) { + Profile(profile, parentSymbol, R); + } + + // Implement isa<T> support. + static inline bool classof(const SymExpr* SE) { + return SE->getKind() == DerivedKind; + } }; // SymIntExpr - Represents symbolic expression like 'x' + 3. @@ -163,14 +205,16 @@ public: // FIXME: We probably need to make this out-of-line to avoid redundant // generation of virtual functions. - QualType getType(ASTContext& C) const { return T; } - + QualType getType(ASTContext& C) const { return T; } + BinaryOperator::Opcode getOpcode() const { return Op; } - + + void dumpToStream(llvm::raw_ostream &os) const; + const SymExpr *getLHS() const { return LHS; } const llvm::APSInt &getRHS() const { return RHS; } - static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs, + static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs, BinaryOperator::Opcode op, const llvm::APSInt& rhs, QualType t) { ID.AddInteger((unsigned) SymIntKind); @@ -183,11 +227,11 @@ public: void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, LHS, Op, RHS, T); } - + // Implement isa<T> support. static inline bool classof(const SymExpr* SE) { return SE->getKind() == SymIntKind; - } + } }; // SymSymExpr - Represents symbolic expression like 'x' + 'y'. @@ -204,11 +248,13 @@ public: const SymExpr *getLHS() const { return LHS; } const SymExpr *getRHS() const { return RHS; } - + // FIXME: We probably need to make this out-of-line to avoid redundant // generation of virtual functions. QualType getType(ASTContext& C) const { return T; } + void dumpToStream(llvm::raw_ostream &os) const; + static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) { ID.AddInteger((unsigned) SymSymKind); @@ -221,45 +267,48 @@ public: void Profile(llvm::FoldingSetNodeID& ID) { Profile(ID, LHS, Op, RHS, T); } - + // Implement isa<T> support. static inline bool classof(const SymExpr* SE) { return SE->getKind() == SymSymKind; - } + } }; class SymbolManager { typedef llvm::FoldingSet<SymExpr> DataSetTy; - DataSetTy DataSet; + DataSetTy DataSet; unsigned SymbolCounter; llvm::BumpPtrAllocator& BPAlloc; BasicValueFactory &BV; ASTContext& Ctx; - + public: - SymbolManager(ASTContext& ctx, BasicValueFactory &bv, + SymbolManager(ASTContext& ctx, BasicValueFactory &bv, llvm::BumpPtrAllocator& bpalloc) : SymbolCounter(0), BPAlloc(bpalloc), BV(bv), Ctx(ctx) {} - + ~SymbolManager(); - + static bool canSymbolicate(QualType T); /// Make a unique symbol for MemRegion R according to its kind. - const SymbolRegionValue* getRegionValueSymbol(const MemRegion* R, + const SymbolRegionValue* getRegionValueSymbol(const MemRegion* R, QualType T = QualType()); const SymbolConjured* getConjuredSymbol(const Stmt* E, QualType T, unsigned VisitCount, const void* SymbolTag = 0); const SymbolConjured* getConjuredSymbol(const Expr* E, unsigned VisitCount, - const void* SymbolTag = 0) { + const void* SymbolTag = 0) { return getConjuredSymbol(E, E->getType(), VisitCount, SymbolTag); } + const SymbolDerived *getDerivedSymbol(SymbolRef parentSymbol, + const TypedRegion *R); + const SymIntExpr *getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const llvm::APSInt& rhs, QualType t); - + const SymIntExpr *getSymIntExpr(const SymExpr &lhs, BinaryOperator::Opcode op, const llvm::APSInt& rhs, QualType t) { return getSymIntExpr(&lhs, op, rhs, t); @@ -267,29 +316,28 @@ public: const SymSymExpr *getSymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType t); - + QualType getType(const SymExpr *SE) const { return SE->getType(Ctx); } - + ASTContext &getContext() { return Ctx; } BasicValueFactory &getBasicVals() { return BV; } }; - + class SymbolReaper { - typedef llvm::ImmutableSet<SymbolRef> SetTy; - typedef SetTy::Factory FactoryTy; - - FactoryTy F; + typedef llvm::DenseSet<SymbolRef> SetTy; + SetTy TheLiving; SetTy TheDead; LiveVariables& Liveness; SymbolManager& SymMgr; - + public: SymbolReaper(LiveVariables& liveness, SymbolManager& symmgr) - : TheLiving(F.GetEmptySet()), TheDead(F.GetEmptySet()), - Liveness(liveness), SymMgr(symmgr) {} + : Liveness(liveness), SymMgr(symmgr) {} + + ~SymbolReaper() {} bool isLive(SymbolRef sym); @@ -300,19 +348,19 @@ public: bool isLive(const Stmt* Loc, const VarDecl* VD) const { return Liveness.isLive(Loc, VD); } - + void markLive(SymbolRef sym); bool maybeDead(SymbolRef sym); - - typedef SetTy::iterator dead_iterator; + + typedef SetTy::const_iterator dead_iterator; dead_iterator dead_begin() const { return TheDead.begin(); } dead_iterator dead_end() const { return TheDead.end(); } - + bool hasDeadSymbols() const { - return !TheDead.isEmpty(); + return !TheDead.empty(); } }; - + class SymbolVisitor { public: // VisitSymbol - A visitor method invoked by @@ -321,11 +369,14 @@ public: virtual bool VisitSymbol(SymbolRef sym) = 0; virtual ~SymbolVisitor(); }; - + } // end clang namespace namespace llvm { - llvm::raw_ostream& operator<<(llvm::raw_ostream& Out, - const clang::SymExpr *SE); +static inline llvm::raw_ostream& operator<<(llvm::raw_ostream& os, + const clang::SymExpr *SE) { + SE->dumpToStream(os); + return os; } +} // end llvm namespace #endif |
