bcraig created this revision.
Herald added a subscriber: mgorny.

Visual Studio 2015 and 2017 don't implement include_next, so we'll use a 
combination of a computed include and a CMAKE input to make it work.  Also, 
retrofit all the existing invocations of #include_next that we could hit in a 
hypothetical MSVC build.

This relies on implementation defined behavior in the MSVC preprocessor.
See C11, 6.10.2.4 ("Source file inclusion") for the statement on implementation 
defined vs. undefined.


https://reviews.llvm.org/D32411

Files:
  CMakeLists.txt
  include/__config
  include/__config_site.in
  include/complex.h
  include/cstddef
  include/ctype.h
  include/errno.h
  include/float.h
  include/inttypes.h
  include/limits.h
  include/locale.h
  include/math.h
  include/setjmp.h
  include/stdbool.h
  include/stddef.h
  include/stdint.h
  include/stdio.h
  include/stdlib.h
  include/string.h
  include/wchar.h
  include/wctype.h

Index: include/wctype.h
===================================================================
--- include/wctype.h
+++ include/wctype.h
@@ -51,7 +51,11 @@
 #pragma GCC system_header
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(wctype.h)
+#else
 #include_next <wctype.h>
+#endif
 
 #ifdef __cplusplus
 
Index: include/wchar.h
===================================================================
--- include/wchar.h
+++ include/wchar.h
@@ -14,7 +14,11 @@
 #pragma GCC system_header
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(wchar.h)
+#else
 #include_next <wchar.h>
+#endif
 
 #elif !defined(_LIBCPP_WCHAR_H)
 #define _LIBCPP_WCHAR_H
@@ -116,7 +120,11 @@
 #define __CORRECT_ISO_CPP_WCHAR_H_PROTO
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(wchar.h)
+#else
 #include_next <wchar.h>
+#endif
 
 // Determine whether we have const-correct overloads for wcschr and friends.
 #if defined(_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_)
Index: include/string.h
===================================================================
--- include/string.h
+++ include/string.h
@@ -58,7 +58,11 @@
 #pragma GCC system_header
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(string.h)
+#else
 #include_next <string.h>
+#endif
 
 // MSVCRT, GNU libc and its derivates may already have the correct prototype in
 // <string.h>. This macro can be defined by users if their C library provides
Index: include/stdlib.h
===================================================================
--- include/stdlib.h
+++ include/stdlib.h
@@ -14,7 +14,11 @@
 #pragma GCC system_header
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(stdlib.h)
+#else
 #include_next <stdlib.h>
+#endif
 
 #elif !defined(_LIBCPP_STDLIB_H)
 #define _LIBCPP_STDLIB_H
@@ -91,7 +95,11 @@
 #pragma GCC system_header
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(stdlib.h)
+#else
 #include_next <stdlib.h>
+#endif
 
 #ifdef __cplusplus
 
Index: include/stdio.h
===================================================================
--- include/stdio.h
+++ include/stdio.h
@@ -14,7 +14,11 @@
 #pragma GCC system_header
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(stdio.h)
+#else
 #include_next <stdio.h>
+#endif
 
 #elif !defined(_LIBCPP_STDIO_H)
 #define _LIBCPP_STDIO_H
@@ -105,7 +109,11 @@
 #pragma GCC system_header
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(stdio.h)
+#else
 #include_next <stdio.h>
+#endif
 
 #ifdef __cplusplus
 
Index: include/stdint.h
===================================================================
--- include/stdint.h
+++ include/stdint.h
@@ -116,6 +116,10 @@
 #   define __STDC_CONSTANT_MACROS
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(stdint.h)
+#else
 #include_next <stdint.h>
+#endif
 
 #endif  // _LIBCPP_STDINT_H
Index: include/stddef.h
===================================================================
--- include/stddef.h
+++ include/stddef.h
@@ -15,7 +15,11 @@
 #pragma GCC system_header
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(stddef.h)
+#else
 #include_next <stddef.h>
+#endif
 
 #elif !defined(_LIBCPP_STDDEF_H)
 #define _LIBCPP_STDDEF_H
@@ -43,7 +47,11 @@
 #pragma GCC system_header
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(stddef.h)
+#else
 #include_next <stddef.h>
+#endif
 
 #ifdef __cplusplus
 
Index: include/stdbool.h
===================================================================
--- include/stdbool.h
+++ include/stdbool.h
@@ -26,7 +26,11 @@
 #pragma GCC system_header
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(stdbool.h)
+#else
 #include_next <stdbool.h>
+#endif
 
 #ifdef __cplusplus
 #undef bool
Index: include/setjmp.h
===================================================================
--- include/setjmp.h
+++ include/setjmp.h
@@ -32,7 +32,11 @@
 #pragma GCC system_header
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(setjmp.h)
+#else
 #include_next <setjmp.h>
+#endif
 
 #ifdef __cplusplus
 
Index: include/math.h
===================================================================
--- include/math.h
+++ include/math.h
@@ -298,7 +298,11 @@
 #pragma GCC system_header
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(math.h)
+#else
 #include_next <math.h>
+#endif
 
 #ifdef __cplusplus
 
Index: include/locale.h
===================================================================
--- include/locale.h
+++ include/locale.h
@@ -40,6 +40,10 @@
 #pragma GCC system_header
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(locale.h)
+#else
 #include_next <locale.h>
+#endif
 
 #endif  // _LIBCPP_LOCALE_H
Index: include/limits.h
===================================================================
--- include/limits.h
+++ include/limits.h
@@ -45,7 +45,11 @@
 #endif
 
 #ifndef __GNUC__
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(limits.h)
+#else
 #include_next <limits.h>
+#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
Index: include/inttypes.h
===================================================================
--- include/inttypes.h
+++ include/inttypes.h
@@ -244,7 +244,11 @@
 #   define __STDC_FORMAT_MACROS
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(inttypes.h)
+#else
 #include_next <inttypes.h>
+#endif
 
 #ifdef __cplusplus
 
Index: include/float.h
===================================================================
--- include/float.h
+++ include/float.h
@@ -66,7 +66,11 @@
 #pragma GCC system_header
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(float.h)
+#else
 #include_next <float.h>
+#endif
 
 #ifdef __cplusplus
 
Index: include/errno.h
===================================================================
--- include/errno.h
+++ include/errno.h
@@ -29,7 +29,11 @@
 #pragma GCC system_header
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(errno.h)
+#else
 #include_next <errno.h>
+#endif
 
 #ifdef __cplusplus
 
Index: include/ctype.h
===================================================================
--- include/ctype.h
+++ include/ctype.h
@@ -36,7 +36,11 @@
 #pragma GCC system_header
 #endif
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(ctype.h)
+#else
 #include_next <ctype.h>
+#endif
 
 #ifdef __cplusplus
 
Index: include/cstddef
===================================================================
--- include/cstddef
+++ include/cstddef
@@ -41,7 +41,11 @@
 #endif
 
 // Don't include our own <stddef.h>; we don't want to declare ::nullptr_t.
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(stddef.h)
+#else
 #include_next <stddef.h>
+#endif
 #include <__nullptr>
 
 _LIBCPP_BEGIN_NAMESPACE_STD
Index: include/complex.h
===================================================================
--- include/complex.h
+++ include/complex.h
@@ -30,7 +30,11 @@
 
 #else  // __cplusplus
 
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT)
+#include _LIBCPP_INCLUDE_NEXT(complex.h)
+#else
 #include_next <complex.h>
+#endif
 
 #endif  // __cplusplus
 
Index: include/__config_site.in
===================================================================
--- include/__config_site.in
+++ include/__config_site.in
@@ -23,5 +23,6 @@
 #cmakedefine _LIBCPP_HAS_THREAD_API_EXTERNAL
 #cmakedefine _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL
 #cmakedefine _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS
+#cmakedefine _LIBCPP_INCLUDE_NEXT(header) <@_LIBCPP_INCLUDE_NEXT@/##header>
 
 #endif // _LIBCPP_CONFIG_SITE
Index: include/__config
===================================================================
--- include/__config
+++ include/__config
@@ -440,7 +440,7 @@
 // Allow for build-time disabling of unsigned integer sanitization
 #if !defined(_LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK) && __has_attribute(no_sanitize)
 #define _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK __attribute__((__no_sanitize__("unsigned-integer-overflow")))
-#endif 
+#endif
 
 #elif defined(_LIBCPP_COMPILER_GCC)
 
@@ -1111,6 +1111,14 @@
 # define _LIBCPP_HAS_NO_IS_AGGREGATE
 #endif
 
+#if defined(_LIBCPP_COMPILER_MSVC)
+#  define _LIBCPP_HAS_NO_INCLUDE_NEXT
+#endif
+#if defined(_LIBCPP_HAS_NO_INCLUDE_NEXT) && !defined(_LIBCPP_INCLUDE_NEXT)
+#  error _LIBCPP_HAS_NO_INCLUDE_NEXT requires clients define \
+   LIBCXX_INCLUDE_NEXT in the cmake invocation
+#endif
+
 #endif // __cplusplus
 
 #endif // _LIBCPP_CONFIG
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt
+++ CMakeLists.txt
@@ -589,6 +589,9 @@
 config_define_if(LIBCXX_HAS_EXTERNAL_THREAD_API _LIBCPP_HAS_THREAD_API_EXTERNAL)
 config_define_if(LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY _LIBCPP_HAS_THREAD_LIBRARY_EXTERNAL)
 config_define_if(LIBCXX_HAS_MUSL_LIBC _LIBCPP_HAS_MUSL_LIBC)
+if (LIBCXX_INCLUDE_NEXT)
+  config_define(${LIBCXX_INCLUDE_NEXT} _LIBCPP_INCLUDE_NEXT)
+endif()
 
 # By default libc++ on Windows expects to use a shared library, which requires
 # the headers to use DLL import/export semantics. However when building a
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to