diff --git a/ChangeLog b/ChangeLog index 8bff69c..59d83f5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2001-11-04 Bruno Haible + + Interoperability with gcc-3.0 -fuse-cxa-atexit. + * autoconf/aclocal.m4 (CL_GLOBAL_CONSTRUCTORS): Add test whether + global destructors actually exist. + * include/cln/modules.h (CL_PROVIDE, CL_PROVIDE_END, CL_PROVIDE_END): + Don't hack the global destructors if there is no global destructors + function. + 2001-11-03 Richard Kreckel * src/float/transcendental/cl_F_sinx.cc (sinx_naive): For small diff --git a/autoconf/aclocal.m4 b/autoconf/aclocal.m4 index 3210f9a..9807abc 100644 --- a/autoconf/aclocal.m4 +++ b/autoconf/aclocal.m4 @@ -570,8 +570,33 @@ rm -f conftest* if test "$cl_cv_cplusplus_ctorprefix" '!=' unknown; then ac_value='"'"$cl_cv_cplusplus_ctorprefix"'"' AC_DEFINE_UNQUOTED(CL_GLOBAL_CONSTRUCTOR_PREFIX,$ac_value) - ac_value=`echo "$ac_value" | sed -e 's,I,D,'` - AC_DEFINE_UNQUOTED(CL_GLOBAL_DESTRUCTOR_PREFIX,$ac_value) +AC_CACHE_CHECK(for the global destructors function prefix, +cl_cv_cplusplus_dtorprefix, [ +cat > conftest.cc << EOF +struct foo { foo (); ~ foo (); }; +foo foobar; +EOF +# look for the assembly language name in the .s file +AC_TRY_COMMAND(${CXX-g++} $CXXFLAGS -S conftest.cc) >/dev/null 2>&1 +if grep '_GLOBAL_\$D\$foobar' conftest.s >/dev/null ; then + cl_cv_cplusplus_dtorprefix='_GLOBAL_$D$' +else + if grep '_GLOBAL_\.D\.foobar' conftest.s >/dev/null ; then + cl_cv_cplusplus_dtorprefix='_GLOBAL_.D.' + else + if grep '_GLOBAL__D_foobar' conftest.s >/dev/null ; then + cl_cv_cplusplus_dtorprefix='_GLOBAL__D_' + else + cl_cv_cplusplus_dtorprefix=none + fi + fi +fi +rm -f conftest* +]) + if test "$cl_cv_cplusplus_dtorprefix" '!=' none; then + ac_value='"'"$cl_cv_cplusplus_ctorprefix"'"' + AC_DEFINE_UNQUOTED(CL_GLOBAL_DESTRUCTOR_PREFIX,$ac_value) + fi dnl Check whether the global constructors/destructors functions are file-scope dnl only by default. This is the case in egcs-1.1.2 or newer. AC_CACHE_CHECK(whether the global constructors function need to be exported, @@ -709,6 +734,9 @@ dnl ## configuration script generated by Autoconf, you may include it under ## the same distribution terms that you use for the rest of that program. +# The next line was added by Bruno Haible 2001-06-08. +builtin([undefine],[symbols]) + # serial 46 AC_PROG_LIBTOOL AC_DEFUN([AC_PROG_LIBTOOL], [AC_REQUIRE([AC_LIBTOOL_SETUP])dnl diff --git a/include/cln/modules.h b/include/cln/modules.h index 314df9c..ff05894 100644 --- a/include/cln/modules.h +++ b/include/cln/modules.h @@ -152,53 +152,91 @@ #if defined(__ia64__) #define CL_JUMP_TO(addr) ASM_VOLATILE("br " #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__); + #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