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 21 namespace clang { 22 23 class LiveVariables; 24 25 namespace ento { 26 27 class EnvironmentManager; 28 class 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. 34 class EnvironmentEntry : public std::pair<const Stmt*, 35 const StackFrameContext *> { 36 public: 37 EnvironmentEntry(const Stmt *s, const LocationContext *L) 38 : std::pair<const Stmt*, 39 const StackFrameContext*>(s, L ? L->getCurrentStackFrame():0) {} 40 41 const Stmt *getStmt() const { return first; } 42 const LocationContext *getLocationContext() const { return second; } 43 44 /// Profile an EnvironmentEntry for inclusion in a FoldingSet. 45 static void Profile(llvm::FoldingSetNodeID &ID, 46 const EnvironmentEntry &E) { 47 ID.AddPointer(E.getStmt()); 48 ID.AddPointer(E.getLocationContext()); 49 } 50 51 void Profile(llvm::FoldingSetNodeID &ID) const { 52 Profile(ID, *this); 53 } 54 }; 55 56 /// An immutable map from EnvironemntEntries to SVals. 57 class Environment { 58 private: 59 friend class EnvironmentManager; 60 61 // Type definitions. 62 typedef llvm::ImmutableMap<EnvironmentEntry, SVal> BindingsTy; 63 64 // Data. 65 BindingsTy ExprBindings; 66 67 Environment(BindingsTy eb) 68 : ExprBindings(eb) {} 69 70 SVal lookupExpr(const EnvironmentEntry &E) const; 71 72 public: 73 typedef BindingsTy::iterator iterator; 74 iterator begin() const { return ExprBindings.begin(); } 75 iterator end() const { return ExprBindings.end(); } 76 77 /// Fetches the current binding of the expression in the 78 /// Environment. 79 SVal getSVal(const EnvironmentEntry &E, 80 SValBuilder &svalBuilder, 81 bool useOnlyDirectBindings = false) const; 82 83 /// Profile - Profile the contents of an Environment object for use 84 /// in a FoldingSet. 85 static void Profile(llvm::FoldingSetNodeID& ID, const Environment* env) { 86 env->ExprBindings.Profile(ID); 87 } 88 89 /// Profile - Used to profile the contents of this object for inclusion 90 /// in a FoldingSet. 91 void Profile(llvm::FoldingSetNodeID& ID) const { 92 Profile(ID, this); 93 } 94 95 bool operator==(const Environment& RHS) const { 96 return ExprBindings == RHS.ExprBindings; 97 } 98 99 void print(raw_ostream &Out, const char *NL, const char *Sep) const; 100 101 private: 102 void printAux(raw_ostream &Out, bool printLocations, 103 const char *NL, const char *Sep) const; 104 }; 105 106 class EnvironmentManager { 107 private: 108 typedef Environment::BindingsTy::Factory FactoryTy; 109 FactoryTy F; 110 111 public: 112 EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {} 113 ~EnvironmentManager() {} 114 115 Environment getInitialEnvironment() { 116 return Environment(F.getEmptyMap()); 117 } 118 119 /// Bind a symbolic value to the given environment entry. 120 Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V, 121 bool Invalidate); 122 123 /// Bind the location 'location' and value 'V' to the specified 124 /// environment entry. 125 Environment bindExprAndLocation(Environment Env, 126 const EnvironmentEntry &E, 127 SVal location, 128 SVal V); 129 130 Environment removeDeadBindings(Environment Env, 131 SymbolReaper &SymReaper, 132 ProgramStateRef state); 133 }; 134 135 } // end GR namespace 136 137 } // end clang namespace 138 139 #endif 140