ManagedStatic.h revision 771cbf30bc1ff025316d1a80aeb5102375c1598e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- llvm/Support/ManagedStatic.h - Static Global wrapper ----*- C++ -*-===//
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file was developed by Chris Lattner and is distributed under
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the University of Illinois Open Source License. See LICENSE.TXT for details.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file defines the ManagedStatic class and the llvm_shutdown() function.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===//
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef LLVM_SUPPORT_MANAGED_STATIC_H
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define LLVM_SUPPORT_MANAGED_STATIC_H
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace llvm {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// object_deleter - Helper method for ManagedStatic.
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class C>
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void object_deleter(void *Ptr) {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete (C*)Ptr;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// ManagedStaticBase - Common base class for ManagedStatic instances.
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ManagedStaticBase {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)protected:
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This should only be used as a static variable, which guarantees that this
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // will be zero initialized.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mutable void *Ptr;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mutable void (*DeleterFn)(void*);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  mutable const ManagedStaticBase *Next;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RegisterManagedStatic(void *ObjPtr, void (*deleter)(void*)) const;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void destroy() const;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// ManagedStatic - This transparently changes the behavior of global statics to
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// be lazily constructed on demand (good for reducing startup times of dynamic
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// libraries that link in LLVM components) and for making destruction be
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// explicit through the llvm_shutdown() function call.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<class C>
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ManagedStatic : public ManagedStaticBase {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Accessors.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C &operator*() {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!Ptr) LazyInit();
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return *static_cast<C*>(Ptr);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  C *operator->() {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!Ptr) LazyInit();
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<C*>(Ptr);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const C &operator*() const {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!Ptr) LazyInit();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return *static_cast<C*>(Ptr);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const C *operator->() const {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!Ptr) LazyInit();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<C*>(Ptr);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)public:
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void LazyInit() const {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RegisterManagedStatic(new C(), object_deleter<C>);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void llvm_shutdown();
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)