175584Sru//===-- LeakDetector.cpp - Implement LeakDetector interface ---------------===//
275584Sru//
375584Sru//                     The LLVM Compiler Infrastructure
475584Sru//
575584Sru// This file is distributed under the University of Illinois Open Source
675584Sru// License. See LICENSE.TXT for details.
775584Sru//
875584Sru//===----------------------------------------------------------------------===//
975584Sru//
1075584Sru// This file implements the LeakDetector class.
1175584Sru//
1275584Sru//===----------------------------------------------------------------------===//
1375584Sru
1475584Sru#include "llvm/Support/LeakDetector.h"
1575584Sru#include "LLVMContextImpl.h"
1675584Sru#include "llvm/ADT/SmallPtrSet.h"
1775584Sru#include "llvm/IR/Value.h"
1875584Sru#include "llvm/Support/Compiler.h"
1975584Sru#include "llvm/Support/ManagedStatic.h"
2075584Sru#include "llvm/Support/Mutex.h"
2175584Sru#include "llvm/Support/Threading.h"
2275584Sruusing namespace llvm;
2375584Sru
2475584Srustatic ManagedStatic<sys::SmartMutex<true> > ObjectsLock;
2575584Srustatic ManagedStatic<LeakDetectorImpl<void> > Objects;
2675584Sru
2775584Srustatic void clearGarbage(LLVMContext &Context) {
2875584Sru  Objects->clear();
2975584Sru  Context.pImpl->LLVMObjects.clear();
3075584Sru}
3175584Sru
3275584Sruvoid LeakDetector::addGarbageObjectImpl(void *Object) {
3375584Sru  sys::SmartScopedLock<true> Lock(*ObjectsLock);
3475584Sru  Objects->addGarbage(Object);
3575584Sru}
3675584Sru
3775584Sruvoid LeakDetector::addGarbageObjectImpl(const Value *Object) {
3875584Sru  LLVMContextImpl *pImpl = Object->getContext().pImpl;
3975584Sru  pImpl->LLVMObjects.addGarbage(Object);
4075584Sru}
4175584Sru
4275584Sruvoid LeakDetector::removeGarbageObjectImpl(void *Object) {
4375584Sru  sys::SmartScopedLock<true> Lock(*ObjectsLock);
4475584Sru  Objects->removeGarbage(Object);
4575584Sru}
4675584Sru
4775584Sruvoid LeakDetector::removeGarbageObjectImpl(const Value *Object) {
4875584Sru  LLVMContextImpl *pImpl = Object->getContext().pImpl;
4975584Sru  pImpl->LLVMObjects.removeGarbage(Object);
5075584Sru}
5175584Sru
5275584Sruvoid LeakDetector::checkForGarbageImpl(LLVMContext &Context,
5375584Sru                                       const std::string &Message) {
5475584Sru  LLVMContextImpl *pImpl = Context.pImpl;
5575584Sru  sys::SmartScopedLock<true> Lock(*ObjectsLock);
5675584Sru
5775584Sru  Objects->setName("GENERIC");
5875584Sru  pImpl->LLVMObjects.setName("LLVM");
5975584Sru
6075584Sru  // use non-short-circuit version so that both checks are performed
6175584Sru  if (Objects->hasGarbage(Message) |
6275584Sru      pImpl->LLVMObjects.hasGarbage(Message))
6375584Sru    errs() << "\nThis is probably because you removed an object, but didn't "
6475584Sru           << "delete it.  Please check your code for memory leaks.\n";
6575584Sru
6675584Sru  // Clear out results so we don't get duplicate warnings on
6775584Sru  // next call...
6875584Sru  clearGarbage(Context);
6975584Sru}
7075584Sru