[PATCH] D12747: Implement [depr.c.headers]

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 6 16:13:01 PDT 2015


<stdio.h>: like <stddef.h>, this provides only pieces if __need_FILE or
__need___FILE is defined
<stdlib.h>: likewise, but for __need_malloc_and_calloc
<string.h> and <wctype.h> are straightforward
<wchar.h> is tricky: C libraries that don't implement the right interface
provide non-const-correct functions like "wchar_t *wmemchr(const wchar_t*,
wchar_t, size_t)". We can't fix that, so we don't try.

On Tue, Oct 6, 2015 at 3:57 PM, Richard Smith <richard at metafoo.co.uk> wrote:

> <stddef.h>. This one is tricky:
>
> 1) There's an (undocumented) interface between the C standard library and
> this header, where the macros __need_ptrdiff_t, __need_size_t,
> __need_wchar_t, __need_NULL, __need_wint_t request just a piece of this
> header rather than the whole thing. If we see any of those, just go
> straight to the underlying header.
>
> 2) We probably don't want <stddef.h> to include <cstddef> (for consistency
> with other headers), but <stddef.h> must provide a ::nullptr_t (which we
> don't want <cstddef> to provide). So neither header includes the other.
> Instead, both include <__nullptr> for std::nullptr_t, and we duplicate the
> definition of max_align_t between them, in the case where the compiler's
> <stddef.h> doesn't provide it.
>
> If you prefer, I could make <stddef.h> include <cstddef> to avoid the
> duplication of the max_align_t logic.
>
> This patch depends on patch 02.
>
> On Tue, Oct 6, 2015 at 3:42 PM, Richard Smith <richard at metafoo.co.uk>
> wrote:
>
>> <setjmp.h>, an easy one. We guarantee a setjmp macro exists even if this
>> header is somehow included from C (the C standard allows that, so it's not
>> worth checking for __cplusplus).
>>
>> On Tue, Oct 6, 2015 at 3:36 PM, Richard Smith <richard at metafoo.co.uk>
>> wrote:
>>
>>> Split <math.h> out of <cmath>. This is a big change, but the same
>>> pattern as the prior ones.
>>>
>>> On Tue, Oct 6, 2015 at 3:28 PM, Richard Smith <richard at metafoo.co.uk>
>>> wrote:
>>>
>>>> Likewise for <errno.h>, <float.h>, <inttypes.h>
>>>>
>>>> On Tue, Oct 6, 2015 at 3:20 PM, Richard Smith <richard at metafoo.co.uk>
>>>> wrote:
>>>>
>>>>> Split <ctype.h> header out of <cctype>
>>>>>
>>>>> On Tue, Oct 6, 2015 at 3:07 PM, Richard Smith <richard at metafoo.co.uk>
>>>>> wrote:
>>>>>
>>>>>> Next: factoring the definition of std::nullptr_t out into a separate
>>>>>> file, so that <cstddef> and <stddef.h> can both use it, without <stddef.h>
>>>>>> including <cstddef> and without <cstddef> providing a ::nullptr_t like
>>>>>> <stddef.h> does.
>>>>>>
>>>>>> On Tue, Oct 6, 2015 at 3:02 PM, Eric Fiselier <eric at efcs.ca> wrote:
>>>>>>
>>>>>>> LGTM.
>>>>>>>
>>>>>>> On Tue, Oct 6, 2015 at 3:58 PM, Richard Smith <richard at metafoo.co.uk>
>>>>>>> wrote:
>>>>>>> > On Mon, Oct 5, 2015 at 7:10 PM, Eric Fiselier <eric at efcs.ca>
>>>>>>> wrote:
>>>>>>> >>
>>>>>>> >> EricWF added a comment.
>>>>>>> >>
>>>>>>> >> I think thing change will help us close a number out outstanding
>>>>>>> bugs. I
>>>>>>> >> don't have any fundamental objections to this approach.  However
>>>>>>> the size of
>>>>>>> >> this patch scares me.  I understand the changes are mostly
>>>>>>> mechanical but
>>>>>>> >> their size can hide things. For example has anybody noticed that
>>>>>>> your
>>>>>>> >> internal changes to `<deque>` are in this patch? It would be nice
>>>>>>> to break
>>>>>>> >> this down into more digestible pieces that could be quickly spot
>>>>>>> checked.
>>>>>>> >
>>>>>>> >
>>>>>>> > OK. First such patch is attached. It just removes the
>>>>>>> macro-capturing
>>>>>>> > wrapper functions.
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20151006/5ac94668/attachment-0001.html>
-------------- next part --------------
diff --git include/cstdio include/cstdio
index 61985d6..50fdd34 100644
--- include/cstdio
+++ include/cstdio
@@ -103,16 +103,6 @@ void perror(const char* s);
 #pragma GCC system_header
 #endif
 
-// snprintf
-#if defined(_LIBCPP_MSVCRT)
-#include "support/win32/support.h"
-#endif
-
-#undef getc
-#undef putc
-#undef clearerr
-#undef feof
-#undef ferror
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 using ::FILE;
diff --git include/stdio.h include/stdio.h
new file mode 100644
index 0000000..bebe1fb
--- /dev/null
+++ include/stdio.h
@@ -0,0 +1,121 @@
+// -*- C++ -*-
+//===---------------------------- stdio.h ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__need_FILE) || defined(__need___FILE)
+#include_next <stdio.h>
+
+#elif !defined(_LIBCPP_STDIO_H)
+#define _LIBCPP_STDIO_H
+
+/*
+    stdio.h synopsis
+
+Macros:
+
+    BUFSIZ
+    EOF
+    FILENAME_MAX
+    FOPEN_MAX
+    L_tmpnam
+    NULL
+    SEEK_CUR
+    SEEK_END
+    SEEK_SET
+    TMP_MAX
+    _IOFBF
+    _IOLBF
+    _IONBF
+    stderr
+    stdin
+    stdout
+
+Types:
+
+FILE
+fpos_t
+size_t
+
+int remove(const char* filename);
+int rename(const char* old, const char* new);
+FILE* tmpfile(void);
+char* tmpnam(char* s);
+int fclose(FILE* stream);
+int fflush(FILE* stream);
+FILE* fopen(const char* restrict filename, const char* restrict mode);
+FILE* freopen(const char* restrict filename, const char * restrict mode,
+              FILE * restrict stream);
+void setbuf(FILE* restrict stream, char* restrict buf);
+int setvbuf(FILE* restrict stream, char* restrict buf, int mode, size_t size);
+int fprintf(FILE* restrict stream, const char* restrict format, ...);
+int fscanf(FILE* restrict stream, const char * restrict format, ...);
+int printf(const char* restrict format, ...);
+int scanf(const char* restrict format, ...);
+int snprintf(char* restrict s, size_t n, const char* restrict format, ...);    // C99
+int sprintf(char* restrict s, const char* restrict format, ...);
+int sscanf(const char* restrict s, const char* restrict format, ...);
+int vfprintf(FILE* restrict stream, const char* restrict format, va_list arg);
+int vfscanf(FILE* restrict stream, const char* restrict format, va_list arg);  // C99
+int vprintf(const char* restrict format, va_list arg);
+int vscanf(const char* restrict format, va_list arg);                          // C99
+int vsnprintf(char* restrict s, size_t n, const char* restrict format,         // C99
+              va_list arg);
+int vsprintf(char* restrict s, const char* restrict format, va_list arg);
+int vsscanf(const char* restrict s, const char* restrict format, va_list arg); // C99
+int fgetc(FILE* stream);
+char* fgets(char* restrict s, int n, FILE* restrict stream);
+int fputc(int c, FILE* stream);
+int fputs(const char* restrict s, FILE* restrict stream);
+int getc(FILE* stream);
+int getchar(void);
+char* gets(char* s);  // removed in C++14
+int putc(int c, FILE* stream);
+int putchar(int c);
+int puts(const char* s);
+int ungetc(int c, FILE* stream);
+size_t fread(void* restrict ptr, size_t size, size_t nmemb,
+             FILE* restrict stream);
+size_t fwrite(const void* restrict ptr, size_t size, size_t nmemb,
+              FILE* restrict stream);
+int fgetpos(FILE* restrict stream, fpos_t* restrict pos);
+int fseek(FILE* stream, long offset, int whence);
+int fsetpos(FILE*stream, const fpos_t* pos);
+long ftell(FILE* stream);
+void rewind(FILE* stream);
+void clearerr(FILE* stream);
+int feof(FILE* stream);
+int ferror(FILE* stream);
+void perror(const char* s);
+*/
+
+#include <__config>
+#include_next <stdio.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#ifdef __cplusplus
+
+// snprintf
+#if defined(_LIBCPP_MSVCRT)
+extern "C++" {
+#include "support/win32/support.h"
+}
+#endif
+
+#undef getc
+#undef putc
+#undef clearerr
+#undef feof
+#undef ferror
+
+#endif
+
+#endif  // _LIBCPP_STDIO_H
diff --git test/std/depr/depr.c.headers/stdio_h.pass.cpp test/std/depr/depr.c.headers/stdio_h.pass.cpp
index ba6714d..3c5dd0e 100644
--- test/std/depr/depr.c.headers/stdio_h.pass.cpp
+++ test/std/depr/depr.c.headers/stdio_h.pass.cpp
@@ -13,6 +13,26 @@
 #include <type_traits>
 #include "test_macros.h"
 
+#ifdef getc
+#error getc is defined
+#endif
+
+#ifdef putc
+#error putc is defined
+#endif
+
+#ifdef clearerr
+#error clearerr is defined
+#endif
+
+#ifdef feof
+#error feof is defined
+#endif
+
+#ifdef ferror
+#error ferror is defined
+#endif
+
 #ifndef BUFSIZ
 #error BUFSIZ not defined
 #endif
-------------- next part --------------
diff --git include/cstdlib include/cstdlib
index 55e15c8..10ed231 100644
--- include/cstdlib
+++ include/cstdlib
@@ -84,9 +84,6 @@ void *aligned_alloc(size_t alignment, size_t size);                       // C11
 
 #include <__config>
 #include <stdlib.h>
-#ifdef _LIBCPP_MSVCRT
-#include "support/win32/locale_win32.h"
-#endif // _LIBCPP_MSVCRT
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -131,20 +128,14 @@ using ::getenv;
 using ::system;
 using ::bsearch;
 using ::qsort;
-#undef abs
 using ::abs;
-#undef labs
 using ::labs;
 #ifndef _LIBCPP_HAS_NO_LONG_LONG
-#undef llabs
 using ::llabs;
 #endif // _LIBCPP_HAS_NO_LONG_LONG
-#undef div
 using ::div;
-#undef ldiv
 using ::ldiv;
 #ifndef _LIBCPP_HAS_NO_LONG_LONG
-#undef lldiv
 using ::lldiv;
 #endif // _LIBCPP_HAS_NO_LONG_LONG
 #ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
@@ -162,19 +153,6 @@ using ::quick_exit;
 using ::aligned_alloc;
 #endif
 
-// MSVCRT already has the correct prototype in <stdlib.h> #ifdef __cplusplus
-#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
-inline _LIBCPP_INLINE_VISIBILITY long      abs(     long __x) _NOEXCEPT {return  labs(__x);}
-#ifndef _LIBCPP_HAS_NO_LONG_LONG
-inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT {return llabs(__x);}
-#endif // _LIBCPP_HAS_NO_LONG_LONG
-
-inline _LIBCPP_INLINE_VISIBILITY  ldiv_t div(     long __x,      long __y) _NOEXCEPT {return  ldiv(__x, __y);}
-#ifndef _LIBCPP_HAS_NO_LONG_LONG
-inline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x, long long __y) _NOEXCEPT {return lldiv(__x, __y);}
-#endif // _LIBCPP_HAS_NO_LONG_LONG
-#endif // _LIBCPP_MSVCRT
-
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_CSTDLIB
diff --git include/stdlib.h include/stdlib.h
new file mode 100644
index 0000000..8137398
--- /dev/null
+++ include/stdlib.h
@@ -0,0 +1,122 @@
+// -*- C++ -*-
+//===--------------------------- stdlib.h ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__need_malloc_and_calloc)
+#include_next <stdlib.h>
+
+#elif !defined(_LIBCPP_STDLIB_H)
+#define _LIBCPP_STDLIB_H
+
+/*
+    stdlib.h synopsis
+
+Macros:
+
+    EXIT_FAILURE
+    EXIT_SUCCESS
+    MB_CUR_MAX
+    NULL
+    RAND_MAX
+
+Types:
+
+    size_t
+    div_t
+    ldiv_t
+    lldiv_t                                                               // C99
+
+double    atof (const char* nptr);
+int       atoi (const char* nptr);
+long      atol (const char* nptr);
+long long atoll(const char* nptr);                                        // C99
+double             strtod  (const char* restrict nptr, char** restrict endptr);
+float              strtof  (const char* restrict nptr, char** restrict endptr); // C99
+long double        strtold (const char* restrict nptr, char** restrict endptr); // C99
+long               strtol  (const char* restrict nptr, char** restrict endptr, int base);
+long long          strtoll (const char* restrict nptr, char** restrict endptr, int base); // C99
+unsigned long      strtoul (const char* restrict nptr, char** restrict endptr, int base);
+unsigned long long strtoull(const char* restrict nptr, char** restrict endptr, int base); // C99
+int rand(void);
+void srand(unsigned int seed);
+void* calloc(size_t nmemb, size_t size);
+void free(void* ptr);
+void* malloc(size_t size);
+void* realloc(void* ptr, size_t size);
+void abort(void);
+int atexit(void (*func)(void));
+void exit(int status);
+void _Exit(int status);
+char* getenv(const char* name);
+int system(const char* string);
+void* bsearch(const void* key, const void* base, size_t nmemb, size_t size,
+              int (*compar)(const void *, const void *));
+void qsort(void* base, size_t nmemb, size_t size,
+           int (*compar)(const void *, const void *));
+int         abs(      int j);
+long        abs(     long j);
+long long   abs(long long j);                                             // C++0X
+long       labs(     long j);
+long long llabs(long long j);                                             // C99
+div_t     div(      int numer,       int denom);
+ldiv_t    div(     long numer,      long denom);
+lldiv_t   div(long long numer, long long denom);                          // C++0X
+ldiv_t   ldiv(     long numer,      long denom);
+lldiv_t lldiv(long long numer, long long denom);                          // C99
+int mblen(const char* s, size_t n);
+int mbtowc(wchar_t* restrict pwc, const char* restrict s, size_t n);
+int wctomb(char* s, wchar_t wchar);
+size_t mbstowcs(wchar_t* restrict pwcs, const char* restrict s, size_t n);
+size_t wcstombs(char* restrict s, const wchar_t* restrict pwcs, size_t n);
+int at_quick_exit(void (*func)(void))                                     // C++11
+void quick_exit(int status);                                              // C++11
+void *aligned_alloc(size_t alignment, size_t size);                       // C11
+
+*/
+
+#include <__config>
+#include_next <stdlib.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#ifdef __cplusplus
+extern "C++" {
+
+#ifdef _LIBCPP_MSVCRT
+#include "support/win32/locale_win32.h"
+#endif // _LIBCPP_MSVCRT
+
+#undef abs
+#undef div
+#undef labs
+#undef ldiv
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+#undef llabs
+#undef lldiv
+#endif
+
+// MSVCRT already has the correct prototype in <stdlib.h> if __cplusplus is defined
+#if !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_AIX)
+inline _LIBCPP_INLINE_VISIBILITY long      abs(     long __x) _NOEXCEPT {return  labs(__x);}
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+inline _LIBCPP_INLINE_VISIBILITY long long abs(long long __x) _NOEXCEPT {return llabs(__x);}
+#endif // _LIBCPP_HAS_NO_LONG_LONG
+
+inline _LIBCPP_INLINE_VISIBILITY  ldiv_t div(     long __x,      long __y) _NOEXCEPT {return  ldiv(__x, __y);}
+#ifndef _LIBCPP_HAS_NO_LONG_LONG
+inline _LIBCPP_INLINE_VISIBILITY lldiv_t div(long long __x, long long __y) _NOEXCEPT {return lldiv(__x, __y);}
+#endif // _LIBCPP_HAS_NO_LONG_LONG
+#endif // _LIBCPP_MSVCRT / __sun__ / _AIX
+
+}  // extern "C++"
+#endif  // __cplusplus
+
+#endif  // _LIBCPP_STDLIB_H
diff --git test/std/depr/depr.c.headers/stdlib_h.pass.cpp test/std/depr/depr.c.headers/stdlib_h.pass.cpp
index 046ec94..a687098 100644
--- test/std/depr/depr.c.headers/stdlib_h.pass.cpp
+++ test/std/depr/depr.c.headers/stdlib_h.pass.cpp
@@ -12,10 +12,28 @@
 #include <stdlib.h>
 #include <type_traits>
 
-// As of 1/10/2015 clang emits a -Wnonnull warnings even if the warning occurs
-// in an unevaluated context. For this reason we manually suppress the warning.
-#if defined(__clang__)
-#pragma clang diagnostic ignored "-Wnonnull"
+#ifdef abs
+#error abs is defined
+#endif
+
+#ifdef labs
+#error labs is defined
+#endif
+
+#ifdef llabs
+#error llabs is defined
+#endif
+
+#ifdef div
+#error div is defined
+#endif
+
+#ifdef ldiv
+#error ldiv is defined
+#endif
+
+#ifdef lldiv
+#error lldiv is defined
 #endif
 
 #ifndef EXIT_FAILURE
-------------- next part --------------
diff --git include/cstring include/cstring
index d60b992..d550695 100644
--- include/cstring
+++ include/cstring
@@ -78,30 +78,13 @@ using ::strcmp;
 using ::strncmp;
 using ::strcoll;
 using ::strxfrm;
-
 using ::memchr;
-
 using ::strchr;
-
 using ::strcspn;
-
 using ::strpbrk;
-
 using ::strrchr;
-
 using ::strspn;
-
 using ::strstr;
-
-// MSVCRT, GNU libc and its derivates already have the correct prototype in <string.h> #ifdef __cplusplus
-#if !defined(__GLIBC__) && !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_STRING_H_CPLUSPLUS_98_CONFORMANCE_)
-inline _LIBCPP_INLINE_VISIBILITY       char* strchr(      char* __s, int __c) {return ::strchr(__s, __c);}
-inline _LIBCPP_INLINE_VISIBILITY       char* strpbrk(      char* __s1, const char* __s2) {return ::strpbrk(__s1, __s2);}
-inline _LIBCPP_INLINE_VISIBILITY       char* strrchr(      char* __s, int __c) {return ::strrchr(__s, __c);}
-inline _LIBCPP_INLINE_VISIBILITY       void* memchr(      void* __s, int __c, size_t __n) {return ::memchr(__s, __c, __n);}
-inline _LIBCPP_INLINE_VISIBILITY       char* strstr(      char* __s1, const char* __s2) {return ::strstr(__s1, __s2);}
-#endif
-
 #ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS
 using ::strtok;
 #endif
diff --git include/string.h include/string.h
new file mode 100644
index 0000000..f2f0aeb
--- /dev/null
+++ include/string.h
@@ -0,0 +1,77 @@
+// -*- C++ -*-
+//===--------------------------- string.h ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_STRING_H
+#define _LIBCPP_STRING_H
+
+/*
+    string.h synopsis
+
+Macros:
+
+    NULL
+
+Types:
+
+    size_t
+
+void* memcpy(void* restrict s1, const void* restrict s2, size_t n);
+void* memmove(void* s1, const void* s2, size_t n);
+char* strcpy (char* restrict s1, const char* restrict s2);
+char* strncpy(char* restrict s1, const char* restrict s2, size_t n);
+char* strcat (char* restrict s1, const char* restrict s2);
+char* strncat(char* restrict s1, const char* restrict s2, size_t n);
+int memcmp(const void* s1, const void* s2, size_t n);
+int strcmp (const char* s1, const char* s2);
+int strncmp(const char* s1, const char* s2, size_t n);
+int strcoll(const char* s1, const char* s2);
+size_t strxfrm(char* restrict s1, const char* restrict s2, size_t n);
+const void* memchr(const void* s, int c, size_t n);
+      void* memchr(      void* s, int c, size_t n);
+const char* strchr(const char* s, int c);
+      char* strchr(      char* s, int c);
+size_t strcspn(const char* s1, const char* s2);
+const char* strpbrk(const char* s1, const char* s2);
+      char* strpbrk(      char* s1, const char* s2);
+const char* strrchr(const char* s, int c);
+      char* strrchr(      char* s, int c);
+size_t strspn(const char* s1, const char* s2);
+const char* strstr(const char* s1, const char* s2);
+      char* strstr(      char* s1, const char* s2);
+char* strtok(char* restrict s1, const char* restrict s2);
+void* memset(void* s, int c, size_t n);
+char* strerror(int errnum);
+size_t strlen(const char* s);
+
+*/
+
+#include <__config>
+#include_next <string.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#ifdef __cplusplus
+extern "C++" {
+
+// MSVCRT, GNU libc and its derivates already have the correct prototype in <string.h> if __cplusplus is defined
+#if !defined(__GLIBC__) && !defined(_LIBCPP_MSVCRT) && !defined(__sun__) && !defined(_STRING_H_CPLUSPLUS_98_CONFORMANCE_)
+inline _LIBCPP_INLINE_VISIBILITY char* strchr(char* __s, int __c) {return ::strchr(__s, __c);}
+inline _LIBCPP_INLINE_VISIBILITY char* strpbrk(char* __s1, const char* __s2) {return ::strpbrk(__s1, __s2);}
+inline _LIBCPP_INLINE_VISIBILITY char* strrchr(char* __s, int __c) {return ::strrchr(__s, __c);}
+inline _LIBCPP_INLINE_VISIBILITY void* memchr(void* __s, int __c, size_t __n) {return ::memchr(__s, __c, __n);}
+inline _LIBCPP_INLINE_VISIBILITY char* strstr(char* __s1, const char* __s2) {return ::strstr(__s1, __s2);}
+#endif
+
+}
+#endif
+
+#endif  // _LIBCPP_STRING_H
-------------- next part --------------
diff --git include/cwchar include/cwchar
index 797a177..ef4806d 100644
--- include/cwchar
+++ include/cwchar
@@ -106,9 +106,6 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,
 #include <__config>
 #include <cwctype>
 #include <wchar.h>
-#if defined(_LIBCPP_MSVCRT) || defined(__MINGW32__)
-#include <support/win32/support.h> // pull in *swprintf defines
-#endif // _LIBCPP_MSVCRT
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -161,16 +158,13 @@ using ::wcscoll;
 using ::wcsncmp;
 using ::wcsxfrm;
 
-#if defined(_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_)
-
+#ifdef _LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS
 using ::wcschr;
 using ::wcspbrk;
 using ::wcsrchr;
 using ::wcsstr;
 using ::wmemchr;
-
 #else
-
 inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wcschr(const wchar_t* __s, wchar_t __c) {return ::wcschr(__s, __c);}
 inline _LIBCPP_INLINE_VISIBILITY       wchar_t* wcschr(      wchar_t* __s, wchar_t __c) {return ::wcschr(__s, __c);}
 
@@ -185,7 +179,6 @@ inline _LIBCPP_INLINE_VISIBILITY       wchar_t* wcsstr(      wchar_t* __s1, cons
 
 inline _LIBCPP_INLINE_VISIBILITY const wchar_t* wmemchr(const wchar_t* __s, wchar_t __c, size_t __n) {return ::wmemchr(__s, __c, __n);}
 inline _LIBCPP_INLINE_VISIBILITY       wchar_t* wmemchr(      wchar_t* __s, wchar_t __c, size_t __n) {return ::wmemchr(__s, __c, __n);}
-
 #endif
 
 using ::wcscspn;
diff --git include/wchar.h include/wchar.h
new file mode 100644
index 0000000..4865866
--- /dev/null
+++ include/wchar.h
@@ -0,0 +1,131 @@
+// -*- C++ -*-
+//===--------------------------- wchar.h ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(__need_wint_t) || defined(__need_mbstate_t)
+#include_next <wchar.h>
+
+#elif !defined(_LIBCPP_WCHAR_H)
+#define _LIBCPP_WCHAR_H
+
+/*
+    wchar.h synopsis
+
+Macros:
+
+    NULL
+    WCHAR_MAX
+    WCHAR_MIN
+    WEOF
+
+Types:
+
+    mbstate_t
+    size_t
+    tm
+    wint_t
+
+int fwprintf(FILE* restrict stream, const wchar_t* restrict format, ...);
+int fwscanf(FILE* restrict stream, const wchar_t* restrict format, ...);
+int swprintf(wchar_t* restrict s, size_t n, const wchar_t* restrict format, ...);
+int swscanf(const wchar_t* restrict s, const wchar_t* restrict format, ...);
+int vfwprintf(FILE* restrict stream, const wchar_t* restrict format, va_list arg);
+int vfwscanf(FILE* restrict stream, const wchar_t* restrict format, va_list arg);  // C99
+int vswprintf(wchar_t* restrict s, size_t n, const wchar_t* restrict format, va_list arg);
+int vswscanf(const wchar_t* restrict s, const wchar_t* restrict format, va_list arg);  // C99
+int vwprintf(const wchar_t* restrict format, va_list arg);
+int vwscanf(const wchar_t* restrict format, va_list arg);  // C99
+int wprintf(const wchar_t* restrict format, ...);
+int wscanf(const wchar_t* restrict format, ...);
+wint_t fgetwc(FILE* stream);
+wchar_t* fgetws(wchar_t* restrict s, int n, FILE* restrict stream);
+wint_t fputwc(wchar_t c, FILE* stream);
+int fputws(const wchar_t* restrict s, FILE* restrict stream);
+int fwide(FILE* stream, int mode);
+wint_t getwc(FILE* stream);
+wint_t getwchar();
+wint_t putwc(wchar_t c, FILE* stream);
+wint_t putwchar(wchar_t c);
+wint_t ungetwc(wint_t c, FILE* stream);
+double wcstod(const wchar_t* restrict nptr, wchar_t** restrict endptr);
+float wcstof(const wchar_t* restrict nptr, wchar_t** restrict endptr);         // C99
+long double wcstold(const wchar_t* restrict nptr, wchar_t** restrict endptr);  // C99
+long wcstol(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);
+long long wcstoll(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);  // C99
+unsigned long wcstoul(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);
+unsigned long long wcstoull(const wchar_t* restrict nptr, wchar_t** restrict endptr, int base);  // C99
+wchar_t* wcscpy(wchar_t* restrict s1, const wchar_t* restrict s2);
+wchar_t* wcsncpy(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);
+wchar_t* wcscat(wchar_t* restrict s1, const wchar_t* restrict s2);
+wchar_t* wcsncat(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);
+int wcscmp(const wchar_t* s1, const wchar_t* s2);
+int wcscoll(const wchar_t* s1, const wchar_t* s2);
+int wcsncmp(const wchar_t* s1, const wchar_t* s2, size_t n);
+size_t wcsxfrm(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);
+const wchar_t* wcschr(const wchar_t* s, wchar_t c);
+      wchar_t* wcschr(      wchar_t* s, wchar_t c);
+size_t wcscspn(const wchar_t* s1, const wchar_t* s2);
+size_t wcslen(const wchar_t* s);
+const wchar_t* wcspbrk(const wchar_t* s1, const wchar_t* s2);
+      wchar_t* wcspbrk(      wchar_t* s1, const wchar_t* s2);
+const wchar_t* wcsrchr(const wchar_t* s, wchar_t c);
+      wchar_t* wcsrchr(      wchar_t* s, wchar_t c);
+size_t wcsspn(const wchar_t* s1, const wchar_t* s2);
+const wchar_t* wcsstr(const wchar_t* s1, const wchar_t* s2);
+      wchar_t* wcsstr(      wchar_t* s1, const wchar_t* s2);
+wchar_t* wcstok(wchar_t* restrict s1, const wchar_t* restrict s2, wchar_t** restrict ptr);
+const wchar_t* wmemchr(const wchar_t* s, wchar_t c, size_t n);
+      wchar_t* wmemchr(      wchar_t* s, wchar_t c, size_t n);
+int wmemcmp(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);
+wchar_t* wmemcpy(wchar_t* restrict s1, const wchar_t* restrict s2, size_t n);
+wchar_t* wmemmove(wchar_t* s1, const wchar_t* s2, size_t n);
+wchar_t* wmemset(wchar_t* s, wchar_t c, size_t n);
+size_t wcsftime(wchar_t* restrict s, size_t maxsize, const wchar_t* restrict format,
+                const tm* restrict timeptr);
+wint_t btowc(int c);
+int wctob(wint_t c);
+int mbsinit(const mbstate_t* ps);
+size_t mbrlen(const char* restrict s, size_t n, mbstate_t* restrict ps);
+size_t mbrtowc(wchar_t* restrict pwc, const char* restrict s, size_t n, mbstate_t* restrict ps);
+size_t wcrtomb(char* restrict s, wchar_t wc, mbstate_t* restrict ps);
+size_t mbsrtowcs(wchar_t* restrict dst, const char** restrict src, size_t len,
+                 mbstate_t* restrict ps);
+size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,
+                 mbstate_t* restrict ps);
+
+*/
+
+#include <__config>
+
+#ifdef __cplusplus
+#define __CORRECT_ISO_CPP_WCHAR_H_PROTO
+#endif
+
+#include_next <wchar.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+// Let <cwchar> know if we have const-correct overloads for wcschr and friends.
+#if defined(_WCHAR_H_CPLUSPLUS_98_CONFORMANCE_)
+#  define _LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS 1
+#elif defined(__GLIBC_PREREQ)
+#  if __GLIBC_PREREQ(2, 10)
+#    define _LIBCPP_WCHAR_H_HAS_CONST_OVERLOADS 1
+#  endif
+#endif
+
+#if defined(__cplusplus) && (defined(_LIBCPP_MSVCRT) || defined(__MINGW32__))
+extern "C++" {
+#include <support/win32/support.h> // pull in *swprintf defines
+}  // extern "C++"
+#endif  // __cplusplus && _LIBCPP_MSVCRT
+
+#endif  // _LIBCPP_WCHAR_H
diff --git test/std/depr/depr.c.headers/wchar_h.pass.cpp test/std/depr/depr.c.headers/wchar_h.pass.cpp
index 031fd1f..3ff1318 100644
--- test/std/depr/depr.c.headers/wchar_h.pass.cpp
+++ test/std/depr/depr.c.headers/wchar_h.pass.cpp
@@ -28,13 +28,9 @@
 #error WEOF not defined
 #endif
 
-#if defined(__clang__)
-#pragma clang diagnostic ignored "-Wmissing-braces"
-#endif
-
 int main()
 {
-    mbstate_t mb = {};
+    mbstate_t mb = {0};
     size_t s = 0;
     tm *tm = 0;
     wint_t w = 0;
@@ -54,19 +50,13 @@ int main()
     static_assert((std::is_same<decltype(vfwscanf(fp, L"", va)), int>::value), "");
     static_assert((std::is_same<decltype(vswprintf(ws, s, L"", va)), int>::value), "");
     static_assert((std::is_same<decltype(vswscanf(L"", L"", va)), int>::value), "");
-    static_assert((std::is_same<decltype(vwprintf(L"", va)), int>::value), "");
-    static_assert((std::is_same<decltype(vwscanf(L"", va)), int>::value), "");
-    static_assert((std::is_same<decltype(wprintf(L"")), int>::value), "");
-    static_assert((std::is_same<decltype(wscanf(L"")), int>::value), "");
     static_assert((std::is_same<decltype(fgetwc(fp)), wint_t>::value), "");
     static_assert((std::is_same<decltype(fgetws(ws, 0, fp)), wchar_t*>::value), "");
     static_assert((std::is_same<decltype(fputwc(L' ', fp)), wint_t>::value), "");
     static_assert((std::is_same<decltype(fputws(L"", fp)), int>::value), "");
     static_assert((std::is_same<decltype(fwide(fp, 0)), int>::value), "");
     static_assert((std::is_same<decltype(getwc(fp)), wint_t>::value), "");
-    static_assert((std::is_same<decltype(getwchar()), wint_t>::value), "");
     static_assert((std::is_same<decltype(putwc(L' ', fp)), wint_t>::value), "");
-    static_assert((std::is_same<decltype(putwchar(L' ')), wint_t>::value), "");
     static_assert((std::is_same<decltype(ungetwc(L' ', fp)), wint_t>::value), "");
     static_assert((std::is_same<decltype(wcstod(L"", (wchar_t**)0)), double>::value), "");
     static_assert((std::is_same<decltype(wcstof(L"", (wchar_t**)0)), float>::value), "");
@@ -83,14 +73,19 @@ int main()
     static_assert((std::is_same<decltype(wcscoll(L"", L"")), int>::value), "");
     static_assert((std::is_same<decltype(wcsncmp(L"", L"", s)), int>::value), "");
     static_assert((std::is_same<decltype(wcsxfrm(ws, L"", s)), size_t>::value), "");
+    static_assert((std::is_same<decltype(wcschr((const wchar_t*)0, L' ')), const wchar_t*>::value), "");
     static_assert((std::is_same<decltype(wcschr((wchar_t*)0, L' ')), wchar_t*>::value), "");
     static_assert((std::is_same<decltype(wcscspn(L"", L"")), size_t>::value), "");
     static_assert((std::is_same<decltype(wcslen(L"")), size_t>::value), "");
+    static_assert((std::is_same<decltype(wcspbrk((const wchar_t*)0, L"")), const wchar_t*>::value), "");
     static_assert((std::is_same<decltype(wcspbrk((wchar_t*)0, L"")), wchar_t*>::value), "");
+    static_assert((std::is_same<decltype(wcsrchr((const wchar_t*)0, L' ')), const wchar_t*>::value), "");
     static_assert((std::is_same<decltype(wcsrchr((wchar_t*)0, L' ')), wchar_t*>::value), "");
     static_assert((std::is_same<decltype(wcsspn(L"", L"")), size_t>::value), "");
+    static_assert((std::is_same<decltype(wcsstr((const wchar_t*)0, L"")), const wchar_t*>::value), "");
     static_assert((std::is_same<decltype(wcsstr((wchar_t*)0, L"")), wchar_t*>::value), "");
     static_assert((std::is_same<decltype(wcstok(ws, L"", (wchar_t**)0)), wchar_t*>::value), "");
+    static_assert((std::is_same<decltype(wmemchr((const wchar_t*)0, L' ', s)), const wchar_t*>::value), "");
     static_assert((std::is_same<decltype(wmemchr((wchar_t*)0, L' ', s)), wchar_t*>::value), "");
     static_assert((std::is_same<decltype(wmemcmp(L"", L"", s)), int>::value), "");
     static_assert((std::is_same<decltype(wmemcpy(ws, L"", s)), wchar_t*>::value), "");
@@ -105,4 +100,16 @@ int main()
     static_assert((std::is_same<decltype(wcrtomb(ns, L' ', &mb)), size_t>::value), "");
     static_assert((std::is_same<decltype(mbsrtowcs(ws, (const char**)0, s, &mb)), size_t>::value), "");
     static_assert((std::is_same<decltype(wcsrtombs(ns, (const wchar_t**)0, s, &mb)), size_t>::value), "");
+
+#ifndef _LIBCPP_HAS_NO_STDIN
+    static_assert((std::is_same<decltype(getwchar()), wint_t>::value), "");
+    static_assert((std::is_same<decltype(vwscanf(L"", va)), int>::value), "");
+    static_assert((std::is_same<decltype(wscanf(L"")), int>::value), "");
+#endif
+
+#ifndef _LIBCPP_HAS_NO_STDOUT
+    static_assert((std::is_same<decltype(putwchar(L' ')), wint_t>::value), "");
+    static_assert((std::is_same<decltype(vwprintf(L"", va)), int>::value), "");
+    static_assert((std::is_same<decltype(wprintf(L"")), int>::value), "");
+#endif
 }
-------------- next part --------------
commit 03fb76eef8eb334092a7646244e8baac8e06b9aa
Author: Richard Smith <richard at metafoo.co.uk>
Date:   Tue Oct 6 16:08:39 2015 -0700

    14: wctype.h

diff --git include/cwctype include/cwctype
index f31dd03..25b2489 100644
--- include/cwctype
+++ include/cwctype
@@ -63,41 +63,23 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 using ::wint_t;
 using ::wctrans_t;
 using ::wctype_t;
-#undef iswalnum
 using ::iswalnum;
-#undef iswalpha
 using ::iswalpha;
-#undef iswblank
 using ::iswblank;
-#undef iswcntrl
 using ::iswcntrl;
-#undef iswdigit
 using ::iswdigit;
-#undef iswgraph
 using ::iswgraph;
-#undef iswlower
 using ::iswlower;
-#undef iswprint
 using ::iswprint;
-#undef iswpunct
 using ::iswpunct;
-#undef iswspace
 using ::iswspace;
-#undef iswupper
 using ::iswupper;
-#undef iswxdigit
 using ::iswxdigit;
-#undef iswctype
 using ::iswctype;
-#undef wctype
 using ::wctype;
-#undef towlower
 using ::towlower;
-#undef towupper
 using ::towupper;
-#undef towctrans
 using ::towctrans;
-#undef wctrans
 using ::wctrans;
 
 _LIBCPP_END_NAMESPACE_STD
diff --git include/wctype.h include/wctype.h
new file mode 100644
index 0000000..4e528c0
--- /dev/null
+++ include/wctype.h
@@ -0,0 +1,78 @@
+// -*- C++ -*-
+//===--------------------------- wctype.h ---------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP_WCTYPE_H
+#define _LIBCPP_WCTYPE_H
+
+/*
+    wctype.h synopsis
+
+Macros:
+
+    WEOF
+
+Types:
+
+    wint_t
+    wctrans_t
+    wctype_t
+
+int iswalnum(wint_t wc);
+int iswalpha(wint_t wc);
+int iswblank(wint_t wc);  // C99
+int iswcntrl(wint_t wc);
+int iswdigit(wint_t wc);
+int iswgraph(wint_t wc);
+int iswlower(wint_t wc);
+int iswprint(wint_t wc);
+int iswpunct(wint_t wc);
+int iswspace(wint_t wc);
+int iswupper(wint_t wc);
+int iswxdigit(wint_t wc);
+int iswctype(wint_t wc, wctype_t desc);
+wctype_t wctype(const char* property);
+wint_t towlower(wint_t wc);
+wint_t towupper(wint_t wc);
+wint_t towctrans(wint_t wc, wctrans_t desc);
+wctrans_t wctrans(const char* property);
+
+*/
+
+#include <__config>
+#include_next <wctype.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#pragma GCC system_header
+#endif
+
+#ifdef __cplusplus
+
+#undef iswalnum
+#undef iswalpha
+#undef iswblank
+#undef iswcntrl
+#undef iswdigit
+#undef iswgraph
+#undef iswlower
+#undef iswprint
+#undef iswpunct
+#undef iswspace
+#undef iswupper
+#undef iswxdigit
+#undef iswctype
+#undef wctype
+#undef towlower
+#undef towupper
+#undef towctrans
+#undef wctrans
+
+#endif  // __cplusplus
+
+#endif  // _LIBCPP_WCTYPE_H


More information about the cfe-commits mailing list