clang API Documentation

Environment.h
Go to the documentation of this file.
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