LLVM API Documentation

LeakDetector.h
Go to the documentation of this file.
00001 //===- LeakDetector.h - Provide leak detection ------------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines a class that can be used to provide very simple memory leak
00011 // checks for an API.  Basically LLVM uses this to make sure that Instructions,
00012 // for example, are deleted when they are supposed to be, and not leaked away.
00013 //
00014 // When compiling with NDEBUG (Release build), this class does nothing, thus
00015 // adding no checking overhead to release builds.  Note that this class is
00016 // implemented in a very simple way, requiring completely manual manipulation
00017 // and checking for garbage, but this is intentional: users should not be using
00018 // this API, only other APIs should.
00019 //
00020 //===----------------------------------------------------------------------===//
00021 
00022 #ifndef LLVM_IR_LEAKDETECTOR_H
00023 #define LLVM_IR_LEAKDETECTOR_H
00024 
00025 #include <string>
00026 
00027 namespace llvm {
00028 
00029 class LLVMContext;
00030 class Value;
00031 class MDNode;
00032 
00033 struct LeakDetector {
00034   /// addGarbageObject - Add a pointer to the internal set of "garbage" object
00035   /// pointers.  This should be called when objects are created, or if they are
00036   /// taken out of an owning collection.
00037   ///
00038   template <class T> static void addGarbageObject(T *Object) {
00039 #ifndef NDEBUG
00040     addGarbageObjectImpl(Object);
00041 #endif
00042   }
00043 
00044   /// removeGarbageObject - Remove a pointer from our internal representation of
00045   /// our "garbage" objects.  This should be called when an object is added to
00046   /// an "owning" collection.
00047   ///
00048   template <class T> static void removeGarbageObject(T *Object) {
00049 #ifndef NDEBUG
00050     removeGarbageObjectImpl(Object);
00051 #endif
00052   }
00053 
00054   /// checkForGarbage - Traverse the internal representation of garbage
00055   /// pointers.  If there are any pointers that have been add'ed, but not
00056   /// remove'd, big obnoxious warnings about memory leaks are issued.
00057   ///
00058   /// The specified message will be printed indicating when the check was
00059   /// performed.
00060   ///
00061   static void checkForGarbage(LLVMContext &C, const std::string &Message) {
00062 #ifndef NDEBUG
00063     checkForGarbageImpl(C, Message);
00064 #endif
00065   }
00066 
00067 private:
00068   /// Overload the normal methods to work better with Value* because they are
00069   /// by far the most common in LLVM.
00070   ///
00071   /// Besides making the warning messages nicer, this hides errors by storing
00072   /// Value* in a different leak-detection container than other classes.
00073   static void addGarbageObjectImpl(const Value *Object);
00074   static void removeGarbageObjectImpl(const Value *Object);
00075 
00076   /// Overload the normal methods to work better with MDNode* to improve error
00077   /// messages.
00078   ///
00079   /// For better or worse, this hides errors when other types are added as
00080   /// garbage, deleted without being removed, and an MDNode is allocated in the
00081   /// same spot.
00082   ///
00083   /// \note Only handle \a MDNode for now, since we can't always get access to
00084   /// an \a LLVMContext for other \a Metadata types.
00085   static void addGarbageObjectImpl(const MDNode *Object);
00086   static void removeGarbageObjectImpl(const MDNode *Object);
00087 
00088   static void addGarbageObjectImpl(void *Object);
00089   static void removeGarbageObjectImpl(void *Object);
00090   static void checkForGarbageImpl(LLVMContext &C, const std::string &Message);
00091 };
00092 
00093 } // End llvm namespace
00094 
00095 #endif