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
21namespace clang {
22
23class LiveVariables;
24
25namespace ento {
26
27class EnvironmentManager;
28class SValBuilder;
29class 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.
35class EnvironmentEntry : public std::pair<const Stmt*,
36                                          const StackFrameContext *> {
37public:
38  EnvironmentEntry(const Stmt *s, const LocationContext *L);
39
40  const Stmt *getStmt() const { return first; }
41  const LocationContext *getLocationContext() const { return second; }
42
43  /// Profile an EnvironmentEntry for inclusion in a FoldingSet.
44  static void Profile(llvm::FoldingSetNodeID &ID,
45                      const EnvironmentEntry &E) {
46    ID.AddPointer(E.getStmt());
47    ID.AddPointer(E.getLocationContext());
48  }
49
50  void Profile(llvm::FoldingSetNodeID &ID) const {
51    Profile(ID, *this);
52  }
53};
54
55/// An immutable map from EnvironemntEntries to SVals.
56class Environment {
57private:
58  friend class EnvironmentManager;
59
60  // Type definitions.
61  typedef llvm::ImmutableMap<EnvironmentEntry, SVal> BindingsTy;
62
63  // Data.
64  BindingsTy ExprBindings;
65
66  Environment(BindingsTy eb)
67    : ExprBindings(eb) {}
68
69  SVal lookupExpr(const EnvironmentEntry &E) const;
70
71public:
72  typedef BindingsTy::iterator iterator;
73  iterator begin() const { return ExprBindings.begin(); }
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.
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.
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
98private:
99  void printAux(raw_ostream &Out, bool printLocations,
100                const char *NL, const char *Sep) const;
101};
102
103class EnvironmentManager {
104private:
105  typedef Environment::BindingsTy::Factory FactoryTy;
106  FactoryTy F;
107
108public:
109  EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {}
110
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