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 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. 55 class Environment { 56 private: 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 70 public: 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 97 private: 98 void printAux(raw_ostream &Out, bool printLocations, 99 const char *NL, const char *Sep) const; 100 }; 101 102 class EnvironmentManager { 103 private: 104 typedef Environment::BindingsTy::Factory FactoryTy; 105 FactoryTy F; 106 107 public: 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