Skip to content

Commit 9a365bc

Browse files
authored
[Clang] [NFC] Add "human" diagnostic argument format (#115835)
This allows formatting large integers in a human friendly way. Example: "5321584" -> "5.32M". Use it where such human numbers are generated manually today.
1 parent edfa75d commit 9a365bc

File tree

5 files changed

+60
-38
lines changed

5 files changed

+60
-38
lines changed

clang/docs/InternalsManual.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,17 @@ Description:
315315
than ``1`` are not supported. This formatter is currently hard-coded to use
316316
English ordinals.
317317

318+
**"human" format**
319+
320+
Example:
321+
``"total size is %human0 bytes"``
322+
Class:
323+
Integers
324+
Description:
325+
This is a formatter which represents the argument number in a human readable
326+
format: the value ``123`` stays ``123``, ``12345`` becomes ``12.34k``,
327+
``6666666` becomes ``6.67M``, and so on for 'G' and 'T'.
328+
318329
**"objcclass" format**
319330

320331
Example:

clang/include/clang/Basic/DiagnosticCommonKinds.td

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -389,14 +389,14 @@ def remark_sloc_usage : Remark<
389389
"source manager location address space usage:">,
390390
InGroup<DiagGroup<"sloc-usage">>, DefaultRemark, ShowInSystemHeader;
391391
def note_total_sloc_usage : Note<
392-
"%0B (%1B) in local locations, %2B (%3B) "
393-
"in locations loaded from AST files, for a total of %4B (%5B) "
394-
"(%6%% of available space)">;
392+
"%0B (%human0B) in local locations, %1B (%human1B) "
393+
"in locations loaded from AST files, for a total of %2B (%human2B) "
394+
"(%3%% of available space)">;
395395
def note_file_sloc_usage : Note<
396-
"file entered %0 time%s0 using %1B (%2B) of space"
397-
"%plural{0:|: plus %3B (%4B) for macro expansions}3">;
396+
"file entered %0 time%s0 using %1B (%human1B) of space"
397+
"%plural{0:|: plus %2B (%human2B) for macro expansions}2">;
398398
def note_file_misc_sloc_usage : Note<
399-
"%0 additional files entered using a total of %1B (%2B) of space">;
399+
"%0 additional files entered using a total of %1B (%human1B) of space">;
400400

401401
// Modules
402402
def err_module_format_unhandled : Error<

clang/lib/Basic/Diagnostic.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,35 @@ static void HandleOrdinalModifier(unsigned ValNo,
652652
Out << ValNo << llvm::getOrdinalSuffix(ValNo);
653653
}
654654

655+
// 123 -> "123".
656+
// 1234 -> "1.23k".
657+
// 123456 -> "123.46k".
658+
// 1234567 -> "1.23M".
659+
// 1234567890 -> "1.23G".
660+
// 1234567890123 -> "1.23T".
661+
static void HandleIntegerHumanModifier(int64_t ValNo,
662+
SmallVectorImpl<char> &OutStr) {
663+
static constexpr std::array<std::pair<int64_t, char>, 4> Units = {
664+
{{1'000'000'000'000L, 'T'},
665+
{1'000'000'000L, 'G'},
666+
{1'000'000L, 'M'},
667+
{1'000L, 'k'}}};
668+
669+
llvm::raw_svector_ostream Out(OutStr);
670+
if (ValNo < 0) {
671+
Out << "-";
672+
ValNo = -ValNo;
673+
}
674+
for (const auto &[UnitSize, UnitSign] : Units) {
675+
if (ValNo >= UnitSize) {
676+
Out << llvm::format("%0.2f%c", ValNo / static_cast<double>(UnitSize),
677+
UnitSign);
678+
return;
679+
}
680+
}
681+
Out << ValNo;
682+
}
683+
655684
/// PluralNumber - Parse an unsigned integer and advance Start.
656685
static unsigned PluralNumber(const char *&Start, const char *End) {
657686
// Programming 101: Parse a decimal number :-)
@@ -988,6 +1017,8 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
9881017
OutStr);
9891018
} else if (ModifierIs(Modifier, ModifierLen, "ordinal")) {
9901019
HandleOrdinalModifier((unsigned)Val, OutStr);
1020+
} else if (ModifierIs(Modifier, ModifierLen, "human")) {
1021+
HandleIntegerHumanModifier(Val, OutStr);
9911022
} else {
9921023
assert(ModifierLen == 0 && "Unknown integer modifier");
9931024
llvm::raw_svector_ostream(OutStr) << Val;
@@ -1006,6 +1037,8 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
10061037
OutStr);
10071038
} else if (ModifierIs(Modifier, ModifierLen, "ordinal")) {
10081039
HandleOrdinalModifier(Val, OutStr);
1040+
} else if (ModifierIs(Modifier, ModifierLen, "human")) {
1041+
HandleIntegerHumanModifier(Val, OutStr);
10091042
} else {
10101043
assert(ModifierLen == 0 && "Unknown integer modifier");
10111044
llvm::raw_svector_ostream(OutStr) << Val;

clang/lib/Basic/SourceManager.cpp

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
#include "llvm/Support/Endian.h"
3030
#include "llvm/Support/ErrorHandling.h"
3131
#include "llvm/Support/FileSystem.h"
32-
#include "llvm/Support/FormatVariadic.h"
3332
#include "llvm/Support/MathExtras.h"
3433
#include "llvm/Support/MemoryBuffer.h"
3534
#include "llvm/Support/Path.h"
@@ -2228,28 +2227,6 @@ LLVM_DUMP_METHOD void SourceManager::dump() const {
22282227
}
22292228
}
22302229

2231-
// 123 -> "123".
2232-
// 1234 -> "1.23k".
2233-
// 123456 -> "123.46k".
2234-
// 1234567 -> "1.23M".
2235-
// 1234567890 -> "1.23G".
2236-
// 1234567890123 -> "1.23T".
2237-
static std::string humanizeNumber(uint64_t Number) {
2238-
static constexpr std::array<std::pair<uint64_t, char>, 4> Units = {
2239-
{{1'000'000'000'000UL, 'T'},
2240-
{1'000'000'000UL, 'G'},
2241-
{1'000'000UL, 'M'},
2242-
{1'000UL, 'k'}}};
2243-
2244-
for (const auto &[UnitSize, UnitSign] : Units) {
2245-
if (Number >= UnitSize) {
2246-
return llvm::formatv("{0:F}{1}", Number / static_cast<double>(UnitSize),
2247-
UnitSign);
2248-
}
2249-
}
2250-
return std::to_string(Number);
2251-
}
2252-
22532230
void SourceManager::noteSLocAddressSpaceUsage(
22542231
DiagnosticsEngine &Diag, std::optional<unsigned> MaxNotes) const {
22552232
struct Info {
@@ -2319,27 +2296,23 @@ void SourceManager::noteSLocAddressSpaceUsage(
23192296
int UsagePercent = static_cast<int>(100.0 * double(LocalUsage + LoadedUsage) /
23202297
MaxLoadedOffset);
23212298
Diag.Report(SourceLocation(), diag::note_total_sloc_usage)
2322-
<< LocalUsage << humanizeNumber(LocalUsage) << LoadedUsage
2323-
<< humanizeNumber(LoadedUsage) << (LocalUsage + LoadedUsage)
2324-
<< humanizeNumber(LocalUsage + LoadedUsage) << UsagePercent;
2299+
<< LocalUsage << LoadedUsage << (LocalUsage + LoadedUsage)
2300+
<< UsagePercent;
23252301

23262302
// Produce notes on sloc address space usage for each file with a high usage.
23272303
uint64_t ReportedSize = 0;
23282304
for (auto &[Entry, FileInfo] :
23292305
llvm::make_range(SortedUsage.begin(), SortedEnd)) {
23302306
Diag.Report(FileInfo.Loc, diag::note_file_sloc_usage)
23312307
<< FileInfo.Inclusions << FileInfo.DirectSize
2332-
<< humanizeNumber(FileInfo.DirectSize)
2333-
<< (FileInfo.TotalSize - FileInfo.DirectSize)
2334-
<< humanizeNumber(FileInfo.TotalSize - FileInfo.DirectSize);
2308+
<< (FileInfo.TotalSize - FileInfo.DirectSize);
23352309
ReportedSize += FileInfo.TotalSize;
23362310
}
23372311

23382312
// Describe any remaining usage not reported in the per-file usage.
23392313
if (ReportedSize != CountedSize) {
23402314
Diag.Report(SourceLocation(), diag::note_file_misc_sloc_usage)
2341-
<< (SortedUsage.end() - SortedEnd) << CountedSize - ReportedSize
2342-
<< humanizeNumber(CountedSize - ReportedSize);
2315+
<< (SortedUsage.end() - SortedEnd) << CountedSize - ReportedSize;
23432316
}
23442317
}
23452318

clang/utils/TableGen/ClangDiagnosticsEmitter.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,7 @@ enum ModifierType {
416416
MT_Plural,
417417
MT_Diff,
418418
MT_Ordinal,
419+
MT_Human,
419420
MT_S,
420421
MT_Q,
421422
MT_ObjCClass,
@@ -434,6 +435,8 @@ static StringRef getModifierName(ModifierType MT) {
434435
return "plural";
435436
case MT_Ordinal:
436437
return "ordinal";
438+
case MT_Human:
439+
return "human";
437440
case MT_S:
438441
return "s";
439442
case MT_Q:
@@ -1030,6 +1033,7 @@ Piece *DiagnosticTextBuilder::DiagText::parseDiagText(StringRef &Text,
10301033
.Case("plural", MT_Plural)
10311034
.Case("s", MT_S)
10321035
.Case("ordinal", MT_Ordinal)
1036+
.Case("human", MT_Human)
10331037
.Case("q", MT_Q)
10341038
.Case("objcclass", MT_ObjCClass)
10351039
.Case("objcinstance", MT_ObjCInstance)
@@ -1131,7 +1135,8 @@ Piece *DiagnosticTextBuilder::DiagText::parseDiagText(StringRef &Text,
11311135
case MT_Placeholder:
11321136
case MT_ObjCClass:
11331137
case MT_ObjCInstance:
1134-
case MT_Ordinal: {
1138+
case MT_Ordinal:
1139+
case MT_Human: {
11351140
Parsed.push_back(New<PlaceholderPiece>(ModType, parseModifier(Text)));
11361141
continue;
11371142
}

0 commit comments

Comments
 (0)