[libsigc++2] Temporarily undefine the nil macro, if it's defined



commit 75466ce1e1d92fe04926f72567417912779cc5c1
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Wed Dec 16 09:39:07 2015 +0100

    Temporarily undefine the nil macro, if it's defined
    
    * build/cxx.m4: Add SIGC_CXX_PRAGMA_PUSH_POP_MACRO.
    * configure.ac: Call SIGC_CXX_PRAGMA_PUSH_POP_MACRO.
    * sigc++config.h.in: Add SIGC_PRAGMA_PUSH_POP_MACRO.
    * sigc++/functors/macros/functor_trait.h.m4:
    * sigc++/adaptors/macros/bind.h.m4:
    * sigc++/adaptors/macros/retype.h.m4:
    * sigc++/functors/macros/slot.h.m4:
    * sigc++/macros/signal.h.m4: If nil and SIGC_PRAGMA_PUSH_POP_MACRO are
    defined, undefine nil temporarily in the header files.
    nil is a keyword in Objective-C++ and in Mac OS X C++. Bug #695235.

 build/cxx.m4                              |   52 +++++++++++++++++++++++++++++
 configure.ac                              |    1 +
 sigc++/adaptors/macros/bind.h.m4          |   12 +++++++
 sigc++/adaptors/macros/retype.h.m4        |   12 +++++++
 sigc++/functors/macros/functor_trait.h.m4 |   15 ++++++++
 sigc++/functors/macros/slot.h.m4          |   12 +++++++
 sigc++/macros/signal.h.m4                 |   12 +++++++
 sigc++config.h.in                         |    4 ++
 8 files changed, 120 insertions(+), 0 deletions(-)
---
diff --git a/build/cxx.m4 b/build/cxx.m4
index 7e92820..201a561 100644
--- a/build/cxx.m4
+++ b/build/cxx.m4
@@ -117,3 +117,55 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
 ])
 AC_MSG_RESULT([$sigcm_cxx_self_reference_in_member_initialization])
 ])
+
+dnl
+dnl SIGC_CXX_PRAGMA_PUSH_POP_MACRO
+dnl
+dnl TODO: When we can break ABI, delete this. It's used when nil is
+dnl temporarily undefined. See comment in functor_trait.h.
+dnl
+AC_DEFUN([SIGC_CXX_PRAGMA_PUSH_POP_MACRO],[
+AC_MSG_CHECKING([if C++ preprocessor supports pragma push_macro() and pop_macro().])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+[[
+  #define BEGIN {
+  #define END   }
+  #pragma push_macro("BEGIN")
+  #pragma push_macro("END")
+  #undef BEGIN
+  #undef END
+
+  // BEGIN and END are not prepreprocessor macros
+  struct Test1
+  {
+    int BEGIN;
+    double END;
+  };
+
+  #pragma pop_macro("BEGIN")
+  #pragma pop_macro("END")
+
+  // BEGIN and END are prepreprocessor macros
+  struct Test2
+  BEGIN
+    int i;
+    double d;
+  END;
+
+  void func1(Test1& x);
+  void func2(Test2& x);
+]],
+[[
+  Test1 test1;
+  Test2 test2;
+  func1(test1);
+  func2(test2);
+]])],
+[
+  sigcm_cxx_pragma_push_pop_macro=yes
+  AC_DEFINE([SIGC_PRAGMA_PUSH_POP_MACRO],[1],[does the C++ preprocessor support pragma push_macro() and 
pop_macro().])
+],[
+  sigcm_cxx_pragma_push_pop_macro=no
+])
+AC_MSG_RESULT([$sigcm_cxx_pragma_push_pop_macro])
+])
diff --git a/configure.ac b/configure.ac
index 67f2191..6e497a4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,6 +53,7 @@ AC_LANG([C++])
 SIGC_CXX_GCC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD
 SIGC_CXX_MSVC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD
 SIGC_CXX_SELF_REFERENCE_IN_MEMBER_INITIALIZATION
+SIGC_CXX_PRAGMA_PUSH_POP_MACRO
 SIGC_CXX_HAS_NAMESPACE_STD
 SIGC_CXX_HAS_SUN_REVERSE_ITERATOR
 
diff --git a/sigc++/adaptors/macros/bind.h.m4 b/sigc++/adaptors/macros/bind.h.m4
index 63039cd..495f7fb 100644
--- a/sigc++/adaptors/macros/bind.h.m4
+++ b/sigc++/adaptors/macros/bind.h.m4
@@ -235,6 +235,13 @@ _FIREWALL([ADAPTORS_BIND])
 #include <sigc++/adaptors/adaptor_trait.h>
 #include <sigc++/adaptors/bound_argument.h>
 
+//TODO: See comment in functor_trait.h.
+#if defined(nil) && defined(SIGC_PRAGMA_PUSH_POP_MACRO)
+  #define SIGC_NIL_HAS_BEEN_PUSHED 1
+  #pragma push_macro("nil")
+  #undef nil
+#endif
+
 namespace sigc {
 
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -403,3 +410,8 @@ bind(const T_functor& _A_func, T_bound1 _A_b1)
 FOR(1,CALL_SIZE,[[BIND_COUNT(%1)]])dnl
 
 } /* namespace sigc */
+
+#ifdef SIGC_NIL_HAS_BEEN_PUSHED
+  #undef SIGC_NIL_HAS_BEEN_PUSHED
+  #pragma pop_macro("nil")
+#endif
diff --git a/sigc++/adaptors/macros/retype.h.m4 b/sigc++/adaptors/macros/retype.h.m4
index 06d23b8..8267c81 100644
--- a/sigc++/adaptors/macros/retype.h.m4
+++ b/sigc++/adaptors/macros/retype.h.m4
@@ -81,6 +81,13 @@ _FIREWALL([ADAPTORS_RETYPE])
 #include <sigc++/functors/mem_fun.h>
 #include <sigc++/functors/slot.h>
 
+//TODO: See comment in functor_trait.h.
+#if defined(nil) && defined(SIGC_PRAGMA_PUSH_POP_MACRO)
+  #define SIGC_NIL_HAS_BEEN_PUSHED 1
+  #pragma push_macro("nil")
+  #undef nil
+#endif
+
 namespace sigc {
 
 /** @defgroup retype retype(), retype_return()
@@ -208,3 +215,8 @@ FOR(0,CALL_SIZE,[[RETYPE_MEM_FUNCTOR(%1,[bound_volatile_])]])dnl
 FOR(0,CALL_SIZE,[[RETYPE_MEM_FUNCTOR(%1,[bound_const_volatile_])]])dnl
 
 } /* namespace sigc */
+
+#ifdef SIGC_NIL_HAS_BEEN_PUSHED
+  #undef SIGC_NIL_HAS_BEEN_PUSHED
+  #pragma pop_macro("nil")
+#endif
diff --git a/sigc++/functors/macros/functor_trait.h.m4 b/sigc++/functors/macros/functor_trait.h.m4
index 142e5f2..176fee2 100644
--- a/sigc++/functors/macros/functor_trait.h.m4
+++ b/sigc++/functors/macros/functor_trait.h.m4
@@ -52,6 +52,16 @@ _FIREWALL([FUNCTORS_FUNCTOR_TRAIT])
 
 namespace sigc {
 
+//TODO: When we can break ABI, replace nil by something else, such as sigc_nil.
+// nil is a keyword in Objective C++. When gcc is used for compiling Objective C++
+// programs, nil is defined as a preprocessor macro.
+// https://bugzilla.gnome.org/show_bug.cgi?id=695235
+#if defined(nil) && defined(SIGC_PRAGMA_PUSH_POP_MACRO)
+  #define SIGC_NIL_HAS_BEEN_PUSHED 1
+  #pragma push_macro("nil")
+  #undef nil
+#endif
+
 /** nil struct type.
  * The nil struct type is used as default template argument in the
  * unnumbered sigc::signal and sigc::slot templates.
@@ -65,6 +75,11 @@ struct nil;
 struct nil {};
 #endif
 
+#ifdef SIGC_NIL_HAS_BEEN_PUSHED
+  #undef SIGC_NIL_HAS_BEEN_PUSHED
+  #pragma pop_macro("nil")
+#endif
+
 /** @defgroup sigcfunctors Functors
  * Functors are copyable types that define operator()().
  *
diff --git a/sigc++/functors/macros/slot.h.m4 b/sigc++/functors/macros/slot.h.m4
index 683841d..5c6436c 100644
--- a/sigc++/functors/macros/slot.h.m4
+++ b/sigc++/functors/macros/slot.h.m4
@@ -355,6 +355,13 @@ _FIREWALL([FUNCTORS_SLOT])
 #include <sigc++/adaptors/adaptor_trait.h>
 #include <sigc++/functors/slot_base.h>
 
+//TODO: See comment in functor_trait.h.
+#if defined(nil) && defined(SIGC_PRAGMA_PUSH_POP_MACRO)
+  #define SIGC_NIL_HAS_BEEN_PUSHED 1
+  #pragma push_macro("nil")
+  #undef nil
+#endif
+
 namespace sigc {
 
 namespace internal {
@@ -441,3 +448,8 @@ SLOT(CALL_SIZE,CALL_SIZE)
 FOR(0,eval(CALL_SIZE-1),[[SLOT(%1,CALL_SIZE)]])
 
 } /* namespace sigc */
+
+#ifdef SIGC_NIL_HAS_BEEN_PUSHED
+  #undef SIGC_NIL_HAS_BEEN_PUSHED
+  #pragma pop_macro("nil")
+#endif
diff --git a/sigc++/macros/signal.h.m4 b/sigc++/macros/signal.h.m4
index cf3add5..b9e2a2b 100644
--- a/sigc++/macros/signal.h.m4
+++ b/sigc++/macros/signal.h.m4
@@ -568,6 +568,13 @@ divert(0)
 #include <sigc++/functors/slot.h>
 #include <sigc++/functors/mem_fun.h>
 
+//TODO: See comment in functor_trait.h.
+#if defined(nil) && defined(SIGC_PRAGMA_PUSH_POP_MACRO)
+  #define SIGC_NIL_HAS_BEEN_PUSHED 1
+  #pragma push_macro("nil")
+  #undef nil
+#endif
+
 //SIGC_TYPEDEF_REDEFINE_ALLOWED:
 // TODO: This should have its own test, but I can not create one that gives the error instead of just a 
warning. murrayc.
 // I have just used this because there is a correlation between these two problems.
@@ -1155,4 +1162,9 @@ FOR(0,eval(CALL_SIZE-1),[[SIGNAL(%1)]])
 
 } /* namespace sigc */
 
+#ifdef SIGC_NIL_HAS_BEEN_PUSHED
+  #undef SIGC_NIL_HAS_BEEN_PUSHED
+  #pragma pop_macro("nil")
+#endif
+
 #endif /* _SIGC_SIGNAL_H_ */
diff --git a/sigc++config.h.in b/sigc++config.h.in
index d9627a8..a8f5ac8 100644
--- a/sigc++config.h.in
+++ b/sigc++config.h.in
@@ -47,6 +47,7 @@
 # define SIGC_MSVC_TEMPLATE_SPECIALIZATION_OPERATOR_OVERLOAD 1
 # define SIGC_NEW_DELETE_IN_LIBRARY_ONLY 1 /* To keep ABI compatibility */
 # define SIGC_HAVE_NAMESPACE_STD 1
+# define SIGC_PRAGMA_PUSH_POP_MACRO 1
 
 #if (_MSC_VER < 1900) && !defined (noexcept)
 #define _ALLOW_KEYWORD_MACROS 1
@@ -73,6 +74,9 @@
    static member field. */
 # undef SIGC_SELF_REFERENCE_IN_MEMBER_INITIALIZATION
 
+/* does the C++ preprocessor support pragma push_macro() and pop_macro(). */
+# undef SIGC_PRAGMA_PUSH_POP_MACRO
+
 #endif /* !SIGC_MSC */
 
 #ifdef SIGC_HAVE_NAMESPACE_STD


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]