-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[C23] Add __TYPE_FMTB__ and __TYPE_FMTb__ predefined macros #82361
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[C23] Add __TYPE_FMTB__ and __TYPE_FMTb__ predefined macros #82361
Conversation
This adds predefined formatting macros in C23 mode for printing unsigned integers in binary format (e.g, __UINT_FAST64_FMTB__). These are used to implement the PRIb (et al) macros in inttypes.h Fixes llvm#81896
...er, removing unrelated changes.
@llvm/pr-subscribers-clang Author: Aaron Ballman (AaronBallman) ChangesThis adds predefined formatting macros in C23 mode for printing unsigned integers in binary format (e.g, UINT_FAST64_FMTB). These are used to implement the PRIb (et al) macros in inttypes.h Fixes #81896 (Was previously reviewed in 82037, this is fixing some failures found post-commit.) Full diff: https://github.com/llvm/llvm-project/pull/82361.diff 3 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 16f79a349c20c8..7083d66ae8f45d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -135,6 +135,11 @@ C23 Feature Support
Fixes (`#81472 <https://github.com/llvm/llvm-project/issues/81472>`_).
+- Clang now generates predefined macros of the form ``__TYPE_FMTB__`` and
+ ``__TYPE_FMTb__`` (e.g., ``__UINT_FAST64_FMTB__``) in C23 mode for use with
+ macros typically exposed from ``<inttypes.h>``, such as ``PRIb8``.
+ (`#81896: <https://github.com/llvm/llvm-project/issues/81896>`_).
+
Non-comprehensive list of changes in this release
-------------------------------------------------
diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 1b250cda42a4dd..9b979d810fa127 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -181,14 +181,21 @@ static void DefineTypeSize(const Twine &MacroName, TargetInfo::IntType Ty,
TI.isTypeSigned(Ty), Builder);
}
-static void DefineFmt(const Twine &Prefix, TargetInfo::IntType Ty,
- const TargetInfo &TI, MacroBuilder &Builder) {
- bool IsSigned = TI.isTypeSigned(Ty);
+static void DefineFmt(const LangOptions &LangOpts, const Twine &Prefix,
+ TargetInfo::IntType Ty, const TargetInfo &TI,
+ MacroBuilder &Builder) {
StringRef FmtModifier = TI.getTypeFormatModifier(Ty);
- for (const char *Fmt = IsSigned ? "di" : "ouxX"; *Fmt; ++Fmt) {
- Builder.defineMacro(Prefix + "_FMT" + Twine(*Fmt) + "__",
- Twine("\"") + FmtModifier + Twine(*Fmt) + "\"");
- }
+ auto Emitter = [&](char Fmt) {
+ Builder.defineMacro(Prefix + "_FMT" + Twine(Fmt) + "__",
+ Twine("\"") + FmtModifier + Twine(Fmt) + "\"");
+ };
+ bool IsSigned = TI.isTypeSigned(Ty);
+ llvm::for_each(StringRef(IsSigned ? "di" : "ouxX"), Emitter);
+
+ // C23 added the b and B modifiers for printing binary output of unsigned
+ // integers. Conditionally define those if compiling in C23 mode.
+ if (LangOpts.C23 && !IsSigned)
+ llvm::for_each(StringRef("bB"), Emitter);
}
static void DefineType(const Twine &MacroName, TargetInfo::IntType Ty,
@@ -217,7 +224,8 @@ static void DefineTypeSizeAndWidth(const Twine &Prefix, TargetInfo::IntType Ty,
DefineTypeWidth(Prefix + "_WIDTH__", Ty, TI, Builder);
}
-static void DefineExactWidthIntType(TargetInfo::IntType Ty,
+static void DefineExactWidthIntType(const LangOptions &LangOpts,
+ TargetInfo::IntType Ty,
const TargetInfo &TI,
MacroBuilder &Builder) {
int TypeWidth = TI.getTypeWidth(Ty);
@@ -236,7 +244,7 @@ static void DefineExactWidthIntType(TargetInfo::IntType Ty,
const char *Prefix = IsSigned ? "__INT" : "__UINT";
DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
- DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder);
+ DefineFmt(LangOpts, Prefix + Twine(TypeWidth), Ty, TI, Builder);
StringRef ConstSuffix(TI.getTypeConstantSuffix(Ty));
Builder.defineMacro(Prefix + Twine(TypeWidth) + "_C_SUFFIX__", ConstSuffix);
@@ -259,7 +267,8 @@ static void DefineExactWidthIntTypeSize(TargetInfo::IntType Ty,
DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
}
-static void DefineLeastWidthIntType(unsigned TypeWidth, bool IsSigned,
+static void DefineLeastWidthIntType(const LangOptions &LangOpts,
+ unsigned TypeWidth, bool IsSigned,
const TargetInfo &TI,
MacroBuilder &Builder) {
TargetInfo::IntType Ty = TI.getLeastIntTypeByWidth(TypeWidth, IsSigned);
@@ -274,11 +283,12 @@ static void DefineLeastWidthIntType(unsigned TypeWidth, bool IsSigned,
DefineTypeSizeAndWidth(Prefix + Twine(TypeWidth), Ty, TI, Builder);
else
DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
- DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder);
+ DefineFmt(LangOpts, Prefix + Twine(TypeWidth), Ty, TI, Builder);
}
-static void DefineFastIntType(unsigned TypeWidth, bool IsSigned,
- const TargetInfo &TI, MacroBuilder &Builder) {
+static void DefineFastIntType(const LangOptions &LangOpts, unsigned TypeWidth,
+ bool IsSigned, const TargetInfo &TI,
+ MacroBuilder &Builder) {
// stdint.h currently defines the fast int types as equivalent to the least
// types.
TargetInfo::IntType Ty = TI.getLeastIntTypeByWidth(TypeWidth, IsSigned);
@@ -293,7 +303,7 @@ static void DefineFastIntType(unsigned TypeWidth, bool IsSigned,
DefineTypeSizeAndWidth(Prefix + Twine(TypeWidth), Ty, TI, Builder);
else
DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
- DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder);
+ DefineFmt(LangOpts, Prefix + Twine(TypeWidth), Ty, TI, Builder);
}
@@ -1120,19 +1130,20 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
DefineTypeSizeof("__SIZEOF_INT128__", 128, TI, Builder);
DefineType("__INTMAX_TYPE__", TI.getIntMaxType(), Builder);
- DefineFmt("__INTMAX", TI.getIntMaxType(), TI, Builder);
+ DefineFmt(LangOpts, "__INTMAX", TI.getIntMaxType(), TI, Builder);
Builder.defineMacro("__INTMAX_C_SUFFIX__",
TI.getTypeConstantSuffix(TI.getIntMaxType()));
DefineType("__UINTMAX_TYPE__", TI.getUIntMaxType(), Builder);
- DefineFmt("__UINTMAX", TI.getUIntMaxType(), TI, Builder);
+ DefineFmt(LangOpts, "__UINTMAX", TI.getUIntMaxType(), TI, Builder);
Builder.defineMacro("__UINTMAX_C_SUFFIX__",
TI.getTypeConstantSuffix(TI.getUIntMaxType()));
DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(LangAS::Default), Builder);
- DefineFmt("__PTRDIFF", TI.getPtrDiffType(LangAS::Default), TI, Builder);
+ DefineFmt(LangOpts, "__PTRDIFF", TI.getPtrDiffType(LangAS::Default), TI,
+ Builder);
DefineType("__INTPTR_TYPE__", TI.getIntPtrType(), Builder);
- DefineFmt("__INTPTR", TI.getIntPtrType(), TI, Builder);
+ DefineFmt(LangOpts, "__INTPTR", TI.getIntPtrType(), TI, Builder);
DefineType("__SIZE_TYPE__", TI.getSizeType(), Builder);
- DefineFmt("__SIZE", TI.getSizeType(), TI, Builder);
+ DefineFmt(LangOpts, "__SIZE", TI.getSizeType(), TI, Builder);
DefineType("__WCHAR_TYPE__", TI.getWCharType(), Builder);
DefineType("__WINT_TYPE__", TI.getWIntType(), Builder);
DefineTypeSizeAndWidth("__SIG_ATOMIC", TI.getSigAtomicType(), TI, Builder);
@@ -1140,7 +1151,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
DefineType("__CHAR32_TYPE__", TI.getChar32Type(), Builder);
DefineType("__UINTPTR_TYPE__", TI.getUIntPtrType(), Builder);
- DefineFmt("__UINTPTR", TI.getUIntPtrType(), TI, Builder);
+ DefineFmt(LangOpts, "__UINTPTR", 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.
@@ -1216,65 +1227,66 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
Builder.defineMacro("__WINT_UNSIGNED__");
// Define exact-width integer types for stdint.h
- DefineExactWidthIntType(TargetInfo::SignedChar, TI, Builder);
+ DefineExactWidthIntType(LangOpts, TargetInfo::SignedChar, TI, Builder);
if (TI.getShortWidth() > TI.getCharWidth())
- DefineExactWidthIntType(TargetInfo::SignedShort, TI, Builder);
+ DefineExactWidthIntType(LangOpts, TargetInfo::SignedShort, TI, Builder);
if (TI.getIntWidth() > TI.getShortWidth())
- DefineExactWidthIntType(TargetInfo::SignedInt, TI, Builder);
+ DefineExactWidthIntType(LangOpts, TargetInfo::SignedInt, TI, Builder);
if (TI.getLongWidth() > TI.getIntWidth())
- DefineExactWidthIntType(TargetInfo::SignedLong, TI, Builder);
+ DefineExactWidthIntType(LangOpts, TargetInfo::SignedLong, TI, Builder);
if (TI.getLongLongWidth() > TI.getLongWidth())
- DefineExactWidthIntType(TargetInfo::SignedLongLong, TI, Builder);
+ DefineExactWidthIntType(LangOpts, TargetInfo::SignedLongLong, TI, Builder);
- DefineExactWidthIntType(TargetInfo::UnsignedChar, TI, Builder);
+ DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedChar, TI, Builder);
DefineExactWidthIntTypeSize(TargetInfo::UnsignedChar, TI, Builder);
DefineExactWidthIntTypeSize(TargetInfo::SignedChar, TI, Builder);
if (TI.getShortWidth() > TI.getCharWidth()) {
- DefineExactWidthIntType(TargetInfo::UnsignedShort, TI, Builder);
+ DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedShort, TI, Builder);
DefineExactWidthIntTypeSize(TargetInfo::UnsignedShort, TI, Builder);
DefineExactWidthIntTypeSize(TargetInfo::SignedShort, TI, Builder);
}
if (TI.getIntWidth() > TI.getShortWidth()) {
- DefineExactWidthIntType(TargetInfo::UnsignedInt, TI, Builder);
+ DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedInt, TI, Builder);
DefineExactWidthIntTypeSize(TargetInfo::UnsignedInt, TI, Builder);
DefineExactWidthIntTypeSize(TargetInfo::SignedInt, TI, Builder);
}
if (TI.getLongWidth() > TI.getIntWidth()) {
- DefineExactWidthIntType(TargetInfo::UnsignedLong, TI, Builder);
+ DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedLong, TI, Builder);
DefineExactWidthIntTypeSize(TargetInfo::UnsignedLong, TI, Builder);
DefineExactWidthIntTypeSize(TargetInfo::SignedLong, TI, Builder);
}
if (TI.getLongLongWidth() > TI.getLongWidth()) {
- DefineExactWidthIntType(TargetInfo::UnsignedLongLong, TI, Builder);
+ DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedLongLong, TI,
+ Builder);
DefineExactWidthIntTypeSize(TargetInfo::UnsignedLongLong, TI, Builder);
DefineExactWidthIntTypeSize(TargetInfo::SignedLongLong, TI, Builder);
}
- DefineLeastWidthIntType(8, true, TI, Builder);
- DefineLeastWidthIntType(8, false, TI, Builder);
- DefineLeastWidthIntType(16, true, TI, Builder);
- DefineLeastWidthIntType(16, false, TI, Builder);
- DefineLeastWidthIntType(32, true, TI, Builder);
- DefineLeastWidthIntType(32, false, TI, Builder);
- DefineLeastWidthIntType(64, true, TI, Builder);
- DefineLeastWidthIntType(64, false, TI, Builder);
-
- DefineFastIntType(8, true, TI, Builder);
- DefineFastIntType(8, false, TI, Builder);
- DefineFastIntType(16, true, TI, Builder);
- DefineFastIntType(16, false, TI, Builder);
- DefineFastIntType(32, true, TI, Builder);
- DefineFastIntType(32, false, TI, Builder);
- DefineFastIntType(64, true, TI, Builder);
- DefineFastIntType(64, false, TI, Builder);
+ DefineLeastWidthIntType(LangOpts, 8, true, TI, Builder);
+ DefineLeastWidthIntType(LangOpts, 8, false, TI, Builder);
+ DefineLeastWidthIntType(LangOpts, 16, true, TI, Builder);
+ DefineLeastWidthIntType(LangOpts, 16, false, TI, Builder);
+ DefineLeastWidthIntType(LangOpts, 32, true, TI, Builder);
+ DefineLeastWidthIntType(LangOpts, 32, false, TI, Builder);
+ DefineLeastWidthIntType(LangOpts, 64, true, TI, Builder);
+ DefineLeastWidthIntType(LangOpts, 64, false, TI, Builder);
+
+ DefineFastIntType(LangOpts, 8, true, TI, Builder);
+ DefineFastIntType(LangOpts, 8, false, TI, Builder);
+ DefineFastIntType(LangOpts, 16, true, TI, Builder);
+ DefineFastIntType(LangOpts, 16, false, TI, Builder);
+ DefineFastIntType(LangOpts, 32, true, TI, Builder);
+ DefineFastIntType(LangOpts, 32, false, TI, Builder);
+ DefineFastIntType(LangOpts, 64, true, TI, Builder);
+ DefineFastIntType(LangOpts, 64, false, TI, Builder);
Builder.defineMacro("__USER_LABEL_PREFIX__", TI.getUserLabelPrefix());
diff --git a/clang/test/Preprocessor/init.c b/clang/test/Preprocessor/init.c
index c3dbd94b2f741b..c4a55efca6f712 100644
--- a/clang/test/Preprocessor/init.c
+++ b/clang/test/Preprocessor/init.c
@@ -93,6 +93,70 @@
// C99-NOT: __GXX_WEAK__
// C99-NOT: __cplusplus
//
+// RUN: %clang_cc1 -std=c17 -triple=x86_64-pc-win32 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix C17-FMT %s
+// RUN: %clang_cc1 -std=c23 -triple=x86_64-pc-win32 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix C23-FMT %s
+//
+// C17-FMT-NOT: __SIZE_FMTB__
+// C17-FMT-NOT: __SIZE_FMTb__
+// C17-FMT-NOT: __UINT8_FMTB__
+// C17-FMT-NOT: __UINT8_FMTb__
+// C17-FMT-NOT: __UINT16_FMTB__
+// C17-FMT-NOT: __UINT16_FMTb__
+// C17-FMT-NOT: __UINT32_FMTB__
+// C17-FMT-NOT: __UINT32_FMTb__
+// C17-FMT-NOT: __UINT64_FMTB__
+// C17-FMT-NOT: __UINT64_FMTb__
+// C17-FMT-NOT: __UINTMAX_FMTB__
+// C17-FMT-NOT: __UINTMAX_FMTb__
+// C17-FMT-NOT: __UINTPTR_FMTB__
+// C17-FMT-NOT: __UINTPTR_FMTb__
+// C17-FMT-NOT: __UINT_FAST16_FMTB__
+// C17-FMT-NOT: __UINT_FAST16_FMTb__
+// C17-FMT-NOT: __UINT_FAST32_FMTB__
+// C17-FMT-NOT: __UINT_FAST32_FMTb__
+// C17-FMT-NOT: __UINT_FAST64_FMTB__
+// C17-FMT-NOT: __UINT_FAST64_FMTb__
+// C17-FMT-NOT: __UINT_FAST8_FMTB__
+// C17-FMT-NOT: __UINT_FAST8_FMTb__
+// C17-FMT-NOT: __UINT_LEAST16_FMTB__
+// C17-FMT-NOT: __UINT_LEAST16_FMTb__
+// C17-FMT-NOT: __UINT_LEAST32_FMTB__
+// C17-FMT-NOT: __UINT_LEAST32_FMTb__
+// C17-FMT-NOT: __UINT_LEAST64_FMTB__
+// C17-FMT-NOT: __UINT_LEAST64_FMTb__
+// C17-FMT-NOT: __UINT_LEAST8_FMTB__
+// C17-FMT-NOT: __UINT_LEAST8_FMTb__
+// C23-FMT: #define __SIZE_FMTB__ "llB"
+// C23-FMT: #define __SIZE_FMTb__ "llb"
+// C23-FMT: #define __UINT16_FMTB__ "hB"
+// C23-FMT: #define __UINT16_FMTb__ "hb"
+// C23-FMT: #define __UINT32_FMTB__ "B"
+// C23-FMT: #define __UINT32_FMTb__ "b"
+// C23-FMT: #define __UINT64_FMTB__ "llB"
+// C23-FMT: #define __UINT64_FMTb__ "llb"
+// C23-FMT: #define __UINT8_FMTB__ "hhB"
+// C23-FMT: #define __UINT8_FMTb__ "hhb"
+// C23-FMT: #define __UINTMAX_FMTB__ "llB"
+// C23-FMT: #define __UINTMAX_FMTb__ "llb"
+// C23-FMT: #define __UINTPTR_FMTB__ "llB"
+// C23-FMT: #define __UINTPTR_FMTb__ "llb"
+// C23-FMT: #define __UINT_FAST16_FMTB__ "hB"
+// C23-FMT: #define __UINT_FAST16_FMTb__ "hb"
+// C23-FMT: #define __UINT_FAST32_FMTB__ "B"
+// C23-FMT: #define __UINT_FAST32_FMTb__ "b"
+// C23-FMT: #define __UINT_FAST64_FMTB__ "llB"
+// C23-FMT: #define __UINT_FAST64_FMTb__ "llb"
+// C23-FMT: #define __UINT_FAST8_FMTB__ "hhB"
+// C23-FMT: #define __UINT_FAST8_FMTb__ "hhb"
+// C23-FMT: #define __UINT_LEAST16_FMTB__ "hB"
+// C23-FMT: #define __UINT_LEAST16_FMTb__ "hb"
+// C23-FMT: #define __UINT_LEAST32_FMTB__ "B"
+// C23-FMT: #define __UINT_LEAST32_FMTb__ "b"
+// C23-FMT: #define __UINT_LEAST64_FMTB__ "llB"
+// C23-FMT: #define __UINT_LEAST64_FMTb__ "llb"
+// C23-FMT: #define __UINT_LEAST8_FMTB__ "hhB"
+// C23-FMT: #define __UINT_LEAST8_FMTb__ "hhb"
+//
//
// RUN: %clang_cc1 -std=c11 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix C11 %s
// RUN: %clang_cc1 -std=c1x -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix C11 %s
|
You can test this locally with the following command:git-clang-format --diff a4ce870859a2d8b5ce8b92732594089e2a81b4fb eb729828e8052b14ac61a36fe1d3b3965c0ef185 -- clang/lib/Frontend/InitPreprocessor.cpp clang/test/Preprocessor/init.c View the diff from clang-format here.diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp
index 9b979d810f..17715121f1 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -306,7 +306,6 @@ static void DefineFastIntType(const LangOptions &LangOpts, unsigned TypeWidth,
DefineFmt(LangOpts, Prefix + Twine(TypeWidth), Ty, TI, Builder);
}
-
/// Get the value the ATOMIC_*_LOCK_FREE macro should have for a type with
/// the specified properties.
static const char *getLockFreeValue(unsigned TypeWidth, const TargetInfo &TI) {
|
This adds predefined formatting macros in C23 mode for printing unsigned integers in binary format (e.g, UINT_FAST64_FMTB). These are used to implement the PRIb (et al) macros in inttypes.h
Fixes #81896
(Was previously reviewed in 82037, this is fixing some failures found post-commit.)