Skip to content

Commit b3050f5

Browse files
authored
[C23] Add __TYPE_FMTB__ and __TYPE_FMTb__ predefined macros (#82037)
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
1 parent 8d6b451 commit b3050f5

File tree

3 files changed

+128
-47
lines changed

3 files changed

+128
-47
lines changed

clang/docs/ReleaseNotes.rst

+5
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@ C23 Feature Support
135135
136136
Fixes (`#81472 <https://github.com/llvm/llvm-project/issues/81472>`_).
137137

138+
- Clang now generates predefined macros of the form ``__TYPE_FMTB__`` and
139+
``__TYPE_FMTb__`` (e.g., ``__UINT_FAST64_FMTB__``) in C23 mode for use with
140+
macros typically exposed from ``<inttypes.h>``, such as ``PRIb8``.
141+
(`#81896: <https://github.com/llvm/llvm-project/issues/81896>`_).
142+
138143
Non-comprehensive list of changes in this release
139144
-------------------------------------------------
140145

clang/lib/Frontend/InitPreprocessor.cpp

+59-47
Original file line numberDiff line numberDiff line change
@@ -181,14 +181,21 @@ static void DefineTypeSize(const Twine &MacroName, TargetInfo::IntType Ty,
181181
TI.isTypeSigned(Ty), Builder);
182182
}
183183

184-
static void DefineFmt(const Twine &Prefix, TargetInfo::IntType Ty,
185-
const TargetInfo &TI, MacroBuilder &Builder) {
186-
bool IsSigned = TI.isTypeSigned(Ty);
184+
static void DefineFmt(const LangOptions &LangOpts, const Twine &Prefix,
185+
TargetInfo::IntType Ty, const TargetInfo &TI,
186+
MacroBuilder &Builder) {
187187
StringRef FmtModifier = TI.getTypeFormatModifier(Ty);
188-
for (const char *Fmt = IsSigned ? "di" : "ouxX"; *Fmt; ++Fmt) {
189-
Builder.defineMacro(Prefix + "_FMT" + Twine(*Fmt) + "__",
190-
Twine("\"") + FmtModifier + Twine(*Fmt) + "\"");
191-
}
188+
auto Emitter = [&](char Fmt) {
189+
Builder.defineMacro(Prefix + "_FMT" + Twine(Fmt) + "__",
190+
Twine("\"") + FmtModifier + Twine(Fmt) + "\"");
191+
};
192+
bool IsSigned = TI.isTypeSigned(Ty);
193+
llvm::for_each(StringRef(IsSigned ? "di" : "ouxX"), Emitter);
194+
195+
// C23 added the b and B modifiers for printing binary output of unsigned
196+
// integers. Conditionally define those if compiling in C23 mode.
197+
if (LangOpts.C23 && !IsSigned)
198+
llvm::for_each(StringRef("bB"), Emitter);
192199
}
193200

194201
static void DefineType(const Twine &MacroName, TargetInfo::IntType Ty,
@@ -217,7 +224,8 @@ static void DefineTypeSizeAndWidth(const Twine &Prefix, TargetInfo::IntType Ty,
217224
DefineTypeWidth(Prefix + "_WIDTH__", Ty, TI, Builder);
218225
}
219226

220-
static void DefineExactWidthIntType(TargetInfo::IntType Ty,
227+
static void DefineExactWidthIntType(const LangOptions &LangOpts,
228+
TargetInfo::IntType Ty,
221229
const TargetInfo &TI,
222230
MacroBuilder &Builder) {
223231
int TypeWidth = TI.getTypeWidth(Ty);
@@ -236,7 +244,7 @@ static void DefineExactWidthIntType(TargetInfo::IntType Ty,
236244
const char *Prefix = IsSigned ? "__INT" : "__UINT";
237245

238246
DefineType(Prefix + Twine(TypeWidth) + "_TYPE__", Ty, Builder);
239-
DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder);
247+
DefineFmt(LangOpts, Prefix + Twine(TypeWidth), Ty, TI, Builder);
240248

241249
StringRef ConstSuffix(TI.getTypeConstantSuffix(Ty));
242250
Builder.defineMacro(Prefix + Twine(TypeWidth) + "_C_SUFFIX__", ConstSuffix);
@@ -259,7 +267,8 @@ static void DefineExactWidthIntTypeSize(TargetInfo::IntType Ty,
259267
DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
260268
}
261269

262-
static void DefineLeastWidthIntType(unsigned TypeWidth, bool IsSigned,
270+
static void DefineLeastWidthIntType(const LangOptions &LangOpts,
271+
unsigned TypeWidth, bool IsSigned,
263272
const TargetInfo &TI,
264273
MacroBuilder &Builder) {
265274
TargetInfo::IntType Ty = TI.getLeastIntTypeByWidth(TypeWidth, IsSigned);
@@ -274,11 +283,12 @@ static void DefineLeastWidthIntType(unsigned TypeWidth, bool IsSigned,
274283
DefineTypeSizeAndWidth(Prefix + Twine(TypeWidth), Ty, TI, Builder);
275284
else
276285
DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
277-
DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder);
286+
DefineFmt(LangOpts, Prefix + Twine(TypeWidth), Ty, TI, Builder);
278287
}
279288

280-
static void DefineFastIntType(unsigned TypeWidth, bool IsSigned,
281-
const TargetInfo &TI, MacroBuilder &Builder) {
289+
static void DefineFastIntType(const LangOptions &LangOpts, unsigned TypeWidth,
290+
bool IsSigned, const TargetInfo &TI,
291+
MacroBuilder &Builder) {
282292
// stdint.h currently defines the fast int types as equivalent to the least
283293
// types.
284294
TargetInfo::IntType Ty = TI.getLeastIntTypeByWidth(TypeWidth, IsSigned);
@@ -293,7 +303,7 @@ static void DefineFastIntType(unsigned TypeWidth, bool IsSigned,
293303
DefineTypeSizeAndWidth(Prefix + Twine(TypeWidth), Ty, TI, Builder);
294304
else
295305
DefineTypeSize(Prefix + Twine(TypeWidth) + "_MAX__", Ty, TI, Builder);
296-
DefineFmt(Prefix + Twine(TypeWidth), Ty, TI, Builder);
306+
DefineFmt(LangOpts, Prefix + Twine(TypeWidth), Ty, TI, Builder);
297307
}
298308

299309

@@ -1120,27 +1130,28 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
11201130
DefineTypeSizeof("__SIZEOF_INT128__", 128, TI, Builder);
11211131

11221132
DefineType("__INTMAX_TYPE__", TI.getIntMaxType(), Builder);
1123-
DefineFmt("__INTMAX", TI.getIntMaxType(), TI, Builder);
1133+
DefineFmt(LangOpts, "__INTMAX", TI.getIntMaxType(), TI, Builder);
11241134
Builder.defineMacro("__INTMAX_C_SUFFIX__",
11251135
TI.getTypeConstantSuffix(TI.getIntMaxType()));
11261136
DefineType("__UINTMAX_TYPE__", TI.getUIntMaxType(), Builder);
1127-
DefineFmt("__UINTMAX", TI.getUIntMaxType(), TI, Builder);
1137+
DefineFmt(LangOpts, "__UINTMAX", TI.getUIntMaxType(), TI, Builder);
11281138
Builder.defineMacro("__UINTMAX_C_SUFFIX__",
11291139
TI.getTypeConstantSuffix(TI.getUIntMaxType()));
11301140
DefineType("__PTRDIFF_TYPE__", TI.getPtrDiffType(LangAS::Default), Builder);
1131-
DefineFmt("__PTRDIFF", TI.getPtrDiffType(LangAS::Default), TI, Builder);
1141+
DefineFmt(LangOpts, "__PTRDIFF", TI.getPtrDiffType(LangAS::Default), TI,
1142+
Builder);
11321143
DefineType("__INTPTR_TYPE__", TI.getIntPtrType(), Builder);
1133-
DefineFmt("__INTPTR", TI.getIntPtrType(), TI, Builder);
1144+
DefineFmt(LangOpts, "__INTPTR", TI.getIntPtrType(), TI, Builder);
11341145
DefineType("__SIZE_TYPE__", TI.getSizeType(), Builder);
1135-
DefineFmt("__SIZE", TI.getSizeType(), TI, Builder);
1146+
DefineFmt(LangOpts, "__SIZE", TI.getSizeType(), TI, Builder);
11361147
DefineType("__WCHAR_TYPE__", TI.getWCharType(), Builder);
11371148
DefineType("__WINT_TYPE__", TI.getWIntType(), Builder);
11381149
DefineTypeSizeAndWidth("__SIG_ATOMIC", TI.getSigAtomicType(), TI, Builder);
11391150
DefineType("__CHAR16_TYPE__", TI.getChar16Type(), Builder);
11401151
DefineType("__CHAR32_TYPE__", TI.getChar32Type(), Builder);
11411152

11421153
DefineType("__UINTPTR_TYPE__", TI.getUIntPtrType(), Builder);
1143-
DefineFmt("__UINTPTR", TI.getUIntPtrType(), TI, Builder);
1154+
DefineFmt(LangOpts, "__UINTPTR", TI.getUIntPtrType(), TI, Builder);
11441155

11451156
// The C standard requires the width of uintptr_t and intptr_t to be the same,
11461157
// 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,
12161227
Builder.defineMacro("__WINT_UNSIGNED__");
12171228

12181229
// Define exact-width integer types for stdint.h
1219-
DefineExactWidthIntType(TargetInfo::SignedChar, TI, Builder);
1230+
DefineExactWidthIntType(LangOpts, TargetInfo::SignedChar, TI, Builder);
12201231

12211232
if (TI.getShortWidth() > TI.getCharWidth())
1222-
DefineExactWidthIntType(TargetInfo::SignedShort, TI, Builder);
1233+
DefineExactWidthIntType(LangOpts, TargetInfo::SignedShort, TI, Builder);
12231234

12241235
if (TI.getIntWidth() > TI.getShortWidth())
1225-
DefineExactWidthIntType(TargetInfo::SignedInt, TI, Builder);
1236+
DefineExactWidthIntType(LangOpts, TargetInfo::SignedInt, TI, Builder);
12261237

12271238
if (TI.getLongWidth() > TI.getIntWidth())
1228-
DefineExactWidthIntType(TargetInfo::SignedLong, TI, Builder);
1239+
DefineExactWidthIntType(LangOpts, TargetInfo::SignedLong, TI, Builder);
12291240

12301241
if (TI.getLongLongWidth() > TI.getLongWidth())
1231-
DefineExactWidthIntType(TargetInfo::SignedLongLong, TI, Builder);
1242+
DefineExactWidthIntType(LangOpts, TargetInfo::SignedLongLong, TI, Builder);
12321243

1233-
DefineExactWidthIntType(TargetInfo::UnsignedChar, TI, Builder);
1244+
DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedChar, TI, Builder);
12341245
DefineExactWidthIntTypeSize(TargetInfo::UnsignedChar, TI, Builder);
12351246
DefineExactWidthIntTypeSize(TargetInfo::SignedChar, TI, Builder);
12361247

12371248
if (TI.getShortWidth() > TI.getCharWidth()) {
1238-
DefineExactWidthIntType(TargetInfo::UnsignedShort, TI, Builder);
1249+
DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedShort, TI, Builder);
12391250
DefineExactWidthIntTypeSize(TargetInfo::UnsignedShort, TI, Builder);
12401251
DefineExactWidthIntTypeSize(TargetInfo::SignedShort, TI, Builder);
12411252
}
12421253

12431254
if (TI.getIntWidth() > TI.getShortWidth()) {
1244-
DefineExactWidthIntType(TargetInfo::UnsignedInt, TI, Builder);
1255+
DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedInt, TI, Builder);
12451256
DefineExactWidthIntTypeSize(TargetInfo::UnsignedInt, TI, Builder);
12461257
DefineExactWidthIntTypeSize(TargetInfo::SignedInt, TI, Builder);
12471258
}
12481259

12491260
if (TI.getLongWidth() > TI.getIntWidth()) {
1250-
DefineExactWidthIntType(TargetInfo::UnsignedLong, TI, Builder);
1261+
DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedLong, TI, Builder);
12511262
DefineExactWidthIntTypeSize(TargetInfo::UnsignedLong, TI, Builder);
12521263
DefineExactWidthIntTypeSize(TargetInfo::SignedLong, TI, Builder);
12531264
}
12541265

12551266
if (TI.getLongLongWidth() > TI.getLongWidth()) {
1256-
DefineExactWidthIntType(TargetInfo::UnsignedLongLong, TI, Builder);
1267+
DefineExactWidthIntType(LangOpts, TargetInfo::UnsignedLongLong, TI,
1268+
Builder);
12571269
DefineExactWidthIntTypeSize(TargetInfo::UnsignedLongLong, TI, Builder);
12581270
DefineExactWidthIntTypeSize(TargetInfo::SignedLongLong, TI, Builder);
12591271
}
12601272

1261-
DefineLeastWidthIntType(8, true, TI, Builder);
1262-
DefineLeastWidthIntType(8, false, TI, Builder);
1263-
DefineLeastWidthIntType(16, true, TI, Builder);
1264-
DefineLeastWidthIntType(16, false, TI, Builder);
1265-
DefineLeastWidthIntType(32, true, TI, Builder);
1266-
DefineLeastWidthIntType(32, false, TI, Builder);
1267-
DefineLeastWidthIntType(64, true, TI, Builder);
1268-
DefineLeastWidthIntType(64, false, TI, Builder);
1269-
1270-
DefineFastIntType(8, true, TI, Builder);
1271-
DefineFastIntType(8, false, TI, Builder);
1272-
DefineFastIntType(16, true, TI, Builder);
1273-
DefineFastIntType(16, false, TI, Builder);
1274-
DefineFastIntType(32, true, TI, Builder);
1275-
DefineFastIntType(32, false, TI, Builder);
1276-
DefineFastIntType(64, true, TI, Builder);
1277-
DefineFastIntType(64, false, TI, Builder);
1273+
DefineLeastWidthIntType(LangOpts, 8, true, TI, Builder);
1274+
DefineLeastWidthIntType(LangOpts, 8, false, TI, Builder);
1275+
DefineLeastWidthIntType(LangOpts, 16, true, TI, Builder);
1276+
DefineLeastWidthIntType(LangOpts, 16, false, TI, Builder);
1277+
DefineLeastWidthIntType(LangOpts, 32, true, TI, Builder);
1278+
DefineLeastWidthIntType(LangOpts, 32, false, TI, Builder);
1279+
DefineLeastWidthIntType(LangOpts, 64, true, TI, Builder);
1280+
DefineLeastWidthIntType(LangOpts, 64, false, TI, Builder);
1281+
1282+
DefineFastIntType(LangOpts, 8, true, TI, Builder);
1283+
DefineFastIntType(LangOpts, 8, false, TI, Builder);
1284+
DefineFastIntType(LangOpts, 16, true, TI, Builder);
1285+
DefineFastIntType(LangOpts, 16, false, TI, Builder);
1286+
DefineFastIntType(LangOpts, 32, true, TI, Builder);
1287+
DefineFastIntType(LangOpts, 32, false, TI, Builder);
1288+
DefineFastIntType(LangOpts, 64, true, TI, Builder);
1289+
DefineFastIntType(LangOpts, 64, false, TI, Builder);
12781290

12791291
Builder.defineMacro("__USER_LABEL_PREFIX__", TI.getUserLabelPrefix());
12801292

clang/test/Preprocessor/init.c

+64
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,70 @@
9393
// C99-NOT: __GXX_WEAK__
9494
// C99-NOT: __cplusplus
9595
//
96+
// RUN: %clang_cc1 -std=c17 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix C17-FMT %s
97+
// RUN: %clang_cc1 -std=c23 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix C23-FMT %s
98+
//
99+
// C17-FMT-NOT: __SIZE_FMTB__
100+
// C17-FMT-NOT: __SIZE_FMTb__
101+
// C17-FMT-NOT: __UINT8_FMTB__
102+
// C17-FMT-NOT: __UINT8_FMTb__
103+
// C17-FMT-NOT: __UINT16_FMTB__
104+
// C17-FMT-NOT: __UINT16_FMTb__
105+
// C17-FMT-NOT: __UINT32_FMTB__
106+
// C17-FMT-NOT: __UINT32_FMTb__
107+
// C17-FMT-NOT: __UINT64_FMTB__
108+
// C17-FMT-NOT: __UINT64_FMTb__
109+
// C17-FMT-NOT: __UINTMAX_FMTB__
110+
// C17-FMT-NOT: __UINTMAX_FMTb__
111+
// C17-FMT-NOT: __UINTPTR_FMTB__
112+
// C17-FMT-NOT: __UINTPTR_FMTb__
113+
// C17-FMT-NOT: __UINT_FAST16_FMTB__
114+
// C17-FMT-NOT: __UINT_FAST16_FMTb__
115+
// C17-FMT-NOT: __UINT_FAST32_FMTB__
116+
// C17-FMT-NOT: __UINT_FAST32_FMTb__
117+
// C17-FMT-NOT: __UINT_FAST64_FMTB__
118+
// C17-FMT-NOT: __UINT_FAST64_FMTb__
119+
// C17-FMT-NOT: __UINT_FAST8_FMTB__
120+
// C17-FMT-NOT: __UINT_FAST8_FMTb__
121+
// C17-FMT-NOT: __UINT_LEAST16_FMTB__
122+
// C17-FMT-NOT: __UINT_LEAST16_FMTb__
123+
// C17-FMT-NOT: __UINT_LEAST32_FMTB__
124+
// C17-FMT-NOT: __UINT_LEAST32_FMTb__
125+
// C17-FMT-NOT: __UINT_LEAST64_FMTB__
126+
// C17-FMT-NOT: __UINT_LEAST64_FMTb__
127+
// C17-FMT-NOT: __UINT_LEAST8_FMTB__
128+
// C17-FMT-NOT: __UINT_LEAST8_FMTb__
129+
// C23-FMT: #define __SIZE_FMTB__ "llB"
130+
// C23-FMT: #define __SIZE_FMTb__ "llb"
131+
// C23-FMT: #define __UINT16_FMTB__ "hB"
132+
// C23-FMT: #define __UINT16_FMTb__ "hb"
133+
// C23-FMT: #define __UINT32_FMTB__ "B"
134+
// C23-FMT: #define __UINT32_FMTb__ "b"
135+
// C23-FMT: #define __UINT64_FMTB__ "llB"
136+
// C23-FMT: #define __UINT64_FMTb__ "llb"
137+
// C23-FMT: #define __UINT8_FMTB__ "hhB"
138+
// C23-FMT: #define __UINT8_FMTb__ "hhb"
139+
// C23-FMT: #define __UINTMAX_FMTB__ "llB"
140+
// C23-FMT: #define __UINTMAX_FMTb__ "llb"
141+
// C23-FMT: #define __UINTPTR_FMTB__ "llB"
142+
// C23-FMT: #define __UINTPTR_FMTb__ "llb"
143+
// C23-FMT: #define __UINT_FAST16_FMTB__ "hB"
144+
// C23-FMT: #define __UINT_FAST16_FMTb__ "hb"
145+
// C23-FMT: #define __UINT_FAST32_FMTB__ "B"
146+
// C23-FMT: #define __UINT_FAST32_FMTb__ "b"
147+
// C23-FMT: #define __UINT_FAST64_FMTB__ "llB"
148+
// C23-FMT: #define __UINT_FAST64_FMTb__ "llb"
149+
// C23-FMT: #define __UINT_FAST8_FMTB__ "hhB"
150+
// C23-FMT: #define __UINT_FAST8_FMTb__ "hhb"
151+
// C23-FMT: #define __UINT_LEAST16_FMTB__ "hB"
152+
// C23-FMT: #define __UINT_LEAST16_FMTb__ "hb"
153+
// C23-FMT: #define __UINT_LEAST32_FMTB__ "B"
154+
// C23-FMT: #define __UINT_LEAST32_FMTb__ "b"
155+
// C23-FMT: #define __UINT_LEAST64_FMTB__ "llB"
156+
// C23-FMT: #define __UINT_LEAST64_FMTb__ "llb"
157+
// C23-FMT: #define __UINT_LEAST8_FMTB__ "hhB"
158+
// C23-FMT: #define __UINT_LEAST8_FMTb__ "hhb"
159+
//
96160
//
97161
// RUN: %clang_cc1 -std=c11 -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix C11 %s
98162
// RUN: %clang_cc1 -std=c1x -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix C11 %s

0 commit comments

Comments
 (0)