LLVM API Documentation
00001 //===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- 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 the ManagedStatic class and the llvm_shutdown() function. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef LLVM_SUPPORT_MANAGED_STATIC_H 00015 #define LLVM_SUPPORT_MANAGED_STATIC_H 00016 00017 namespace llvm { 00018 00019 /// object_deleter - Helper method for ManagedStatic. 00020 /// 00021 template<class C> 00022 void object_deleter(void *Ptr) { 00023 delete (C*)Ptr; 00024 } 00025 00026 /// ManagedStaticBase - Common base class for ManagedStatic instances. 00027 class ManagedStaticBase { 00028 protected: 00029 // This should only be used as a static variable, which guarantees that this 00030 // will be zero initialized. 00031 mutable void *Ptr; 00032 mutable void (*DeleterFn)(void*); 00033 mutable const ManagedStaticBase *Next; 00034 00035 void RegisterManagedStatic(void *ObjPtr, void (*deleter)(void*)) const; 00036 public: 00037 /// isConstructed - Return true if this object has not been created yet. 00038 bool isConstructed() const { return Ptr != 0; } 00039 00040 void destroy() const; 00041 }; 00042 00043 /// ManagedStatic - This transparently changes the behavior of global statics to 00044 /// be lazily constructed on demand (good for reducing startup times of dynamic 00045 /// libraries that link in LLVM components) and for making destruction be 00046 /// explicit through the llvm_shutdown() function call. 00047 /// 00048 template<class C> 00049 class ManagedStatic : public ManagedStaticBase { 00050 public: 00051 00052 // Accessors. 00053 C &operator*() { 00054 if (!Ptr) LazyInit(); 00055 return *static_cast<C*>(Ptr); 00056 } 00057 C *operator->() { 00058 if (!Ptr) LazyInit(); 00059 return static_cast<C*>(Ptr); 00060 } 00061 const C &operator*() const { 00062 if (!Ptr) LazyInit(); 00063 return *static_cast<C*>(Ptr); 00064 } 00065 const C *operator->() const { 00066 if (!Ptr) LazyInit(); 00067 return static_cast<C*>(Ptr); 00068 } 00069 00070 public: 00071 void LazyInit() const { 00072 RegisterManagedStatic(new C(), object_deleter<C>); 00073 } 00074 }; 00075 00076 template<void (*CleanupFn)(void*)> 00077 class ManagedCleanup : public ManagedStaticBase { 00078 public: 00079 void Register() { RegisterManagedStatic(0, CleanupFn); } 00080 }; 00081 00082 00083 /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. 00084 void llvm_shutdown(); 00085 00086 00087 /// llvm_shutdown_obj - This is a simple helper class that calls 00088 /// llvm_shutdown() when it is destroyed. 00089 struct llvm_shutdown_obj { 00090 llvm_shutdown_obj() {} 00091 ~llvm_shutdown_obj() { llvm_shutdown(); } 00092 }; 00093 00094 } 00095 00096 #endif