From 5d87f60f894764bd435086e311605884638d2384 Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Tue, 15 Nov 2022 17:08:01 -0500 Subject: [PATCH] [libc++] Only include_next C library headers when they exist Some platforms don't provide all C library headers. In practice, libc++ only requires a few C library headers to exist, and only a few functions on those headers. Missing functions that libc++ doesn't need for its own implementation are handled properly by the using_if_exists attribute, however a missing header is currently a hard error when we try to do #include_next. This patch should make libc++ more flexible on platforms that do not provide C headers that libc++ doesn't actually require for its own implementation. The only downside is that it may move some errors from the #include_next point to later in the compilation if we actually try to use something that isn't provided, which could be somewhat confusing. However, these errors should be caught by folks trying to port libc++ over to a new platform (when running the libc++ test suite), not by end users. NOTE: This is a reapplicaton of 226409, which was reverted in 674729813 because it broke the build. The issue has now been fixed with https://reviews.llvm.org/D138062. Differential Revision: https://reviews.llvm.org/D136683 --- libcxx/include/complex.h | 12 ++++-------- libcxx/include/ctype.h | 4 +++- libcxx/include/errno.h | 4 +++- libcxx/include/fenv.h | 4 +++- libcxx/include/float.h | 4 +++- libcxx/include/inttypes.h | 4 +++- libcxx/include/limits.h | 6 +++++- libcxx/include/locale.h | 4 +++- libcxx/include/math.h | 4 +++- libcxx/include/setjmp.h | 4 +++- libcxx/include/stdbool.h | 4 +++- libcxx/include/stddef.h | 4 +++- libcxx/include/stdint.h | 4 +++- libcxx/include/stdio.h | 4 +++- libcxx/include/stdlib.h | 4 +++- libcxx/include/string.h | 4 +++- libcxx/include/tgmath.h | 14 ++++++-------- libcxx/include/wchar.h | 4 +++- 18 files changed, 60 insertions(+), 32 deletions(-) diff --git a/libcxx/include/complex.h b/libcxx/include/complex.h index a281466..a3da21c 100644 --- a/libcxx/include/complex.h +++ b/libcxx/include/complex.h @@ -24,13 +24,9 @@ #endif #ifdef __cplusplus - -#include - -#else // __cplusplus - -#include_next - -#endif // __cplusplus +# include +#elif __has_include_next() +# include_next +#endif #endif // _LIBCPP_COMPLEX_H diff --git a/libcxx/include/ctype.h b/libcxx/include/ctype.h index ba09250..728173e 100644 --- a/libcxx/include/ctype.h +++ b/libcxx/include/ctype.h @@ -35,7 +35,9 @@ int toupper(int c); # pragma GCC system_header #endif -#include_next +#if __has_include_next() +# include_next +#endif #ifdef __cplusplus diff --git a/libcxx/include/errno.h b/libcxx/include/errno.h index ea0559f..7b02d2b 100644 --- a/libcxx/include/errno.h +++ b/libcxx/include/errno.h @@ -28,7 +28,9 @@ Macros: # pragma GCC system_header #endif -#include_next +#if __has_include_next() +# include_next +#endif #ifdef __cplusplus diff --git a/libcxx/include/fenv.h b/libcxx/include/fenv.h index a9ba680..15e4156 100644 --- a/libcxx/include/fenv.h +++ b/libcxx/include/fenv.h @@ -56,7 +56,9 @@ int feupdateenv(const fenv_t* envp); # pragma GCC system_header #endif -#include_next +#if __has_include_next() +# include_next +#endif #ifdef __cplusplus diff --git a/libcxx/include/float.h b/libcxx/include/float.h index 6060812..9e5f711 100644 --- a/libcxx/include/float.h +++ b/libcxx/include/float.h @@ -76,7 +76,9 @@ Macros: # pragma GCC system_header #endif -#include_next +#if __has_include_next() +# include_next +#endif #ifdef __cplusplus diff --git a/libcxx/include/inttypes.h b/libcxx/include/inttypes.h index e0fd71f..b755526 100644 --- a/libcxx/include/inttypes.h +++ b/libcxx/include/inttypes.h @@ -248,7 +248,9 @@ uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int # define __STDC_FORMAT_MACROS #endif -#include_next +#if __has_include_next() +# include_next +#endif #ifdef __cplusplus diff --git a/libcxx/include/limits.h b/libcxx/include/limits.h index 3e1e85a..032a909 100644 --- a/libcxx/include/limits.h +++ b/libcxx/include/limits.h @@ -44,7 +44,11 @@ Macros: #endif #ifndef __GNUC__ -#include_next + +# if __has_include_next() +# include_next +# endif + #else // GCC header limits.h recursively includes itself through another header called // syslimits.h for some reason. This setup breaks down if we directly diff --git a/libcxx/include/locale.h b/libcxx/include/locale.h index 17c0a70..3fb8120 100644 --- a/libcxx/include/locale.h +++ b/libcxx/include/locale.h @@ -43,6 +43,8 @@ Functions: # pragma GCC system_header #endif -#include_next +#if __has_include_next() +# include_next +#endif #endif // _LIBCPP_LOCALE_H diff --git a/libcxx/include/math.h b/libcxx/include/math.h index d5a7095..d609430 100644 --- a/libcxx/include/math.h +++ b/libcxx/include/math.h @@ -297,7 +297,9 @@ long double truncl(long double x); # pragma GCC system_header #endif -#include_next +# if __has_include_next() +# include_next +# endif #ifdef __cplusplus diff --git a/libcxx/include/setjmp.h b/libcxx/include/setjmp.h index de4f9ed..f4a2bbc 100644 --- a/libcxx/include/setjmp.h +++ b/libcxx/include/setjmp.h @@ -31,7 +31,9 @@ void longjmp(jmp_buf env, int val); # pragma GCC system_header #endif -#include_next +#if __has_include_next() +# include_next +#endif #ifdef __cplusplus diff --git a/libcxx/include/stdbool.h b/libcxx/include/stdbool.h index 0bc1aa8..5bba005 100644 --- a/libcxx/include/stdbool.h +++ b/libcxx/include/stdbool.h @@ -24,7 +24,9 @@ Macros: # pragma GCC system_header #endif -#include_next +#if __has_include_next() +# include_next +#endif #ifdef __cplusplus #undef bool diff --git a/libcxx/include/stddef.h b/libcxx/include/stddef.h index 19e344f..f1725db 100644 --- a/libcxx/include/stddef.h +++ b/libcxx/include/stddef.h @@ -42,7 +42,9 @@ Types: # pragma GCC system_header #endif -#include_next +# if __has_include_next() +# include_next +# endif #ifdef __cplusplus typedef decltype(nullptr) nullptr_t; diff --git a/libcxx/include/stdint.h b/libcxx/include/stdint.h index ee71f62..fa7b011 100644 --- a/libcxx/include/stdint.h +++ b/libcxx/include/stdint.h @@ -120,6 +120,8 @@ Macros: # define __STDC_CONSTANT_MACROS #endif -#include_next +#if __has_include_next() +# include_next +#endif #endif // _LIBCPP_STDINT_H diff --git a/libcxx/include/stdio.h b/libcxx/include/stdio.h index ad1b4c0..cea43aa 100644 --- a/libcxx/include/stdio.h +++ b/libcxx/include/stdio.h @@ -104,7 +104,9 @@ void perror(const char* s); # pragma GCC system_header #endif -#include_next +# if __has_include_next() +# include_next +# endif #ifdef __cplusplus diff --git a/libcxx/include/stdlib.h b/libcxx/include/stdlib.h index e4dce9c..64581b6 100644 --- a/libcxx/include/stdlib.h +++ b/libcxx/include/stdlib.h @@ -90,7 +90,9 @@ void *aligned_alloc(size_t alignment, size_t size); // C11 # pragma GCC system_header #endif -#include_next +# if __has_include_next() +# include_next +# endif #ifdef __cplusplus extern "C++" { diff --git a/libcxx/include/string.h b/libcxx/include/string.h index 082c632..627cbae 100644 --- a/libcxx/include/string.h +++ b/libcxx/include/string.h @@ -57,7 +57,9 @@ size_t strlen(const char* s); # pragma GCC system_header #endif -#include_next +#if __has_include_next() +# include_next +#endif // MSVCRT, GNU libc and its derivates may already have the correct prototype in // . This macro can be defined by users if their C library provides diff --git a/libcxx/include/tgmath.h b/libcxx/include/tgmath.h index c650917..e6f0a4a 100644 --- a/libcxx/include/tgmath.h +++ b/libcxx/include/tgmath.h @@ -24,13 +24,11 @@ #endif #ifdef __cplusplus - -#include - -#else // __cplusplus - -#include_next - -#endif // __cplusplus +# include +#else +# if __has_include_next() +# include_next +# endif +#endif #endif // _LIBCPP_TGMATH_H diff --git a/libcxx/include/wchar.h b/libcxx/include/wchar.h index 0fba53b..c684508 100644 --- a/libcxx/include/wchar.h +++ b/libcxx/include/wchar.h @@ -120,7 +120,9 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len, #define __CORRECT_ISO_CPP_WCHAR_H_PROTO #endif -#include_next +# if __has_include_next() +# include_next +# endif // Determine whether we have const-correct overloads for wcschr and friends. #if defined(_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_) -- 2.7.4