aaron.ballman updated this revision to Diff 394291.
aaron.ballman added a reviewer: joerg.
aaron.ballman added a comment.

Updating based on off-list review feedback and adding a new reviewer.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115253/new/

https://reviews.llvm.org/D115253

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Headers/limits.h
  clang/lib/Headers/stdint.h
  clang/test/Headers/limits.cpp
  clang/test/Headers/stdint.c
  clang/test/Preprocessor/init-aarch64.c
  clang/test/Preprocessor/init.c
  clang/www/c_status.html

Index: clang/www/c_status.html
===================================================================
--- clang/www/c_status.html
+++ clang/www/c_status.html
@@ -715,11 +715,7 @@
     <tr>
       <td>Two's complement sign representation</td>
       <td><a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2412.pdf";>N2412</a></td>
-      <td class="partial" align="center">
-        <details><summary>Partial</summary>
-          Lacking width macros in limits.h and stdint.h
-        </details>
-      </td>
+      <td class="unreleased" align="center">Clang 14</td>
     </tr>
     <tr>
       <td>Adding the u8 character prefix</td>
Index: clang/test/Preprocessor/init.c
===================================================================
--- clang/test/Preprocessor/init.c
+++ clang/test/Preprocessor/init.c
@@ -1519,6 +1519,7 @@
 // WEBASSEMBLY-NEXT:#define __ATOMIC_RELEASE 3
 // WEBASSEMBLY-NEXT:#define __ATOMIC_SEQ_CST 5
 // WEBASSEMBLY-NEXT:#define __BIGGEST_ALIGNMENT__ 16
+// WEBASSEMBLY-NEXT:#define __BOOL_WIDTH__ 8
 // WEBASSEMBLY-NEXT:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
 // WEBASSEMBLY-NEXT:#define __CHAR16_TYPE__ unsigned short
 // WEBASSEMBLY-NEXT:#define __CHAR32_TYPE__ unsigned int
@@ -1608,21 +1609,25 @@
 // WEBASSEMBLY-NEXT:#define __INT16_FMTi__ "hi"
 // WEBASSEMBLY-NEXT:#define __INT16_MAX__ 32767
 // WEBASSEMBLY-NEXT:#define __INT16_TYPE__ short
+// WEBASSEMBLY-NEXT:#define __INT16_WIDTH__ 16
 // WEBASSEMBLY-NEXT:#define __INT32_C_SUFFIX__
 // WEBASSEMBLY-NEXT:#define __INT32_FMTd__ "d"
 // WEBASSEMBLY-NEXT:#define __INT32_FMTi__ "i"
 // WEBASSEMBLY-NEXT:#define __INT32_MAX__ 2147483647
 // WEBASSEMBLY-NEXT:#define __INT32_TYPE__ int
+// WEBASSEMBLY-NEXT:#define __INT32_WIDTH__ 32
 // WEBASSEMBLY-NEXT:#define __INT64_C_SUFFIX__ LL
 // WEBASSEMBLY-NEXT:#define __INT64_FMTd__ "lld"
 // WEBASSEMBLY-NEXT:#define __INT64_FMTi__ "lli"
 // WEBASSEMBLY-NEXT:#define __INT64_MAX__ 9223372036854775807LL
 // WEBASSEMBLY-NEXT:#define __INT64_TYPE__ long long int
+// WEBASSEMBLY-NEXT:#define __INT64_WIDTH__ 64
 // WEBASSEMBLY-NEXT:#define __INT8_C_SUFFIX__
 // WEBASSEMBLY-NEXT:#define __INT8_FMTd__ "hhd"
 // WEBASSEMBLY-NEXT:#define __INT8_FMTi__ "hhi"
 // WEBASSEMBLY-NEXT:#define __INT8_MAX__ 127
 // WEBASSEMBLY-NEXT:#define __INT8_TYPE__ signed char
+// WEBASSEMBLY-NEXT:#define __INT8_WIDTH__ 8
 // WEBASSEMBLY-NEXT:#define __INTMAX_C_SUFFIX__ LL
 // WEBASSEMBLY-NEXT:#define __INTMAX_FMTd__ "lld"
 // WEBASSEMBLY-NEXT:#define __INTMAX_FMTi__ "lli"
@@ -1640,34 +1645,42 @@
 // WEBASSEMBLY-NEXT:#define __INT_FAST16_FMTi__ "hi"
 // WEBASSEMBLY-NEXT:#define __INT_FAST16_MAX__ 32767
 // WEBASSEMBLY-NEXT:#define __INT_FAST16_TYPE__ short
+// WEBASSEMBLY-NEXT:#define __INT_FAST16_WIDTH__ 16
 // WEBASSEMBLY-NEXT:#define __INT_FAST32_FMTd__ "d"
 // WEBASSEMBLY-NEXT:#define __INT_FAST32_FMTi__ "i"
 // WEBASSEMBLY-NEXT:#define __INT_FAST32_MAX__ 2147483647
 // WEBASSEMBLY-NEXT:#define __INT_FAST32_TYPE__ int
+// WEBASSEMBLY-NEXT:#define __INT_FAST32_WIDTH__ 32
 // WEBASSEMBLY-NEXT:#define __INT_FAST64_FMTd__ "lld"
 // WEBASSEMBLY-NEXT:#define __INT_FAST64_FMTi__ "lli"
 // WEBASSEMBLY-NEXT:#define __INT_FAST64_MAX__ 9223372036854775807LL
 // WEBASSEMBLY-NEXT:#define __INT_FAST64_TYPE__ long long int
+// WEBASSEMBLY-NEXT:#define __INT_FAST64_WIDTH__ 64
 // WEBASSEMBLY-NEXT:#define __INT_FAST8_FMTd__ "hhd"
 // WEBASSEMBLY-NEXT:#define __INT_FAST8_FMTi__ "hhi"
 // WEBASSEMBLY-NEXT:#define __INT_FAST8_MAX__ 127
 // WEBASSEMBLY-NEXT:#define __INT_FAST8_TYPE__ signed char
+// WEBASSEMBLY-NEXT:#define __INT_FAST8_WIDTH__ 8
 // WEBASSEMBLY-NEXT:#define __INT_LEAST16_FMTd__ "hd"
 // WEBASSEMBLY-NEXT:#define __INT_LEAST16_FMTi__ "hi"
 // WEBASSEMBLY-NEXT:#define __INT_LEAST16_MAX__ 32767
 // WEBASSEMBLY-NEXT:#define __INT_LEAST16_TYPE__ short
+// WEBASSEMBLY-NEXT:#define __INT_LEAST16_WIDTH__ 16
 // WEBASSEMBLY-NEXT:#define __INT_LEAST32_FMTd__ "d"
 // WEBASSEMBLY-NEXT:#define __INT_LEAST32_FMTi__ "i"
 // WEBASSEMBLY-NEXT:#define __INT_LEAST32_MAX__ 2147483647
 // WEBASSEMBLY-NEXT:#define __INT_LEAST32_TYPE__ int
+// WEBASSEMBLY-NEXT:#define __INT_LEAST32_WIDTH__ 32
 // WEBASSEMBLY-NEXT:#define __INT_LEAST64_FMTd__ "lld"
 // WEBASSEMBLY-NEXT:#define __INT_LEAST64_FMTi__ "lli"
 // WEBASSEMBLY-NEXT:#define __INT_LEAST64_MAX__ 9223372036854775807LL
 // WEBASSEMBLY-NEXT:#define __INT_LEAST64_TYPE__ long long int
+// WEBASSEMBLY-NEXT:#define __INT_LEAST64_WIDTH__ 64
 // WEBASSEMBLY-NEXT:#define __INT_LEAST8_FMTd__ "hhd"
 // WEBASSEMBLY-NEXT:#define __INT_LEAST8_FMTi__ "hhi"
 // WEBASSEMBLY-NEXT:#define __INT_LEAST8_MAX__ 127
 // WEBASSEMBLY-NEXT:#define __INT_LEAST8_TYPE__ signed char
+// WEBASSEMBLY-NEXT:#define __INT_LEAST8_WIDTH__ 8
 // WEBASSEMBLY-NEXT:#define __INT_MAX__ 2147483647
 // WEBASSEMBLY-NEXT:#define __LDBL_DECIMAL_DIG__ 36
 // WEBASSEMBLY-NEXT:#define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
@@ -1759,6 +1772,7 @@
 // WEBASSEMBLY-NEXT:#define __UINT16_FMTx__ "hx"
 // WEBASSEMBLY-NEXT:#define __UINT16_MAX__ 65535
 // WEBASSEMBLY-NEXT:#define __UINT16_TYPE__ unsigned short
+// WEBASSEMBLY-NEXT:#define __UINT16_WIDTH__ 16
 // WEBASSEMBLY-NEXT:#define __UINT32_C_SUFFIX__ U
 // WEBASSEMBLY-NEXT:#define __UINT32_FMTX__ "X"
 // WEBASSEMBLY-NEXT:#define __UINT32_FMTo__ "o"
@@ -1766,6 +1780,7 @@
 // WEBASSEMBLY-NEXT:#define __UINT32_FMTx__ "x"
 // WEBASSEMBLY-NEXT:#define __UINT32_MAX__ 4294967295U
 // WEBASSEMBLY-NEXT:#define __UINT32_TYPE__ unsigned int
+// WEBASSEMBLY-NEXT:#define __UINT32_WIDTH__ 32
 // WEBASSEMBLY-NEXT:#define __UINT64_C_SUFFIX__ ULL
 // WEBASSEMBLY-NEXT:#define __UINT64_FMTX__ "llX"
 // WEBASSEMBLY-NEXT:#define __UINT64_FMTo__ "llo"
@@ -1773,6 +1788,7 @@
 // WEBASSEMBLY-NEXT:#define __UINT64_FMTx__ "llx"
 // WEBASSEMBLY-NEXT:#define __UINT64_MAX__ 18446744073709551615ULL
 // WEBASSEMBLY-NEXT:#define __UINT64_TYPE__ long long unsigned int
+// WEBASSEMBLY-NEXT:#define __UINT64_WIDTH__ 64
 // WEBASSEMBLY-NEXT:#define __UINT8_C_SUFFIX__
 // WEBASSEMBLY-NEXT:#define __UINT8_FMTX__ "hhX"
 // WEBASSEMBLY-NEXT:#define __UINT8_FMTo__ "hho"
@@ -1780,6 +1796,7 @@
 // WEBASSEMBLY-NEXT:#define __UINT8_FMTx__ "hhx"
 // WEBASSEMBLY-NEXT:#define __UINT8_MAX__ 255
 // WEBASSEMBLY-NEXT:#define __UINT8_TYPE__ unsigned char
+// WEBASSEMBLY-NEXT:#define __UINT8_WIDTH__ 8
 // WEBASSEMBLY-NEXT:#define __UINTMAX_C_SUFFIX__ ULL
 // WEBASSEMBLY-NEXT:#define __UINTMAX_FMTX__ "llX"
 // WEBASSEMBLY-NEXT:#define __UINTMAX_FMTo__ "llo"
@@ -1803,49 +1820,62 @@
 // WEBASSEMBLY-NEXT:#define __UINT_FAST16_FMTx__ "hx"
 // WEBASSEMBLY-NEXT:#define __UINT_FAST16_MAX__ 65535
 // WEBASSEMBLY-NEXT:#define __UINT_FAST16_TYPE__ unsigned short
+// WEBASSEMBLY-NEXT:#define __UINT_FAST16_WIDTH__ 16
 // WEBASSEMBLY-NEXT:#define __UINT_FAST32_FMTX__ "X"
 // WEBASSEMBLY-NEXT:#define __UINT_FAST32_FMTo__ "o"
 // WEBASSEMBLY-NEXT:#define __UINT_FAST32_FMTu__ "u"
 // WEBASSEMBLY-NEXT:#define __UINT_FAST32_FMTx__ "x"
 // WEBASSEMBLY-NEXT:#define __UINT_FAST32_MAX__ 4294967295U
 // WEBASSEMBLY-NEXT:#define __UINT_FAST32_TYPE__ unsigned int
+// WEBASSEMBLY-NEXT:#define __UINT_FAST32_WIDTH__ 32
 // WEBASSEMBLY-NEXT:#define __UINT_FAST64_FMTX__ "llX"
 // WEBASSEMBLY-NEXT:#define __UINT_FAST64_FMTo__ "llo"
 // WEBASSEMBLY-NEXT:#define __UINT_FAST64_FMTu__ "llu"
 // WEBASSEMBLY-NEXT:#define __UINT_FAST64_FMTx__ "llx"
 // WEBASSEMBLY-NEXT:#define __UINT_FAST64_MAX__ 18446744073709551615ULL
 // WEBASSEMBLY-NEXT:#define __UINT_FAST64_TYPE__ long long unsigned int
+// WEBASSEMBLY-NEXT:#define __UINT_FAST64_WIDTH__ 64
 // WEBASSEMBLY-NEXT:#define __UINT_FAST8_FMTX__ "hhX"
 // WEBASSEMBLY-NEXT:#define __UINT_FAST8_FMTo__ "hho"
 // WEBASSEMBLY-NEXT:#define __UINT_FAST8_FMTu__ "hhu"
 // WEBASSEMBLY-NEXT:#define __UINT_FAST8_FMTx__ "hhx"
 // WEBASSEMBLY-NEXT:#define __UINT_FAST8_MAX__ 255
 // WEBASSEMBLY-NEXT:#define __UINT_FAST8_TYPE__ unsigned char
+// WEBASSEMBLY-NEXT:#define __UINT_FAST8_WIDTH__ 8
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST16_FMTX__ "hX"
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST16_FMTo__ "ho"
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST16_FMTu__ "hu"
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST16_FMTx__ "hx"
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST16_MAX__ 65535
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST16_TYPE__ unsigned short
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST16_WIDTH__ 16
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST32_FMTX__ "X"
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST32_FMTo__ "o"
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST32_FMTu__ "u"
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST32_FMTx__ "x"
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST32_MAX__ 4294967295U
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST32_TYPE__ unsigned int
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST32_WIDTH__ 32
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST64_FMTX__ "llX"
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST64_FMTo__ "llo"
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST64_FMTu__ "llu"
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST64_FMTx__ "llx"
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST64_MAX__ 18446744073709551615ULL
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST64_TYPE__ long long unsigned int
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST64_WIDTH__ 64
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST8_FMTX__ "hhX"
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST8_FMTo__ "hho"
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST8_FMTu__ "hhu"
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST8_FMTx__ "hhx"
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST8_MAX__ 255
 // WEBASSEMBLY-NEXT:#define __UINT_LEAST8_TYPE__ unsigned char
+// WEBASSEMBLY-NEXT:#define __UINT_LEAST8_WIDTH__ 8
+// WEBASSEMBLY-NEXT:#define __UINT_WIDTH__ 32
+// WEBASSEMBLY-NEXT:#define __ULLONG_WIDTH__ 64
+// WEBASSEMBLY32-NEXT:#define __ULONG_WIDTH__ 32
+// WEBASSEMBLY64-NEXT:#define __ULONG_WIDTH__ 64
 // WEBASSEMBLY-NEXT:#define __USER_LABEL_PREFIX__
+// WEBASSEMBLY-NEXT:#define __USHRT_WIDTH__ 16
 // WEBASSEMBLY-NEXT:#define __VERSION__ "{{.*}}"
 // WEBASSEMBLY-NEXT:#define __WCHAR_MAX__ 2147483647
 // WEBASSEMBLY-NEXT:#define __WCHAR_TYPE__ int
Index: clang/test/Preprocessor/init-aarch64.c
===================================================================
--- clang/test/Preprocessor/init-aarch64.c
+++ clang/test/Preprocessor/init-aarch64.c
@@ -40,6 +40,7 @@
 // AARCH64-NEXT: #define __ATOMIC_SEQ_CST 5
 // AARCH64:      #define __BIGGEST_ALIGNMENT__ 16
 // AARCH64_BE-NEXT: #define __BIG_ENDIAN__ 1
+// AARCH64-NEXT: #define __BOOL_WIDTH__ 8
 // AARCH64_BE-NEXT: #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
 // AARCH64_LE-NEXT: #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
 // AARCH64-NEXT: #define __CHAR16_TYPE__ unsigned short
@@ -114,21 +115,25 @@
 // AARCH64-NEXT: #define __INT16_FMTi__ "hi"
 // AARCH64-NEXT: #define __INT16_MAX__ 32767
 // AARCH64-NEXT: #define __INT16_TYPE__ short
+// AARCH64-NEXT: #define __INT16_WIDTH__ 16
 // AARCH64-NEXT: #define __INT32_C_SUFFIX__ 
 // AARCH64-NEXT: #define __INT32_FMTd__ "d"
 // AARCH64-NEXT: #define __INT32_FMTi__ "i"
 // AARCH64-NEXT: #define __INT32_MAX__ 2147483647
 // AARCH64-NEXT: #define __INT32_TYPE__ int
+// AARCH64-NEXT: #define __INT32_WIDTH__ 32
 // AARCH64-NEXT: #define __INT64_C_SUFFIX__ L
 // AARCH64-NEXT: #define __INT64_FMTd__ "ld"
 // AARCH64-NEXT: #define __INT64_FMTi__ "li"
 // AARCH64-NEXT: #define __INT64_MAX__ 9223372036854775807L
 // AARCH64-NEXT: #define __INT64_TYPE__ long int
+// AARCH64-NEXT: #define __INT64_WIDTH__ 64
 // AARCH64-NEXT: #define __INT8_C_SUFFIX__ 
 // AARCH64-NEXT: #define __INT8_FMTd__ "hhd"
 // AARCH64-NEXT: #define __INT8_FMTi__ "hhi"
 // AARCH64-NEXT: #define __INT8_MAX__ 127
 // AARCH64-NEXT: #define __INT8_TYPE__ signed char
+// AARCH64-NEXT: #define __INT8_WIDTH__ 8
 // AARCH64-NEXT: #define __INTMAX_C_SUFFIX__ L
 // AARCH64-NEXT: #define __INTMAX_FMTd__ "ld"
 // AARCH64-NEXT: #define __INTMAX_FMTi__ "li"
@@ -144,34 +149,42 @@
 // AARCH64-NEXT: #define __INT_FAST16_FMTi__ "hi"
 // AARCH64-NEXT: #define __INT_FAST16_MAX__ 32767
 // AARCH64-NEXT: #define __INT_FAST16_TYPE__ short
+// AARCH64-NEXT: #define __INT_FAST16_WIDTH__ 16
 // AARCH64-NEXT: #define __INT_FAST32_FMTd__ "d"
 // AARCH64-NEXT: #define __INT_FAST32_FMTi__ "i"
 // AARCH64-NEXT: #define __INT_FAST32_MAX__ 2147483647
 // AARCH64-NEXT: #define __INT_FAST32_TYPE__ int
+// AARCH64-NEXT: #define __INT_FAST32_WIDTH__ 32
 // AARCH64-NEXT: #define __INT_FAST64_FMTd__ "ld"
 // AARCH64-NEXT: #define __INT_FAST64_FMTi__ "li"
 // AARCH64-NEXT: #define __INT_FAST64_MAX__ 9223372036854775807L
 // AARCH64-NEXT: #define __INT_FAST64_TYPE__ long int
+// AARCH64-NEXT: #define __INT_FAST64_WIDTH__ 64
 // AARCH64-NEXT: #define __INT_FAST8_FMTd__ "hhd"
 // AARCH64-NEXT: #define __INT_FAST8_FMTi__ "hhi"
 // AARCH64-NEXT: #define __INT_FAST8_MAX__ 127
 // AARCH64-NEXT: #define __INT_FAST8_TYPE__ signed char
+// AARCH64-NEXT: #define __INT_FAST8_WIDTH__ 8
 // AARCH64-NEXT: #define __INT_LEAST16_FMTd__ "hd"
 // AARCH64-NEXT: #define __INT_LEAST16_FMTi__ "hi"
 // AARCH64-NEXT: #define __INT_LEAST16_MAX__ 32767
 // AARCH64-NEXT: #define __INT_LEAST16_TYPE__ short
+// AARCH64-NEXT: #define __INT_LEAST16_WIDTH__ 16
 // AARCH64-NEXT: #define __INT_LEAST32_FMTd__ "d"
 // AARCH64-NEXT: #define __INT_LEAST32_FMTi__ "i"
 // AARCH64-NEXT: #define __INT_LEAST32_MAX__ 2147483647
 // AARCH64-NEXT: #define __INT_LEAST32_TYPE__ int
+// AARCH64-NEXT: #define __INT_LEAST32_WIDTH__ 32
 // AARCH64-NEXT: #define __INT_LEAST64_FMTd__ "ld"
 // AARCH64-NEXT: #define __INT_LEAST64_FMTi__ "li"
 // AARCH64-NEXT: #define __INT_LEAST64_MAX__ 9223372036854775807L
 // AARCH64-NEXT: #define __INT_LEAST64_TYPE__ long int
+// AARCH64-NEXT: #define __INT_LEAST64_WIDTH__ 64
 // AARCH64-NEXT: #define __INT_LEAST8_FMTd__ "hhd"
 // AARCH64-NEXT: #define __INT_LEAST8_FMTi__ "hhi"
 // AARCH64-NEXT: #define __INT_LEAST8_MAX__ 127
 // AARCH64-NEXT: #define __INT_LEAST8_TYPE__ signed char
+// AARCH64-NEXT: #define __INT_LEAST8_WIDTH__ 8
 // AARCH64-NEXT: #define __INT_MAX__ 2147483647
 // AARCH64-NEXT: #define __LDBL_DECIMAL_DIG__ 36
 // AARCH64-NEXT: #define __LDBL_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966L
@@ -246,6 +259,7 @@
 // AARCH64-NEXT: #define __UINT16_FMTx__ "hx"
 // AARCH64-NEXT: #define __UINT16_MAX__ 65535
 // AARCH64-NEXT: #define __UINT16_TYPE__ unsigned short
+// AARCH64-NEXT: #define __UINT16_WIDTH__ 16
 // AARCH64-NEXT: #define __UINT32_C_SUFFIX__ U
 // AARCH64-NEXT: #define __UINT32_FMTX__ "X"
 // AARCH64-NEXT: #define __UINT32_FMTo__ "o"
@@ -253,6 +267,7 @@
 // AARCH64-NEXT: #define __UINT32_FMTx__ "x"
 // AARCH64-NEXT: #define __UINT32_MAX__ 4294967295U
 // AARCH64-NEXT: #define __UINT32_TYPE__ unsigned int
+// AARCH64-NEXT: #define __UINT32_WIDTH__ 32
 // AARCH64-NEXT: #define __UINT64_C_SUFFIX__ UL
 // AARCH64-NEXT: #define __UINT64_FMTX__ "lX"
 // AARCH64-NEXT: #define __UINT64_FMTo__ "lo"
@@ -260,6 +275,7 @@
 // AARCH64-NEXT: #define __UINT64_FMTx__ "lx"
 // AARCH64-NEXT: #define __UINT64_MAX__ 18446744073709551615UL
 // AARCH64-NEXT: #define __UINT64_TYPE__ long unsigned int
+// AARCH64-NEXT: #define __UINT64_WIDTH__ 64
 // AARCH64-NEXT: #define __UINT8_C_SUFFIX__ 
 // AARCH64-NEXT: #define __UINT8_FMTX__ "hhX"
 // AARCH64-NEXT: #define __UINT8_FMTo__ "hho"
@@ -267,6 +283,7 @@
 // AARCH64-NEXT: #define __UINT8_FMTx__ "hhx"
 // AARCH64-NEXT: #define __UINT8_MAX__ 255
 // AARCH64-NEXT: #define __UINT8_TYPE__ unsigned char
+// AARCH64-NEXT: #define __UINT8_WIDTH__ 8
 // AARCH64-NEXT: #define __UINTMAX_C_SUFFIX__ UL
 // AARCH64-NEXT: #define __UINTMAX_FMTX__ "lX"
 // AARCH64-NEXT: #define __UINTMAX_FMTo__ "lo"
@@ -288,49 +305,61 @@
 // AARCH64-NEXT: #define __UINT_FAST16_FMTx__ "hx"
 // AARCH64-NEXT: #define __UINT_FAST16_MAX__ 65535
 // AARCH64-NEXT: #define __UINT_FAST16_TYPE__ unsigned short
+// AARCH64-NEXT: #define __UINT_FAST16_WIDTH__ 16
 // AARCH64-NEXT: #define __UINT_FAST32_FMTX__ "X"
 // AARCH64-NEXT: #define __UINT_FAST32_FMTo__ "o"
 // AARCH64-NEXT: #define __UINT_FAST32_FMTu__ "u"
 // AARCH64-NEXT: #define __UINT_FAST32_FMTx__ "x"
 // AARCH64-NEXT: #define __UINT_FAST32_MAX__ 4294967295U
 // AARCH64-NEXT: #define __UINT_FAST32_TYPE__ unsigned int
+// AARCH64-NEXT: #define __UINT_FAST32_WIDTH__ 32
 // AARCH64-NEXT: #define __UINT_FAST64_FMTX__ "lX"
 // AARCH64-NEXT: #define __UINT_FAST64_FMTo__ "lo"
 // AARCH64-NEXT: #define __UINT_FAST64_FMTu__ "lu"
 // AARCH64-NEXT: #define __UINT_FAST64_FMTx__ "lx"
 // AARCH64-NEXT: #define __UINT_FAST64_MAX__ 18446744073709551615UL
 // AARCH64-NEXT: #define __UINT_FAST64_TYPE__ long unsigned int
+// AARCH64-NEXT: #define __UINT_FAST64_WIDTH__ 64
 // AARCH64-NEXT: #define __UINT_FAST8_FMTX__ "hhX"
 // AARCH64-NEXT: #define __UINT_FAST8_FMTo__ "hho"
 // AARCH64-NEXT: #define __UINT_FAST8_FMTu__ "hhu"
 // AARCH64-NEXT: #define __UINT_FAST8_FMTx__ "hhx"
 // AARCH64-NEXT: #define __UINT_FAST8_MAX__ 255
 // AARCH64-NEXT: #define __UINT_FAST8_TYPE__ unsigned char
+// AARCH64-NEXT: #define __UINT_FAST8_WIDTH__ 8
 // AARCH64-NEXT: #define __UINT_LEAST16_FMTX__ "hX"
 // AARCH64-NEXT: #define __UINT_LEAST16_FMTo__ "ho"
 // AARCH64-NEXT: #define __UINT_LEAST16_FMTu__ "hu"
 // AARCH64-NEXT: #define __UINT_LEAST16_FMTx__ "hx"
 // AARCH64-NEXT: #define __UINT_LEAST16_MAX__ 65535
 // AARCH64-NEXT: #define __UINT_LEAST16_TYPE__ unsigned short
+// AARCH64-NEXT: #define __UINT_LEAST16_WIDTH__ 16
 // AARCH64-NEXT: #define __UINT_LEAST32_FMTX__ "X"
 // AARCH64-NEXT: #define __UINT_LEAST32_FMTo__ "o"
 // AARCH64-NEXT: #define __UINT_LEAST32_FMTu__ "u"
 // AARCH64-NEXT: #define __UINT_LEAST32_FMTx__ "x"
 // AARCH64-NEXT: #define __UINT_LEAST32_MAX__ 4294967295U
 // AARCH64-NEXT: #define __UINT_LEAST32_TYPE__ unsigned int
+// AARCH64-NEXT: #define __UINT_LEAST32_WIDTH__ 32
 // AARCH64-NEXT: #define __UINT_LEAST64_FMTX__ "lX"
 // AARCH64-NEXT: #define __UINT_LEAST64_FMTo__ "lo"
 // AARCH64-NEXT: #define __UINT_LEAST64_FMTu__ "lu"
 // AARCH64-NEXT: #define __UINT_LEAST64_FMTx__ "lx"
 // AARCH64-NEXT: #define __UINT_LEAST64_MAX__ 18446744073709551615UL
 // AARCH64-NEXT: #define __UINT_LEAST64_TYPE__ long unsigned int
+// AARCH64-NEXT: #define __UINT_LEAST64_WIDTH__ 64
 // AARCH64-NEXT: #define __UINT_LEAST8_FMTX__ "hhX"
 // AARCH64-NEXT: #define __UINT_LEAST8_FMTo__ "hho"
 // AARCH64-NEXT: #define __UINT_LEAST8_FMTu__ "hhu"
 // AARCH64-NEXT: #define __UINT_LEAST8_FMTx__ "hhx"
 // AARCH64-NEXT: #define __UINT_LEAST8_MAX__ 255
 // AARCH64-NEXT: #define __UINT_LEAST8_TYPE__ unsigned char
+// AARCH64-NEXT: #define __UINT_LEAST8_WIDTH__ 8
+// AARCH64-NEXT: #define __UINT_WIDTH__ 32
+// AARCH64-NEXT: #define __ULLONG_WIDTH__ 64
+// AARCH64-NEXT: #define __ULONG_WIDTH__ 64
 // AARCH64-NEXT: #define __USER_LABEL_PREFIX__ 
+// AARCH64-NEXT: #define __USHRT_WIDTH__ 16
 // AARCH64-NEXT: #define __VERSION__ "{{.*}}"
 // AARCH64-NEXT: #define __WCHAR_MAX__ 4294967295U
 // AARCH64-NEXT: #define __WCHAR_TYPE__ unsigned int
Index: clang/test/Headers/stdint.c
===================================================================
--- /dev/null
+++ clang/test/Headers/stdint.c
@@ -0,0 +1,253 @@
+// RUN: %clang_cc1 -ffreestanding -fsyntax-only -verify -std=c17 %s
+// RUN: %clang_cc1 -ffreestanding -fsyntax-only -verify -std=c2x %s
+// RUN: %clang_cc1 %s -ffreestanding -std=c2x -fsyntax-only -triple=aarch64-none-none
+// RUN: %clang_cc1 %s -ffreestanding -std=c2x -fsyntax-only -triple=arm-none-none
+// RUN: %clang_cc1 %s -ffreestanding -std=c2x -fsyntax-only -triple=i386-none-none
+// RUN: %clang_cc1 %s -ffreestanding -std=c2x -fsyntax-only -triple=mips-none-none
+// RUN: %clang_cc1 %s -ffreestanding -std=c2x -fsyntax-only -triple=mips64-none-none
+// RUN: %clang_cc1 %s -ffreestanding -std=c2x -fsyntax-only -triple=msp430-none-none
+// RUN: %clang_cc1 %s -ffreestanding -std=c2x -fsyntax-only -triple=powerpc64-none-none
+// RUN: %clang_cc1 %s -ffreestanding -std=c2x -fsyntax-only -triple=powerpc64-none-netbsd
+// RUN: %clang_cc1 %s -ffreestanding -std=c2x -fsyntax-only -triple=powerpc-none-none
+// RUN: %clang_cc1 %s -ffreestanding -std=c2x -fsyntax-only -triple=s390x-none-none
+// RUN: %clang_cc1 %s -ffreestanding -std=c2x -fsyntax-only -triple=sparc-none-none
+// RUN: %clang_cc1 %s -ffreestanding -std=c2x -fsyntax-only -triple=tce-none-none
+// RUN: %clang_cc1 %s -ffreestanding -std=c2x -fsyntax-only -triple=x86_64-none-none
+// RUN: %clang_cc1 %s -ffreestanding -std=c2x -fsyntax-only -triple=x86_64-pc-linux-gnu
+// RUN: %clang_cc1 %s -ffreestanding -std=c2x -fsyntax-only -triple=i386-mingw32
+// RUN: %clang_cc1 %s -ffreestanding -std=c2x -fsyntax-only -triple=xcore-none-none
+// expected-no-diagnostics
+
+#include <stdint.h>
+
+/* FIXME: This is using the placeholder dates Clang produces for these macros
+   in C2x mode; switch to the correct values once they've been published. */
+#if __STDC_VERSION__ >= 202000L
+/* Validate the standard requirements. */
+_Static_assert(SIG_ATOMIC_WIDTH >= 8);
+_Static_assert(SIZE_WIDTH >= 16);
+_Static_assert(SIZE_WIDTH / __CHAR_BIT__ == sizeof(sizeof(0)));
+_Static_assert(WCHAR_WIDTH >= 8);
+_Static_assert(WCHAR_WIDTH / __CHAR_BIT__ == sizeof(L't'));
+_Static_assert(WINT_WIDTH >= 16);
+_Static_assert(UINTPTR_WIDTH >= 16);
+_Static_assert(UINTPTR_WIDTH / __CHAR_BIT__ == sizeof(uintptr_t));
+_Static_assert(INTPTR_WIDTH == UINTPTR_WIDTH);
+_Static_assert(INTPTR_WIDTH / __CHAR_BIT__ == sizeof(intptr_t));
+
+/* FIXME: the TCE target is not a conforming C target because it defines these
+   values to be less than 64. */
+#if !defined(__TCE__)
+_Static_assert(UINTMAX_WIDTH >= 64);
+_Static_assert(UINTMAX_WIDTH / __CHAR_BIT__ == sizeof(uintmax_t));
+_Static_assert(INTMAX_WIDTH == UINTMAX_WIDTH);
+_Static_assert(INTMAX_WIDTH / __CHAR_BIT__ == sizeof(intmax_t));
+#endif
+
+/* NB: WG14 N2412 set this to 17, but WG14 N2808 set it back to 16. */
+_Static_assert(PTRDIFF_WIDTH >= 16);
+#else
+/* None of these are defined. */
+int PTRDIFF_WIDTH, SIG_ATOMIC_WIDTH, SIZE_WIDTH, WCHAR_WIDTH, WINT_WIDTH,
+    INTPTR_WIDTH, UINTPTR_WIDTH, INTMAX_WIDTH, UINTMAX_WIDTH;
+#endif
+
+#if defined(INT8_MAX)
+_Static_assert(INT8_WIDTH == 8, "");
+_Static_assert(UINT8_WIDTH == INT8_WIDTH, "");
+_Static_assert(INT8_WIDTH / __CHAR_BIT__ == sizeof(int8_t), "");
+_Static_assert(UINT8_WIDTH / __CHAR_BIT__ == sizeof(uint8_t), "");
+#else
+int INT8_WIDTH, UINT8_WIDTH; /* None of these are defined. */
+#endif
+#if defined(INT_LEAST8_MAX)
+_Static_assert(INT_LEAST8_WIDTH >= 8, "");
+_Static_assert(INT_LEAST8_WIDTH / __CHAR_BIT__ == sizeof(int_least8_t), "");
+_Static_assert(UINT_LEAST8_WIDTH == INT_LEAST8_WIDTH, "");
+_Static_assert(UINT_LEAST8_WIDTH / __CHAR_BIT__ == sizeof(uint_least8_t), "");
+#else
+int INT_LEAST8_WIDTH, UINT_LEAST8_WIDTH; /* None of these are defined. */
+#endif
+#if defined(INT_FAST8_MAX)
+_Static_assert(INT_FAST8_WIDTH >= 8, "");
+_Static_assert(INT_FAST8_WIDTH / __CHAR_BIT__ == sizeof(int_fast8_t), "");
+_Static_assert(UINT_FAST8_WIDTH == INT_FAST8_WIDTH, "");
+_Static_assert(UINT_FAST8_WIDTH / __CHAR_BIT__ == sizeof(uint_fast8_t), "");
+#else
+int INT_FAST8_WIDTH, UINT_FAST8_WIDTH; /* None of these are defined. */
+#endif
+
+#if defined(INT16_MAX)
+_Static_assert(INT16_WIDTH == 16, "");
+_Static_assert(UINT16_WIDTH == INT16_WIDTH, "");
+_Static_assert(INT16_WIDTH / __CHAR_BIT__ == sizeof(int16_t), "");
+_Static_assert(UINT16_WIDTH / __CHAR_BIT__ == sizeof(uint16_t), "");
+#else
+int INT16_WIDTH, UINT16_WIDTH; /* None of these are defined. */
+#endif
+#if defined(INT_LEAST16_MAX)
+_Static_assert(INT_LEAST16_WIDTH >= 16, "");
+_Static_assert(INT_LEAST16_WIDTH / __CHAR_BIT__ == sizeof(int_least16_t), "");
+_Static_assert(UINT_LEAST16_WIDTH == INT_LEAST16_WIDTH, "");
+_Static_assert(UINT_LEAST16_WIDTH / __CHAR_BIT__ == sizeof(uint_least16_t), "");
+#else
+int INT_LEAST16_WIDTH, UINT_LEAST16_WIDTH; /* None of these are defined. */
+#endif
+#if defined(INT_FAST16_MAX)
+_Static_assert(INT_FAST16_WIDTH >= 16, "");
+_Static_assert(INT_FAST16_WIDTH / __CHAR_BIT__ == sizeof(int_fast16_t), "");
+_Static_assert(UINT_FAST16_WIDTH == INT_FAST16_WIDTH, "");
+_Static_assert(UINT_FAST16_WIDTH / __CHAR_BIT__ == sizeof(int_fast16_t), "");
+#else
+int INT_FAST16_WIDTH, UINT_FAST16_WIDTH; /* None of these are defined. */
+#endif
+
+#if defined(INT24_MAX)
+_Static_assert(INT24_WIDTH == 24, "");
+_Static_assert(UINT24_WIDTH == INT24_WIDTH, "");
+_Static_assert(INT24_WIDTH / __CHAR_BIT__ == sizeof(int24_t), "");
+_Static_assert(UINT24_WIDTH / __CHAR_BIT__ == sizeof(uint24_t), "");
+#else
+int INT24_WIDTH, UINT24_WIDTH; /* None of these are defined. */
+#endif
+#if defined(INT_LEAST24_MAX)
+_Static_assert(INT_LEAST24_WIDTH >= 24, "");
+_Static_assert(INT_LEAST24_WIDTH / __CHAR_BIT__ == sizeof(int_least24_t), "");
+_Static_assert(UINT_LEAST24_WIDTH == INT_LEAST24_WIDTH, "");
+_Static_assert(UINT_LEAST24_WIDTH / __CHAR_BIT__ == sizeof(uint_least24_t), "");
+#else
+int INT_LEAST24_WIDTH, UINT_LEAST24_WIDTH; /* None of these are defined. */
+#endif
+#if defined(INT_FAST24_MAX)
+_Static_assert(INT_FAST24_WIDTH >= 24, "");
+_Static_assert(INT_FAST24_WIDTH / __CHAR_BIT__ == sizeof(int_fast24_t), "");
+_Static_assert(UINT_FAST24_WIDTH == INT_FAST24_WIDTH, "");
+_Static_assert(UINT_FAST24_WIDTH / __CHAR_BIT__ == sizeof(uint_fast24_t), "");
+#else
+int INT_FAST24_WIDTH, UINT_FAST24_WIDTH; /* None of these are defined. */
+#endif
+
+#if defined(INT32_MAX)
+_Static_assert(INT32_WIDTH == 32, "");
+_Static_assert(UINT32_WIDTH == INT32_WIDTH, "");
+_Static_assert(INT32_WIDTH / __CHAR_BIT__ == sizeof(int32_t), "");
+_Static_assert(UINT32_WIDTH / __CHAR_BIT__ == sizeof(uint32_t), "");
+#else
+int INT32_WIDTH, UINT32_WIDTH; /* None of these are defined. */
+#endif
+#if defined(INT_LEAST32_MAX)
+_Static_assert(INT_LEAST32_WIDTH >= 32, "");
+_Static_assert(INT_LEAST32_WIDTH / __CHAR_BIT__ == sizeof(int_least32_t), "");
+_Static_assert(UINT_LEAST32_WIDTH == INT_LEAST32_WIDTH, "");
+_Static_assert(UINT_LEAST32_WIDTH / __CHAR_BIT__ == sizeof(uint_least32_t), "");
+#else
+int INT_LEAST32_WIDTH, UINT_LEAST32_WIDTH; /* None of these are defined. */
+#endif
+#if defined(INT_FAST32_MAX)
+_Static_assert(INT_FAST32_WIDTH >= 32, "");
+_Static_assert(INT_FAST32_WIDTH / __CHAR_BIT__ == sizeof(int_fast32_t), "");
+_Static_assert(UINT_FAST32_WIDTH == INT_FAST32_WIDTH, "");
+_Static_assert(UINT_FAST32_WIDTH / __CHAR_BIT__ == sizeof(uint_fast32_t), "");
+#else
+int INT_FAST32_WIDTH, UINT_FAST32_WIDTH; /* None of these are defined. */
+#endif
+
+#if defined(INT40_MAX)
+_Static_assert(INT40_WIDTH == 40, "");
+_Static_assert(UINT40_WIDTH == INT40_WIDTH, "");
+_Static_assert(INT40_WIDTH / __CHAR_BIT__ == sizeof(int40_t), "");
+_Static_assert(UINT40_WIDTH / __CHAR_BIT__ == sizeof(uint40_t), "");
+#else
+int INT40_WIDTH, UINT40_WIDTH; /* None of these are defined. */
+#endif
+#if defined(INT_LEAST40_MAX)
+_Static_assert(INT_LEAST40_WIDTH >= 40, "");
+_Static_assert(INT_LEAST40_WIDTH / __CHAR_BIT__ == sizeof(int_least40_t), "");
+_Static_assert(UINT_LEAST40_WIDTH == INT_LEAST40_WIDTH, "");
+_Static_assert(UINT_LEAST40_WIDTH / __CHAR_BIT__ == sizeof(int_least40_t), "");
+#else
+int INT_LEAST40_WIDTH, UINT_LEAST40_WIDTH; /* None of these are defined. */
+#endif
+#if defined(INT_FAST40_MAX)
+_Static_assert(INT_FAST40_WIDTH >= 40, "");
+_Static_assert(INT_FAST40_WIDTH / __CHAR_BIT__ == sizeof(int_fast40_t), "");
+_Static_assert(UINT_FAST40_WIDTH == INT_FAST40_WIDTH, "");
+_Static_assert(UINT_FAST40_WIDTH / __CHAR_BIT__ == sizeof(uint_fast40_t), "");
+#else
+int INT_FAST40_WIDTH, UINT_FAST40_WIDTH; /* None of these are defined. */
+#endif
+
+#if defined(INT48_MAX)
+_Static_assert(INT48_WIDTH == 48, "");
+_Static_assert(UINT48_WIDTH == INT48_WIDTH, "");
+_Static_assert(INT48_WIDTH / __CHAR_BIT__ == sizeof(int48_t), "");
+_Static_assert(UINT48_WIDTH / __CHAR_BIT__ == sizeof(uint48_t), "");
+#else
+int INT48_WIDTH, UINT48_WIDTH; /* None of these are defined. */
+#endif
+#if defined(INT_LEAST48_MAX)
+_Static_assert(INT_LEAST48_WIDTH >= 48, "");
+_Static_assert(INT_LEAST48_WIDTH / __CHAR_BIT__ == sizeof(int_least48_t), "");
+_Static_assert(UINT_LEAST48_WIDTH == INT_LEAST48_WIDTH, "");
+_Static_assert(UINT_LEAST48_WIDTH / __CHAR_BIT__ == sizeof(int_least48_t), "");
+#else
+int INT_LEAST48_WIDTH, UINT_LEAST48_WIDTH; /* None of these are defined. */
+#endif
+#if defined(INT_FAST48_MAX)
+_Static_assert(INT_FAST48_WIDTH >= 48, "");
+_Static_assert(INT_FAST48_WIDTH / __CHAR_BIT__ == sizeof(int_fast48_t), "");
+_Static_assert(UINT_FAST48_WIDTH == INT_FAST48_WIDTH, "");
+_Static_assert(UINT_FAST48_WIDTH / __CHAR_BIT__ == sizeof(int_fast48_t), "");
+#else
+int INT_FAST48_WIDTH, UINT_FAST48_WIDTH; /* None of these are defined. */
+#endif
+
+#if defined(INT56_MAX)
+_Static_assert(INT56_WIDTH == 56, "");
+_Static_assert(UINT56_WIDTH == INT56_WIDTH, "");
+_Static_assert(INT56_WIDTH / __CHAR_BIT__ == sizeof(int56_t), "");
+_Static_assert(UINT56_WIDTH / __CHAR_BIT__ == sizeof(uint56_t), "");
+#else
+int INT56_WIDTH, UINT56_WIDTH; /* None of these are defined. */
+#endif
+#if defined(INT_LEAST56_MAX)
+_Static_assert(INT_LEAST56_WIDTH >= 56, "");
+_Static_assert(INT_LEAST56_WIDTH / __CHAR_BIT__ == sizeof(int_least56_t), "");
+_Static_assert(UINT_LEAST56_WIDTH == INT_LEAST56_WIDTH, "");
+_Static_assert(UINT_LEAST56_WIDTH / __CHAR_BIT__ == sizeof(int_least56_t), "");
+#else
+int INT_LEAST56_WIDTH, UINT_LEAST56_WIDTH; /* None of these are defined. */
+#endif
+#if defined(INT_FAST56_MAX)
+_Static_assert(INT_FAST56_WIDTH >= 56, "");
+_Static_assert(INT_FAST56_WIDTH / __CHAR_BIT__ == sizeof(int_fast56_t), "");
+_Static_assert(UINT_FAST56_WIDTH == INT_FAST56_WIDTH, "");
+_Static_assert(UINT_FAST56_WIDTH / __CHAR_BIT__ == sizeof(int_fast56_t), "");
+#else
+int INT_FAST56_WIDTH, UINT_FAST56_WIDTH; /* None of these are defined. */
+#endif
+
+#if defined(INT64_MAX)
+_Static_assert(INT64_WIDTH == 64, "");
+_Static_assert(UINT64_WIDTH == INT64_WIDTH, "");
+_Static_assert(INT64_WIDTH / __CHAR_BIT__ == sizeof(int64_t), "");
+_Static_assert(UINT64_WIDTH / __CHAR_BIT__ == sizeof(uint64_t), "");
+#else
+int INT64_WIDTH, UINT64_WIDTH; /* None of these are defined. */
+#endif
+#if defined(INT_LEAST64_MAX)
+_Static_assert(INT_LEAST64_WIDTH >= 64, "");
+_Static_assert(INT_LEAST64_WIDTH / __CHAR_BIT__ == sizeof(int_least64_t), "");
+_Static_assert(UINT_LEAST64_WIDTH == INT_LEAST64_WIDTH, "");
+_Static_assert(UINT_LEAST64_WIDTH / __CHAR_BIT__ == sizeof(int_least64_t), "");
+#else
+int INT_LEAST64_WIDTH, UINT_LEAST64_WIDTH; /* None of these are defined. */
+#endif
+#if defined(INT_FAST64_MAX)
+_Static_assert(INT_FAST64_WIDTH >= 64, "");
+_Static_assert(INT_FAST64_WIDTH / __CHAR_BIT__ == sizeof(int_fast64_t), "");
+_Static_assert(UINT_FAST64_WIDTH == INT_FAST64_WIDTH, "");
+_Static_assert(UINT_FAST64_WIDTH / __CHAR_BIT__ == sizeof(int_fast64_t), "");
+#else
+int INT_FAST64_WIDTH, UINT_FAST64_WIDTH; /* None of these are defined. */
+#endif
Index: clang/test/Headers/limits.cpp
===================================================================
--- clang/test/Headers/limits.cpp
+++ clang/test/Headers/limits.cpp
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -ffreestanding -fsyntax-only -verify %s
 // RUN: %clang_cc1 -fno-signed-char -ffreestanding -fsyntax-only -verify %s
 // RUN: %clang_cc1 -std=c++11 -ffreestanding -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c2x -ffreestanding -fsyntax-only -verify -x c %s
 // expected-no-diagnostics
 
 #include <limits.h>
@@ -29,9 +30,8 @@
 
 _Static_assert(CHAR_BIT >= 8, "");
 
-const bool char_is_signed = (char)-1 < (char)0;
-_Static_assert(CHAR_MIN == (char_is_signed ? -CHAR_MAX-1 : 0), "");
-_Static_assert(CHAR_MAX == (char_is_signed ? -(CHAR_MIN+1) : (char)~0ULL), "");
+_Static_assert(CHAR_MIN == (((char)-1 < (char)0) ? -CHAR_MAX-1 : 0), "");
+_Static_assert(CHAR_MAX == (((char)-1 < (char)0) ? -(CHAR_MIN+1) : (char)~0ULL), "");
 
 #if __STDC_VERSION__ >= 199901 || __cplusplus >= 201103L
 _Static_assert(LLONG_MAX == -(LLONG_MIN+1LL), "");
@@ -40,3 +40,41 @@
 #else
 int LLONG_MIN, LLONG_MAX, ULLONG_MAX; // Not defined.
 #endif
+
+/* FIXME: This is using the placeholder dates Clang produces for these macros
+   in C2x mode; switch to the correct values once they've been published. */
+#if __STDC_VERSION__ >= 202000L
+/* Validate the standard requirements. */
+_Static_assert(BOOL_WIDTH >= 1);
+
+_Static_assert(CHAR_WIDTH == CHAR_BIT);
+_Static_assert(CHAR_WIDTH / CHAR_BIT == sizeof(char));
+_Static_assert(SCHAR_WIDTH == CHAR_BIT);
+_Static_assert(SCHAR_WIDTH / CHAR_BIT == sizeof(signed char));
+_Static_assert(UCHAR_WIDTH == CHAR_BIT);
+_Static_assert(UCHAR_WIDTH / CHAR_BIT == sizeof(unsigned char));
+
+_Static_assert(USHRT_WIDTH >= 16);
+_Static_assert(USHRT_WIDTH / CHAR_BIT == sizeof(unsigned short));
+_Static_assert(SHRT_WIDTH == USHRT_WIDTH);
+_Static_assert(SHRT_WIDTH / CHAR_BIT == sizeof(signed short));
+
+_Static_assert(UINT_WIDTH >= 16);
+_Static_assert(UINT_WIDTH / CHAR_BIT == sizeof(unsigned int));
+_Static_assert(INT_WIDTH == UINT_WIDTH);
+_Static_assert(INT_WIDTH / CHAR_BIT == sizeof(signed int));
+
+_Static_assert(ULONG_WIDTH >= 32);
+_Static_assert(ULONG_WIDTH / CHAR_BIT == sizeof(unsigned long));
+_Static_assert(LONG_WIDTH == ULONG_WIDTH);
+_Static_assert(LONG_WIDTH / CHAR_BIT == sizeof(signed long));
+
+_Static_assert(ULLONG_WIDTH >= 64);
+_Static_assert(ULLONG_WIDTH / CHAR_BIT == sizeof(unsigned long long));
+_Static_assert(LLONG_WIDTH == ULLONG_WIDTH);
+_Static_assert(LLONG_WIDTH / CHAR_BIT == sizeof(signed long long));
+#else
+/* None of these are defined. */
+int BOOL_WIDTH, CHAR_WIDTH, SCHAR_WIDTH, UCHAR_WIDTH, USHRT_WIDTH, SHRT_WIDTH,
+    UINT_WIDTH, INT_WIDTH, ULONG_WIDTH, LONG_WIDTH, ULLONG_WIDTH, LLONG_WIDTH;
+#endif
Index: clang/lib/Headers/stdint.h
===================================================================
--- clang/lib/Headers/stdint.h
+++ clang/lib/Headers/stdint.h
@@ -461,17 +461,23 @@
 # define INT64_MAX           INT64_C( 9223372036854775807)
 # define INT64_MIN         (-INT64_C( 9223372036854775807)-1)
 # define UINT64_MAX         UINT64_C(18446744073709551615)
+# define UINT64_WIDTH        64
+# define INT64_WIDTH         UINT64_WIDTH
 # define __INT_LEAST64_MIN   INT64_MIN
 # define __INT_LEAST64_MAX   INT64_MAX
+# define __UINT_LEAST64_WIDTH UINT64_WIDTH
 # define __UINT_LEAST64_MAX UINT64_MAX
 # define __INT_LEAST32_MIN   INT64_MIN
 # define __INT_LEAST32_MAX   INT64_MAX
+# define __UINT_LEAST32_WIDTH UINT64_WIDTH
 # define __UINT_LEAST32_MAX UINT64_MAX
 # define __INT_LEAST16_MIN   INT64_MIN
 # define __INT_LEAST16_MAX   INT64_MAX
+# define __UINT_LEAST16_WIDTH UINT64_WIDTH
 # define __UINT_LEAST16_MAX UINT64_MAX
 # define __INT_LEAST8_MIN    INT64_MIN
 # define __INT_LEAST8_MAX    INT64_MAX
+# define __UINT_LEAST8_WIDTH UINT64_WIDTH
 # define __UINT_LEAST8_MAX  UINT64_MAX
 #endif /* __INT64_TYPE__ */
 
@@ -479,9 +485,13 @@
 # define INT_LEAST64_MIN   __INT_LEAST64_MIN
 # define INT_LEAST64_MAX   __INT_LEAST64_MAX
 # define UINT_LEAST64_MAX __UINT_LEAST64_MAX
+# define UINT_LEAST64_WIDTH __UINT_LEAST64_WIDTH
+# define INT_LEAST64_WIDTH  UINT_LEAST64_WIDTH
 # define INT_FAST64_MIN    __INT_LEAST64_MIN
 # define INT_FAST64_MAX    __INT_LEAST64_MAX
 # define UINT_FAST64_MAX  __UINT_LEAST64_MAX
+# define UINT_FAST64_WIDTH  __UINT_LEAST64_WIDTH
+# define INT_FAST64_WIDTH   UINT_FAST64_WIDTH
 #endif /* __INT_LEAST64_MIN */
 
 
@@ -489,20 +499,29 @@
 # define INT56_MAX           INT56_C(36028797018963967)
 # define INT56_MIN         (-INT56_C(36028797018963967)-1)
 # define UINT56_MAX         UINT56_C(72057594037927935)
+# define UINT56_WIDTH        56
+# define INT56_WIDTH         UINT56_WIDTH
 # define INT_LEAST56_MIN     INT56_MIN
 # define INT_LEAST56_MAX     INT56_MAX
+# define UINT_LEAST56_WIDTH  UINT56_WIDTH
+# define INT_LEAST56_WIDTH	 UINT_LEAST56_WIDTH
 # define UINT_LEAST56_MAX   UINT56_MAX
 # define INT_FAST56_MIN      INT56_MIN
 # define INT_FAST56_MAX      INT56_MAX
+# define UINT_FAST56_WIDTH	 UINT56_WIDTH
+# define INT_FAST56_WIDTH    UINT_FAST56_WIDTH
 # define UINT_FAST56_MAX    UINT56_MAX
 # define __INT_LEAST32_MIN   INT56_MIN
 # define __INT_LEAST32_MAX   INT56_MAX
+# define __UINT_LEAST32_WIDTH UINT56_WIDTH
 # define __UINT_LEAST32_MAX UINT56_MAX
 # define __INT_LEAST16_MIN   INT56_MIN
 # define __INT_LEAST16_MAX   INT56_MAX
+# define __UINT_LEAST16_WIDTH UINT56_WIDTH
 # define __UINT_LEAST16_MAX UINT56_MAX
 # define __INT_LEAST8_MIN    INT56_MIN
 # define __INT_LEAST8_MAX    INT56_MAX
+# define __UINT_LEAST8_WIDTH UINT56_WIDTH
 # define __UINT_LEAST8_MAX  UINT56_MAX
 #endif /* __INT56_TYPE__ */
 
@@ -511,20 +530,29 @@
 # define INT48_MAX           INT48_C(140737488355327)
 # define INT48_MIN         (-INT48_C(140737488355327)-1)
 # define UINT48_MAX         UINT48_C(281474976710655)
+# define UINT48_WIDTH        48
+# define INT48_WIDTH         UINT48_WIDTH
 # define INT_LEAST48_MIN     INT48_MIN
 # define INT_LEAST48_MAX     INT48_MAX
+# define UINT_LEAST48_WIDTH  UINT48_WIDTH
+# define INT_LEAST48_WIDTH	 UINT_LEAST48_WIDTH
 # define UINT_LEAST48_MAX   UINT48_MAX
 # define INT_FAST48_MIN      INT48_MIN
 # define INT_FAST48_MAX      INT48_MAX
+# define UINT_FAST48_WIDTH	 UINT48_WIDTH
+# define INT_FAST48_WIDTH    UINT_FAST48_WIDTH
 # define UINT_FAST48_MAX    UINT48_MAX
 # define __INT_LEAST32_MIN   INT48_MIN
 # define __INT_LEAST32_MAX   INT48_MAX
+# define __UINT_LEAST32_WIDTH UINT48_WIDTH
 # define __UINT_LEAST32_MAX UINT48_MAX
 # define __INT_LEAST16_MIN   INT48_MIN
 # define __INT_LEAST16_MAX   INT48_MAX
+# define __UINT_LEAST16_WIDTH UINT48_WIDTH
 # define __UINT_LEAST16_MAX UINT48_MAX
 # define __INT_LEAST8_MIN    INT48_MIN
 # define __INT_LEAST8_MAX    INT48_MAX
+# define __UINT_LEAST8_WIDTH UINT48_WIDTH
 # define __UINT_LEAST8_MAX  UINT48_MAX
 #endif /* __INT48_TYPE__ */
 
@@ -533,20 +561,29 @@
 # define INT40_MAX           INT40_C(549755813887)
 # define INT40_MIN         (-INT40_C(549755813887)-1)
 # define UINT40_MAX         UINT40_C(1099511627775)
+# define UINT40_WIDTH        40
+# define INT40_WIDTH         UINT40_WIDTH
 # define INT_LEAST40_MIN     INT40_MIN
 # define INT_LEAST40_MAX     INT40_MAX
+# define UINT_LEAST40_WIDTH  UINT40_WIDTH
+# define INT_LEAST40_WIDTH	 UINT_LEAST40_WIDTH
 # define UINT_LEAST40_MAX   UINT40_MAX
 # define INT_FAST40_MIN      INT40_MIN
 # define INT_FAST40_MAX      INT40_MAX
+# define UINT_FAST40_WIDTH	 UINT40_WIDTH
+# define INT_FAST40_WIDTH    UINT_FAST40_WIDTH
 # define UINT_FAST40_MAX    UINT40_MAX
 # define __INT_LEAST32_MIN   INT40_MIN
 # define __INT_LEAST32_MAX   INT40_MAX
+# define __UINT_LEAST32_WIDTH UINT40_WIDTH
 # define __UINT_LEAST32_MAX UINT40_MAX
 # define __INT_LEAST16_MIN   INT40_MIN
 # define __INT_LEAST16_MAX   INT40_MAX
+# define __UINT_LEAST16_WIDTH UINT40_WIDTH
 # define __UINT_LEAST16_MAX UINT40_MAX
 # define __INT_LEAST8_MIN    INT40_MIN
 # define __INT_LEAST8_MAX    INT40_MAX
+# define __UINT_LEAST8_WIDTH UINT40_WIDTH
 # define __UINT_LEAST8_MAX  UINT40_MAX
 #endif /* __INT40_TYPE__ */
 
@@ -555,14 +592,19 @@
 # define INT32_MAX           INT32_C(2147483647)
 # define INT32_MIN         (-INT32_C(2147483647)-1)
 # define UINT32_MAX         UINT32_C(4294967295)
+# define UINT32_WIDTH        32
+# define INT32_WIDTH         UINT32_WIDTH
 # define __INT_LEAST32_MIN   INT32_MIN
 # define __INT_LEAST32_MAX   INT32_MAX
+# define __UINT_LEAST32_WIDTH UINT32_WIDTH
 # define __UINT_LEAST32_MAX UINT32_MAX
 # define __INT_LEAST16_MIN   INT32_MIN
 # define __INT_LEAST16_MAX   INT32_MAX
+# define __UINT_LEAST16_WIDTH UINT32_WIDTH
 # define __UINT_LEAST16_MAX UINT32_MAX
 # define __INT_LEAST8_MIN    INT32_MIN
 # define __INT_LEAST8_MAX    INT32_MAX
+# define __UINT_LEAST8_WIDTH UINT32_WIDTH
 # define __UINT_LEAST8_MAX  UINT32_MAX
 #endif /* __INT32_TYPE__ */
 
@@ -570,9 +612,13 @@
 # define INT_LEAST32_MIN   __INT_LEAST32_MIN
 # define INT_LEAST32_MAX   __INT_LEAST32_MAX
 # define UINT_LEAST32_MAX __UINT_LEAST32_MAX
+# define UINT_LEAST32_WIDTH __UINT_LEAST32_WIDTH
+# define INT_LEAST32_WIDTH  UINT_LEAST32_WIDTH
 # define INT_FAST32_MIN    __INT_LEAST32_MIN
 # define INT_FAST32_MAX    __INT_LEAST32_MAX
 # define UINT_FAST32_MAX  __UINT_LEAST32_MAX
+# define UINT_FAST32_WIDTH __UINT_LEAST32_WIDTH
+# define INT_FAST32_WIDTH  UINT_FAST32_WIDTH
 #endif /* __INT_LEAST32_MIN */
 
 
@@ -580,17 +626,25 @@
 # define INT24_MAX           INT24_C(8388607)
 # define INT24_MIN         (-INT24_C(8388607)-1)
 # define UINT24_MAX         UINT24_C(16777215)
+# define UINT24_WIDTH        24
+# define INT24_WIDTH         UINT24_WIDTH
 # define INT_LEAST24_MIN     INT24_MIN
 # define INT_LEAST24_MAX     INT24_MAX
+# define UINT_LEAST24_WIDTH  UINT24_WIDTH
+# define INT_LEAST24_WIDTH   UINT_LEAST24_WIDTH
 # define UINT_LEAST24_MAX   UINT24_MAX
 # define INT_FAST24_MIN      INT24_MIN
 # define INT_FAST24_MAX      INT24_MAX
+# define UINT_FAST24_WIDTH   UINT24_WIDTH
+# define INT_FAST24_WIDTH    UINT_FAST24_WIDTH
 # define UINT_FAST24_MAX    UINT24_MAX
 # define __INT_LEAST16_MIN   INT24_MIN
 # define __INT_LEAST16_MAX   INT24_MAX
+# define __UINT_LEAST16_WIDTH UINT24_WIDTH
 # define __UINT_LEAST16_MAX UINT24_MAX
 # define __INT_LEAST8_MIN    INT24_MIN
 # define __INT_LEAST8_MAX    INT24_MAX
+# define __UINT_LEAST8_WIDTH UINT24_WIDTH
 # define __UINT_LEAST8_MAX  UINT24_MAX
 #endif /* __INT24_TYPE__ */
 
@@ -599,11 +653,15 @@
 #define INT16_MAX            INT16_C(32767)
 #define INT16_MIN          (-INT16_C(32767)-1)
 #define UINT16_MAX          UINT16_C(65535)
+#define UINT16_WIDTH         16
+#define INT16_WIDTH          UINT16_WIDTH
 # define __INT_LEAST16_MIN   INT16_MIN
 # define __INT_LEAST16_MAX   INT16_MAX
+# define __UINT_LEAST16_WIDTH UINT16_WIDTH
 # define __UINT_LEAST16_MAX UINT16_MAX
 # define __INT_LEAST8_MIN    INT16_MIN
 # define __INT_LEAST8_MAX    INT16_MAX
+# define __UINT_LEAST8_WIDTH UINT16_WIDTH
 # define __UINT_LEAST8_MAX  UINT16_MAX
 #endif /* __INT16_TYPE__ */
 
@@ -611,9 +669,13 @@
 # define INT_LEAST16_MIN   __INT_LEAST16_MIN
 # define INT_LEAST16_MAX   __INT_LEAST16_MAX
 # define UINT_LEAST16_MAX __UINT_LEAST16_MAX
+# define UINT_LEAST16_WIDTH __UINT_LEAST16_WIDTH
+# define INT_LEAST16_WIDTH  UINT_LEAST16_WIDTH
 # define INT_FAST16_MIN    __INT_LEAST16_MIN
 # define INT_FAST16_MAX    __INT_LEAST16_MAX
 # define UINT_FAST16_MAX  __UINT_LEAST16_MAX
+# define UINT_FAST16_WIDTH __UINT_LEAST16_WIDTH
+# define INT_FAST16_WIDTH  UINT_FAST16_WIDTH
 #endif /* __INT_LEAST16_MIN */
 
 
@@ -621,18 +683,26 @@
 # define INT8_MAX            INT8_C(127)
 # define INT8_MIN          (-INT8_C(127)-1)
 # define UINT8_MAX          UINT8_C(255)
+# define UINT8_WIDTH        8
+# define INT8_WIDTH         UINT8_WIDTH
+
 # define __INT_LEAST8_MIN    INT8_MIN
 # define __INT_LEAST8_MAX    INT8_MAX
 # define __UINT_LEAST8_MAX  UINT8_MAX
+# define __UINT_LEAST8_WIDTH UINT8_WIDTH
 #endif /* __INT8_TYPE__ */
 
 #ifdef __INT_LEAST8_MIN
 # define INT_LEAST8_MIN   __INT_LEAST8_MIN
 # define INT_LEAST8_MAX   __INT_LEAST8_MAX
 # define UINT_LEAST8_MAX __UINT_LEAST8_MAX
+# define UINT_LEAST8_WIDTH __UINT_LEAST8_WIDTH
+# define INT_LEAST8_WIDTH  UINT_LEAST8_WIDTH
 # define INT_FAST8_MIN    __INT_LEAST8_MIN
 # define INT_FAST8_MAX    __INT_LEAST8_MAX
 # define UINT_FAST8_MAX  __UINT_LEAST8_MAX
+# define UINT_FAST8_WIDTH __UINT_LEAST8_WIDTH
+# define INT_FAST8_WIDTH  UINT_FAST8_WIDTH
 #endif /* __INT_LEAST8_MIN */
 
 /* Some utility macros */
@@ -652,6 +722,16 @@
 #define PTRDIFF_MAX   __PTRDIFF_MAX__
 #define    SIZE_MAX      __SIZE_MAX__
 
+/* C2x 7.20.2.4 Width of integer types capable of holding object pointers. */
+/* FIXME: This is using the placeholder dates Clang produces for these macros
+   in C2x mode; switch to the correct values once they've been published. */
+#if __STDC_VERSION__ >= 202000L
+/* NB: The C standard requires that these be the same value, but the compiler
+   exposes separate internal width macros. */
+#define INTPTR_WIDTH  __INTPTR_WIDTH__
+#define UINTPTR_WIDTH __UINTPTR_WIDTH__
+#endif
+
 /* ISO9899:2011 7.20 (C11 Annex K): Define RSIZE_MAX if __STDC_WANT_LIB_EXT1__
  * is enabled. */
 #if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1
@@ -663,6 +743,16 @@
 #define  INTMAX_MAX   __INTMAX_MAX__
 #define UINTMAX_MAX  __UINTMAX_MAX__
 
+/* C2x 7.20.2.5 Width of greatest-width integer types. */
+/* FIXME: This is using the placeholder dates Clang produces for these macros
+   in C2x mode; switch to the correct values once they've been published. */
+#if __STDC_VERSION__ >= 202000L
+/* NB: The C standard requires that these be the same value, but the compiler
+   exposes separate internal width macros. */
+#define INTMAX_WIDTH __INTMAX_WIDTH__
+#define UINTMAX_WIDTH __UINTMAX_WIDTH__
+#endif
+
 /* C99 7.18.3 Limits of other integer types. */
 #define SIG_ATOMIC_MIN __INTN_MIN(__SIG_ATOMIC_WIDTH__)
 #define SIG_ATOMIC_MAX __INTN_MAX(__SIG_ATOMIC_WIDTH__)
@@ -689,5 +779,16 @@
 #define  INTMAX_C(v) __int_c(v,  __INTMAX_C_SUFFIX__)
 #define UINTMAX_C(v) __int_c(v, __UINTMAX_C_SUFFIX__)
 
+/* C2x 7.20.3.x Width of other integer types. */
+/* FIXME: This is using the placeholder dates Clang produces for these macros
+   in C2x mode; switch to the correct values once they've been published. */
+#if __STDC_VERSION__ >= 202000L
+#define PTRDIFF_WIDTH    __PTRDIFF_WIDTH__
+#define SIG_ATOMIC_WIDTH __SIG_ATOMIC_WIDTH__
+#define SIZE_WIDTH       __SIZE_WIDTH__
+#define WCHAR_WIDTH      __WCHAR_WIDTH__
+#define WINT_WIDTH       __WINT_WIDTH__
+#endif
+
 #endif /* __STDC_HOSTED__ */
 #endif /* __CLANG_STDINT_H */
Index: clang/lib/Headers/limits.h
===================================================================
--- clang/lib/Headers/limits.h
+++ clang/lib/Headers/limits.h
@@ -62,6 +62,24 @@
 
 #define CHAR_BIT  __CHAR_BIT__
 
+/* C2x 5.2.4.2.1 */
+/* FIXME: This is using the placeholder dates Clang produces for these macros
+   in C2x mode; switch to the correct values once they've been published. */
+#if __STDC_VERSION__ >= 202000L
+#define BOOL_WIDTH   __BOOL_WIDTH__
+#define CHAR_WIDTH   CHAR_BIT
+#define SCHAR_WIDTH  CHAR_BIT
+#define UCHAR_WIDTH  CHAR_BIT
+#define USHRT_WIDTH  __USHRT_WIDTH__
+#define SHRT_WIDTH   USHRT_WIDTH
+#define UINT_WIDTH   __UINT_WIDTH__
+#define INT_WIDTH    UINT_WIDTH
+#define ULONG_WIDTH  __ULONG_WIDTH__
+#define LONG_WIDTH   ULONG_WIDTH
+#define ULLONG_WIDTH __ULLONG_WIDTH__
+#define LLONG_WIDTH  ULLONG_WIDTH
+#endif
+
 #ifdef __CHAR_UNSIGNED__  /* -funsigned-char */
 #define CHAR_MIN 0
 #define CHAR_MAX UCHAR_MAX
Index: clang/lib/Frontend/InitPreprocessor.cpp
===================================================================
--- clang/lib/Frontend/InitPreprocessor.cpp
+++ clang/lib/Frontend/InitPreprocessor.cpp
@@ -194,7 +194,7 @@
   Builder.defineMacro(MacroName, TargetInfo::getTypeName(Ty));
 }
 
-static void DefineTypeWidth(StringRef MacroName, TargetInfo::IntType Ty,
+static void DefineTypeWidth(const Twine &MacroName, TargetInfo::IntType Ty,
                             const TargetInfo &TI, MacroBuilder &Builder) {
   Builder.defineMacro(MacroName, Twine(TI.getTypeWidth(Ty)));
 }
@@ -205,6 +205,16 @@
                       Twine(BitWidth / TI.getCharWidth()));
 }
 
+// This will generate a macro based on the prefix with `_MAX__` as the suffix
+// for the max value representable for the type, and a macro with a `_WIDTH__`
+// suffix for the width of the type.
+static void DefineTypeSizeAndWidth(const Twine &Prefix, TargetInfo::IntType Ty,
+                                   const TargetInfo &TI,
+                                   MacroBuilder &Builder) {
+  DefineTypeSize(Prefix + "_MAX__", Ty, TI, Builder);
+  DefineTypeWidth(Prefix + "_WIDTH__", Ty, TI, Builder);
+}
+
 static void DefineExactWidthIntType(TargetInfo::IntType Ty,
                                     const TargetInfo &TI,
                                     MacroBuilder &Builder) {
@@ -242,7 +252,7 @@
     Ty = IsSigned ? TI.getInt64Type() : TI.getUInt64Type();
 
   const char *Prefix = IsSigned ? "__INT" : "__UINT";
-  DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
+  DefineTypeSizeAndWidth(Prefix + Twine(TypeWidth), Ty, TI, Builder);
 }
 
 static void DefineLeastWidthIntType(unsigned TypeWidth, bool IsSigned,
@@ -254,7 +264,7 @@
 
   const char *Prefix = IsSigned ? "__INT_LEAST" : "__UINT_LEAST";
   DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
-  DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
+  DefineTypeSizeAndWidth(Prefix + Twine(TypeWidth), Ty, TI, Builder);
   DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder);
 }
 
@@ -268,8 +278,7 @@
 
   const char *Prefix = IsSigned ? "__INT_FAST" : "__UINT_FAST";
   DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
-  DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
-
+  DefineTypeSizeAndWidth(Prefix + Twine(TypeWidth), Ty, TI, Builder);
   DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder);
 }
 
@@ -887,20 +896,26 @@
   assert(TI.getCharWidth() == 8 && "Only support 8-bit char so far");
   Builder.defineMacro("__CHAR_BIT__", Twine(TI.getCharWidth()));
 
+  Builder.defineMacro("__BOOL_WIDTH__", Twine(TI.getBoolWidth()));
+  Builder.defineMacro("__USHRT_WIDTH__", Twine(TI.getShortWidth()));
+  Builder.defineMacro("__UINT_WIDTH__", Twine(TI.getIntWidth()));
+  Builder.defineMacro("__ULONG_WIDTH__", Twine(TI.getLongWidth()));
+  Builder.defineMacro("__ULLONG_WIDTH__", Twine(TI.getLongLongWidth()));
+
   DefineTypeSize("__SCHAR_MAX__", TargetInfo::SignedChar, TI, Builder);
   DefineTypeSize("__SHRT_MAX__", TargetInfo::SignedShort, TI, Builder);
   DefineTypeSize("__INT_MAX__", TargetInfo::SignedInt, TI, Builder);
   DefineTypeSize("__LONG_MAX__", TargetInfo::SignedLong, TI, Builder);
   DefineTypeSize("__LONG_LONG_MAX__", TargetInfo::SignedLongLong, TI, Builder);
-  DefineTypeSize("__WCHAR_MAX__", TI.getWCharType(), TI, Builder);
-  DefineTypeSize("__WINT_MAX__", TI.getWIntType(), TI, Builder);
-  DefineTypeSize("__INTMAX_MAX__", TI.getIntMaxType(), TI, Builder);
-  DefineTypeSize("__SIZE_MAX__", TI.getSizeType(), TI, Builder);
+  DefineTypeSizeAndWidth("__WCHAR", TI.getWCharType(), TI, Builder);
+  DefineTypeSizeAndWidth("__WINT", TI.getWIntType(), TI, Builder);
+  DefineTypeSizeAndWidth("__INTMAX", TI.getIntMaxType(), TI, Builder);
+  DefineTypeSizeAndWidth("__SIZE", TI.getSizeType(), TI, Builder);
 
-  DefineTypeSize("__UINTMAX_MAX__", TI.getUIntMaxType(), TI, Builder);
-  DefineTypeSize("__PTRDIFF_MAX__", TI.getPtrDiffType(0), TI, Builder);
-  DefineTypeSize("__INTPTR_MAX__", TI.getIntPtrType(), TI, Builder);
-  DefineTypeSize("__UINTPTR_MAX__", TI.getUIntPtrType(), TI, Builder);
+  DefineTypeSizeAndWidth("__UINTMAX", TI.getUIntMaxType(), TI, Builder);
+  DefineTypeSizeAndWidth("__PTRDIFF", TI.getPtrDiffType(0), TI, Builder);
+  DefineTypeSizeAndWidth("__INTPTR", TI.getIntPtrType(), TI, Builder);
+  DefineTypeSizeAndWidth("__UINTPTR", TI.getUIntPtrType(), TI, Builder);
 
   DefineTypeSizeof("__SIZEOF_DOUBLE__", TI.getDoubleWidth(), TI, Builder);
   DefineTypeSizeof("__SIZEOF_FLOAT__", TI.getFloatWidth(), TI, Builder);
@@ -929,29 +944,29 @@
   DefineFmt("__UINTMAX", TI.getUIntMaxType(), TI, Builder);
   Builder.defineMacro("__UINTMAX_C_SUFFIX__",
                       TI.getTypeConstantSuffix(TI.getUIntMaxType()));
-  DefineTypeWidth("__INTMAX_WIDTH__",  TI.getIntMaxType(), TI, Builder);
   DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(0), Builder);
   DefineFmt("__PTRDIFF", TI.getPtrDiffType(0), TI, Builder);
-  DefineTypeWidth("__PTRDIFF_WIDTH__", TI.getPtrDiffType(0), TI, Builder);
   DefineType("__INTPTR_TYPE__", TI.getIntPtrType(), Builder);
   DefineFmt("__INTPTR", TI.getIntPtrType(), TI, Builder);
-  DefineTypeWidth("__INTPTR_WIDTH__", TI.getIntPtrType(), TI, Builder);
   DefineType("__SIZE_TYPE__", TI.getSizeType(), Builder);
   DefineFmt("__SIZE", TI.getSizeType(), TI, Builder);
-  DefineTypeWidth("__SIZE_WIDTH__", TI.getSizeType(), TI, Builder);
   DefineType("__WCHAR_TYPE__", TI.getWCharType(), Builder);
-  DefineTypeWidth("__WCHAR_WIDTH__", TI.getWCharType(), TI, Builder);
   DefineType("__WINT_TYPE__", TI.getWIntType(), Builder);
-  DefineTypeWidth("__WINT_WIDTH__", TI.getWIntType(), TI, Builder);
-  DefineTypeWidth("__SIG_ATOMIC_WIDTH__", TI.getSigAtomicType(), TI, Builder);
-  DefineTypeSize("__SIG_ATOMIC_MAX__", TI.getSigAtomicType(), TI, Builder);
+  DefineTypeSizeAndWidth("__SIG_ATOMIC", TI.getSigAtomicType(), TI, Builder);
   DefineType("__CHAR16_TYPE__", TI.getChar16Type(), Builder);
   DefineType("__CHAR32_TYPE__", TI.getChar32Type(), Builder);
 
-  DefineTypeWidth("__UINTMAX_WIDTH__",  TI.getUIntMaxType(), TI, Builder);
   DefineType("__UINTPTR_TYPE__", TI.getUIntPtrType(), Builder);
   DefineFmt("__UINTPTR", TI.getUIntPtrType(), TI, Builder);
-  DefineTypeWidth("__UINTPTR_WIDTH__", TI.getUIntPtrType(), TI, Builder);
+
+  // The C standard requires the width of uintptr_t and intptr_t to be the same,
+  // per 7.20.2.4p1. Same for intmax_t and uintmax_t, per 7.20.2.5p1.
+  assert(TI.getTypeWidth(TI.getUIntPtrType()) ==
+             TI.getTypeWidth(TI.getIntPtrType()) &&
+         "uintptr_t and intptr_t have different widths?");
+  assert(TI.getTypeWidth(TI.getUIntMaxType()) ==
+             TI.getTypeWidth(TI.getIntMaxType()) &&
+         "uintmax_t and intmax_t have different widths?");
 
   if (TI.hasFloat16Type())
     DefineFloatMacros(Builder, "FLT16", &TI.getHalfFormat(), "F16");
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -156,6 +156,10 @@
   stabilized, so this type should not yet be used in interfaces that require
   ABI stability.
 
+- Implemented `WG14 N2412 <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2412.pdf>`_,
+  which adds ``*_WIDTH`` macros to limits.h and stdint.h to report the bit
+  width of various integer datatypes.
+
 C++ Language Changes in Clang
 -----------------------------
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to