]> www.ginac.de Git - cln.git/blobdiff - include/cln/modules.h
* Change all C include headers to ISO style within C++ code.
[cln.git] / include / cln / modules.h
index 913e4439ff58df098cc74e9b999ebb74009496e1..26fc291c01cf8e2c69be92ab81531d495e27b799 100644 (file)
@@ -7,7 +7,7 @@
 // specified in C++. AIX 4 has a linker which apparently does order
 // the modules according to dependencies, so that low-level modules
 // will be initialized earlier than the high-level modules which depend
-// on them. I have a patch for GNU ld that does the same thing.
+// on them. I (Bruno) have a patch for GNU ld that does the same thing.
 //
 // But for now, I take a half-automatic approach to the correct module
 // ordering problem: PROVIDE/REQUIRE, as in Common Lisp.
     #define ASM_UNDERSCORE_PREFIX ""
   #endif
   // Globalize a label defined in the same translation unit.
-  // See macro ASM_GLOBALIZE_LABEL in the egcs sources.
-  #if defined(__i386__) || defined(__m68k__) || defined(__mips__) || defined(__mips64__) || defined(__alpha__) || defined(__rs6000__)
+  // See macro ASM_GLOBALIZE_LABEL in the gcc sources.
+  #if defined(__i386__) || defined(__m68k__) || defined(__mips__) || defined(__mips64__) || defined(__alpha__) || defined(__rs6000__) || defined(__x86_64__) || defined(__s390__)
     // Some m68k systems use "xdef" or "global" or ".global"...
     #define CL_GLOBALIZE_LABEL(label)  __asm__("\t.globl " label);
   #endif
-  #if defined(__sparc__) || defined(__sparc64__) || defined(__arm__)
+  #if defined(__sparc__) || defined(__sparc64__) || defined(__arm__) || defined(__ia64__)
     // Some arm systems use "EXPORT" or ".globl"...
     #define CL_GLOBALIZE_LABEL(label)  __asm__("\t.global " label);
   #endif
     #define CL_GLOBALIZE_CTORDTOR_LABEL(label)
   #endif
   // Output a label inside a function.
-  // See macro ASM_OUTPUT_LABEL in the egcs sources.
+  // See macro ASM_OUTPUT_LABEL in the gcc sources.
   #if defined(__hppa__)
-    #define CL_OUTPUT_LABEL(label)  ASM_VOLATILE ("\n" label)
+    // Some hppa (Linux) systems want `label:', HPUX used to use just `label'.
+    // I tried to find out, but was unable to find the assembler on my HPUX-11
+    // boxen so decided to potentially ditch the support (no joke).  Please
+    // send an email if you can explain to me what's going on! (-rbk. 07/2001)
+    #define CL_OUTPUT_LABEL(label)  ASM_VOLATILE ("\n" label ":")
   #else
     #define CL_OUTPUT_LABEL(label)  ASM_VOLATILE ("\n" label ":")
   #endif
   // except that the latter inhibits inlining of the function containing it
   // in gcc-2.95. For new CPUs, look for "jump" and "indirect_jump" in gcc's
   // machine description.
-  #if defined(__i386__)
+  #if defined(__i386__) || defined(__x86_64__)
     #define CL_JUMP_TO(addr)  ASM_VOLATILE("jmp %*%0" : : "rm" ((void*)(addr)))
   #endif
   #if defined(__m68k__)
   #if defined(__convex__)
     #define CL_JUMP_TO(addr)  ASM_VOLATILE("jmp (%0)" : : "r" ((void*)(addr)))
   #endif
-  #define CL_PROVIDE(module)  \
-    extern "C" void cl_module__##module##__firstglobalfun () {}                \
-    extern "C" void cl_module__##module##__ctorend (void);             \
-    extern "C" void cl_module__##module##__dtorend (void);             \
-    CL_GLOBALIZE_JUMP_LABEL(cl_module__##module##__ctorend)            \
-    CL_GLOBALIZE_JUMP_LABEL(cl_module__##module##__dtorend)            \
-    CL_GLOBALIZE_CTORDTOR_LABEL(                                       \
-               ASM_UNDERSCORE_PREFIX CL_GLOBAL_CONSTRUCTOR_PREFIX      \
-               "cl_module__" #module "__firstglobalfun")               \
-    CL_GLOBALIZE_CTORDTOR_LABEL(                                       \
-               ASM_UNDERSCORE_PREFIX CL_GLOBAL_DESTRUCTOR_PREFIX       \
-               "cl_module__" #module "__firstglobalfun")               \
-    static int cl_module__##module##__counter;                         \
-    struct cl_module__##module##__controller {                         \
-      inline cl_module__##module##__controller ()                      \
-        { if (cl_module__##module##__counter++)                                \
-            { CL_JUMP_TO(cl_module__##module##__ctorend); }            \
-        }                                                              \
-      inline ~cl_module__##module##__controller ()                     \
-        { CL_OUTPUT_LABEL (ASM_UNDERSCORE_PREFIX "cl_module__" #module "__dtorend"); } \
-    };                                                                 \
-    static cl_module__##module##__controller cl_module__##module##__ctordummy;
-  #define CL_PROVIDE_END(module)  \
-    struct cl_module__##module##__destroyer {                          \
-      inline cl_module__##module##__destroyer ()                       \
-        { CL_OUTPUT_LABEL (ASM_UNDERSCORE_PREFIX "cl_module__" #module "__ctorend"); } \
-      inline ~cl_module__##module##__destroyer ()                      \
-        { if (--cl_module__##module##__counter)                                \
-            { CL_JUMP_TO(cl_module__##module##__dtorend); }            \
-        }                                                              \
-    };                                                                 \
-    static cl_module__##module##__destroyer cl_module__##module##__dtordummy;
-  #define CL_REQUIRE(module)  \
-    extern "C" void cl_module__##module##__ctor (void)                 \
-      __asm__ (ASM_UNDERSCORE_PREFIX CL_GLOBAL_CONSTRUCTOR_PREFIX      \
-               "cl_module__" #module "__firstglobalfun");              \
-    extern "C" void cl_module__##module##__dtor (void)                 \
-      __asm__ (ASM_UNDERSCORE_PREFIX CL_GLOBAL_DESTRUCTOR_PREFIX       \
-               "cl_module__" #module "__firstglobalfun");              \
-    struct _CL_REQUIRE_CLASSNAME(module,__LINE__) {                    \
-      inline _CL_REQUIRE_CLASSNAME(module,__LINE__) ()                 \
-        { cl_module__##module##__ctor (); }                            \
-      inline ~_CL_REQUIRE_CLASSNAME(module,__LINE__) ()                        \
-        { cl_module__##module##__dtor (); }                            \
-    };                                                                 \
-    static _CL_REQUIRE_CLASSNAME(module,__LINE__)                      \
-      _CL_REQUIRE_CLASSNAME(module##_requirer,__LINE__);
+  #if defined(__ia64__)
+    #define CL_JUMP_TO(addr)  ASM_VOLATILE("br " #addr)
+  #endif
+  #if defined(__s390__)
+    #define CL_JUMP_TO(addr)  ASM_VOLATILE("br %0" : : "a" ((void*)(addr)))
+  #endif
+  #ifdef CL_GLOBAL_DESTRUCTOR_PREFIX
+    #define CL_PROVIDE(module)  \
+      extern "C" void cl_module__##module##__firstglobalfun () {}      \
+      extern "C" void cl_module__##module##__ctorend (void);           \
+      extern "C" void cl_module__##module##__dtorend (void);           \
+      CL_GLOBALIZE_JUMP_LABEL(cl_module__##module##__ctorend)          \
+      CL_GLOBALIZE_JUMP_LABEL(cl_module__##module##__dtorend)          \
+      CL_GLOBALIZE_CTORDTOR_LABEL(                                     \
+                 ASM_UNDERSCORE_PREFIX CL_GLOBAL_CONSTRUCTOR_PREFIX    \
+                 "cl_module__" #module "__firstglobalfun")             \
+      CL_GLOBALIZE_CTORDTOR_LABEL(                                     \
+                 ASM_UNDERSCORE_PREFIX CL_GLOBAL_DESTRUCTOR_PREFIX     \
+                 "cl_module__" #module "__firstglobalfun")             \
+      static int cl_module__##module##__counter;                       \
+      struct cl_module__##module##__controller {                       \
+        inline cl_module__##module##__controller ()                    \
+          { if (cl_module__##module##__counter++)                      \
+              { CL_JUMP_TO(cl_module__##module##__ctorend); }          \
+          }                                                            \
+        inline ~cl_module__##module##__controller ()                   \
+          { CL_OUTPUT_LABEL (ASM_UNDERSCORE_PREFIX "cl_module__" #module "__dtorend"); } \
+      };                                                                       \
+      static cl_module__##module##__controller cl_module__##module##__ctordummy;
+    #define CL_PROVIDE_END(module)  \
+      struct cl_module__##module##__destroyer {                                \
+        inline cl_module__##module##__destroyer ()                     \
+          { CL_OUTPUT_LABEL (ASM_UNDERSCORE_PREFIX "cl_module__" #module "__ctorend"); } \
+        inline ~cl_module__##module##__destroyer ()                    \
+          { if (--cl_module__##module##__counter)                      \
+              { CL_JUMP_TO(cl_module__##module##__dtorend); }          \
+          }                                                            \
+      };                                                               \
+      static cl_module__##module##__destroyer cl_module__##module##__dtordummy;
+    #define CL_REQUIRE(module)  \
+      extern "C" void cl_module__##module##__ctor (void)               \
+        __asm__ (ASM_UNDERSCORE_PREFIX CL_GLOBAL_CONSTRUCTOR_PREFIX    \
+                 "cl_module__" #module "__firstglobalfun");            \
+      extern "C" void cl_module__##module##__dtor (void)               \
+        __asm__ (ASM_UNDERSCORE_PREFIX CL_GLOBAL_DESTRUCTOR_PREFIX     \
+                 "cl_module__" #module "__firstglobalfun");            \
+      struct _CL_REQUIRE_CLASSNAME(module,__LINE__) {                  \
+        inline _CL_REQUIRE_CLASSNAME(module,__LINE__) ()               \
+          { cl_module__##module##__ctor (); }                          \
+        inline ~_CL_REQUIRE_CLASSNAME(module,__LINE__) ()              \
+          { cl_module__##module##__dtor (); }                          \
+      };                                                               \
+      static _CL_REQUIRE_CLASSNAME(module,__LINE__)                    \
+        _CL_REQUIRE_CLASSNAME(module##_requirer,__LINE__);
+  #else
+    // gcc-3.0 -fuse-cxa-atexit doesn't have a single per-module destructor
+    // function anymore. Instead, for each object's static constructor it
+    // executes, it pushes the corresponding object's destructor onto a list.
+    // Thus we need to hack the constructors only.
+    #define CL_PROVIDE(module)  \
+      extern "C" void cl_module__##module##__firstglobalfun () {}      \
+      extern "C" void cl_module__##module##__ctorend (void);           \
+      CL_GLOBALIZE_JUMP_LABEL(cl_module__##module##__ctorend)          \
+      CL_GLOBALIZE_CTORDTOR_LABEL(                                     \
+                 ASM_UNDERSCORE_PREFIX CL_GLOBAL_CONSTRUCTOR_PREFIX    \
+                 "cl_module__" #module "__firstglobalfun")             \
+      static int cl_module__##module##__counter;                       \
+      struct cl_module__##module##__controller {                       \
+        inline cl_module__##module##__controller ()                    \
+          { if (cl_module__##module##__counter++)                      \
+              { CL_JUMP_TO(cl_module__##module##__ctorend); }          \
+          }                                                            \
+      };                                                               \
+      static cl_module__##module##__controller cl_module__##module##__ctordummy;
+    #define CL_PROVIDE_END(module)  \
+      struct cl_module__##module##__destroyer {                                \
+        inline cl_module__##module##__destroyer ()                     \
+          { CL_OUTPUT_LABEL (ASM_UNDERSCORE_PREFIX "cl_module__" #module "__ctorend"); } \
+      };                                                               \
+      static cl_module__##module##__destroyer cl_module__##module##__dtordummy;
+    #define CL_REQUIRE(module)  \
+      extern "C" void cl_module__##module##__ctor (void)               \
+        __asm__ (ASM_UNDERSCORE_PREFIX CL_GLOBAL_CONSTRUCTOR_PREFIX    \
+                 "cl_module__" #module "__firstglobalfun");            \
+      struct _CL_REQUIRE_CLASSNAME(module,__LINE__) {                  \
+        inline _CL_REQUIRE_CLASSNAME(module,__LINE__) ()               \
+          { cl_module__##module##__ctor (); }                          \
+      };                                                               \
+      static _CL_REQUIRE_CLASSNAME(module,__LINE__)                    \
+        _CL_REQUIRE_CLASSNAME(module##_requirer,__LINE__);
+  #endif
   #define _CL_REQUIRE_CLASSNAME(module,line) __CL_REQUIRE_CLASSNAME(module,line)
   #define __CL_REQUIRE_CLASSNAME(module,line) cl_module__##module##__##line
 #else
   #define CL_REQUIRE(module)
 #endif
 
+// Concatenation of macroexpanded tokens.
+// Equivalent to CL_CONCAT in src/base/cl_macros.h which we do not want
+// to expose, however.
+#define CL_CONCATENATE_(xxx,yyy)  xxx##yyy
+#define CL_CONCATENATE(xxx,yyy)  CL_CONCATENATE_(xxx,yyy)
+
+// Sometimes a link time dependency is needed, but without requirements
+// on initialization order.
+//
+// CL_FORCE_LINK(dummy,external_variable)
+// forces a link time reference to the external_variable.
+#include <cstdlib>
+#if 0
+// This definition does not work.  It gets optimized away by g++ 3.1.
+#define CL_FORCE_LINK(dummy,external_variable) \
+  static const void* const dummy[] = { &dummy, &external_variable };
+#else
+#define CL_FORCE_LINK(dummy,external_variable) \
+  static const                                                         \
+  struct dummy {                                                       \
+    inline dummy () {                                                  \
+      if ((void*) &external_variable == (void*) this)                  \
+        abort();                                                       \
+    }                                                                  \
+  }                                                                    \
+  CL_CONCATENATE(dummy,_instance);
+#endif
+
 #endif /* _CL_MODULES_H */