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