Environment.h revision 8bef8238181a30e52dea380789a7e2d760eac532
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_GR_ENVIRONMENT_H
15#define LLVM_CLANG_GR_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;
29
30/// An entry in the environment consists of a Stmt and an LocationContext.
31/// This allows the environment to manage context-sensitive bindings,
32/// which is essentially for modeling recursive function analysis, among
33/// other things.
34class EnvironmentEntry : public std::pair<const Stmt*,
35                                          const StackFrameContext *> {
36public:
37  EnvironmentEntry(const Stmt *s, const LocationContext *L)
38    : std::pair<const Stmt*,
39                const StackFrameContext*>(s, L ? L->getCurrentStackFrame():0) {}
40
41  const Stmt *getStmt() const { return first; }
42  const LocationContext *getLocationContext() const { return second; }
43
44  /// Profile an EnvironmentEntry for inclusion in a FoldingSet.
45  static void Profile(llvm::FoldingSetNodeID &ID,
46                      const EnvironmentEntry &E) {
47    ID.AddPointer(E.getStmt());
48    ID.AddPointer(E.getLocationContext());
49  }
50
51  void Profile(llvm::FoldingSetNodeID &ID) const {
52    Profile(ID, *this);
53  }
54};
55
56/// An immutable map from EnvironemntEntries to SVals.
57class Environment {
58private:
59  friend class EnvironmentManager;
60
61  // Type definitions.
62  typedef llvm::ImmutableMap<EnvironmentEntry, SVal> BindingsTy;
63
64  // Data.
65  BindingsTy ExprBindings;
66
67  Environment(BindingsTy eb)
68    : ExprBindings(eb) {}
69
70  SVal lookupExpr(const EnvironmentEntry &E) const;
71
72public:
73  typedef BindingsTy::iterator iterator;
74  iterator begin() const { return ExprBindings.begin(); }
75  iterator end() const { return ExprBindings.end(); }
76
77  /// Fetches the current binding of the expression in the
78  /// Environment.
79  SVal getSVal(const EnvironmentEntry &E,
80               SValBuilder &svalBuilder,
81               bool useOnlyDirectBindings = false) const;
82
83  /// Profile - Profile the contents of an Environment object for use
84  ///  in a FoldingSet.
85  static void Profile(llvm::FoldingSetNodeID& ID, const Environment* env) {
86    env->ExprBindings.Profile(ID);
87  }
88
89  /// Profile - Used to profile the contents of this object for inclusion
90  ///  in a FoldingSet.
91  void Profile(llvm::FoldingSetNodeID& ID) const {
92    Profile(ID, this);
93  }
94
95  bool operator==(const Environment& RHS) const {
96    return ExprBindings == RHS.ExprBindings;
97  }
98
99  void print(raw_ostream &Out, const char *NL, const char *Sep) const;
100
101private:
102  void printAux(raw_ostream &Out, bool printLocations,
103                const char *NL, const char *Sep) const;
104};
105
106class EnvironmentManager {
107private:
108  typedef Environment::BindingsTy::Factory FactoryTy;
109  FactoryTy F;
110
111public:
112  EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {}
113  ~EnvironmentManager() {}
114
115  Environment getInitialEnvironment() {
116    return Environment(F.getEmptyMap());
117  }
118
119  /// Bind a symbolic value to the given environment entry.
120  Environment bindExpr(Environment Env, const EnvironmentEntry &E, SVal V,
121                       bool Invalidate);
122
123  /// Bind the location 'location' and value 'V' to the specified
124  /// environment entry.
125  Environment bindExprAndLocation(Environment Env,
126                                  const EnvironmentEntry &E,
127                                  SVal location,
128                                  SVal V);
129
130  Environment removeDeadBindings(Environment Env,
131                                 SymbolReaper &SymReaper,
132                                 ProgramStateRef state);
133};
134
135} // end GR namespace
136
137} // end clang namespace
138
139#endif
140