1 /* C++ compatible function declaration macros. 2 Copyright (C) 2010-2012 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 */ 272