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 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 getStmt()39 const Stmt *getStmt() const { return first; } getLocationContext()40 const LocationContext *getLocationContext() const { return second; } 41 42 /// Profile an EnvironmentEntry for inclusion in a FoldingSet. Profile(llvm::FoldingSetNodeID & ID,const EnvironmentEntry & E)43 static void Profile(llvm::FoldingSetNodeID &ID, 44 const EnvironmentEntry &E) { 45 ID.AddPointer(E.getStmt()); 46 ID.AddPointer(E.getLocationContext()); 47 } 48 Profile(llvm::FoldingSetNodeID & ID)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 Environment(BindingsTy eb)65 Environment(BindingsTy eb) 66 : ExprBindings(eb) {} 67 68 SVal lookupExpr(const EnvironmentEntry &E) const; 69 70 public: 71 typedef BindingsTy::iterator iterator; begin()72 iterator begin() const { return ExprBindings.begin(); } end()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. Profile(llvm::FoldingSetNodeID & ID,const Environment * env)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. Profile(llvm::FoldingSetNodeID & ID)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: EnvironmentManager(llvm::BumpPtrAllocator & Allocator)108 EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {} 109 getInitialEnvironment()110 Environment getInitialEnvironment() { 111 return Environment(F.getEmptyMap()); 112 } 113 114 /// Bind a symbolic value to the given environment entry. 115 Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V, 116 bool Invalidate); 117 118 Environment removeDeadBindings(Environment Env, 119 SymbolReaper &SymReaper, 120 ProgramStateRef state); 121 }; 122 123 } // end GR namespace 124 125 } // end clang namespace 126 127 #endif 128