diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index c83792ce641b..edae06e68c34 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -56,6 +56,7 @@ template struct ProgramStateTrait { class ProgramStateManager; +/// \class ProgramState /// ProgramState - This class encapsulates: /// /// 1. A mapping from expressions to values (Environment) @@ -179,10 +180,7 @@ public: DefinedOrUnknownSVal upperBound, bool assumption) const; - //==---------------------------------------------------------------------==// - // Utility methods for getting regions. - //==---------------------------------------------------------------------==// - + /// Utility method for getting regions. const VarRegion* getRegion(const VarDecl *D, const LocationContext *LC) const; //==---------------------------------------------------------------------==// @@ -262,11 +260,22 @@ public: SVal getSValAsScalarOrLoc(const MemRegion *R) const; + /// \brief Visits the symbols reachable from the given SVal using the provided + /// SymbolVisitor. + /// + /// This is a convenience API. Consider using ScanReachableSymbols class + /// directly when making multiple scans on the same state with the same + /// visitor to avoid repeated initialization cost. + /// \sa ScanReachableSymbols bool scanReachableSymbols(SVal val, SymbolVisitor& visitor) const; + /// \brief Visits the symbols reachable from the SVals in the given range + /// using the provided SymbolVisitor. bool scanReachableSymbols(const SVal *I, const SVal *E, SymbolVisitor &visitor) const; + /// \brief Visits the symbols reachable from the regions in the given + /// MemRegions range using the provided SymbolVisitor. bool scanReachableSymbols(const MemRegion * const *I, const MemRegion * const *E, SymbolVisitor &visitor) const; @@ -772,6 +781,32 @@ CB ProgramState::scanReachableSymbols(const MemRegion * const *beg, return cb; } +/// \class ScanReachableSymbols +/// A Utility class that allows to visit the reachable symbols using a custom +/// SymbolVisitor. +class ScanReachableSymbols : public SubRegionMap::Visitor { + typedef llvm::DenseMap VisitedItems; + + VisitedItems visited; + const ProgramState *state; + SymbolVisitor &visitor; + llvm::OwningPtr SRM; +public: + + ScanReachableSymbols(const ProgramState *st, SymbolVisitor& v) + : state(st), visitor(v) {} + + bool scan(nonloc::CompoundVal val); + bool scan(SVal val); + bool scan(const MemRegion *R); + bool scan(const SymExpr *sym); + + // From SubRegionMap::Visitor. + bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) { + return scan(SubRegion); + } +}; + } // end GR namespace } // end clang namespace diff --git a/clang/lib/StaticAnalyzer/Core/Environment.cpp b/clang/lib/StaticAnalyzer/Core/Environment.cpp index 2d37e53ceeef..0ca116863151 100644 --- a/clang/lib/StaticAnalyzer/Core/Environment.cpp +++ b/clang/lib/StaticAnalyzer/Core/Environment.cpp @@ -156,6 +156,9 @@ EnvironmentManager::removeDeadBindings(Environment Env, SmallVector, 10> deferredLocations; + MarkLiveCallback CB(SymReaper); + ScanReachableSymbols RSScaner(ST, CB); + // Iterate over the block-expr bindings. for (Environment::iterator I = Env.begin(), E = Env.end(); I != E; ++I) { @@ -183,8 +186,7 @@ EnvironmentManager::removeDeadBindings(Environment Env, } // Mark all symbols in the block expr's value live. - MarkLiveCallback cb(SymReaper); - ST->scanReachableSymbols(X, cb); + RSScaner.scan(X); continue; } diff --git a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp index 6a03a3e8cceb..73788cc42efb 100644 --- a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp +++ b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -513,35 +513,6 @@ const ProgramState *ProgramStateManager::removeGDM(const ProgramState *state, vo return getPersistentState(NewState); } -//===----------------------------------------------------------------------===// -// Utility. -//===----------------------------------------------------------------------===// - -namespace { -class ScanReachableSymbols : public SubRegionMap::Visitor { - typedef llvm::DenseMap VisitedItems; - - VisitedItems visited; - const ProgramState *state; - SymbolVisitor &visitor; - llvm::OwningPtr SRM; -public: - - ScanReachableSymbols(const ProgramState *st, SymbolVisitor& v) - : state(st), visitor(v) {} - - bool scan(nonloc::CompoundVal val); - bool scan(SVal val); - bool scan(const MemRegion *R); - bool scan(const SymExpr *sym); - - // From SubRegionMap::Visitor. - bool Visit(const MemRegion* Parent, const MemRegion* SubRegion) { - return scan(SubRegion); - } -}; -} - bool ScanReachableSymbols::scan(nonloc::CompoundVal val) { for (nonloc::CompoundVal::iterator I=val.begin(), E=val.end(); I!=E; ++I) if (!scan(*I))