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