1218887Sdim//== Environment.h - Map from Stmt* to Locations/Values ---------*- C++ -*--==// 2218887Sdim// 3218887Sdim// The LLVM Compiler Infrastructure 4218887Sdim// 5218887Sdim// This file is distributed under the University of Illinois Open Source 6218887Sdim// License. See LICENSE.TXT for details. 7218887Sdim// 8218887Sdim//===----------------------------------------------------------------------===// 9218887Sdim// 10218887Sdim// This file defined the Environment and EnvironmentManager classes. 11218887Sdim// 12218887Sdim//===----------------------------------------------------------------------===// 13218887Sdim 14218887Sdim#ifndef LLVM_CLANG_GR_ENVIRONMENT_H 15218887Sdim#define LLVM_CLANG_GR_ENVIRONMENT_H 16218887Sdim 17234353Sdim#include "clang/Analysis/AnalysisContext.h" 18218887Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 19218887Sdim#include "llvm/ADT/ImmutableMap.h" 20218887Sdim 21218887Sdimnamespace clang { 22218887Sdim 23218887Sdimclass LiveVariables; 24218887Sdim 25218887Sdimnamespace ento { 26218887Sdim 27218887Sdimclass EnvironmentManager; 28218887Sdimclass SValBuilder; 29218887Sdim 30234353Sdim/// An entry in the environment consists of a Stmt and an LocationContext. 31234353Sdim/// This allows the environment to manage context-sensitive bindings, 32234353Sdim/// which is essentially for modeling recursive function analysis, among 33234353Sdim/// other things. 34234353Sdimclass EnvironmentEntry : public std::pair<const Stmt*, 35234353Sdim const StackFrameContext *> { 36234353Sdimpublic: 37243830Sdim EnvironmentEntry(const Stmt *s, const LocationContext *L); 38234353Sdim 39234353Sdim const Stmt *getStmt() const { return first; } 40234353Sdim const LocationContext *getLocationContext() const { return second; } 41234353Sdim 42234353Sdim /// Profile an EnvironmentEntry for inclusion in a FoldingSet. 43234353Sdim static void Profile(llvm::FoldingSetNodeID &ID, 44234353Sdim const EnvironmentEntry &E) { 45234353Sdim ID.AddPointer(E.getStmt()); 46234353Sdim ID.AddPointer(E.getLocationContext()); 47234353Sdim } 48234353Sdim 49234353Sdim void Profile(llvm::FoldingSetNodeID &ID) const { 50234353Sdim Profile(ID, *this); 51234353Sdim } 52234353Sdim}; 53234353Sdim 54234353Sdim/// An immutable map from EnvironemntEntries to SVals. 55218887Sdimclass Environment { 56218887Sdimprivate: 57218887Sdim friend class EnvironmentManager; 58218887Sdim 59218887Sdim // Type definitions. 60234353Sdim typedef llvm::ImmutableMap<EnvironmentEntry, SVal> BindingsTy; 61218887Sdim 62218887Sdim // Data. 63218887Sdim BindingsTy ExprBindings; 64218887Sdim 65218887Sdim Environment(BindingsTy eb) 66218887Sdim : ExprBindings(eb) {} 67218887Sdim 68234353Sdim SVal lookupExpr(const EnvironmentEntry &E) const; 69218887Sdim 70218887Sdimpublic: 71218887Sdim typedef BindingsTy::iterator iterator; 72218887Sdim iterator begin() const { return ExprBindings.begin(); } 73218887Sdim iterator end() const { return ExprBindings.end(); } 74218887Sdim 75234353Sdim /// Fetches the current binding of the expression in the 76234353Sdim /// Environment. 77243830Sdim SVal getSVal(const EnvironmentEntry &E, SValBuilder &svalBuilder) const; 78218887Sdim 79218887Sdim /// Profile - Profile the contents of an Environment object for use 80218887Sdim /// in a FoldingSet. 81218887Sdim static void Profile(llvm::FoldingSetNodeID& ID, const Environment* env) { 82218887Sdim env->ExprBindings.Profile(ID); 83218887Sdim } 84218887Sdim 85218887Sdim /// Profile - Used to profile the contents of this object for inclusion 86218887Sdim /// in a FoldingSet. 87218887Sdim void Profile(llvm::FoldingSetNodeID& ID) const { 88218887Sdim Profile(ID, this); 89218887Sdim } 90218887Sdim 91218887Sdim bool operator==(const Environment& RHS) const { 92218887Sdim return ExprBindings == RHS.ExprBindings; 93218887Sdim } 94234353Sdim 95234353Sdim void print(raw_ostream &Out, const char *NL, const char *Sep) const; 96234353Sdim 97234353Sdimprivate: 98234353Sdim void printAux(raw_ostream &Out, bool printLocations, 99234353Sdim const char *NL, const char *Sep) const; 100218887Sdim}; 101218887Sdim 102218887Sdimclass EnvironmentManager { 103218887Sdimprivate: 104218887Sdim typedef Environment::BindingsTy::Factory FactoryTy; 105218887Sdim FactoryTy F; 106218887Sdim 107218887Sdimpublic: 108218887Sdim EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {} 109218887Sdim ~EnvironmentManager() {} 110218887Sdim 111218887Sdim Environment getInitialEnvironment() { 112218887Sdim return Environment(F.getEmptyMap()); 113218887Sdim } 114218887Sdim 115234353Sdim /// Bind a symbolic value to the given environment entry. 116234353Sdim Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V, 117218887Sdim bool Invalidate); 118218887Sdim 119218887Sdim Environment removeDeadBindings(Environment Env, 120234353Sdim SymbolReaper &SymReaper, 121234353Sdim ProgramStateRef state); 122218887Sdim}; 123218887Sdim 124218887Sdim} // end GR namespace 125218887Sdim 126218887Sdim} // end clang namespace 127218887Sdim 128218887Sdim#endif 129