1//== Environment.h - Map from Stmt* to Locations/Values ---------*- C++ -*--==// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defined the Environment and EnvironmentManager classes. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENVIRONMENT_H 15#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENVIRONMENT_H 16 17#include "clang/Analysis/AnalysisContext.h" 18#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 19#include "llvm/ADT/ImmutableMap.h" 20 21namespace clang { 22 23class LiveVariables; 24 25namespace ento { 26 27class EnvironmentManager; 28class SValBuilder; 29class SymbolReaper; 30 31/// An entry in the environment consists of a Stmt and an LocationContext. 32/// This allows the environment to manage context-sensitive bindings, 33/// which is essentially for modeling recursive function analysis, among 34/// other things. 35class EnvironmentEntry : public std::pair<const Stmt*, 36 const StackFrameContext *> { 37public: 38 EnvironmentEntry(const Stmt *s, const LocationContext *L); 39 40 const Stmt *getStmt() const { return first; } 41 const LocationContext *getLocationContext() const { return second; } 42 43 /// Profile an EnvironmentEntry for inclusion in a FoldingSet. 44 static void Profile(llvm::FoldingSetNodeID &ID, 45 const EnvironmentEntry &E) { 46 ID.AddPointer(E.getStmt()); 47 ID.AddPointer(E.getLocationContext()); 48 } 49 50 void Profile(llvm::FoldingSetNodeID &ID) const { 51 Profile(ID, *this); 52 } 53}; 54 55/// An immutable map from EnvironemntEntries to SVals. 56class Environment { 57private: 58 friend class EnvironmentManager; 59 60 // Type definitions. 61 typedef llvm::ImmutableMap<EnvironmentEntry, SVal> BindingsTy; 62 63 // Data. 64 BindingsTy ExprBindings; 65 66 Environment(BindingsTy eb) 67 : ExprBindings(eb) {} 68 69 SVal lookupExpr(const EnvironmentEntry &E) const; 70 71public: 72 typedef BindingsTy::iterator iterator; 73 iterator begin() const { return ExprBindings.begin(); } 74 iterator end() const { return ExprBindings.end(); } 75 76 /// Fetches the current binding of the expression in the 77 /// Environment. 78 SVal getSVal(const EnvironmentEntry &E, SValBuilder &svalBuilder) const; 79 80 /// Profile - Profile the contents of an Environment object for use 81 /// in a FoldingSet. 82 static void Profile(llvm::FoldingSetNodeID& ID, const Environment* env) { 83 env->ExprBindings.Profile(ID); 84 } 85 86 /// Profile - Used to profile the contents of this object for inclusion 87 /// in a FoldingSet. 88 void Profile(llvm::FoldingSetNodeID& ID) const { 89 Profile(ID, this); 90 } 91 92 bool operator==(const Environment& RHS) const { 93 return ExprBindings == RHS.ExprBindings; 94 } 95 96 void print(raw_ostream &Out, const char *NL, const char *Sep) const; 97 98private: 99 void printAux(raw_ostream &Out, bool printLocations, 100 const char *NL, const char *Sep) const; 101}; 102 103class EnvironmentManager { 104private: 105 typedef Environment::BindingsTy::Factory FactoryTy; 106 FactoryTy F; 107 108public: 109 EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {} 110 111 Environment getInitialEnvironment() { 112 return Environment(F.getEmptyMap()); 113 } 114 115 /// Bind a symbolic value to the given environment entry. 116 Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V, 117 bool Invalidate); 118 119 Environment removeDeadBindings(Environment Env, 120 SymbolReaper &SymReaper, 121 ProgramStateRef state); 122}; 123 124} // end GR namespace 125 126} // end clang namespace 127 128#endif 129