1*4ce1b016SDaniel Fojt /* C++ compatible function declaration macros. 2*4ce1b016SDaniel Fojt Copyright (C) 2010-2020 Free Software Foundation, Inc. 3*4ce1b016SDaniel Fojt 4*4ce1b016SDaniel Fojt This program is free software: you can redistribute it and/or modify it 5*4ce1b016SDaniel Fojt under the terms of the GNU General Public License as published 6*4ce1b016SDaniel Fojt by the Free Software Foundation; either version 3 of the License, or 7*4ce1b016SDaniel Fojt (at your option) any later version. 8*4ce1b016SDaniel Fojt 9*4ce1b016SDaniel Fojt This program is distributed in the hope that it will be useful, 10*4ce1b016SDaniel Fojt but WITHOUT ANY WARRANTY; without even the implied warranty of 11*4ce1b016SDaniel Fojt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12*4ce1b016SDaniel Fojt General Public License for more details. 13*4ce1b016SDaniel Fojt 14*4ce1b016SDaniel Fojt You should have received a copy of the GNU General Public License 15*4ce1b016SDaniel Fojt along with this program. If not, see <https://www.gnu.org/licenses/>. */ 16*4ce1b016SDaniel Fojt 1756a835a5SJohn Marino #ifndef _GL_CXXDEFS_H 1856a835a5SJohn Marino #define _GL_CXXDEFS_H 1956a835a5SJohn Marino 20*4ce1b016SDaniel Fojt /* Begin/end the GNULIB_NAMESPACE namespace. */ 21*4ce1b016SDaniel Fojt #if defined __cplusplus && defined GNULIB_NAMESPACE 22*4ce1b016SDaniel Fojt # define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE { 23*4ce1b016SDaniel Fojt # define _GL_END_NAMESPACE } 24*4ce1b016SDaniel Fojt #else 25*4ce1b016SDaniel Fojt # define _GL_BEGIN_NAMESPACE 26*4ce1b016SDaniel Fojt # define _GL_END_NAMESPACE 27*4ce1b016SDaniel Fojt #endif 28*4ce1b016SDaniel Fojt 2956a835a5SJohn Marino /* The three most frequent use cases of these macros are: 3056a835a5SJohn Marino 3156a835a5SJohn Marino * For providing a substitute for a function that is missing on some 3256a835a5SJohn Marino platforms, but is declared and works fine on the platforms on which 3356a835a5SJohn Marino it exists: 3456a835a5SJohn Marino 3556a835a5SJohn Marino #if @GNULIB_FOO@ 3656a835a5SJohn Marino # if !@HAVE_FOO@ 3756a835a5SJohn Marino _GL_FUNCDECL_SYS (foo, ...); 3856a835a5SJohn Marino # endif 3956a835a5SJohn Marino _GL_CXXALIAS_SYS (foo, ...); 4056a835a5SJohn Marino _GL_CXXALIASWARN (foo); 4156a835a5SJohn Marino #elif defined GNULIB_POSIXCHECK 4256a835a5SJohn Marino ... 4356a835a5SJohn Marino #endif 4456a835a5SJohn Marino 4556a835a5SJohn Marino * For providing a replacement for a function that exists on all platforms, 4656a835a5SJohn Marino but is broken/insufficient and needs to be replaced on some platforms: 4756a835a5SJohn Marino 4856a835a5SJohn Marino #if @GNULIB_FOO@ 4956a835a5SJohn Marino # if @REPLACE_FOO@ 5056a835a5SJohn Marino # if !(defined __cplusplus && defined GNULIB_NAMESPACE) 5156a835a5SJohn Marino # undef foo 5256a835a5SJohn Marino # define foo rpl_foo 5356a835a5SJohn Marino # endif 5456a835a5SJohn Marino _GL_FUNCDECL_RPL (foo, ...); 5556a835a5SJohn Marino _GL_CXXALIAS_RPL (foo, ...); 5656a835a5SJohn Marino # else 5756a835a5SJohn Marino _GL_CXXALIAS_SYS (foo, ...); 5856a835a5SJohn Marino # endif 5956a835a5SJohn Marino _GL_CXXALIASWARN (foo); 6056a835a5SJohn Marino #elif defined GNULIB_POSIXCHECK 6156a835a5SJohn Marino ... 6256a835a5SJohn Marino #endif 6356a835a5SJohn Marino 6456a835a5SJohn Marino * For providing a replacement for a function that exists on some platforms 6556a835a5SJohn Marino but is broken/insufficient and needs to be replaced on some of them and 6656a835a5SJohn Marino is additionally either missing or undeclared on some other platforms: 6756a835a5SJohn Marino 6856a835a5SJohn Marino #if @GNULIB_FOO@ 6956a835a5SJohn Marino # if @REPLACE_FOO@ 7056a835a5SJohn Marino # if !(defined __cplusplus && defined GNULIB_NAMESPACE) 7156a835a5SJohn Marino # undef foo 7256a835a5SJohn Marino # define foo rpl_foo 7356a835a5SJohn Marino # endif 7456a835a5SJohn Marino _GL_FUNCDECL_RPL (foo, ...); 7556a835a5SJohn Marino _GL_CXXALIAS_RPL (foo, ...); 7656a835a5SJohn Marino # else 7756a835a5SJohn Marino # if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@ 7856a835a5SJohn Marino _GL_FUNCDECL_SYS (foo, ...); 7956a835a5SJohn Marino # endif 8056a835a5SJohn Marino _GL_CXXALIAS_SYS (foo, ...); 8156a835a5SJohn Marino # endif 8256a835a5SJohn Marino _GL_CXXALIASWARN (foo); 8356a835a5SJohn Marino #elif defined GNULIB_POSIXCHECK 8456a835a5SJohn Marino ... 8556a835a5SJohn Marino #endif 8656a835a5SJohn Marino */ 8756a835a5SJohn Marino 8856a835a5SJohn Marino /* _GL_EXTERN_C declaration; 8956a835a5SJohn Marino performs the declaration with C linkage. */ 9056a835a5SJohn Marino #if defined __cplusplus 9156a835a5SJohn Marino # define _GL_EXTERN_C extern "C" 9256a835a5SJohn Marino #else 9356a835a5SJohn Marino # define _GL_EXTERN_C extern 9456a835a5SJohn Marino #endif 9556a835a5SJohn Marino 9656a835a5SJohn Marino /* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes); 9756a835a5SJohn Marino declares a replacement function, named rpl_func, with the given prototype, 9856a835a5SJohn Marino consisting of return type, parameters, and attributes. 9956a835a5SJohn Marino Example: 10056a835a5SJohn Marino _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...) 10156a835a5SJohn Marino _GL_ARG_NONNULL ((1))); 10256a835a5SJohn Marino */ 10356a835a5SJohn Marino #define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \ 10456a835a5SJohn Marino _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes) 10556a835a5SJohn Marino #define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \ 10656a835a5SJohn Marino _GL_EXTERN_C rettype rpl_func parameters_and_attributes 10756a835a5SJohn Marino 10856a835a5SJohn Marino /* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes); 10956a835a5SJohn Marino declares the system function, named func, with the given prototype, 11056a835a5SJohn Marino consisting of return type, parameters, and attributes. 11156a835a5SJohn Marino Example: 11256a835a5SJohn Marino _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...) 11356a835a5SJohn Marino _GL_ARG_NONNULL ((1))); 11456a835a5SJohn Marino */ 11556a835a5SJohn Marino #define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \ 11656a835a5SJohn Marino _GL_EXTERN_C rettype func parameters_and_attributes 11756a835a5SJohn Marino 11856a835a5SJohn Marino /* _GL_CXXALIAS_RPL (func, rettype, parameters); 11956a835a5SJohn Marino declares a C++ alias called GNULIB_NAMESPACE::func 12056a835a5SJohn Marino that redirects to rpl_func, if GNULIB_NAMESPACE is defined. 12156a835a5SJohn Marino Example: 12256a835a5SJohn Marino _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...)); 123*4ce1b016SDaniel Fojt 124*4ce1b016SDaniel Fojt Wrapping rpl_func in an object with an inline conversion operator 125*4ce1b016SDaniel Fojt avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is 126*4ce1b016SDaniel Fojt actually used in the program. */ 12756a835a5SJohn Marino #define _GL_CXXALIAS_RPL(func,rettype,parameters) \ 12856a835a5SJohn Marino _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters) 12956a835a5SJohn Marino #if defined __cplusplus && defined GNULIB_NAMESPACE 13056a835a5SJohn Marino # define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ 13156a835a5SJohn Marino namespace GNULIB_NAMESPACE \ 13256a835a5SJohn Marino { \ 133*4ce1b016SDaniel Fojt static const struct _gl_ ## func ## _wrapper \ 134*4ce1b016SDaniel Fojt { \ 135*4ce1b016SDaniel Fojt typedef rettype (*type) parameters; \ 136*4ce1b016SDaniel Fojt \ 137*4ce1b016SDaniel Fojt inline operator type () const \ 138*4ce1b016SDaniel Fojt { \ 139*4ce1b016SDaniel Fojt return ::rpl_func; \ 140*4ce1b016SDaniel Fojt } \ 141*4ce1b016SDaniel Fojt } func = {}; \ 14256a835a5SJohn Marino } \ 14356a835a5SJohn Marino _GL_EXTERN_C int _gl_cxxalias_dummy 14456a835a5SJohn Marino #else 14556a835a5SJohn Marino # define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \ 14656a835a5SJohn Marino _GL_EXTERN_C int _gl_cxxalias_dummy 14756a835a5SJohn Marino #endif 14856a835a5SJohn Marino 14956a835a5SJohn Marino /* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters); 15056a835a5SJohn Marino is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters); 15156a835a5SJohn Marino except that the C function rpl_func may have a slightly different 15256a835a5SJohn Marino declaration. A cast is used to silence the "invalid conversion" error 15356a835a5SJohn Marino that would otherwise occur. */ 15456a835a5SJohn Marino #if defined __cplusplus && defined GNULIB_NAMESPACE 15556a835a5SJohn Marino # define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ 15656a835a5SJohn Marino namespace GNULIB_NAMESPACE \ 15756a835a5SJohn Marino { \ 158*4ce1b016SDaniel Fojt static const struct _gl_ ## func ## _wrapper \ 159*4ce1b016SDaniel Fojt { \ 160*4ce1b016SDaniel Fojt typedef rettype (*type) parameters; \ 161*4ce1b016SDaniel Fojt \ 162*4ce1b016SDaniel Fojt inline operator type () const \ 163*4ce1b016SDaniel Fojt { \ 164*4ce1b016SDaniel Fojt return reinterpret_cast<type>(::rpl_func); \ 165*4ce1b016SDaniel Fojt } \ 166*4ce1b016SDaniel Fojt } func = {}; \ 16756a835a5SJohn Marino } \ 16856a835a5SJohn Marino _GL_EXTERN_C int _gl_cxxalias_dummy 16956a835a5SJohn Marino #else 17056a835a5SJohn Marino # define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \ 17156a835a5SJohn Marino _GL_EXTERN_C int _gl_cxxalias_dummy 17256a835a5SJohn Marino #endif 17356a835a5SJohn Marino 17456a835a5SJohn Marino /* _GL_CXXALIAS_SYS (func, rettype, parameters); 17556a835a5SJohn Marino declares a C++ alias called GNULIB_NAMESPACE::func 17656a835a5SJohn Marino that redirects to the system provided function func, if GNULIB_NAMESPACE 17756a835a5SJohn Marino is defined. 17856a835a5SJohn Marino Example: 17956a835a5SJohn Marino _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...)); 180*4ce1b016SDaniel Fojt 181*4ce1b016SDaniel Fojt Wrapping func in an object with an inline conversion operator 182*4ce1b016SDaniel Fojt avoids a reference to func unless GNULIB_NAMESPACE::func is 183*4ce1b016SDaniel Fojt actually used in the program. */ 18456a835a5SJohn Marino #if defined __cplusplus && defined GNULIB_NAMESPACE 18556a835a5SJohn Marino # define _GL_CXXALIAS_SYS(func,rettype,parameters) \ 18656a835a5SJohn Marino namespace GNULIB_NAMESPACE \ 18756a835a5SJohn Marino { \ 188*4ce1b016SDaniel Fojt static const struct _gl_ ## func ## _wrapper \ 189*4ce1b016SDaniel Fojt { \ 190*4ce1b016SDaniel Fojt typedef rettype (*type) parameters; \ 191*4ce1b016SDaniel Fojt \ 192*4ce1b016SDaniel Fojt inline operator type () const \ 193*4ce1b016SDaniel Fojt { \ 194*4ce1b016SDaniel Fojt return ::func; \ 195*4ce1b016SDaniel Fojt } \ 196*4ce1b016SDaniel Fojt } func = {}; \ 19756a835a5SJohn Marino } \ 19856a835a5SJohn Marino _GL_EXTERN_C int _gl_cxxalias_dummy 19956a835a5SJohn Marino #else 20056a835a5SJohn Marino # define _GL_CXXALIAS_SYS(func,rettype,parameters) \ 20156a835a5SJohn Marino _GL_EXTERN_C int _gl_cxxalias_dummy 20256a835a5SJohn Marino #endif 20356a835a5SJohn Marino 20456a835a5SJohn Marino /* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters); 20556a835a5SJohn Marino is like _GL_CXXALIAS_SYS (func, rettype, parameters); 20656a835a5SJohn Marino except that the C function func may have a slightly different declaration. 20756a835a5SJohn Marino A cast is used to silence the "invalid conversion" error that would 20856a835a5SJohn Marino otherwise occur. */ 20956a835a5SJohn Marino #if defined __cplusplus && defined GNULIB_NAMESPACE 21056a835a5SJohn Marino # define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ 21156a835a5SJohn Marino namespace GNULIB_NAMESPACE \ 21256a835a5SJohn Marino { \ 213*4ce1b016SDaniel Fojt static const struct _gl_ ## func ## _wrapper \ 214*4ce1b016SDaniel Fojt { \ 215*4ce1b016SDaniel Fojt typedef rettype (*type) parameters; \ 216*4ce1b016SDaniel Fojt \ 217*4ce1b016SDaniel Fojt inline operator type () const \ 218*4ce1b016SDaniel Fojt { \ 219*4ce1b016SDaniel Fojt return reinterpret_cast<type>(::func); \ 220*4ce1b016SDaniel Fojt } \ 221*4ce1b016SDaniel Fojt } func = {}; \ 22256a835a5SJohn Marino } \ 22356a835a5SJohn Marino _GL_EXTERN_C int _gl_cxxalias_dummy 22456a835a5SJohn Marino #else 22556a835a5SJohn Marino # define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \ 22656a835a5SJohn Marino _GL_EXTERN_C int _gl_cxxalias_dummy 22756a835a5SJohn Marino #endif 22856a835a5SJohn Marino 22956a835a5SJohn Marino /* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2); 23056a835a5SJohn Marino is like _GL_CXXALIAS_SYS (func, rettype, parameters); 23156a835a5SJohn Marino except that the C function is picked among a set of overloaded functions, 23256a835a5SJohn Marino namely the one with rettype2 and parameters2. Two consecutive casts 23356a835a5SJohn Marino are used to silence the "cannot find a match" and "invalid conversion" 23456a835a5SJohn Marino errors that would otherwise occur. */ 23556a835a5SJohn Marino #if defined __cplusplus && defined GNULIB_NAMESPACE 23656a835a5SJohn Marino /* The outer cast must be a reinterpret_cast. 23756a835a5SJohn Marino The inner cast: When the function is defined as a set of overloaded 23856a835a5SJohn Marino functions, it works as a static_cast<>, choosing the designated variant. 23956a835a5SJohn Marino When the function is defined as a single variant, it works as a 24056a835a5SJohn Marino reinterpret_cast<>. The parenthesized cast syntax works both ways. */ 24156a835a5SJohn Marino # define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ 24256a835a5SJohn Marino namespace GNULIB_NAMESPACE \ 24356a835a5SJohn Marino { \ 244*4ce1b016SDaniel Fojt static const struct _gl_ ## func ## _wrapper \ 245*4ce1b016SDaniel Fojt { \ 246*4ce1b016SDaniel Fojt typedef rettype (*type) parameters; \ 247*4ce1b016SDaniel Fojt \ 248*4ce1b016SDaniel Fojt inline operator type () const \ 249*4ce1b016SDaniel Fojt { \ 250*4ce1b016SDaniel Fojt return reinterpret_cast<type>((rettype2 (*) parameters2)(::func)); \ 251*4ce1b016SDaniel Fojt } \ 252*4ce1b016SDaniel Fojt } func = {}; \ 25356a835a5SJohn Marino } \ 25456a835a5SJohn Marino _GL_EXTERN_C int _gl_cxxalias_dummy 25556a835a5SJohn Marino #else 25656a835a5SJohn Marino # define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \ 25756a835a5SJohn Marino _GL_EXTERN_C int _gl_cxxalias_dummy 25856a835a5SJohn Marino #endif 25956a835a5SJohn Marino 26056a835a5SJohn Marino /* _GL_CXXALIASWARN (func); 26156a835a5SJohn Marino causes a warning to be emitted when ::func is used but not when 26256a835a5SJohn Marino GNULIB_NAMESPACE::func is used. func must be defined without overloaded 26356a835a5SJohn Marino variants. */ 26456a835a5SJohn Marino #if defined __cplusplus && defined GNULIB_NAMESPACE 26556a835a5SJohn Marino # define _GL_CXXALIASWARN(func) \ 26656a835a5SJohn Marino _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE) 26756a835a5SJohn Marino # define _GL_CXXALIASWARN_1(func,namespace) \ 26856a835a5SJohn Marino _GL_CXXALIASWARN_2 (func, namespace) 269*4ce1b016SDaniel Fojt /* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>, 27056a835a5SJohn Marino we enable the warning only when not optimizing. */ 27156a835a5SJohn Marino # if !__OPTIMIZE__ 27256a835a5SJohn Marino # define _GL_CXXALIASWARN_2(func,namespace) \ 27356a835a5SJohn Marino _GL_WARN_ON_USE (func, \ 27456a835a5SJohn Marino "The symbol ::" #func " refers to the system function. " \ 27556a835a5SJohn Marino "Use " #namespace "::" #func " instead.") 27656a835a5SJohn Marino # elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING 27756a835a5SJohn Marino # define _GL_CXXALIASWARN_2(func,namespace) \ 27856a835a5SJohn Marino extern __typeof__ (func) func 27956a835a5SJohn Marino # else 28056a835a5SJohn Marino # define _GL_CXXALIASWARN_2(func,namespace) \ 28156a835a5SJohn Marino _GL_EXTERN_C int _gl_cxxalias_dummy 28256a835a5SJohn Marino # endif 28356a835a5SJohn Marino #else 28456a835a5SJohn Marino # define _GL_CXXALIASWARN(func) \ 28556a835a5SJohn Marino _GL_EXTERN_C int _gl_cxxalias_dummy 28656a835a5SJohn Marino #endif 28756a835a5SJohn Marino 28856a835a5SJohn Marino /* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes); 28956a835a5SJohn Marino causes a warning to be emitted when the given overloaded variant of ::func 29056a835a5SJohn Marino is used but not when GNULIB_NAMESPACE::func is used. */ 29156a835a5SJohn Marino #if defined __cplusplus && defined GNULIB_NAMESPACE 29256a835a5SJohn Marino # define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ 29356a835a5SJohn Marino _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \ 29456a835a5SJohn Marino GNULIB_NAMESPACE) 29556a835a5SJohn Marino # define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \ 29656a835a5SJohn Marino _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace) 297*4ce1b016SDaniel Fojt /* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>, 29856a835a5SJohn Marino we enable the warning only when not optimizing. */ 29956a835a5SJohn Marino # if !__OPTIMIZE__ 30056a835a5SJohn Marino # define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ 30156a835a5SJohn Marino _GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \ 30256a835a5SJohn Marino "The symbol ::" #func " refers to the system function. " \ 30356a835a5SJohn Marino "Use " #namespace "::" #func " instead.") 30456a835a5SJohn Marino # elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING 30556a835a5SJohn Marino # define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ 30656a835a5SJohn Marino extern __typeof__ (func) func 30756a835a5SJohn Marino # else 30856a835a5SJohn Marino # define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \ 30956a835a5SJohn Marino _GL_EXTERN_C int _gl_cxxalias_dummy 31056a835a5SJohn Marino # endif 31156a835a5SJohn Marino #else 31256a835a5SJohn Marino # define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \ 31356a835a5SJohn Marino _GL_EXTERN_C int _gl_cxxalias_dummy 31456a835a5SJohn Marino #endif 31556a835a5SJohn Marino 31656a835a5SJohn Marino #endif /* _GL_CXXDEFS_H */ 317