summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2002-09-08 18:51:16 +0000
committerChris Lattner <sabre@nondot.org>2002-09-08 18:51:16 +0000
commit4f986cebfd70ce27e8dc0178c302ffb5792f5e26 (patch)
treed197eb9f4e214377c3f000c57ea82ee52a7d9981 /llvm/lib
parent57c6a2123d09cc62e2da5a6d48ca1bb5c1d5eb03 (diff)
downloadbcm5719-llvm-4f986cebfd70ce27e8dc0178c302ffb5792f5e26.tar.gz
bcm5719-llvm-4f986cebfd70ce27e8dc0178c302ffb5792f5e26.zip
Checkin initial support for automatic memory leak detection routines
llvm-svn: 3618
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Support/LeakDetector.cpp66
1 files changed, 66 insertions, 0 deletions
diff --git a/llvm/lib/Support/LeakDetector.cpp b/llvm/lib/Support/LeakDetector.cpp
new file mode 100644
index 00000000000..0d7b4bedf3d
--- /dev/null
+++ b/llvm/lib/Support/LeakDetector.cpp
@@ -0,0 +1,66 @@
+//===-- LeakDetector.cpp - Implement LeakDetector interface ---------------===//
+//
+// This file implements the LeakDetector class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Support/LeakDetector.h"
+#include "llvm/Value.h"
+#include <set>
+#include <iostream>
+
+// Lazily allocate set so that release build doesn't have to do anything.
+static std::set<const void*> *Objects = 0;
+static std::set<const Value*> *LLVMObjects = 0;
+
+void LeakDetector::addGarbageObjectImpl(void *Object) {
+ if (Objects == 0)
+ Objects = new std::set<const void*>();
+ assert(Objects->count(Object) == 0 && "Object already in set!");
+ Objects->insert(Object);
+}
+
+void LeakDetector::removeGarbageObjectImpl(void *Object) {
+ if (Objects)
+ Objects->erase(Object);
+}
+
+void LeakDetector::addGarbageObjectImpl(const Value *Object) {
+ if (LLVMObjects == 0)
+ LLVMObjects = new std::set<const Value*>();
+ assert(LLVMObjects->count(Object) == 0 && "Object already in set!");
+ LLVMObjects->insert(Object);
+}
+
+void LeakDetector::removeGarbageObjectImpl(const Value *Object) {
+ if (LLVMObjects)
+ LLVMObjects->erase(Object);
+}
+
+void LeakDetector::checkForGarbageImpl(const std::string &Message) {
+ if ((Objects && !Objects->empty()) || (LLVMObjects && !LLVMObjects->empty())){
+ std::cerr << "Leaked objects found: " << Message << "\n";
+
+ if (Objects && !Objects->empty()) {
+ std::cerr << " Non-Value objects leaked:";
+ for (std::set<const void*>::iterator I = Objects->begin(),
+ E = Objects->end(); I != E; ++I)
+ std::cerr << " " << *I;
+ }
+
+ if (LLVMObjects && !LLVMObjects->empty()) {
+ std::cerr << " LLVM Value subclasses leaked:";
+ for (std::set<const Value*>::iterator I = LLVMObjects->begin(),
+ E = LLVMObjects->end(); I != E; ++I)
+ std::cerr << **I << "\n";
+ }
+
+ std::cerr << "This is probably because you removed an LLVM value "
+ << "(Instruction, BasicBlock, \netc), but didn't delete it. "
+ << "Please check your code for memory leaks.\n";
+
+ // Clear out results so we don't get duplicate warnings on next call...
+ delete Objects; delete LLVMObjects;
+ Objects = 0; LLVMObjects = 0;
+ }
+}
OpenPOWER on IntegriCloud