Environment.h revision 7affe151f5689b2d3547b8947c4099532c78a021
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_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 *> { 36public: 37 EnvironmentEntry(const Stmt *s, const LocationContext *L); 38 39 const Stmt *getStmt() const { return first; } 40 const LocationContext *getLocationContext() const { return second; } 41 42 /// Profile an EnvironmentEntry for inclusion in a FoldingSet. 43 static void Profile(llvm::FoldingSetNodeID &ID, 44 const EnvironmentEntry &E) { 45 ID.AddPointer(E.getStmt()); 46 ID.AddPointer(E.getLocationContext()); 47 } 48 49 void Profile(llvm::FoldingSetNodeID &ID) const { 50 Profile(ID, *this); 51 } 52}; 53 54/// An immutable map from EnvironemntEntries to SVals. 55class Environment { 56private: 57 friend class EnvironmentManager; 58 59 // Type definitions. 60 typedef llvm::ImmutableMap<EnvironmentEntry, SVal> BindingsTy; 61 62 // Data. 63 BindingsTy ExprBindings; 64 65 Environment(BindingsTy eb) 66 : ExprBindings(eb) {} 67 68 SVal lookupExpr(const EnvironmentEntry &E) const; 69 70public: 71 typedef BindingsTy::iterator iterator; 72 iterator begin() const { return ExprBindings.begin(); } 73 iterator end() const { return ExprBindings.end(); } 74 75 /// Fetches the current binding of the expression in the 76 /// Environment. 77 SVal getSVal(const EnvironmentEntry &E, SValBuilder &svalBuilder) const; 78 79 /// Profile - Profile the contents of an Environment object for use 80 /// in a FoldingSet. 81 static void Profile(llvm::FoldingSetNodeID& ID, const Environment* env) { 82 env->ExprBindings.Profile(ID); 83 } 84 85 /// Profile - Used to profile the contents of this object for inclusion 86 /// in a FoldingSet. 87 void Profile(llvm::FoldingSetNodeID& ID) const { 88 Profile(ID, this); 89 } 90 91 bool operator==(const Environment& RHS) const { 92 return ExprBindings == RHS.ExprBindings; 93 } 94 95 void print(raw_ostream &Out, const char *NL, const char *Sep) const; 96 97private: 98 void printAux(raw_ostream &Out, bool printLocations, 99 const char *NL, const char *Sep) const; 100}; 101 102class EnvironmentManager { 103private: 104 typedef Environment::BindingsTy::Factory FactoryTy; 105 FactoryTy F; 106 107public: 108 EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {} 109 ~EnvironmentManager() {} 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