Environment.h revision d72ee907f76000446c706471e93d1f299104f9a7
18133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek//== Environment.h - Map from Expr* to Locations/Values ---------*- C++ -*--==// 28133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek// 38133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek// The LLVM Compiler Infrastructure 48133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek// 58133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek// This file is distributed under the University of Illinois Open Source 68133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek// License. See LICENSE.TXT for details. 78133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek// 88133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek//===----------------------------------------------------------------------===// 98133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek// 108133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek// This file defined the Environment and EnvironmentManager classes. 118133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek// 128133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek//===----------------------------------------------------------------------===// 138133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 148133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek#ifndef LLVM_CLANG_ANALYSIS_ENVIRONMENT_H 158133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek#define LLVM_CLANG_ANALYSIS_ENVIRONMENT_H 168133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 178133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek#include "llvm/ADT/ImmutableMap.h" 188133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek#include "clang/Analysis/PathSensitive/RValues.h" 198133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek#include "llvm/Support/Allocator.h" 208133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek#include "llvm/ADT/FoldingSet.h" 218133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 228133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremeneknamespace clang { 238133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 248133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenekclass EnvironmentManager; 25d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenekclass BasicValueFactory; 268133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 278133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenekclass Environment : public llvm::FoldingSetNode { 288133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenekprivate: 298133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 308133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek friend class EnvironmentManager; 318133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 328133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek // Type definitions. 338133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek typedef llvm::ImmutableMap<Expr*,RVal> BindingsTy; 348133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 358133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek // Data. 368133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek BindingsTy SubExprBindings; 378133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek BindingsTy BlkExprBindings; 388133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 398133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek Environment(BindingsTy seb, BindingsTy beb) 408133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek : SubExprBindings(seb), BlkExprBindings(beb) {} 418133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 428133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenekpublic: 438133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 448133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek typedef BindingsTy::iterator seb_iterator; 458133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek seb_iterator seb_begin() const { return SubExprBindings.begin(); } 468133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek seb_iterator seb_end() const { return SubExprBindings.end(); } 478133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 488133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek typedef BindingsTy::iterator beb_iterator; 498133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek beb_iterator beb_begin() const { return BlkExprBindings.begin(); } 508133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek beb_iterator beb_end() const { return BlkExprBindings.end(); } 518133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 528133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek RVal LookupSubExpr(Expr* E) const { 538133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek const RVal* X = SubExprBindings.lookup(E); 548133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek return X ? *X : UnknownVal(); 558133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek } 568133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 578133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek RVal LookupBlkExpr(Expr* E) const { 588133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek const RVal* X = BlkExprBindings.lookup(E); 598133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek return X ? *X : UnknownVal(); 608133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek } 618133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 628133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek RVal LookupExpr(Expr* E) const { 638133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek const RVal* X = SubExprBindings.lookup(E); 648133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek if (X) return *X; 658133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek X = BlkExprBindings.lookup(E); 668133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek return X ? *X : UnknownVal(); 678133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek } 688133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 69d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek RVal GetRVal(Expr* Ex, BasicValueFactory& BasicVals) const; 70d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek RVal GetBlkExprRVal(Expr* Ex, BasicValueFactory& BasicVals) const; 71d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek 728133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek /// Profile - Profile the contents of an Environment object for use 738133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek /// in a FoldingSet. 748133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek static void Profile(llvm::FoldingSetNodeID& ID, const Environment* E) { 758133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek E->SubExprBindings.Profile(ID); 768133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek E->BlkExprBindings.Profile(ID); 778133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek } 788133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 798133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek /// Profile - Used to profile the contents of this object for inclusion 808133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek /// in a FoldingSet. 818133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek void Profile(llvm::FoldingSetNodeID& ID) const { 828133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek Profile(ID, this); 83d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek } 84d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek 85d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek bool operator==(const Environment& RHS) const { 86d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek return SubExprBindings == RHS.SubExprBindings && 87d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek BlkExprBindings == RHS.BlkExprBindings; 88d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek } 898133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek}; 908133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 918133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenekclass EnvironmentManager { 928133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenekprivate: 938133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek typedef Environment::BindingsTy::Factory FactoryTy; 948133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek FactoryTy F; 958133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 968133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenekpublic: 978133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 988133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek EnvironmentManager(llvm::BumpPtrAllocator& Allocator) : F(Allocator) {} 998133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek ~EnvironmentManager() {} 1008133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 1018133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek /// RemoveBlkExpr - Return a new environment object with the same bindings as 1028133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek /// the provided environment except with any bindings for the provided Expr* 1038133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek /// removed. This method only removes bindings for block-level expressions. 1048133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek /// Using this method on a non-block level expression will return the 1058133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek /// same environment object. 1068133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek Environment RemoveBlkExpr(const Environment& Env, Expr* E) { 1078133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek return Environment(Env.SubExprBindings, F.Remove(Env.BlkExprBindings, E)); 1088133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek } 1098133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 1108133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek Environment RemoveSubExpr(const Environment& Env, Expr* E) { 1118133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek return Environment(F.Remove(Env.SubExprBindings, E), Env.BlkExprBindings); 1128133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek } 1138133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 1148133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek Environment AddBlkExpr(const Environment& Env, Expr* E, RVal V) { 1158133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek return Environment(Env.SubExprBindings, F.Add(Env.BlkExprBindings, E, V)); 1168133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek } 1178133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 1188133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek Environment AddSubExpr(const Environment& Env, Expr* E, RVal V) { 1198133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek return Environment(F.Add(Env.SubExprBindings, E, V), Env.BlkExprBindings); 1208133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek } 1218133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 1228133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek /// RemoveSubExprBindings - Return a new environment object with 1238133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek /// the same bindings as the provided environment except with all the 1248133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek /// subexpression bindings removed. 1258133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek Environment RemoveSubExprBindings(const Environment& Env) { 1268133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek return Environment(F.GetEmptyMap(), Env.BlkExprBindings); 1278133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek } 1288133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 1298133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek Environment getInitialEnvironment() { 1308133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek return Environment(F.GetEmptyMap(), F.GetEmptyMap()); 1318133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek } 132d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek 133d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek Environment SetRVal(const Environment& Env, Expr* E, RVal V, 134d72ee907f76000446c706471e93d1f299104f9a7Ted Kremenek bool isBlkExpr, bool Invalidate); 1358133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek}; 1368133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 1378133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek} // end clang namespace 1388133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek 1398133a26c166be89fb4f0a339db1e2fe923c51a70Ted Kremenek#endif 140