Environment.h revision 243830
119102Sse//== Environment.h - Map from Stmt* to Locations/Values ---------*- C++ -*--==// 274532Sru// 319102Sse// The LLVM Compiler Infrastructure 419102Sse// 574816Sru// This file is distributed under the University of Illinois Open Source 680029Sobrien// License. See LICENSE.TXT for details. 727401Swpaul// 819102Sse//===----------------------------------------------------------------------===// 919102Sse// 10// This file defined the Environment and EnvironmentManager classes. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_GR_ENVIRONMENT_H 15#define LLVM_CLANG_GR_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; 29 30/// An entry in the environment consists of a Stmt and an LocationContext. 31/// This allows the environment to manage context-sensitive bindings, 32/// which is essentially for modeling recursive function analysis, among 33/// other things. 34class EnvironmentEntry : public std::pair<const Stmt*, 35 const StackFrameContext *> { 36 friend class EnvironmentManager; 37 EnvironmentEntry makeLocation() const; 38 39public: 40 EnvironmentEntry(const Stmt *s, const LocationContext *L); 41 42 const Stmt *getStmt() const { return first; } 43 const LocationContext *getLocationContext() const { return second; } 44 45 /// Profile an EnvironmentEntry for inclusion in a FoldingSet. 46 static void Profile(llvm::FoldingSetNodeID &ID, 47 const EnvironmentEntry &E) { 48 ID.AddPointer(E.getStmt()); 49 ID.AddPointer(E.getLocationContext()); 50 } 51 52 void Profile(llvm::FoldingSetNodeID &ID) const { 53 Profile(ID, *this); 54 } 55}; 56 57/// An immutable map from EnvironemntEntries to SVals. 58class Environment { 59private: 60 friend class EnvironmentManager; 61 62 // Type definitions. 63 typedef llvm::ImmutableMap<EnvironmentEntry, SVal> BindingsTy; 64 65 // Data. 66 BindingsTy ExprBindings; 67 68 Environment(BindingsTy eb) 69 : ExprBindings(eb) {} 70 71 SVal lookupExpr(const EnvironmentEntry &E) const; 72 73public: 74 typedef BindingsTy::iterator iterator; 75 iterator begin() const { return ExprBindings.begin(); } 76 iterator end() const { return ExprBindings.end(); } 77 78 /// Fetches the current binding of the expression in the 79 /// Environment. 80 SVal getSVal(const EnvironmentEntry &E, SValBuilder &svalBuilder) const; 81 82 /// Profile - Profile the contents of an Environment object for use 83 /// in a FoldingSet. 84 static void Profile(llvm::FoldingSetNodeID& ID, const Environment* env) { 85 env->ExprBindings.Profile(ID); 86 } 87 88 /// Profile - Used to profile the contents of this object for inclusion 89 /// in a FoldingSet. 90 void Profile(llvm::FoldingSetNodeID& ID) const { 91 Profile(ID, this); 92 } 93 94 bool operator==(const Environment& RHS) const { 95 return ExprBindings == RHS.ExprBindings; 96 } 97 98 void print(raw_ostream &Out, const char *NL, const char *Sep) const; 99 100private: 101 void printAux(raw_ostream &Out, bool printLocations, 102 const char *NL, const char *Sep) const; 103}; 104 105class EnvironmentManager { 106private: 107 typedef Environment::BindingsTy::Factory FactoryTy; 108 FactoryTy F; 109 110public: 111 EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {} 112 ~EnvironmentManager() {} 113 114 Environment getInitialEnvironment() { 115 return Environment(F.getEmptyMap()); 116 } 117 118 /// Bind a symbolic value to the given environment entry. 119 Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V, 120 bool Invalidate); 121 122 /// Bind the location 'location' and value 'V' to the specified 123 /// environment entry. 124 Environment bindExprAndLocation(Environment Env, 125 const EnvironmentEntry &E, 126 SVal location, 127 SVal V); 128 129 Environment removeDeadBindings(Environment Env, 130 SymbolReaper &SymReaper, 131 ProgramStateRef state); 132}; 133 134} // end GR namespace 135 136} // end clang namespace 137 138#endif 139