diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -25,6 +25,7 @@ #include "clang/Serialization/ASTReader.h" #include "llvm/ADT/APFloat.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" using namespace clang; static bool MacroBodyEndsInBackslash(StringRef MacroBody) { @@ -914,6 +915,12 @@ Builder.defineMacro("__LONG_WIDTH__", Twine(TI.getLongWidth())); Builder.defineMacro("__LLONG_WIDTH__", Twine(TI.getLongLongWidth())); + // The max size of a _BitInt is limited in SemaType.cpp to this value. If + // someday a target needs to pick a different value for this macro, be sure + // to update Sema::BuildBitIntType() as well. + Builder.defineMacro("__BITINT_MAXWIDTH__", + Twine(llvm::IntegerType::MAX_INT_BITS)); + DefineTypeSize("__SCHAR_MAX__", TargetInfo::SignedChar, TI, Builder); DefineTypeSize("__SHRT_MAX__", TargetInfo::SignedShort, TI, Builder); DefineTypeSize("__INT_MAX__", TargetInfo::SignedInt, TI, Builder); diff --git a/clang/lib/Headers/limits.h b/clang/lib/Headers/limits.h --- a/clang/lib/Headers/limits.h +++ b/clang/lib/Headers/limits.h @@ -78,6 +78,8 @@ #define LONG_WIDTH __LONG_WIDTH__ #define ULLONG_WIDTH __LLONG_WIDTH__ #define LLONG_WIDTH __LLONG_WIDTH__ + +#define BITINT_MAXWIDTH __BITINT_MAXWIDTH__ #endif #ifdef __CHAR_UNSIGNED__ /* -funsigned-char */ diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2267,6 +2267,10 @@ return QualType(); } + // The max size of a _BitInt is exposed to the user via the + // __BITINT_MAXWIDTH__ macro from InitPreprocessor.cpp. If someday a target + // needs to pick a different max value, be sure to update + // InitializePredefinedMacros() as well. if (NumBits > llvm::IntegerType::MAX_INT_BITS) { Diag(Loc, diag::err_bit_int_max_size) << IsUnsigned << llvm::IntegerType::MAX_INT_BITS; diff --git a/clang/test/Headers/limits.cpp b/clang/test/Headers/limits.cpp --- a/clang/test/Headers/limits.cpp +++ b/clang/test/Headers/limits.cpp @@ -74,8 +74,11 @@ _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)); + +_Static_assert(BITINT_MAXWIDTH >= ULLONG_WIDTH); #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; + UINT_WIDTH, INT_WIDTH, ULONG_WIDTH, LONG_WIDTH, ULLONG_WIDTH, LLONG_WIDTH, + BITINT_MAXWIDTH; #endif diff --git a/clang/test/Preprocessor/init-aarch64.c b/clang/test/Preprocessor/init-aarch64.c --- a/clang/test/Preprocessor/init-aarch64.c +++ b/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 __BITINT_MAXWIDTH__ 8388608 // AARCH64-NEXT: #define __BOOL_WIDTH__ 8 // AARCH64_BE-NEXT: #define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__ // AARCH64_LE-NEXT: #define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ diff --git a/clang/test/Preprocessor/init.c b/clang/test/Preprocessor/init.c --- a/clang/test/Preprocessor/init.c +++ b/clang/test/Preprocessor/init.c @@ -1520,6 +1520,7 @@ // WEBASSEMBLY-NEXT:#define __ATOMIC_RELEASE 3 // WEBASSEMBLY-NEXT:#define __ATOMIC_SEQ_CST 5 // WEBASSEMBLY-NEXT:#define __BIGGEST_ALIGNMENT__ 16 +// WEBASSEMBLY-NEXT:#define __BITINT_MAXWIDTH__ 8388608 // WEBASSEMBLY-NEXT:#define __BOOL_WIDTH__ 8 // WEBASSEMBLY-NEXT:#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__ // WEBASSEMBLY-NEXT:#define __CHAR16_TYPE__ unsigned short