/ c++defs.h
c++defs.h
  1  /* C++ compatible function declaration macros.
  2     Copyright (C) 2010-2011 Free Software Foundation, Inc.
  3  
  4     This program is free software: you can redistribute it and/or modify it
  5     under the terms of the GNU General Public License as published
  6     by the Free Software Foundation; either version 3 of the License, or
  7     (at your option) any later version.
  8  
  9     This program is distributed in the hope that it will be useful,
 10     but WITHOUT ANY WARRANTY; without even the implied warranty of
 11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 12     General Public License for more details.
 13  
 14     You should have received a copy of the GNU General Public License
 15     along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 16  
 17  #ifndef _GL_CXXDEFS_H
 18  #define _GL_CXXDEFS_H
 19  
 20  /* The three most frequent use cases of these macros are:
 21  
 22     * For providing a substitute for a function that is missing on some
 23       platforms, but is declared and works fine on the platforms on which
 24       it exists:
 25  
 26         #if @GNULIB_FOO@
 27         # if !@HAVE_FOO@
 28         _GL_FUNCDECL_SYS (foo, ...);
 29         # endif
 30         _GL_CXXALIAS_SYS (foo, ...);
 31         _GL_CXXALIASWARN (foo);
 32         #elif defined GNULIB_POSIXCHECK
 33         ...
 34         #endif
 35  
 36     * For providing a replacement for a function that exists on all platforms,
 37       but is broken/insufficient and needs to be replaced on some platforms:
 38  
 39         #if @GNULIB_FOO@
 40         # if @REPLACE_FOO@
 41         #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 42         #   undef foo
 43         #   define foo rpl_foo
 44         #  endif
 45         _GL_FUNCDECL_RPL (foo, ...);
 46         _GL_CXXALIAS_RPL (foo, ...);
 47         # else
 48         _GL_CXXALIAS_SYS (foo, ...);
 49         # endif
 50         _GL_CXXALIASWARN (foo);
 51         #elif defined GNULIB_POSIXCHECK
 52         ...
 53         #endif
 54  
 55     * For providing a replacement for a function that exists on some platforms
 56       but is broken/insufficient and needs to be replaced on some of them and
 57       is additionally either missing or undeclared on some other platforms:
 58  
 59         #if @GNULIB_FOO@
 60         # if @REPLACE_FOO@
 61         #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
 62         #   undef foo
 63         #   define foo rpl_foo
 64         #  endif
 65         _GL_FUNCDECL_RPL (foo, ...);
 66         _GL_CXXALIAS_RPL (foo, ...);
 67         # else
 68         #  if !@HAVE_FOO@   or   if !@HAVE_DECL_FOO@
 69         _GL_FUNCDECL_SYS (foo, ...);
 70         #  endif
 71         _GL_CXXALIAS_SYS (foo, ...);
 72         # endif
 73         _GL_CXXALIASWARN (foo);
 74         #elif defined GNULIB_POSIXCHECK
 75         ...
 76         #endif
 77  */
 78  
 79  /* _GL_EXTERN_C declaration;
 80     performs the declaration with C linkage.  */
 81  #if defined __cplusplus
 82  # define _GL_EXTERN_C extern "C"
 83  #else
 84  # define _GL_EXTERN_C extern
 85  #endif
 86  
 87  /* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);
 88     declares a replacement function, named rpl_func, with the given prototype,
 89     consisting of return type, parameters, and attributes.
 90     Example:
 91       _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
 92                                    _GL_ARG_NONNULL ((1)));
 93   */
 94  #define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \
 95    _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)
 96  #define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \
 97    _GL_EXTERN_C rettype rpl_func parameters_and_attributes
 98  
 99  /* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);
100     declares the system function, named func, with the given prototype,
101     consisting of return type, parameters, and attributes.
102     Example:
103       _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)
104                                    _GL_ARG_NONNULL ((1)));
105   */
106  #define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \
107    _GL_EXTERN_C rettype func parameters_and_attributes
108  
109  /* _GL_CXXALIAS_RPL (func, rettype, parameters);
110     declares a C++ alias called GNULIB_NAMESPACE::func
111     that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
112     Example:
113       _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
114   */
115  #define _GL_CXXALIAS_RPL(func,rettype,parameters) \
116    _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
117  #if defined __cplusplus && defined GNULIB_NAMESPACE
118  # define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
119      namespace GNULIB_NAMESPACE                                \
120      {                                                         \
121        rettype (*const func) parameters = ::rpl_func;          \
122      }                                                         \
123      _GL_EXTERN_C int _gl_cxxalias_dummy
124  #else
125  # define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
126      _GL_EXTERN_C int _gl_cxxalias_dummy
127  #endif
128  
129  /* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);
130     is like  _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);
131     except that the C function rpl_func may have a slightly different
132     declaration.  A cast is used to silence the "invalid conversion" error
133     that would otherwise occur.  */
134  #if defined __cplusplus && defined GNULIB_NAMESPACE
135  # define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
136      namespace GNULIB_NAMESPACE                                     \
137      {                                                              \
138        rettype (*const func) parameters =                           \
139          reinterpret_cast<rettype(*)parameters>(::rpl_func);        \
140      }                                                              \
141      _GL_EXTERN_C int _gl_cxxalias_dummy
142  #else
143  # define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
144      _GL_EXTERN_C int _gl_cxxalias_dummy
145  #endif
146  
147  /* _GL_CXXALIAS_SYS (func, rettype, parameters);
148     declares a C++ alias called GNULIB_NAMESPACE::func
149     that redirects to the system provided function func, if GNULIB_NAMESPACE
150     is defined.
151     Example:
152       _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
153   */
154  #if defined __cplusplus && defined GNULIB_NAMESPACE
155    /* If we were to write
156         rettype (*const func) parameters = ::func;
157       like above in _GL_CXXALIAS_RPL_1, the compiler could optimize calls
158       better (remove an indirection through a 'static' pointer variable),
159       but then the _GL_CXXALIASWARN macro below would cause a warning not only
160       for uses of ::func but also for uses of GNULIB_NAMESPACE::func.  */
161  # define _GL_CXXALIAS_SYS(func,rettype,parameters) \
162      namespace GNULIB_NAMESPACE                     \
163      {                                              \
164        static rettype (*func) parameters = ::func;  \
165      }                                              \
166      _GL_EXTERN_C int _gl_cxxalias_dummy
167  #else
168  # define _GL_CXXALIAS_SYS(func,rettype,parameters) \
169      _GL_EXTERN_C int _gl_cxxalias_dummy
170  #endif
171  
172  /* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);
173     is like  _GL_CXXALIAS_SYS (func, rettype, parameters);
174     except that the C function func may have a slightly different declaration.
175     A cast is used to silence the "invalid conversion" error that would
176     otherwise occur.  */
177  #if defined __cplusplus && defined GNULIB_NAMESPACE
178  # define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
179      namespace GNULIB_NAMESPACE                          \
180      {                                                   \
181        static rettype (*func) parameters =               \
182          reinterpret_cast<rettype(*)parameters>(::func); \
183      }                                                   \
184      _GL_EXTERN_C int _gl_cxxalias_dummy
185  #else
186  # define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
187      _GL_EXTERN_C int _gl_cxxalias_dummy
188  #endif
189  
190  /* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);
191     is like  _GL_CXXALIAS_SYS (func, rettype, parameters);
192     except that the C function is picked among a set of overloaded functions,
193     namely the one with rettype2 and parameters2.  Two consecutive casts
194     are used to silence the "cannot find a match" and "invalid conversion"
195     errors that would otherwise occur.  */
196  #if defined __cplusplus && defined GNULIB_NAMESPACE
197    /* The outer cast must be a reinterpret_cast.
198       The inner cast: When the function is defined as a set of overloaded
199       functions, it works as a static_cast<>, choosing the designated variant.
200       When the function is defined as a single variant, it works as a
201       reinterpret_cast<>. The parenthesized cast syntax works both ways.  */
202  # define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
203      namespace GNULIB_NAMESPACE                                                \
204      {                                                                         \
205        static rettype (*func) parameters =                                     \
206          reinterpret_cast<rettype(*)parameters>(                               \
207            (rettype2(*)parameters2)(::func));                                  \
208      }                                                                         \
209      _GL_EXTERN_C int _gl_cxxalias_dummy
210  #else
211  # define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
212      _GL_EXTERN_C int _gl_cxxalias_dummy
213  #endif
214  
215  /* _GL_CXXALIASWARN (func);
216     causes a warning to be emitted when ::func is used but not when
217     GNULIB_NAMESPACE::func is used.  func must be defined without overloaded
218     variants.  */
219  #if defined __cplusplus && defined GNULIB_NAMESPACE
220  # define _GL_CXXALIASWARN(func) \
221     _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)
222  # define _GL_CXXALIASWARN_1(func,namespace) \
223     _GL_CXXALIASWARN_2 (func, namespace)
224  /* To work around GCC bug <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
225     we enable the warning only when not optimizing.  */
226  # if !__OPTIMIZE__
227  #  define _GL_CXXALIASWARN_2(func,namespace) \
228      _GL_WARN_ON_USE (func, \
229                       "The symbol ::" #func " refers to the system function. " \
230                       "Use " #namespace "::" #func " instead.")
231  # elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
232  #  define _GL_CXXALIASWARN_2(func,namespace) \
233       extern __typeof__ (func) func
234  # else
235  #  define _GL_CXXALIASWARN_2(func,namespace) \
236       _GL_EXTERN_C int _gl_cxxalias_dummy
237  # endif
238  #else
239  # define _GL_CXXALIASWARN(func) \
240      _GL_EXTERN_C int _gl_cxxalias_dummy
241  #endif
242  
243  /* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);
244     causes a warning to be emitted when the given overloaded variant of ::func
245     is used but not when GNULIB_NAMESPACE::func is used.  */
246  #if defined __cplusplus && defined GNULIB_NAMESPACE
247  # define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
248     _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \
249                          GNULIB_NAMESPACE)
250  # define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \
251     _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)
252  /* To work around GCC bug <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
253     we enable the warning only when not optimizing.  */
254  # if !__OPTIMIZE__
255  #  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
256      _GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \
257                           "The symbol ::" #func " refers to the system function. " \
258                           "Use " #namespace "::" #func " instead.")
259  # elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
260  #  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
261       extern __typeof__ (func) func
262  # else
263  #  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
264       _GL_EXTERN_C int _gl_cxxalias_dummy
265  # endif
266  #else
267  # define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
268      _GL_EXTERN_C int _gl_cxxalias_dummy
269  #endif
270  
271  #endif /* _GL_CXXDEFS_H */