Skip to content

Commit 8c3adce

Browse files
author
djtodoro
committed
[JSON] Handle uint64_t type
There was no handling of uint64_t in the LLVM JSON library. This patch adds support for that. The motivation is the https://reviews.llvm.org/D109217. Differential Revision: https://reviews.llvm.org/D109347
1 parent bc9b106 commit 8c3adce

File tree

3 files changed

+66
-6
lines changed

3 files changed

+66
-6
lines changed

llvm/include/llvm/Support/JSON.h

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ inline bool operator!=(const Array &L, const Array &R) { return !(L == R); }
234234
/// Each Value is one of the JSON kinds:
235235
/// null (nullptr_t)
236236
/// boolean (bool)
237-
/// number (double or int64)
237+
/// number (double, int64 or uint64)
238238
/// string (StringRef)
239239
/// array (json::Array)
240240
/// object (json::Object)
@@ -342,9 +342,20 @@ class Value {
342342
Value(T B) : Type(T_Boolean) {
343343
create<bool>(B);
344344
}
345-
// Integers (except boolean). Must be non-narrowing convertible to int64_t.
345+
346+
// Unsigned 64-bit long integers.
347+
template <typename T,
348+
typename = std::enable_if_t<std::is_same<T, uint64_t>::value>,
349+
bool = false, bool = false>
350+
Value(T V) : Type(T_UINT64) {
351+
create<uint64_t>(uint64_t{V});
352+
}
353+
354+
// Integers (except boolean and uint64_t).
355+
// Must be non-narrowing convertible to int64_t.
346356
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>,
347-
typename = std::enable_if_t<!std::is_same<T, bool>::value>>
357+
typename = std::enable_if_t<!std::is_same<T, bool>::value>,
358+
typename = std::enable_if_t<!std::is_same<T, uint64_t>::value>>
348359
Value(T I) : Type(T_Integer) {
349360
create<int64_t>(int64_t{I});
350361
}
@@ -382,6 +393,7 @@ class Value {
382393
return Boolean;
383394
case T_Double:
384395
case T_Integer:
396+
case T_UINT64:
385397
return Number;
386398
case T_String:
387399
case T_StringRef:
@@ -410,6 +422,8 @@ class Value {
410422
return as<double>();
411423
if (LLVM_LIKELY(Type == T_Integer))
412424
return as<int64_t>();
425+
if (LLVM_LIKELY(Type == T_UINT64))
426+
return as<uint64_t>();
413427
return llvm::None;
414428
}
415429
// Succeeds if the Value is a Number, and exactly representable as int64_t.
@@ -425,6 +439,16 @@ class Value {
425439
}
426440
return llvm::None;
427441
}
442+
llvm::Optional<uint64_t> getAsUINT64() const {
443+
if (Type == T_UINT64)
444+
return as<uint64_t>();
445+
else if (Type == T_Integer) {
446+
int64_t N = as<int64_t>();
447+
if (N >= 0)
448+
return as<uint64_t>();
449+
}
450+
return llvm::None;
451+
}
428452
llvm::Optional<llvm::StringRef> getAsString() const {
429453
if (Type == T_String)
430454
return llvm::StringRef(as<std::string>());
@@ -467,20 +491,22 @@ class Value {
467491

468492
friend class OStream;
469493

470-
enum ValueType : char {
494+
enum ValueType : char16_t {
471495
T_Null,
472496
T_Boolean,
473497
T_Double,
474498
T_Integer,
499+
T_UINT64,
475500
T_StringRef,
476501
T_String,
477502
T_Object,
478503
T_Array,
479504
};
480505
// All members mutable, see moveFrom().
481506
mutable ValueType Type;
482-
mutable llvm::AlignedCharArrayUnion<bool, double, int64_t, llvm::StringRef,
483-
std::string, json::Array, json::Object>
507+
mutable llvm::AlignedCharArrayUnion<bool, double, int64_t, uint64_t,
508+
llvm::StringRef, std::string, json::Array,
509+
json::Object>
484510
Union;
485511
friend bool operator==(const Value &, const Value &);
486512
};
@@ -683,6 +709,14 @@ inline bool fromJSON(const Value &E, bool &Out, Path P) {
683709
P.report("expected boolean");
684710
return false;
685711
}
712+
inline bool fromJSON(const Value &E, uint64_t &Out, Path P) {
713+
if (auto S = E.getAsUINT64()) {
714+
Out = *S;
715+
return true;
716+
}
717+
P.report("expected uint64_t");
718+
return false;
719+
}
686720
inline bool fromJSON(const Value &E, std::nullptr_t &Out, Path P) {
687721
if (auto S = E.getAsNull()) {
688722
Out = *S;

llvm/lib/Support/JSON.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ void Value::copyFrom(const Value &M) {
109109
case T_Boolean:
110110
case T_Double:
111111
case T_Integer:
112+
case T_UINT64:
112113
memcpy(&Union, &M.Union, sizeof(Union));
113114
break;
114115
case T_StringRef:
@@ -133,6 +134,7 @@ void Value::moveFrom(const Value &&M) {
133134
case T_Boolean:
134135
case T_Double:
135136
case T_Integer:
137+
case T_UINT64:
136138
memcpy(&Union, &M.Union, sizeof(Union));
137139
break;
138140
case T_StringRef:
@@ -159,6 +161,7 @@ void Value::destroy() {
159161
case T_Boolean:
160162
case T_Double:
161163
case T_Integer:
164+
case T_UINT64:
162165
break;
163166
case T_StringRef:
164167
as<StringRef>().~StringRef();
@@ -750,6 +753,8 @@ void llvm::json::OStream::value(const Value &V) {
750753
valueBegin();
751754
if (V.Type == Value::T_Integer)
752755
OS << *V.getAsInteger();
756+
else if (V.Type == Value::T_UINT64)
757+
OS << *V.getAsUINT64();
753758
else
754759
OS << format("%.*g", std::numeric_limits<double>::max_digits10,
755760
*V.getAsNumber());

llvm/unittests/Support/JSONTest.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,27 @@ TEST(JSONTest, Integers) {
356356
}
357357
}
358358

359+
// Verify uint64_t type.
360+
TEST(JSONTest, U64Integers) {
361+
Value Val = uint64_t{3100100100};
362+
uint64_t Var = 3100100100;
363+
EXPECT_EQ(Val, Var);
364+
365+
// Test the parse() part.
366+
const char *Str = "4611686018427387905";
367+
llvm::Expected<Value> Doc = parse(Str);
368+
369+
EXPECT_TRUE(!!Doc);
370+
EXPECT_EQ(Doc->getAsInteger(), int64_t{4611686018427387905});
371+
EXPECT_EQ(Doc->getAsUINT64(), uint64_t{4611686018427387905});
372+
373+
const char *Str2 = "-78278238238328222";
374+
llvm::Expected<Value> Doc2 = parse(Str2);
375+
EXPECT_TRUE(!!Doc2);
376+
EXPECT_EQ(Doc2->getAsInteger(), int64_t{-78278238238328222});
377+
EXPECT_EQ(Doc2->getAsUINT64(), llvm::None);
378+
}
379+
359380
// Sample struct with typical JSON-mapping rules.
360381
struct CustomStruct {
361382
CustomStruct() : B(false) {}

0 commit comments

Comments
 (0)