MemRegion.h revision 250101353b711a409b075f1bc11070dddec7100b
1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//== MemRegion.h - Abstract memory regions for static analysis --*- C++ -*--==// 2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// The LLVM Compiler Infrastructure 4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 54a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// This file is distributed under the University of Illinois Open Source 6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// License. See LICENSE.TXT for details. 7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//===----------------------------------------------------------------------===// 9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// 10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This file defines MemRegion and its subclasses. MemRegion defines a 11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// partially-typed abstraction of memory useful for path-sensitive dataflow 124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// analyses. 134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch// 144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch//===----------------------------------------------------------------------===// 15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#ifndef LLVM_CLANG_ANALYSIS_MEMREGION_H 17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define LLVM_CLANG_ANALYSIS_MEMREGION_H 18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "clang/AST/Decl.h" 20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "clang/AST/DeclObjC.h" 21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "clang/Analysis/PathSensitive/SymbolManager.h" 22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "clang/Analysis/PathSensitive/SVals.h" 234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "clang/AST/ASTContext.h" 24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "llvm/Support/Casting.h" 25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "llvm/ADT/FoldingSet.h" 26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "llvm/ADT/ImmutableList.h" 27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "llvm/ADT/ImmutableMap.h" 28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "llvm/Support/Allocator.h" 29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string> 30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace llvm { class raw_ostream; } 32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace clang { 34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MemRegionManager; 36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/// MemRegion - The root abstract class for all memory regions. 39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MemRegion : public llvm::FoldingSetNode { 40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottpublic: 41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott enum Kind { MemSpaceRegionKind, 42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SymbolicRegionKind, 434a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch AllocaRegionKind, 44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Typed regions. 45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott BEG_TYPED_REGIONS, 46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CodeTextRegionKind, 47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott CompoundLiteralRegionKind, 48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott StringRegionKind, ElementRegionKind, 49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott TypedViewRegionKind, 50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // Decl Regions. 51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott BEG_DECL_REGIONS, 52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott VarRegionKind, FieldRegionKind, 53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott ObjCIvarRegionKind, ObjCObjectRegionKind, 54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott END_DECL_REGIONS, 55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott END_TYPED_REGIONS }; 56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottprivate: 57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const Kind kind; 58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottprotected: 60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MemRegion(Kind k) : kind(k) {} 61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual ~MemRegion(); 62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottpublic: 64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott // virtual MemExtent getExtent(MemRegionManager& mrm) const = 0; 65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0; 66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott std::string getString() const; 68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual void print(llvm::raw_ostream& os) const; 70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott Kind getKind() const { return kind; } 72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott template<typename RegionTy> const RegionTy* getAs() const; 74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott virtual bool isBoundable(ASTContext&) const { return true; } 76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool classof(const MemRegion*) { return true; } 78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/// MemSpaceRegion - A memory region that represents and "memory space"; 81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/// for example, the set of global variables, the stack frame, etc. 82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass MemSpaceRegion : public MemRegion { 83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott friend class MemRegionManager; 84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott MemSpaceRegion() : MemRegion(MemSpaceRegionKind) {} 85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottpublic: 87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott //RegionExtent getExtent() const { return UndefinedExtent(); } 88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott void Profile(llvm::FoldingSetNodeID& ID) const; 90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool isBoundable(ASTContext &) const { return false; } 92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott static bool classof(const MemRegion* R) { 94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return R->getKind() == MemSpaceRegionKind; 95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}; 97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/// SubRegion - A region that subsets another larger region. Most regions 99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/// are subclasses of SubRegion. 100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottclass SubRegion : public MemRegion { 101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottprotected: 102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const MemRegion* superRegion; 103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {} 104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottpublic: 106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott const MemRegion* getSuperRegion() const { 107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott return superRegion; 108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott } 109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott bool isSubRegionOf(const MemRegion* R) const; 111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott 112 static bool classof(const MemRegion* R) { 113 return R->getKind() > MemSpaceRegionKind; 114 } 115}; 116 117/// AllocaRegion - A region that represents an untyped blob of bytes created 118/// by a call to 'alloca'. 119class AllocaRegion : public SubRegion { 120 friend class MemRegionManager; 121protected: 122 unsigned Cnt; // Block counter. Used to distinguish different pieces of 123 // memory allocated by alloca at the same call site. 124 const Expr* Ex; 125 126 AllocaRegion(const Expr* ex, unsigned cnt, const MemRegion* superRegion) 127 : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {} 128 129public: 130 131 const Expr* getExpr() const { return Ex; } 132 133 void Profile(llvm::FoldingSetNodeID& ID) const; 134 135 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr* Ex, 136 unsigned Cnt); 137 138 void print(llvm::raw_ostream& os) const; 139 140 static bool classof(const MemRegion* R) { 141 return R->getKind() == AllocaRegionKind; 142 } 143}; 144 145/// TypedRegion - An abstract class representing regions that are typed. 146class TypedRegion : public SubRegion { 147protected: 148 TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {} 149 150public: 151 virtual QualType getValueType(ASTContext &C) const = 0; 152 153 virtual QualType getLocationType(ASTContext& C) const { 154 // FIXME: We can possibly optimize this later to cache this value. 155 return C.getPointerType(getValueType(C)); 156 } 157 158 QualType getDesugaredValueType(ASTContext& C) const { 159 QualType T = getValueType(C); 160 return T.getTypePtr() ? T->getDesugaredType() : T; 161 } 162 163 QualType getDesugaredLocationType(ASTContext& C) const { 164 return getLocationType(C)->getDesugaredType(); 165 } 166 167 bool isBoundable(ASTContext &C) const { 168 return !getValueType(C).isNull(); 169 } 170 171 static bool classof(const MemRegion* R) { 172 unsigned k = R->getKind(); 173 return k > BEG_TYPED_REGIONS && k < END_TYPED_REGIONS; 174 } 175}; 176 177/// CodeTextRegion - A region that represents code texts of a function. It wraps 178/// two kinds of code texts: real function and symbolic function. Real function 179/// is a function declared in the program. Symbolic function is a function 180/// pointer that we don't know which function it points to. 181class CodeTextRegion : public TypedRegion { 182public: 183 enum CodeKind { Declared, Symbolic }; 184 185private: 186 // The function pointer kind that this CodeTextRegion represents. 187 CodeKind codekind; 188 189 // Data may be a SymbolRef or FunctionDecl*. 190 const void* Data; 191 192 // Cached function pointer type. 193 QualType LocationType; 194 195public: 196 197 CodeTextRegion(const FunctionDecl* fd, QualType t, const MemRegion* sreg) 198 : TypedRegion(sreg, CodeTextRegionKind), 199 codekind(Declared), 200 Data(fd), 201 LocationType(t) {} 202 203 CodeTextRegion(SymbolRef sym, QualType t, const MemRegion* sreg) 204 : TypedRegion(sreg, CodeTextRegionKind), 205 codekind(Symbolic), 206 Data(sym), 207 LocationType(t) {} 208 209 QualType getValueType(ASTContext &C) const { 210 // Do not get the object type of a CodeTextRegion. 211 assert(0); 212 return QualType(); 213 } 214 215 QualType getLocationType(ASTContext &C) const { 216 return LocationType; 217 } 218 219 bool isDeclared() const { return codekind == Declared; } 220 bool isSymbolic() const { return codekind == Symbolic; } 221 222 const FunctionDecl* getDecl() const { 223 assert(codekind == Declared); 224 return static_cast<const FunctionDecl*>(Data); 225 } 226 227 SymbolRef getSymbol() const { 228 assert(codekind == Symbolic); 229 return const_cast<SymbolRef>(static_cast<const SymbolRef>(Data)); 230 } 231 232 bool isBoundable(ASTContext&) const { return false; } 233 234 virtual void print(llvm::raw_ostream& os) const; 235 236 void Profile(llvm::FoldingSetNodeID& ID) const; 237 238 static void ProfileRegion(llvm::FoldingSetNodeID& ID, 239 const void* data, QualType t); 240 241 static bool classof(const MemRegion* R) { 242 return R->getKind() == CodeTextRegionKind; 243 } 244}; 245 246/// SymbolicRegion - A special, "non-concrete" region. Unlike other region 247/// clases, SymbolicRegion represents a region that serves as an alias for 248/// either a real region, a NULL pointer, etc. It essentially is used to 249/// map the concept of symbolic values into the domain of regions. Symbolic 250/// regions do not need to be typed. 251class SymbolicRegion : public SubRegion { 252protected: 253 const SymbolRef sym; 254 255public: 256 SymbolicRegion(const SymbolRef s, const MemRegion* sreg) 257 : SubRegion(sreg, SymbolicRegionKind), sym(s) {} 258 259 SymbolRef getSymbol() const { 260 return sym; 261 } 262 263 void Profile(llvm::FoldingSetNodeID& ID) const; 264 265 static void ProfileRegion(llvm::FoldingSetNodeID& ID, 266 SymbolRef sym, 267 const MemRegion* superRegion); 268 269 void print(llvm::raw_ostream& os) const; 270 271 static bool classof(const MemRegion* R) { 272 return R->getKind() == SymbolicRegionKind; 273 } 274}; 275 276/// StringRegion - Region associated with a StringLiteral. 277class StringRegion : public TypedRegion { 278 friend class MemRegionManager; 279 const StringLiteral* Str; 280protected: 281 282 StringRegion(const StringLiteral* str, const MemRegion* sreg) 283 : TypedRegion(sreg, StringRegionKind), Str(str) {} 284 285 static void ProfileRegion(llvm::FoldingSetNodeID& ID, 286 const StringLiteral* Str, 287 const MemRegion* superRegion); 288 289public: 290 291 const StringLiteral* getStringLiteral() const { return Str; } 292 293 QualType getValueType(ASTContext& C) const { 294 return Str->getType(); 295 } 296 297 void Profile(llvm::FoldingSetNodeID& ID) const { 298 ProfileRegion(ID, Str, superRegion); 299 } 300 301 void print(llvm::raw_ostream& os) const; 302 303 static bool classof(const MemRegion* R) { 304 return R->getKind() == StringRegionKind; 305 } 306}; 307 308class TypedViewRegion : public TypedRegion { 309 friend class MemRegionManager; 310 QualType LValueType; 311 312 TypedViewRegion(QualType lvalueType, const MemRegion* sreg) 313 : TypedRegion(sreg, TypedViewRegionKind), LValueType(lvalueType) {} 314 315 static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T, 316 const MemRegion* superRegion); 317 318public: 319 320 void print(llvm::raw_ostream& os) const; 321 322 QualType getLocationType(ASTContext&) const { 323 return LValueType; 324 } 325 326 QualType getValueType(ASTContext&) const { 327 const PointerType* PTy = LValueType->getAsPointerType(); 328 assert(PTy); 329 return PTy->getPointeeType(); 330 } 331 332 bool isBoundable(ASTContext &C) const { 333 return isa<PointerType>(LValueType); 334 } 335 336 void Profile(llvm::FoldingSetNodeID& ID) const { 337 ProfileRegion(ID, LValueType, superRegion); 338 } 339 340 static bool classof(const MemRegion* R) { 341 return R->getKind() == TypedViewRegionKind; 342 } 343 344 const MemRegion *removeViews() const; 345}; 346 347 348/// CompoundLiteralRegion - A memory region representing a compound literal. 349/// Compound literals are essentially temporaries that are stack allocated 350/// or in the global constant pool. 351class CompoundLiteralRegion : public TypedRegion { 352private: 353 friend class MemRegionManager; 354 const CompoundLiteralExpr* CL; 355 356 CompoundLiteralRegion(const CompoundLiteralExpr* cl, const MemRegion* sReg) 357 : TypedRegion(sReg, CompoundLiteralRegionKind), CL(cl) {} 358 359 static void ProfileRegion(llvm::FoldingSetNodeID& ID, 360 const CompoundLiteralExpr* CL, 361 const MemRegion* superRegion); 362public: 363 QualType getValueType(ASTContext& C) const { 364 return C.getCanonicalType(CL->getType()); 365 } 366 367 void Profile(llvm::FoldingSetNodeID& ID) const; 368 369 void print(llvm::raw_ostream& os) const; 370 371 const CompoundLiteralExpr* getLiteralExpr() const { return CL; } 372 373 static bool classof(const MemRegion* R) { 374 return R->getKind() == CompoundLiteralRegionKind; 375 } 376}; 377 378class DeclRegion : public TypedRegion { 379protected: 380 const Decl* D; 381 382 DeclRegion(const Decl* d, const MemRegion* sReg, Kind k) 383 : TypedRegion(sReg, k), D(d) {} 384 385 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D, 386 const MemRegion* superRegion, Kind k); 387 388public: 389 const Decl* getDecl() const { return D; } 390 void Profile(llvm::FoldingSetNodeID& ID) const; 391 392 static bool classof(const MemRegion* R) { 393 unsigned k = R->getKind(); 394 return k > BEG_DECL_REGIONS && k < END_DECL_REGIONS; 395 } 396}; 397 398class VarRegion : public DeclRegion { 399 friend class MemRegionManager; 400 401 VarRegion(const VarDecl* vd, const MemRegion* sReg) 402 : DeclRegion(vd, sReg, VarRegionKind) {} 403 404 static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl* VD, 405 const MemRegion* superRegion) { 406 DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind); 407 } 408 409public: 410 const VarDecl* getDecl() const { return cast<VarDecl>(D); } 411 412 QualType getValueType(ASTContext& C) const { 413 // FIXME: We can cache this if needed. 414 return C.getCanonicalType(getDecl()->getType()); 415 } 416 417 void print(llvm::raw_ostream& os) const; 418 419 static bool classof(const MemRegion* R) { 420 return R->getKind() == VarRegionKind; 421 } 422}; 423 424class FieldRegion : public DeclRegion { 425 friend class MemRegionManager; 426 427 FieldRegion(const FieldDecl* fd, const MemRegion* sReg) 428 : DeclRegion(fd, sReg, FieldRegionKind) {} 429 430public: 431 432 void print(llvm::raw_ostream& os) const; 433 434 const FieldDecl* getDecl() const { return cast<FieldDecl>(D); } 435 436 QualType getValueType(ASTContext& C) const { 437 // FIXME: We can cache this if needed. 438 return C.getCanonicalType(getDecl()->getType()); 439 } 440 441 static void ProfileRegion(llvm::FoldingSetNodeID& ID, FieldDecl* FD, 442 const MemRegion* superRegion) { 443 DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind); 444 } 445 446 static bool classof(const MemRegion* R) { 447 return R->getKind() == FieldRegionKind; 448 } 449}; 450 451class ObjCObjectRegion : public DeclRegion { 452 453 friend class MemRegionManager; 454 455 ObjCObjectRegion(const ObjCInterfaceDecl* ivd, const MemRegion* sReg) 456 : DeclRegion(ivd, sReg, ObjCObjectRegionKind) {} 457 458 static void ProfileRegion(llvm::FoldingSetNodeID& ID, ObjCInterfaceDecl* ivd, 459 const MemRegion* superRegion) { 460 DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCObjectRegionKind); 461 } 462 463public: 464 const ObjCInterfaceDecl* getInterface() const { 465 return cast<ObjCInterfaceDecl>(D); 466 } 467 468 QualType getValueType(ASTContext& C) const { 469 return C.getObjCInterfaceType(getInterface()); 470 } 471 472 static bool classof(const MemRegion* R) { 473 return R->getKind() == ObjCObjectRegionKind; 474 } 475}; 476 477class ObjCIvarRegion : public DeclRegion { 478 479 friend class MemRegionManager; 480 481 ObjCIvarRegion(const ObjCIvarDecl* ivd, const MemRegion* sReg) 482 : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {} 483 484 static void ProfileRegion(llvm::FoldingSetNodeID& ID, ObjCIvarDecl* ivd, 485 const MemRegion* superRegion) { 486 DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind); 487 } 488 489public: 490 const ObjCIvarDecl* getDecl() const { return cast<ObjCIvarDecl>(D); } 491 QualType getValueType(ASTContext&) const { return getDecl()->getType(); } 492 493 static bool classof(const MemRegion* R) { 494 return R->getKind() == ObjCIvarRegionKind; 495 } 496}; 497 498class ElementRegion : public TypedRegion { 499 friend class MemRegionManager; 500 501 QualType ElementType; 502 SVal Index; 503 504 ElementRegion(QualType elementType, SVal Idx, const MemRegion* sReg) 505 : TypedRegion(sReg, ElementRegionKind), 506 ElementType(elementType), Index(Idx) { 507 assert((!isa<nonloc::ConcreteInt>(&Idx) || 508 cast<nonloc::ConcreteInt>(&Idx)->getValue().isSigned()) && 509 "The index must be signed"); 510 } 511 512 static void ProfileRegion(llvm::FoldingSetNodeID& ID, QualType elementType, 513 SVal Idx, const MemRegion* superRegion); 514 515public: 516 517 SVal getIndex() const { return Index; } 518 519 QualType getValueType(ASTContext&) const { 520 return ElementType; 521 } 522 523 QualType getElementType() const { 524 return ElementType; 525 } 526 527 void print(llvm::raw_ostream& os) const; 528 529 void Profile(llvm::FoldingSetNodeID& ID) const; 530 531 static bool classof(const MemRegion* R) { 532 return R->getKind() == ElementRegionKind; 533 } 534}; 535 536template<typename RegionTy> 537const RegionTy* MemRegion::getAs() const { 538 const MemRegion *R = this; 539 540 do { 541 if (const RegionTy* RT = dyn_cast<RegionTy>(R)) 542 return RT; 543 544 if (const TypedViewRegion *TR = dyn_cast<TypedViewRegion>(R)) { 545 R = TR->getSuperRegion(); 546 continue; 547 } 548 549 break; 550 } 551 while (R); 552 553 return 0; 554} 555 556//===----------------------------------------------------------------------===// 557// MemRegionManager - Factory object for creating regions. 558//===----------------------------------------------------------------------===// 559 560class MemRegionManager { 561 llvm::BumpPtrAllocator& A; 562 llvm::FoldingSet<MemRegion> Regions; 563 564 MemSpaceRegion* globals; 565 MemSpaceRegion* stack; 566 MemSpaceRegion* heap; 567 MemSpaceRegion* unknown; 568 MemSpaceRegion* code; 569 570public: 571 MemRegionManager(llvm::BumpPtrAllocator& a) 572 : A(a), globals(0), stack(0), heap(0), unknown(0), code(0) {} 573 574 ~MemRegionManager() {} 575 576 /// getStackRegion - Retrieve the memory region associated with the 577 /// current stack frame. 578 MemSpaceRegion* getStackRegion(); 579 580 /// getGlobalsRegion - Retrieve the memory region associated with 581 /// all global variables. 582 MemSpaceRegion* getGlobalsRegion(); 583 584 /// getHeapRegion - Retrieve the memory region associated with the 585 /// generic "heap". 586 MemSpaceRegion* getHeapRegion(); 587 588 /// getUnknownRegion - Retrieve the memory region associated with unknown 589 /// memory space. 590 MemSpaceRegion* getUnknownRegion(); 591 592 MemSpaceRegion* getCodeRegion(); 593 594 bool isGlobalsRegion(const MemRegion* R) { 595 assert(R); 596 return R == globals; 597 } 598 599 /// onStack - check if the region is allocated on the stack. 600 bool onStack(const MemRegion* R); 601 602 /// onHeap - check if the region is allocated on the heap, usually by malloc. 603 bool onHeap(const MemRegion* R); 604 605 bool hasStackStorage(const MemRegion* R); 606 607 /// getAllocaRegion - Retrieve a region associated with a call to alloca(). 608 AllocaRegion* getAllocaRegion(const Expr* Ex, unsigned Cnt); 609 610 /// getCompoundLiteralRegion - Retrieve the region associated with a 611 /// given CompoundLiteral. 612 CompoundLiteralRegion* 613 getCompoundLiteralRegion(const CompoundLiteralExpr* CL); 614 615 /// getSymbolicRegion - Retrieve or create a "symbolic" memory region. 616 SymbolicRegion* getSymbolicRegion(SymbolRef sym); 617 618 StringRegion* getStringRegion(const StringLiteral* Str); 619 620 /// getVarRegion - Retrieve or create the memory region associated with 621 /// a specified VarDecl. 622 VarRegion* getVarRegion(const VarDecl* vd); 623 624 /// getElementRegion - Retrieve the memory region associated with the 625 /// associated element type, index, and super region. 626 ElementRegion* getElementRegion(QualType elementType, SVal Idx, 627 const MemRegion* superRegion,ASTContext &Ctx); 628 629 /// getFieldRegion - Retrieve or create the memory region associated with 630 /// a specified FieldDecl. 'superRegion' corresponds to the containing 631 /// memory region (which typically represents the memory representing 632 /// a structure or class). 633 FieldRegion* getFieldRegion(const FieldDecl* fd, 634 const MemRegion* superRegion); 635 636 /// getObjCObjectRegion - Retrieve or create the memory region associated with 637 /// the instance of a specified Objective-C class. 638 ObjCObjectRegion* getObjCObjectRegion(const ObjCInterfaceDecl* ID, 639 const MemRegion* superRegion); 640 641 /// getObjCIvarRegion - Retrieve or create the memory region associated with 642 /// a specified Objective-c instance variable. 'superRegion' corresponds 643 /// to the containing region (which typically represents the Objective-C 644 /// object). 645 ObjCIvarRegion* getObjCIvarRegion(const ObjCIvarDecl* ivd, 646 const MemRegion* superRegion); 647 648 TypedViewRegion* getTypedViewRegion(QualType LValueType, 649 const MemRegion* superRegion); 650 651 CodeTextRegion* getCodeTextRegion(SymbolRef sym, QualType t); 652 CodeTextRegion* getCodeTextRegion(const FunctionDecl* fd, QualType t); 653 654 template <typename RegionTy, typename A1> 655 RegionTy* getRegion(const A1 a1); 656 657private: 658 MemSpaceRegion* LazyAllocate(MemSpaceRegion*& region); 659}; 660 661//===----------------------------------------------------------------------===// 662// Out-of-line member template definitions. 663//===----------------------------------------------------------------------===// 664 665template<typename RegionTy> struct MemRegionManagerTrait; 666 667template <typename RegionTy, typename A1> 668RegionTy* MemRegionManager::getRegion(const A1 a1) { 669 670 const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion = 671 MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1); 672 673 llvm::FoldingSetNodeID ID; 674 RegionTy::ProfileRegion(ID, a1, superRegion); 675 void* InsertPos; 676 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 677 InsertPos)); 678 679 if (!R) { 680 R = (RegionTy*) A.Allocate<RegionTy>(); 681 new (R) RegionTy(a1, superRegion); 682 Regions.InsertNode(R, InsertPos); 683 } 684 685 return R; 686} 687 688//===----------------------------------------------------------------------===// 689// Traits for constructing regions. 690//===----------------------------------------------------------------------===// 691 692template <> struct MemRegionManagerTrait<CompoundLiteralRegion> { 693 typedef MemRegion SuperRegionTy; 694 static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr, 695 const CompoundLiteralExpr *CL) { 696 697 return CL->isFileScope() ? MRMgr.getGlobalsRegion() 698 : MRMgr.getStackRegion(); 699 } 700}; 701 702template <> struct MemRegionManagerTrait<StringRegion> { 703 typedef MemSpaceRegion SuperRegionTy; 704 static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr, 705 const StringLiteral*) { 706 return MRMgr.getGlobalsRegion(); 707 } 708}; 709 710template <> struct MemRegionManagerTrait<VarRegion> { 711 typedef MemRegion SuperRegionTy; 712 static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr, 713 const VarDecl *d) { 714 return d->hasLocalStorage() ? MRMgr.getStackRegion() 715 : MRMgr.getGlobalsRegion(); 716 } 717}; 718 719template <> struct MemRegionManagerTrait<SymbolicRegion> { 720 typedef MemRegion SuperRegionTy; 721 static const SuperRegionTy* getSuperRegion(MemRegionManager& MRMgr, 722 SymbolRef) { 723 return MRMgr.getUnknownRegion(); 724 } 725}; 726 727 728} // end clang namespace 729 730//===----------------------------------------------------------------------===// 731// Pretty-printing regions. 732//===----------------------------------------------------------------------===// 733 734namespace llvm { 735static inline raw_ostream& operator<<(raw_ostream& O, 736 const clang::MemRegion* R) { 737 R->print(O); 738 return O; 739} 740} // end llvm namespace 741 742#endif 743