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