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_STATICANALYZER_CORE_PATHSENSITIVE_ENVIRONMENT_H 00015 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_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 00039 const Stmt *getStmt() const { return first; } 00040 const LocationContext *getLocationContext() const { return second; } 00041 00042 /// Profile an EnvironmentEntry for inclusion in a FoldingSet. 00043 static void Profile(llvm::FoldingSetNodeID &ID, 00044 const EnvironmentEntry &E) { 00045 ID.AddPointer(E.getStmt()); 00046 ID.AddPointer(E.getLocationContext()); 00047 } 00048 00049 void Profile(llvm::FoldingSetNodeID &ID) const { 00050 Profile(ID, *this); 00051 } 00052 }; 00053 00054 /// An immutable map from EnvironemntEntries to SVals. 00055 class Environment { 00056 private: 00057 friend class EnvironmentManager; 00058 00059 // Type definitions. 00060 typedef llvm::ImmutableMap<EnvironmentEntry, SVal> BindingsTy; 00061 00062 // Data. 00063 BindingsTy ExprBindings; 00064 00065 Environment(BindingsTy eb) 00066 : ExprBindings(eb) {} 00067 00068 SVal lookupExpr(const EnvironmentEntry &E) const; 00069 00070 public: 00071 typedef BindingsTy::iterator iterator; 00072 iterator begin() const { return ExprBindings.begin(); } 00073 iterator end() const { return ExprBindings.end(); } 00074 00075 /// Fetches the current binding of the expression in the 00076 /// Environment. 00077 SVal getSVal(const EnvironmentEntry &E, SValBuilder &svalBuilder) const; 00078 00079 /// Profile - Profile the contents of an Environment object for use 00080 /// in a FoldingSet. 00081 static void Profile(llvm::FoldingSetNodeID& ID, const Environment* env) { 00082 env->ExprBindings.Profile(ID); 00083 } 00084 00085 /// Profile - Used to profile the contents of this object for inclusion 00086 /// in a FoldingSet. 00087 void Profile(llvm::FoldingSetNodeID& ID) const { 00088 Profile(ID, this); 00089 } 00090 00091 bool operator==(const Environment& RHS) const { 00092 return ExprBindings == RHS.ExprBindings; 00093 } 00094 00095 void print(raw_ostream &Out, const char *NL, const char *Sep) const; 00096 00097 private: 00098 void printAux(raw_ostream &Out, bool printLocations, 00099 const char *NL, const char *Sep) const; 00100 }; 00101 00102 class EnvironmentManager { 00103 private: 00104 typedef Environment::BindingsTy::Factory FactoryTy; 00105 FactoryTy F; 00106 00107 public: 00108 EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {} 00109 ~EnvironmentManager() {} 00110 00111 Environment getInitialEnvironment() { 00112 return Environment(F.getEmptyMap()); 00113 } 00114 00115 /// Bind a symbolic value to the given environment entry. 00116 Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V, 00117 bool Invalidate); 00118 00119 Environment removeDeadBindings(Environment Env, 00120 SymbolReaper &SymReaper, 00121 ProgramStateRef state); 00122 }; 00123 00124 } // end GR namespace 00125 00126 } // end clang namespace 00127 00128 #endif