Environment.h revision 5eca482fe895ea57bc82410222e6426c09e63284
190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//== Environment.h - Map from Stmt* to Locations/Values ---------*- C++ -*--==// 2f71323e297a928af368937089d3ed71239786f86Andreas Huber// 390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// The LLVM Compiler Infrastructure 4f71323e297a928af368937089d3ed71239786f86Andreas Huber// 5f71323e297a928af368937089d3ed71239786f86Andreas Huber// This file is distributed under the University of Illinois Open Source 6f71323e297a928af368937089d3ed71239786f86Andreas Huber// License. See LICENSE.TXT for details. 7f71323e297a928af368937089d3ed71239786f86Andreas Huber// 8f71323e297a928af368937089d3ed71239786f86Andreas Huber//===----------------------------------------------------------------------===// 990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// 1090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// This file defined the Environment and EnvironmentManager classes. 1190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber// 1290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber//===----------------------------------------------------------------------===// 1390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 1479f15823c34ae1e423108295e416213200bb280fAndreas Huber#ifndef LLVM_CLANG_GR_ENVIRONMENT_H 1579f15823c34ae1e423108295e416213200bb280fAndreas Huber#define LLVM_CLANG_GR_ENVIRONMENT_H 1679f15823c34ae1e423108295e416213200bb280fAndreas Huber 1779f15823c34ae1e423108295e416213200bb280fAndreas Huber#include "clang/Analysis/AnalysisContext.h" 1879f15823c34ae1e423108295e416213200bb280fAndreas Huber#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" 1990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include "llvm/ADT/ImmutableMap.h" 2090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 2190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubernamespace clang { 22f71323e297a928af368937089d3ed71239786f86Andreas Huber 23f71323e297a928af368937089d3ed71239786f86Andreas Huberclass LiveVariables; 2490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber 2590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Hubernamespace ento { 26f71323e297a928af368937089d3ed71239786f86Andreas Huber 2779f15823c34ae1e423108295e416213200bb280fAndreas Huberclass EnvironmentManager; 2879f15823c34ae1e423108295e416213200bb280fAndreas Huberclass SValBuilder; 2979f15823c34ae1e423108295e416213200bb280fAndreas Huber 3079f15823c34ae1e423108295e416213200bb280fAndreas Huber/// An entry in the environment consists of a Stmt and an LocationContext. 3179f15823c34ae1e423108295e416213200bb280fAndreas Huber/// This allows the environment to manage context-sensitive bindings, 32ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/// which is essentially for modeling recursive function analysis, among 3379f15823c34ae1e423108295e416213200bb280fAndreas Huber/// other things. 3479f15823c34ae1e423108295e416213200bb280fAndreas Huberclass EnvironmentEntry : public std::pair<const Stmt*, 3579f15823c34ae1e423108295e416213200bb280fAndreas Huber const StackFrameContext *> { 361b362b15af34006e6a11974088a46d42b903418eJohannpublic: 3779f15823c34ae1e423108295e416213200bb280fAndreas Huber EnvironmentEntry(const Stmt *s, const LocationContext *L) 3879f15823c34ae1e423108295e416213200bb280fAndreas Huber : std::pair<const Stmt*, 3979f15823c34ae1e423108295e416213200bb280fAndreas Huber const StackFrameContext*>(s, L ? L->getCurrentStackFrame():0) {} 4079f15823c34ae1e423108295e416213200bb280fAndreas Huber 4179f15823c34ae1e423108295e416213200bb280fAndreas Huber const Stmt *getStmt() const { return first; } 4279f15823c34ae1e423108295e416213200bb280fAndreas Huber const LocationContext *getLocationContext() const { return second; } 4379f15823c34ae1e423108295e416213200bb280fAndreas Huber 4479f15823c34ae1e423108295e416213200bb280fAndreas Huber /// Profile an EnvironmentEntry for inclusion in a FoldingSet. 4579f15823c34ae1e423108295e416213200bb280fAndreas Huber static void Profile(llvm::FoldingSetNodeID &ID, 4679f15823c34ae1e423108295e416213200bb280fAndreas Huber const EnvironmentEntry &E) { 4779f15823c34ae1e423108295e416213200bb280fAndreas Huber ID.AddPointer(E.getStmt()); 4879f15823c34ae1e423108295e416213200bb280fAndreas Huber ID.AddPointer(E.getLocationContext()); 4979f15823c34ae1e423108295e416213200bb280fAndreas Huber } 5079f15823c34ae1e423108295e416213200bb280fAndreas Huber 5179f15823c34ae1e423108295e416213200bb280fAndreas Huber void Profile(llvm::FoldingSetNodeID &ID) const { 5279f15823c34ae1e423108295e416213200bb280fAndreas Huber Profile(ID, *this); 5379f15823c34ae1e423108295e416213200bb280fAndreas Huber } 5479f15823c34ae1e423108295e416213200bb280fAndreas Huber}; 5579f15823c34ae1e423108295e416213200bb280fAndreas Huber 56ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang/// An immutable map from EnvironemntEntries to SVals. 571b362b15af34006e6a11974088a46d42b903418eJohannclass Environment { 5879f15823c34ae1e423108295e416213200bb280fAndreas Huberprivate: 5979f15823c34ae1e423108295e416213200bb280fAndreas Huber friend class EnvironmentManager; 6079f15823c34ae1e423108295e416213200bb280fAndreas Huber 6179f15823c34ae1e423108295e416213200bb280fAndreas Huber // Type definitions. 6279f15823c34ae1e423108295e416213200bb280fAndreas Huber typedef llvm::ImmutableMap<EnvironmentEntry, SVal> BindingsTy; 6379f15823c34ae1e423108295e416213200bb280fAndreas Huber 641b362b15af34006e6a11974088a46d42b903418eJohann // Data. 6579f15823c34ae1e423108295e416213200bb280fAndreas Huber BindingsTy ExprBindings; 66f71323e297a928af368937089d3ed71239786f86Andreas Huber 6779f15823c34ae1e423108295e416213200bb280fAndreas Huber Environment(BindingsTy eb) 6879f15823c34ae1e423108295e416213200bb280fAndreas Huber : ExprBindings(eb) {} 6979f15823c34ae1e423108295e416213200bb280fAndreas Huber 7079f15823c34ae1e423108295e416213200bb280fAndreas Huber SVal lookupExpr(const EnvironmentEntry &E) const; 7179f15823c34ae1e423108295e416213200bb280fAndreas Huber 7279f15823c34ae1e423108295e416213200bb280fAndreas Huberpublic: 7379f15823c34ae1e423108295e416213200bb280fAndreas Huber typedef BindingsTy::iterator iterator; 74f71323e297a928af368937089d3ed71239786f86Andreas Huber iterator begin() const { return ExprBindings.begin(); } 75f71323e297a928af368937089d3ed71239786f86Andreas Huber iterator end() const { return ExprBindings.end(); } 76f71323e297a928af368937089d3ed71239786f86Andreas Huber 77f71323e297a928af368937089d3ed71239786f86Andreas Huber /// Fetches the current binding of the expression in the 78f71323e297a928af368937089d3ed71239786f86Andreas Huber /// Environment. 79f71323e297a928af368937089d3ed71239786f86Andreas Huber SVal getSVal(const EnvironmentEntry &E, 80f71323e297a928af368937089d3ed71239786f86Andreas Huber SValBuilder &svalBuilder, 81f71323e297a928af368937089d3ed71239786f86Andreas Huber bool useOnlyDirectBindings = false) const; 82f71323e297a928af368937089d3ed71239786f86Andreas Huber 83f71323e297a928af368937089d3ed71239786f86Andreas Huber /// Profile - Profile the contents of an Environment object for use 84f71323e297a928af368937089d3ed71239786f86Andreas Huber /// in a FoldingSet. 85f71323e297a928af368937089d3ed71239786f86Andreas Huber static void Profile(llvm::FoldingSetNodeID& ID, const Environment* env) { 86f71323e297a928af368937089d3ed71239786f86Andreas Huber env->ExprBindings.Profile(ID); 87f71323e297a928af368937089d3ed71239786f86Andreas Huber } 88f71323e297a928af368937089d3ed71239786f86Andreas Huber 89f71323e297a928af368937089d3ed71239786f86Andreas Huber /// Profile - Used to profile the contents of this object for inclusion 90f71323e297a928af368937089d3ed71239786f86Andreas Huber /// in a FoldingSet. 91f71323e297a928af368937089d3ed71239786f86Andreas Huber void Profile(llvm::FoldingSetNodeID& ID) const { 9279f15823c34ae1e423108295e416213200bb280fAndreas Huber Profile(ID, this); 93f71323e297a928af368937089d3ed71239786f86Andreas Huber } 94538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 95538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber bool operator==(const Environment& RHS) const { 96f71323e297a928af368937089d3ed71239786f86Andreas Huber return ExprBindings == RHS.ExprBindings; 97538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber } 98538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 99f71323e297a928af368937089d3ed71239786f86Andreas Huber void print(raw_ostream &Out, const char *NL, const char *Sep) const; 100538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 101538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberprivate: 102f71323e297a928af368937089d3ed71239786f86Andreas Huber void printAux(raw_ostream &Out, bool printLocations, 103f71323e297a928af368937089d3ed71239786f86Andreas Huber const char *NL, const char *Sep) const; 104f71323e297a928af368937089d3ed71239786f86Andreas Huber}; 105f71323e297a928af368937089d3ed71239786f86Andreas Huber 106f71323e297a928af368937089d3ed71239786f86Andreas Huberclass EnvironmentManager { 107f71323e297a928af368937089d3ed71239786f86Andreas Huberprivate: 108f71323e297a928af368937089d3ed71239786f86Andreas Huber typedef Environment::BindingsTy::Factory FactoryTy; 109f71323e297a928af368937089d3ed71239786f86Andreas Huber FactoryTy F; 110f71323e297a928af368937089d3ed71239786f86Andreas Huber 111f71323e297a928af368937089d3ed71239786f86Andreas Huberpublic: 112f71323e297a928af368937089d3ed71239786f86Andreas Huber EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {} 113f71323e297a928af368937089d3ed71239786f86Andreas Huber ~EnvironmentManager() {} 114f71323e297a928af368937089d3ed71239786f86Andreas Huber 115f71323e297a928af368937089d3ed71239786f86Andreas Huber Environment getInitialEnvironment() { 116f71323e297a928af368937089d3ed71239786f86Andreas Huber return Environment(F.getEmptyMap()); 117f71323e297a928af368937089d3ed71239786f86Andreas Huber } 118f71323e297a928af368937089d3ed71239786f86Andreas Huber 119f71323e297a928af368937089d3ed71239786f86Andreas Huber /// Bind a symbolic value to the given environment entry. 120f71323e297a928af368937089d3ed71239786f86Andreas Huber Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V, 121f71323e297a928af368937089d3ed71239786f86Andreas Huber bool Invalidate); 122538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 123f71323e297a928af368937089d3ed71239786f86Andreas Huber /// Bind the location 'location' and value 'V' to the specified 124f71323e297a928af368937089d3ed71239786f86Andreas Huber /// environment entry. 125f71323e297a928af368937089d3ed71239786f86Andreas Huber Environment bindExprAndLocation(Environment Env, 126f71323e297a928af368937089d3ed71239786f86Andreas Huber const EnvironmentEntry &E, 127f71323e297a928af368937089d3ed71239786f86Andreas Huber SVal location, 128f71323e297a928af368937089d3ed71239786f86Andreas Huber SVal V); 129f71323e297a928af368937089d3ed71239786f86Andreas Huber 130f71323e297a928af368937089d3ed71239786f86Andreas Huber Environment removeDeadBindings(Environment Env, 131f71323e297a928af368937089d3ed71239786f86Andreas Huber SymbolReaper &SymReaper, 132f71323e297a928af368937089d3ed71239786f86Andreas Huber const ProgramState *state); 133f71323e297a928af368937089d3ed71239786f86Andreas Huber}; 134f71323e297a928af368937089d3ed71239786f86Andreas Huber 135f71323e297a928af368937089d3ed71239786f86Andreas Huber} // end GR namespace 136538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber 137538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber} // end clang namespace 138f71323e297a928af368937089d3ed71239786f86Andreas Huber 139f71323e297a928af368937089d3ed71239786f86Andreas Huber#endif 140f71323e297a928af368937089d3ed71239786f86Andreas Huber