c++defs.h 11 KB

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