Finegrainify namespacification
[oota-llvm.git] / lib / Support / LeakDetector.cpp
1 //===-- LeakDetector.cpp - Implement LeakDetector interface ---------------===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the LeakDetector class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "Support/LeakDetector.h"
15 #include "llvm/Value.h"
16 #include <set>
17
18 namespace llvm {
19
20 // Lazily allocate set so that release build doesn't have to do anything.
21 static std::set<const void*> *Objects = 0;
22 static std::set<const Value*> *LLVMObjects = 0;
23
24 // Because the most common usage pattern, by far, is to add a garbage object,
25 // then remove it immediately, we optimize this case.  When an object is added,
26 // it is not added to the set immediately, it is added to the CachedValue Value.
27 // If it is immediately removed, no set search need be performed.
28 //
29 static const Value *CachedValue;
30
31 void LeakDetector::addGarbageObjectImpl(void *Object) {
32   if (Objects == 0)
33     Objects = new std::set<const void*>();
34   assert(Objects->count(Object) == 0 && "Object already in set!");
35   Objects->insert(Object);
36 }
37
38 void LeakDetector::removeGarbageObjectImpl(void *Object) {
39   if (Objects)
40     Objects->erase(Object);
41 }
42
43 void LeakDetector::addGarbageObjectImpl(const Value *Object) {
44   if (CachedValue) {
45     if (LLVMObjects == 0)
46       LLVMObjects = new std::set<const Value*>();
47     assert(LLVMObjects->count(CachedValue) == 0 && "Object already in set!");
48     LLVMObjects->insert(CachedValue);
49   }
50   CachedValue = Object;
51 }
52
53 void LeakDetector::removeGarbageObjectImpl(const Value *Object) {
54   if (Object == CachedValue)
55     CachedValue = 0;             // Cache hit!
56   else if (LLVMObjects)
57     LLVMObjects->erase(Object);
58 }
59
60 void LeakDetector::checkForGarbageImpl(const std::string &Message) {
61   if (CachedValue)  // Flush the cache to the set...
62     addGarbageObjectImpl((Value*)0);
63
64   assert(CachedValue == 0 && "No value should be cached anymore!");
65
66   if ((Objects && !Objects->empty()) || (LLVMObjects && !LLVMObjects->empty())){
67     std::cerr << "Leaked objects found: " << Message << "\n";
68
69     if (Objects && !Objects->empty()) {
70       std::cerr << "  Non-Value objects leaked:";
71       for (std::set<const void*>::iterator I = Objects->begin(),
72              E = Objects->end(); I != E; ++I)
73         std::cerr << " " << *I;
74     }
75
76     if (LLVMObjects && !LLVMObjects->empty()) {
77       std::cerr << "  LLVM Value subclasses leaked:";
78       for (std::set<const Value*>::iterator I = LLVMObjects->begin(),
79              E = LLVMObjects->end(); I != E; ++I)
80         std::cerr << **I << "\n";
81     }
82
83     std::cerr << "This is probably because you removed an LLVM value "
84               << "(Instruction, BasicBlock, \netc), but didn't delete it.  "
85               << "Please check your code for memory leaks.\n";
86
87     // Clear out results so we don't get duplicate warnings on next call...
88     delete Objects; delete LLVMObjects;
89     Objects = 0; LLVMObjects = 0;
90   }
91 }
92
93 } // End llvm namespace