diff options
| author | Sam McCall <sam.mccall@gmail.com> | 2018-07-09 12:16:40 +0000 | 
|---|---|---|
| committer | Sam McCall <sam.mccall@gmail.com> | 2018-07-09 12:16:40 +0000 | 
| commit | d93eaeb7c399488b16753b1786a30ec6a59761c7 (patch) | |
| tree | 67793aef0e29ef86851aee92b0f0c1cdc018240e /llvm/unittests/Support | |
| parent | 6f33b330ae1808ab2a5d7184abafefc5d5821059 (diff) | |
| download | bcm5719-llvm-d93eaeb7c399488b16753b1786a30ec6a59761c7.tar.gz bcm5719-llvm-d93eaeb7c399488b16753b1786a30ec6a59761c7.zip  | |
[Support] Make JSON handle doubles and int64s losslessly
Summary:
This patch adds a new "integer" ValueType, and renames Number -> Double.
This allows us to preserve the full precision of int64_t when parsing integers
from the wire, or constructing from an integer.
The API is unchanged, other than giving asInteger() a clearer contract.
In addition, always output doubles with enough precision that parsing will
reconstruct the same double.
Reviewers: simon_tatham
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D46209
llvm-svn: 336541
Diffstat (limited to 'llvm/unittests/Support')
| -rw-r--r-- | llvm/unittests/Support/JSONTest.cpp | 60 | 
1 files changed, 60 insertions, 0 deletions
diff --git a/llvm/unittests/Support/JSONTest.cpp b/llvm/unittests/Support/JSONTest.cpp index bf7f4ae96d0..08307c10d2d 100644 --- a/llvm/unittests/Support/JSONTest.cpp +++ b/llvm/unittests/Support/JSONTest.cpp @@ -227,6 +227,66 @@ TEST(JSONTest, Inspection) {    }  } +// Verify special integer handling - we try to preserve exact int64 values. +TEST(JSONTest, Integers) { +  struct { +    const char *Desc; +    Value Val; +    const char *Str; +    llvm::Optional<int64_t> AsInt; +    llvm::Optional<double> AsNumber; +  } TestCases[] = { +      { +          "Non-integer. Stored as double, not convertible.", +          double{1.5}, +          "1.5", +          llvm::None, +          1.5, +      }, + +      { +          "Integer, not exact double. Stored as int64, convertible.", +          int64_t{0x4000000000000001}, +          "4611686018427387905", +          int64_t{0x4000000000000001}, +          double{0x4000000000000000}, +      }, + +      { +          "Negative integer, not exact double. Stored as int64, convertible.", +          int64_t{-0x4000000000000001}, +          "-4611686018427387905", +          int64_t{-0x4000000000000001}, +          double{-0x4000000000000000}, +      }, + +      { +          "Dynamically exact integer. Stored as double, convertible.", +          double{0x6000000000000000}, +          "6.9175290276410819e+18", +          int64_t{0x6000000000000000}, +          double{0x6000000000000000}, +      }, + +      { +          "Dynamically integer, >64 bits. Stored as double, not convertible.", +          1.5 * double{0x8000000000000000}, +          "1.3835058055282164e+19", +          llvm::None, +          1.5 * double{0x8000000000000000}, +      }, +  }; +  for (const auto &T : TestCases) { +    EXPECT_EQ(T.Str, s(T.Val)) << T.Desc; +    llvm::Expected<Value> Doc = parse(T.Str); +    EXPECT_TRUE(!!Doc) << T.Desc; +    EXPECT_EQ(Doc->getAsInteger(), T.AsInt) << T.Desc; +    EXPECT_EQ(Doc->getAsNumber(), T.AsNumber) << T.Desc; +    EXPECT_EQ(T.Val, *Doc) << T.Desc; +    EXPECT_EQ(T.Str, s(*Doc)) << T.Desc; +  } +} +  // Sample struct with typical JSON-mapping rules.  struct CustomStruct {    CustomStruct() : B(false) {}  | 

