Skip to content

Commit 9e3aa50

Browse files
committed
[support] Provide overload to PrintNumber that use C++ types
This attempts to address an issue with overload resolution for `PrintNumber` with `size_t` parameters on Darwin, brought up in https://reviews.llvm.org/D146492. On Aarch64 Darwin, `uint64_t` has a different typedef than `size_t` (e.g., `unsigned long long` vs. `unsigned long`), whereas on Linux and Windows they are the same. This commit also reverts the static_cast's added in 064e249, since they are no longer needed. Reviewed By: jhenderson Differential Revision: https://reviews.llvm.org/D146771
1 parent 99ab3d9 commit 9e3aa50

File tree

4 files changed

+94
-28
lines changed

4 files changed

+94
-28
lines changed

llvm/include/llvm/Support/JSON.h

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,11 @@ namespace json {
7474
// - When retrieving strings from Values (e.g. asString()), the result will
7575
// always be valid UTF-8.
7676

77+
template <typename T>
78+
constexpr bool is_uint_64_bit_v =
79+
std::is_integral_v<T> && std::is_unsigned_v<T> &&
80+
sizeof(T) == sizeof(uint64_t);
81+
7782
/// Returns true if \p S is valid UTF-8, which is required for use as JSON.
7883
/// If it returns false, \p Offset is set to a byte offset near the first error.
7984
bool isUTF8(llvm::StringRef S, size_t *ErrOffset = nullptr);
@@ -336,19 +341,17 @@ class Value {
336341
create<bool>(B);
337342
}
338343

339-
// Unsigned 64-bit long integers.
340-
template <typename T,
341-
typename = std::enable_if_t<std::is_same<T, uint64_t>::value>,
342-
bool = false, bool = false>
344+
// Unsigned 64-bit integers.
345+
template <typename T, typename = std::enable_if_t<is_uint_64_bit_v<T>>>
343346
Value(T V) : Type(T_UINT64) {
344347
create<uint64_t>(uint64_t{V});
345348
}
346349

347350
// Integers (except boolean and uint64_t).
348351
// Must be non-narrowing convertible to int64_t.
349-
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>,
350-
typename = std::enable_if_t<!std::is_same<T, bool>::value>,
351-
typename = std::enable_if_t<!std::is_same<T, uint64_t>::value>>
352+
template <typename T, typename = std::enable_if_t<std::is_integral_v<T>>,
353+
typename = std::enable_if_t<!std::is_same_v<T, bool>>,
354+
typename = std::enable_if_t<!is_uint_64_bit_v<T>>>
352355
Value(T I) : Type(T_Integer) {
353356
create<int64_t>(int64_t{I});
354357
}
@@ -424,6 +427,12 @@ class Value {
424427
std::optional<int64_t> getAsInteger() const {
425428
if (LLVM_LIKELY(Type == T_Integer))
426429
return as<int64_t>();
430+
if (LLVM_LIKELY(Type == T_UINT64)) {
431+
uint64_t U = as<uint64_t>();
432+
if (LLVM_LIKELY(U <= uint64_t(std::numeric_limits<int64_t>::max()))) {
433+
return U;
434+
}
435+
}
427436
if (LLVM_LIKELY(Type == T_Double)) {
428437
double D = as<double>();
429438
if (LLVM_LIKELY(std::modf(D, &D) == 0.0 &&

llvm/include/llvm/Support/ScopedPrinter.h

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -198,36 +198,48 @@ class ScopedPrinter {
198198
printFlagsImpl(Label, hex(Value), SetFlags);
199199
}
200200

201-
virtual void printNumber(StringRef Label, uint64_t Value) {
201+
virtual void printNumber(StringRef Label, char Value) {
202+
startLine() << Label << ": " << static_cast<int>(Value) << "\n";
203+
}
204+
205+
virtual void printNumber(StringRef Label, signed char Value) {
206+
startLine() << Label << ": " << static_cast<int>(Value) << "\n";
207+
}
208+
209+
virtual void printNumber(StringRef Label, unsigned char Value) {
210+
startLine() << Label << ": " << static_cast<unsigned>(Value) << "\n";
211+
}
212+
213+
virtual void printNumber(StringRef Label, short Value) {
202214
startLine() << Label << ": " << Value << "\n";
203215
}
204216

205-
virtual void printNumber(StringRef Label, uint32_t Value) {
217+
virtual void printNumber(StringRef Label, unsigned short Value) {
206218
startLine() << Label << ": " << Value << "\n";
207219
}
208220

209-
virtual void printNumber(StringRef Label, uint16_t Value) {
221+
virtual void printNumber(StringRef Label, int Value) {
210222
startLine() << Label << ": " << Value << "\n";
211223
}
212224

213-
virtual void printNumber(StringRef Label, uint8_t Value) {
214-
startLine() << Label << ": " << unsigned(Value) << "\n";
225+
virtual void printNumber(StringRef Label, unsigned int Value) {
226+
startLine() << Label << ": " << Value << "\n";
215227
}
216228

217-
virtual void printNumber(StringRef Label, int64_t Value) {
229+
virtual void printNumber(StringRef Label, long Value) {
218230
startLine() << Label << ": " << Value << "\n";
219231
}
220232

221-
virtual void printNumber(StringRef Label, int32_t Value) {
233+
virtual void printNumber(StringRef Label, unsigned long Value) {
222234
startLine() << Label << ": " << Value << "\n";
223235
}
224236

225-
virtual void printNumber(StringRef Label, int16_t Value) {
237+
virtual void printNumber(StringRef Label, long long Value) {
226238
startLine() << Label << ": " << Value << "\n";
227239
}
228240

229-
virtual void printNumber(StringRef Label, int8_t Value) {
230-
startLine() << Label << ": " << int(Value) << "\n";
241+
virtual void printNumber(StringRef Label, unsigned long long Value) {
242+
startLine() << Label << ": " << Value << "\n";
231243
}
232244

233245
virtual void printNumber(StringRef Label, const APSInt &Value) {
@@ -562,35 +574,47 @@ class JSONScopedPrinter : public ScopedPrinter {
562574
return SP->getKind() == ScopedPrinter::ScopedPrinterKind::JSON;
563575
}
564576

565-
void printNumber(StringRef Label, uint64_t Value) override {
577+
void printNumber(StringRef Label, char Value) override {
578+
JOS.attribute(Label, Value);
579+
}
580+
581+
void printNumber(StringRef Label, signed char Value) override {
582+
JOS.attribute(Label, Value);
583+
}
584+
585+
void printNumber(StringRef Label, unsigned char Value) override {
586+
JOS.attribute(Label, Value);
587+
}
588+
589+
void printNumber(StringRef Label, short Value) override {
566590
JOS.attribute(Label, Value);
567591
}
568592

569-
void printNumber(StringRef Label, uint32_t Value) override {
593+
void printNumber(StringRef Label, unsigned short Value) override {
570594
JOS.attribute(Label, Value);
571595
}
572596

573-
void printNumber(StringRef Label, uint16_t Value) override {
597+
void printNumber(StringRef Label, int Value) override {
574598
JOS.attribute(Label, Value);
575599
}
576600

577-
void printNumber(StringRef Label, uint8_t Value) override {
601+
void printNumber(StringRef Label, unsigned int Value) override {
578602
JOS.attribute(Label, Value);
579603
}
580604

581-
void printNumber(StringRef Label, int64_t Value) override {
605+
void printNumber(StringRef Label, long Value) override {
582606
JOS.attribute(Label, Value);
583607
}
584608

585-
void printNumber(StringRef Label, int32_t Value) override {
609+
void printNumber(StringRef Label, unsigned long Value) override {
586610
JOS.attribute(Label, Value);
587611
}
588612

589-
void printNumber(StringRef Label, int16_t Value) override {
613+
void printNumber(StringRef Label, long long Value) override {
590614
JOS.attribute(Label, Value);
591615
}
592616

593-
void printNumber(StringRef Label, int8_t Value) override {
617+
void printNumber(StringRef Label, unsigned long long Value) override {
594618
JOS.attribute(Label, Value);
595619
}
596620

llvm/tools/llvm-readobj/ELFDumper.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7275,14 +7275,14 @@ void LLVMELFDumper<ELFT>::printHashHistogramStats(size_t NBucket,
72757275
StringRef BucketName = IsGnu ? "Bucket" : "Chain";
72767276
StringRef ListName = IsGnu ? "Buckets" : "Chains";
72777277
DictScope Outer(W, HistName);
7278-
W.printNumber("TotalBuckets", static_cast<uint64_t>(NBucket));
7278+
W.printNumber("TotalBuckets", NBucket);
72797279
ListScope Buckets(W, ListName);
72807280
size_t CumulativeNonZero = 0;
72817281
for (size_t I = 0; I < MaxChain; ++I) {
72827282
CumulativeNonZero += Count[I] * I;
72837283
DictScope Bucket(W, BucketName);
7284-
W.printNumber("Length", static_cast<uint64_t>(I));
7285-
W.printNumber("Count", static_cast<uint64_t>(Count[I]));
7284+
W.printNumber("Length", I);
7285+
W.printNumber("Count", Count[I]);
72867286
W.printNumber("Percentage", (float)(Count[I] * 100.0) / NBucket);
72877287
W.printNumber("Coverage", (float)(CumulativeNonZero * 100.0) / TotalSyms);
72887288
}

llvm/unittests/Support/JSONTest.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,39 @@ TEST(JSONTest, U64Integers) {
442442
}
443443
}
444444

445+
template <typename T> void checkCppIntegers() {
446+
Value Val = T{10};
447+
T Var = 10;
448+
EXPECT_EQ(Val, Var);
449+
450+
Val = T{std::numeric_limits<T>::max()};
451+
Var = std::numeric_limits<T>::max();
452+
EXPECT_EQ(Val, Var);
453+
454+
Val = T{std::numeric_limits<T>::min()};
455+
Var = std::numeric_limits<T>::min();
456+
EXPECT_EQ(Val, Var);
457+
}
458+
459+
// Test that underlying C++ integer types behave as expected.
460+
TEST(JSONTest, CppIntegers) {
461+
checkCppIntegers<char>();
462+
checkCppIntegers<signed char>();
463+
checkCppIntegers<unsigned char>();
464+
465+
checkCppIntegers<short>();
466+
checkCppIntegers<unsigned short>();
467+
468+
checkCppIntegers<int>();
469+
checkCppIntegers<unsigned int>();
470+
471+
checkCppIntegers<long>();
472+
checkCppIntegers<unsigned long>();
473+
474+
checkCppIntegers<long long>();
475+
checkCppIntegers<unsigned long long>();
476+
}
477+
445478
// Sample struct with typical JSON-mapping rules.
446479
struct CustomStruct {
447480
CustomStruct() : B(false) {}

0 commit comments

Comments
 (0)