clang API Documentation
00001 //== Environment.h - Map from Stmt* to Locations/Values ---------*- C++ -*--==// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defined the Environment and EnvironmentManager classes. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_CLANG_GR_ENVIRONMENT_H 00015 #define LLVM_CLANG_GR_ENVIRONMENT_H 00016 00017 #include "clang/Analysis/AnalysisContext.h" 00018 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 00019 #include "llvm/ADT/ImmutableMap.h" 00020 00021 namespace clang { 00022 00023 class LiveVariables; 00024 00025 namespace ento { 00026 00027 class EnvironmentManager; 00028 class SValBuilder; 00029 00030 /// An entry in the environment consists of a Stmt and an LocationContext. 00031 /// This allows the environment to manage context-sensitive bindings, 00032 /// which is essentially for modeling recursive function analysis, among 00033 /// other things. 00034 class EnvironmentEntry : public std::pair<const Stmt*, 00035 const StackFrameContext *> { 00036 public: 00037 EnvironmentEntry(const Stmt *s, const LocationContext *L) 00038 : std::pair<const Stmt*, 00039 const StackFrameContext*>(s, L ? L->getCurrentStackFrame():0) {} 00040 00041 const Stmt *getStmt() const { return first; } 00042 const LocationContext *getLocationContext() const { return second; } 00043 00044 /// Profile an EnvironmentEntry for inclusion in a FoldingSet. 00045 static void Profile(llvm::FoldingSetNodeID &ID, 00046 const EnvironmentEntry &E) { 00047 ID.AddPointer(E.getStmt()); 00048 ID.AddPointer(E.getLocationContext()); 00049 } 00050 00051 void Profile(llvm::FoldingSetNodeID &ID) const { 00052 Profile(ID, *this); 00053 } 00054 }; 00055 00056 /// An immutable map from EnvironemntEntries to SVals. 00057 class Environment { 00058 private: 00059 friend class EnvironmentManager; 00060 00061 // Type definitions. 00062 typedef llvm::ImmutableMap<EnvironmentEntry, SVal> BindingsTy; 00063 00064 // Data. 00065 BindingsTy ExprBindings; 00066 00067 Environment(BindingsTy eb) 00068 : ExprBindings(eb) {} 00069 00070 SVal lookupExpr(const EnvironmentEntry &E) const; 00071 00072 public: 00073 typedef BindingsTy::iterator iterator; 00074 iterator begin() const { return ExprBindings.begin(); } 00075 iterator end() const { return ExprBindings.end(); } 00076 00077 /// Fetches the current binding of the expression in the 00078 /// Environment. 00079 SVal getSVal(const EnvironmentEntry &E, 00080 SValBuilder &svalBuilder, 00081 bool useOnlyDirectBindings = false) const; 00082 00083 /// Profile - Profile the contents of an Environment object for use 00084 /// in a FoldingSet. 00085 static void Profile(llvm::FoldingSetNodeID& ID, const Environment* env) { 00086 env->ExprBindings.Profile(ID); 00087 } 00088 00089 /// Profile - Used to profile the contents of this object for inclusion 00090 /// in a FoldingSet. 00091 void Profile(llvm::FoldingSetNodeID& ID) const { 00092 Profile(ID, this); 00093 } 00094 00095 bool operator==(const Environment& RHS) const { 00096 return ExprBindings == RHS.ExprBindings; 00097 } 00098 00099 void print(raw_ostream &Out, const char *NL, const char *Sep) const; 00100 00101 private: 00102 void printAux(raw_ostream &Out, bool printLocations, 00103 const char *NL, const char *Sep) const; 00104 }; 00105 00106 class EnvironmentManager { 00107 private: 00108 typedef Environment::BindingsTy::Factory FactoryTy; 00109 FactoryTy F; 00110 00111 public: 00112 EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {} 00113 ~EnvironmentManager() {} 00114 00115 Environment getInitialEnvironment() { 00116 return Environment(F.getEmptyMap()); 00117 } 00118 00119 /// Bind a symbolic value to the given environment entry. 00120 Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V, 00121 bool Invalidate); 00122 00123 /// Bind the location 'location' and value 'V' to the specified 00124 /// environment entry. 00125 Environment bindExprAndLocation(Environment Env, 00126 const EnvironmentEntry &E, 00127 SVal location, 00128 SVal V); 00129 00130 Environment removeDeadBindings(Environment Env, 00131 SymbolReaper &SymReaper, 00132 ProgramStateRef state); 00133 }; 00134 00135 } // end GR namespace 00136 00137 } // end clang namespace 00138 00139 #endif