diff options
Diffstat (limited to 'include/clang/Checker/PathSensitive/SymbolManager.h')
-rw-r--r-- | include/clang/Checker/PathSensitive/SymbolManager.h | 79 |
1 files changed, 76 insertions, 3 deletions
diff --git a/include/clang/Checker/PathSensitive/SymbolManager.h b/include/clang/Checker/PathSensitive/SymbolManager.h index ffbd289..26ed0c1 100644 --- a/include/clang/Checker/PathSensitive/SymbolManager.h +++ b/include/clang/Checker/PathSensitive/SymbolManager.h @@ -40,6 +40,7 @@ class SymExpr : public llvm::FoldingSetNode { public: enum Kind { BEGIN_SYMBOLS, RegionValueKind, ConjuredKind, DerivedKind, ExtentKind, + MetadataKind, END_SYMBOLS, SymIntKind, SymSymKind }; private: @@ -190,6 +191,9 @@ public: } }; +/// SymbolExtent - Represents the extent (size in bytes) of a bounded region. +/// Clients should not ask the SymbolManager for a region's extent. Always use +/// SubRegion::getExtent instead -- the value returned may not be a symbol. class SymbolExtent : public SymbolData { const SubRegion *R; @@ -218,6 +222,51 @@ public: } }; +/// SymbolMetadata - Represents path-dependent metadata about a specific region. +/// Metadata symbols remain live as long as they are marked as in use before +/// dead-symbol sweeping AND their associated regions are still alive. +/// Intended for use by checkers. +class SymbolMetadata : public SymbolData { + const MemRegion* R; + const Stmt* S; + QualType T; + unsigned Count; + const void* Tag; +public: + SymbolMetadata(SymbolID sym, const MemRegion* r, const Stmt* s, QualType t, + unsigned count, const void* tag) + : SymbolData(MetadataKind, sym), R(r), S(s), T(t), Count(count), Tag(tag) {} + + const MemRegion *getRegion() const { return R; } + const Stmt* getStmt() const { return S; } + unsigned getCount() const { return Count; } + const void* getTag() const { return Tag; } + + QualType getType(ASTContext&) const; + + void dumpToStream(llvm::raw_ostream &os) const; + + static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion *R, + const Stmt *S, QualType T, unsigned Count, + const void *Tag) { + profile.AddInteger((unsigned) MetadataKind); + profile.AddPointer(R); + profile.AddPointer(S); + profile.Add(T); + profile.AddInteger(Count); + profile.AddPointer(Tag); + } + + virtual void Profile(llvm::FoldingSetNodeID& profile) { + Profile(profile, R, S, T, Count, Tag); + } + + // Implement isa<T> support. + static inline bool classof(const SymExpr* SE) { + return SE->getKind() == MetadataKind; + } +}; + // SymIntExpr - Represents symbolic expression like 'x' + 3. class SymIntExpr : public SymExpr { const SymExpr *LHS; @@ -336,6 +385,10 @@ public: const SymbolExtent *getExtentSymbol(const SubRegion *R); + const SymbolMetadata* getMetadataSymbol(const MemRegion* R, const Stmt* S, + QualType T, unsigned VisitCount, + const void* SymbolTag = 0); + const SymIntExpr *getSymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const llvm::APSInt& rhs, QualType t); @@ -359,6 +412,7 @@ class SymbolReaper { typedef llvm::DenseSet<SymbolRef> SetTy; SetTy TheLiving; + SetTy MetadataInUse; SetTy TheDead; const LocationContext *LCtx; const Stmt *Loc; @@ -374,12 +428,24 @@ public: const Stmt *getCurrentStatement() const { return Loc; } bool isLive(SymbolRef sym); - bool isLive(const Stmt *ExprVal) const; - bool isLive(const VarRegion *VR) const; - + + // markLive - Unconditionally marks a symbol as live. This should never be + // used by checkers, only by the state infrastructure such as the store and + // environment. Checkers should instead use metadata symbols and markInUse. void markLive(SymbolRef sym); + + // markInUse - Marks a symbol as important to a checker. For metadata symbols, + // this will keep the symbol alive as long as its associated region is also + // live. For other symbols, this has no effect; checkers are not permitted + // to influence the life of other symbols. This should be used before any + // symbol marking has occurred, i.e. in the MarkLiveSymbols callback. + void markInUse(SymbolRef sym); + + // maybeDead - If a symbol is known to be live, marks the symbol as live. + // Otherwise, if the symbol cannot be proven live, it is marked as dead. + // Returns true if the symbol is dead, false if live. bool maybeDead(SymbolRef sym); typedef SetTy::const_iterator dead_iterator; @@ -389,6 +455,13 @@ public: bool hasDeadSymbols() const { return !TheDead.empty(); } + + /// isDead - Returns whether or not a symbol has been confirmed dead. This + /// should only be called once all marking of dead symbols has completed. + /// (For checkers, this means only in the EvalDeadSymbols callback.) + bool isDead(SymbolRef sym) const { + return TheDead.count(sym); + } }; class SymbolVisitor { |