summaryrefslogtreecommitdiffstats
path: root/unittests
diff options
context:
space:
mode:
Diffstat (limited to 'unittests')
-rw-r--r--unittests/ADT/APFloatTest.cpp517
-rw-r--r--unittests/ADT/APIntTest.cpp183
-rw-r--r--unittests/ADT/SmallStringTest.cpp48
-rw-r--r--unittests/ADT/SmallVectorTest.cpp27
-rw-r--r--unittests/ADT/SparseBitVectorTest.cpp36
-rw-r--r--unittests/ADT/StringMapTest.cpp24
-rw-r--r--unittests/ADT/StringRefTest.cpp155
-rw-r--r--unittests/ADT/TripleTest.cpp84
-rw-r--r--unittests/ADT/TwineTest.cpp75
-rw-r--r--unittests/ExecutionEngine/ExecutionEngineTest.cpp129
-rw-r--r--unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp14
-rw-r--r--unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp277
-rw-r--r--unittests/ExecutionEngine/JIT/JITTest.cpp277
-rw-r--r--unittests/ExecutionEngine/Makefile7
-rw-r--r--unittests/Makefile9
-rw-r--r--unittests/Makefile.unittest6
-rw-r--r--unittests/Support/AllocatorTest.cpp143
-rw-r--r--unittests/Support/CommandLineTest.cpp60
-rw-r--r--unittests/Support/ConstantRangeTest.cpp351
-rw-r--r--unittests/Support/MathExtrasTest.cpp2
-rw-r--r--unittests/Support/RegexTest.cpp65
-rw-r--r--unittests/Support/TypeBuilderTest.cpp281
-rw-r--r--unittests/Support/ValueHandleTest.cpp118
-rw-r--r--unittests/Support/raw_ostream_test.cpp45
-rw-r--r--unittests/Transforms/Makefile17
-rw-r--r--unittests/Transforms/Utils/Cloning.cpp87
-rw-r--r--unittests/Transforms/Utils/Makefile15
-rw-r--r--unittests/VMCore/ConstantsTest.cpp5
-rw-r--r--unittests/VMCore/MetadataTest.cpp112
-rw-r--r--unittests/VMCore/PassManagerTest.cpp36
30 files changed, 2912 insertions, 293 deletions
diff --git a/unittests/ADT/APFloatTest.cpp b/unittests/ADT/APFloatTest.cpp
new file mode 100644
index 0000000..92f020b
--- /dev/null
+++ b/unittests/ADT/APFloatTest.cpp
@@ -0,0 +1,517 @@
+//===- llvm/unittest/ADT/APFloat.cpp - APFloat unit tests ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <ostream>
+#include "llvm/Support/raw_ostream.h"
+#include "gtest/gtest.h"
+#include "llvm/ADT/APFloat.h"
+#include "llvm/ADT/SmallString.h"
+
+using namespace llvm;
+
+static double convertToDoubleFromString(const char *Str) {
+ llvm::APFloat F(0.0);
+ F.convertFromString(Str, llvm::APFloat::rmNearestTiesToEven);
+ return F.convertToDouble();
+}
+
+namespace {
+
+TEST(APFloatTest, Zero) {
+ EXPECT_EQ(0.0f, APFloat(APFloat::IEEEsingle, 0.0f).convertToFloat());
+ EXPECT_EQ(-0.0f, APFloat(APFloat::IEEEsingle, -0.0f).convertToFloat());
+
+ EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble, 0.0).convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, -0.0).convertToDouble());
+}
+
+TEST(APFloatTest, fromZeroDecimalString) {
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0.").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0.").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, ".0").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+.0").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-.0").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0.0").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0.0").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.0").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "00000.").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+00000.").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-00000.").convertToDouble());
+
+ EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble, ".00000").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+.00000").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-.00000").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0000.00000").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0000.00000").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0000.00000").convertToDouble());
+}
+
+TEST(APFloatTest, fromZeroDecimalSingleExponentString) {
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0e1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0e1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0e1").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0e+1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0e+1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0e+1").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0e-1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0e-1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0e-1").convertToDouble());
+
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0.e1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0.e1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.e1").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0.e+1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0.e+1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.e+1").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0.e-1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0.e-1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.e-1").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, ".0e1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+.0e1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-.0e1").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, ".0e+1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+.0e+1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-.0e+1").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, ".0e-1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+.0e-1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-.0e-1").convertToDouble());
+
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0.0e1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0.0e1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.0e1").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0.0e+1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0.0e+1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.0e+1").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0.0e-1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0.0e-1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0.0e-1").convertToDouble());
+
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "000.0000e1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+000.0000e+1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-000.0000e+1").convertToDouble());
+}
+
+TEST(APFloatTest, fromZeroDecimalLargeExponentString) {
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0e1234").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0e1234").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0e1234").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0e+1234").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0e+1234").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0e+1234").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0e-1234").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0e-1234").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0e-1234").convertToDouble());
+
+ EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble, "000.0000e1234").convertToDouble());
+ EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble, "000.0000e-1234").convertToDouble());
+
+ EXPECT_EQ(0.0, APFloat(APFloat::IEEEdouble, StringRef("0e1234\02", 6)).convertToDouble());
+}
+
+TEST(APFloatTest, fromZeroHexadecimalString) {
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0p1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0p1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0p1").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0p+1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0p+1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0p+1").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0p-1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0p-1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0p-1").convertToDouble());
+
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0.p1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0.p1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0.p1").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0.p+1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0.p+1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0.p+1").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0.p-1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0.p-1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0.p-1").convertToDouble());
+
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x.0p1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x.0p1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x.0p1").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x.0p+1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x.0p+1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x.0p+1").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x.0p-1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x.0p-1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x.0p-1").convertToDouble());
+
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0.0p1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0.0p1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0.0p1").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0.0p+1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0.0p+1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0.0p+1").convertToDouble());
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0.0p-1").convertToDouble());
+ EXPECT_EQ(+0.0, APFloat(APFloat::IEEEdouble, "+0x0.0p-1").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0.0p-1").convertToDouble());
+
+
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x00000.p1").convertToDouble());
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0000.00000p1").convertToDouble());
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x.00000p1").convertToDouble());
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0.p1").convertToDouble());
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0p1234").convertToDouble());
+ EXPECT_EQ(-0.0, APFloat(APFloat::IEEEdouble, "-0x0p1234").convertToDouble());
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x00000.p1234").convertToDouble());
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0000.00000p1234").convertToDouble());
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x.00000p1234").convertToDouble());
+ EXPECT_EQ( 0.0, APFloat(APFloat::IEEEdouble, "0x0.p1234").convertToDouble());
+}
+
+TEST(APFloatTest, fromDecimalString) {
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble, "1").convertToDouble());
+ EXPECT_EQ(2.0, APFloat(APFloat::IEEEdouble, "2.").convertToDouble());
+ EXPECT_EQ(0.5, APFloat(APFloat::IEEEdouble, ".5").convertToDouble());
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble, "1.0").convertToDouble());
+ EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble, "-2").convertToDouble());
+ EXPECT_EQ(-4.0, APFloat(APFloat::IEEEdouble, "-4.").convertToDouble());
+ EXPECT_EQ(-0.5, APFloat(APFloat::IEEEdouble, "-.5").convertToDouble());
+ EXPECT_EQ(-1.5, APFloat(APFloat::IEEEdouble, "-1.5").convertToDouble());
+ EXPECT_EQ(1.25e12, APFloat(APFloat::IEEEdouble, "1.25e12").convertToDouble());
+ EXPECT_EQ(1.25e+12, APFloat(APFloat::IEEEdouble, "1.25e+12").convertToDouble());
+ EXPECT_EQ(1.25e-12, APFloat(APFloat::IEEEdouble, "1.25e-12").convertToDouble());
+ EXPECT_EQ(1024.0, APFloat(APFloat::IEEEdouble, "1024.").convertToDouble());
+ EXPECT_EQ(1024.05, APFloat(APFloat::IEEEdouble, "1024.05000").convertToDouble());
+ EXPECT_EQ(0.05, APFloat(APFloat::IEEEdouble, ".05000").convertToDouble());
+ EXPECT_EQ(2.0, APFloat(APFloat::IEEEdouble, "2.").convertToDouble());
+ EXPECT_EQ(2.0e2, APFloat(APFloat::IEEEdouble, "2.e2").convertToDouble());
+ EXPECT_EQ(2.0e+2, APFloat(APFloat::IEEEdouble, "2.e+2").convertToDouble());
+ EXPECT_EQ(2.0e-2, APFloat(APFloat::IEEEdouble, "2.e-2").convertToDouble());
+ EXPECT_EQ(2.05e2, APFloat(APFloat::IEEEdouble, "002.05000e2").convertToDouble());
+ EXPECT_EQ(2.05e+2, APFloat(APFloat::IEEEdouble, "002.05000e+2").convertToDouble());
+ EXPECT_EQ(2.05e-2, APFloat(APFloat::IEEEdouble, "002.05000e-2").convertToDouble());
+ EXPECT_EQ(2.05e12, APFloat(APFloat::IEEEdouble, "002.05000e12").convertToDouble());
+ EXPECT_EQ(2.05e+12, APFloat(APFloat::IEEEdouble, "002.05000e+12").convertToDouble());
+ EXPECT_EQ(2.05e-12, APFloat(APFloat::IEEEdouble, "002.05000e-12").convertToDouble());
+}
+
+TEST(APFloatTest, fromHexadecimalString) {
+ EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble, "0x1p0").convertToDouble());
+ EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble, "+0x1p0").convertToDouble());
+ EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble, "-0x1p0").convertToDouble());
+
+ EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble, "0x1p+0").convertToDouble());
+ EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble, "+0x1p+0").convertToDouble());
+ EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble, "-0x1p+0").convertToDouble());
+
+ EXPECT_EQ( 1.0, APFloat(APFloat::IEEEdouble, "0x1p-0").convertToDouble());
+ EXPECT_EQ(+1.0, APFloat(APFloat::IEEEdouble, "+0x1p-0").convertToDouble());
+ EXPECT_EQ(-1.0, APFloat(APFloat::IEEEdouble, "-0x1p-0").convertToDouble());
+
+
+ EXPECT_EQ( 2.0, APFloat(APFloat::IEEEdouble, "0x1p1").convertToDouble());
+ EXPECT_EQ(+2.0, APFloat(APFloat::IEEEdouble, "+0x1p1").convertToDouble());
+ EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble, "-0x1p1").convertToDouble());
+
+ EXPECT_EQ( 2.0, APFloat(APFloat::IEEEdouble, "0x1p+1").convertToDouble());
+ EXPECT_EQ(+2.0, APFloat(APFloat::IEEEdouble, "+0x1p+1").convertToDouble());
+ EXPECT_EQ(-2.0, APFloat(APFloat::IEEEdouble, "-0x1p+1").convertToDouble());
+
+ EXPECT_EQ( 0.5, APFloat(APFloat::IEEEdouble, "0x1p-1").convertToDouble());
+ EXPECT_EQ(+0.5, APFloat(APFloat::IEEEdouble, "+0x1p-1").convertToDouble());
+ EXPECT_EQ(-0.5, APFloat(APFloat::IEEEdouble, "-0x1p-1").convertToDouble());
+
+
+ EXPECT_EQ( 3.0, APFloat(APFloat::IEEEdouble, "0x1.8p1").convertToDouble());
+ EXPECT_EQ(+3.0, APFloat(APFloat::IEEEdouble, "+0x1.8p1").convertToDouble());
+ EXPECT_EQ(-3.0, APFloat(APFloat::IEEEdouble, "-0x1.8p1").convertToDouble());
+
+ EXPECT_EQ( 3.0, APFloat(APFloat::IEEEdouble, "0x1.8p+1").convertToDouble());
+ EXPECT_EQ(+3.0, APFloat(APFloat::IEEEdouble, "+0x1.8p+1").convertToDouble());
+ EXPECT_EQ(-3.0, APFloat(APFloat::IEEEdouble, "-0x1.8p+1").convertToDouble());
+
+ EXPECT_EQ( 0.75, APFloat(APFloat::IEEEdouble, "0x1.8p-1").convertToDouble());
+ EXPECT_EQ(+0.75, APFloat(APFloat::IEEEdouble, "+0x1.8p-1").convertToDouble());
+ EXPECT_EQ(-0.75, APFloat(APFloat::IEEEdouble, "-0x1.8p-1").convertToDouble());
+
+
+ EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble, "0x1000.000p1").convertToDouble());
+ EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble, "+0x1000.000p1").convertToDouble());
+ EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble, "-0x1000.000p1").convertToDouble());
+
+ EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble, "0x1000.000p+1").convertToDouble());
+ EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble, "+0x1000.000p+1").convertToDouble());
+ EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble, "-0x1000.000p+1").convertToDouble());
+
+ EXPECT_EQ( 2048.0, APFloat(APFloat::IEEEdouble, "0x1000.000p-1").convertToDouble());
+ EXPECT_EQ(+2048.0, APFloat(APFloat::IEEEdouble, "+0x1000.000p-1").convertToDouble());
+ EXPECT_EQ(-2048.0, APFloat(APFloat::IEEEdouble, "-0x1000.000p-1").convertToDouble());
+
+
+ EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble, "0x1000p1").convertToDouble());
+ EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble, "+0x1000p1").convertToDouble());
+ EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble, "-0x1000p1").convertToDouble());
+
+ EXPECT_EQ( 8192.0, APFloat(APFloat::IEEEdouble, "0x1000p+1").convertToDouble());
+ EXPECT_EQ(+8192.0, APFloat(APFloat::IEEEdouble, "+0x1000p+1").convertToDouble());
+ EXPECT_EQ(-8192.0, APFloat(APFloat::IEEEdouble, "-0x1000p+1").convertToDouble());
+
+ EXPECT_EQ( 2048.0, APFloat(APFloat::IEEEdouble, "0x1000p-1").convertToDouble());
+ EXPECT_EQ(+2048.0, APFloat(APFloat::IEEEdouble, "+0x1000p-1").convertToDouble());
+ EXPECT_EQ(-2048.0, APFloat(APFloat::IEEEdouble, "-0x1000p-1").convertToDouble());
+
+
+ EXPECT_EQ( 16384.0, APFloat(APFloat::IEEEdouble, "0x10p10").convertToDouble());
+ EXPECT_EQ(+16384.0, APFloat(APFloat::IEEEdouble, "+0x10p10").convertToDouble());
+ EXPECT_EQ(-16384.0, APFloat(APFloat::IEEEdouble, "-0x10p10").convertToDouble());
+
+ EXPECT_EQ( 16384.0, APFloat(APFloat::IEEEdouble, "0x10p+10").convertToDouble());
+ EXPECT_EQ(+16384.0, APFloat(APFloat::IEEEdouble, "+0x10p+10").convertToDouble());
+ EXPECT_EQ(-16384.0, APFloat(APFloat::IEEEdouble, "-0x10p+10").convertToDouble());
+
+ EXPECT_EQ( 0.015625, APFloat(APFloat::IEEEdouble, "0x10p-10").convertToDouble());
+ EXPECT_EQ(+0.015625, APFloat(APFloat::IEEEdouble, "+0x10p-10").convertToDouble());
+ EXPECT_EQ(-0.015625, APFloat(APFloat::IEEEdouble, "-0x10p-10").convertToDouble());
+
+ EXPECT_EQ(1.0625, APFloat(APFloat::IEEEdouble, "0x1.1p0").convertToDouble());
+ EXPECT_EQ(1.0, APFloat(APFloat::IEEEdouble, "0x1p0").convertToDouble());
+
+ EXPECT_EQ(2.71828, convertToDoubleFromString("2.71828"));
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+TEST(APFloatTest, SemanticsDeath) {
+ EXPECT_DEATH(APFloat(APFloat::IEEEsingle, 0.0f).convertToDouble(), "Float semantics are not IEEEdouble");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, 0.0 ).convertToFloat(), "Float semantics are not IEEEsingle");
+}
+
+TEST(APFloatTest, StringDecimalDeath) {
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, ""), "Invalid string length");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+"), "String has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-"), "String has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("\0", 1)), "Invalid character in significand");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1\0", 2)), "Invalid character in significand");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1\02", 3)), "Invalid character in significand");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1\02e1", 5)), "Invalid character in significand");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1e\0", 3)), "Invalid character in exponent");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1e1\0", 4)), "Invalid character in exponent");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("1e1\02", 5)), "Invalid character in exponent");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1.0f"), "Invalid character in significand");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, ".."), "String contains multiple dots");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "..0"), "String contains multiple dots");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1.0.0"), "String contains multiple dots");
+}
+
+TEST(APFloatTest, StringDecimalSignificandDeath) {
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "."), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+."), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-."), "Significand has no digits");
+
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "e"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+e"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-e"), "Significand has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "e1"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+e1"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-e1"), "Significand has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, ".e1"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+.e1"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-.e1"), "Significand has no digits");
+
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, ".e"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+.e"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-.e"), "Significand has no digits");
+}
+
+TEST(APFloatTest, StringDecimalExponentDeath) {
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1e"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+1e"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-1e"), "Exponent has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1.e"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+1.e"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-1.e"), "Exponent has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, ".1e"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+.1e"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-.1e"), "Exponent has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1.1e"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+1.1e"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-1.1e"), "Exponent has no digits");
+
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1e+"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1e-"), "Exponent has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, ".1e"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, ".1e+"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, ".1e-"), "Exponent has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1.0e"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1.0e+"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "1.0e-"), "Exponent has no digits");
+}
+
+TEST(APFloatTest, StringHexadecimalDeath) {
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x"), "Invalid string");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x"), "Invalid string");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x"), "Invalid string");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x0"), "Hex strings require an exponent");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x0"), "Hex strings require an exponent");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x0"), "Hex strings require an exponent");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x0."), "Hex strings require an exponent");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x0."), "Hex strings require an exponent");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x0."), "Hex strings require an exponent");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x.0"), "Hex strings require an exponent");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x.0"), "Hex strings require an exponent");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x.0"), "Hex strings require an exponent");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x0.0"), "Hex strings require an exponent");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x0.0"), "Hex strings require an exponent");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x0.0"), "Hex strings require an exponent");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x\0", 3)), "Invalid character in significand");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1\0", 4)), "Invalid character in significand");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1\02", 5)), "Invalid character in significand");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1\02p1", 7)), "Invalid character in significand");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1p\0", 5)), "Invalid character in exponent");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1p1\0", 6)), "Invalid character in exponent");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, StringRef("0x1p1\02", 7)), "Invalid character in exponent");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1p0f"), "Invalid character in exponent");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x..p1"), "String contains multiple dots");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x..0p1"), "String contains multiple dots");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1.0.0p1"), "String contains multiple dots");
+}
+
+TEST(APFloatTest, StringHexadecimalSignificandDeath) {
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x."), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x."), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x."), "Significand has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0xp"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0xp"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0xp"), "Significand has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0xp+"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0xp+"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0xp+"), "Significand has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0xp-"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0xp-"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0xp-"), "Significand has no digits");
+
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x.p"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x.p"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x.p"), "Significand has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x.p+"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x.p+"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x.p+"), "Significand has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x.p-"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x.p-"), "Significand has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x.p-"), "Significand has no digits");
+}
+
+TEST(APFloatTest, StringHexadecimalExponentDeath) {
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1p"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1p"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1p"), "Exponent has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1p+"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1p+"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1p+"), "Exponent has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1p-"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1p-"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1p-"), "Exponent has no digits");
+
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1.p"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1.p"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1.p"), "Exponent has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1.p+"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1.p+"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1.p+"), "Exponent has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1.p-"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1.p-"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1.p-"), "Exponent has no digits");
+
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x.1p"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x.1p"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x.1p"), "Exponent has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x.1p+"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x.1p+"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x.1p+"), "Exponent has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x.1p-"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x.1p-"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x.1p-"), "Exponent has no digits");
+
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1.1p"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1.1p"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1.1p"), "Exponent has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1.1p+"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1.1p+"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1.1p+"), "Exponent has no digits");
+
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "0x1.1p-"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "+0x1.1p-"), "Exponent has no digits");
+ EXPECT_DEATH(APFloat(APFloat::IEEEdouble, "-0x1.1p-"), "Exponent has no digits");
+}
+#endif
+
+}
diff --git a/unittests/ADT/APIntTest.cpp b/unittests/ADT/APIntTest.cpp
index 648faf1..0b13aa4 100644
--- a/unittests/ADT/APIntTest.cpp
+++ b/unittests/ADT/APIntTest.cpp
@@ -8,7 +8,6 @@
//===----------------------------------------------------------------------===//
#include <ostream>
-#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/SmallString.h"
@@ -164,12 +163,182 @@ TEST(APIntTest, i1) {
}
TEST(APIntTest, fromString) {
- EXPECT_EQ(APInt(1, 0), APInt(1, "0", 1, 10));
- EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 10));
- EXPECT_EQ(APInt(1, 1), APInt(1, "-1", 2, 10));
- EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 2));
- EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 8));
- EXPECT_EQ(APInt(1, 1), APInt(1, "1", 1, 16));
+ EXPECT_EQ(APInt(32, 0), APInt(32, "0", 2));
+ EXPECT_EQ(APInt(32, 1), APInt(32, "1", 2));
+ EXPECT_EQ(APInt(32, 2), APInt(32, "10", 2));
+ EXPECT_EQ(APInt(32, 3), APInt(32, "11", 2));
+ EXPECT_EQ(APInt(32, 4), APInt(32, "100", 2));
+
+ EXPECT_EQ(APInt(32, 0), APInt(32, "+0", 2));
+ EXPECT_EQ(APInt(32, 1), APInt(32, "+1", 2));
+ EXPECT_EQ(APInt(32, 2), APInt(32, "+10", 2));
+ EXPECT_EQ(APInt(32, 3), APInt(32, "+11", 2));
+ EXPECT_EQ(APInt(32, 4), APInt(32, "+100", 2));
+
+ EXPECT_EQ(APInt(32, uint64_t(-0LL)), APInt(32, "-0", 2));
+ EXPECT_EQ(APInt(32, uint64_t(-1LL)), APInt(32, "-1", 2));
+ EXPECT_EQ(APInt(32, uint64_t(-2LL)), APInt(32, "-10", 2));
+ EXPECT_EQ(APInt(32, uint64_t(-3LL)), APInt(32, "-11", 2));
+ EXPECT_EQ(APInt(32, uint64_t(-4LL)), APInt(32, "-100", 2));
+
+
+ EXPECT_EQ(APInt(32, 0), APInt(32, "0", 8));
+ EXPECT_EQ(APInt(32, 1), APInt(32, "1", 8));
+ EXPECT_EQ(APInt(32, 7), APInt(32, "7", 8));
+ EXPECT_EQ(APInt(32, 8), APInt(32, "10", 8));
+ EXPECT_EQ(APInt(32, 15), APInt(32, "17", 8));
+ EXPECT_EQ(APInt(32, 16), APInt(32, "20", 8));
+
+ EXPECT_EQ(APInt(32, +0), APInt(32, "+0", 8));
+ EXPECT_EQ(APInt(32, +1), APInt(32, "+1", 8));
+ EXPECT_EQ(APInt(32, +7), APInt(32, "+7", 8));
+ EXPECT_EQ(APInt(32, +8), APInt(32, "+10", 8));
+ EXPECT_EQ(APInt(32, +15), APInt(32, "+17", 8));
+ EXPECT_EQ(APInt(32, +16), APInt(32, "+20", 8));
+
+ EXPECT_EQ(APInt(32, uint64_t(-0LL)), APInt(32, "-0", 8));
+ EXPECT_EQ(APInt(32, uint64_t(-1LL)), APInt(32, "-1", 8));
+ EXPECT_EQ(APInt(32, uint64_t(-7LL)), APInt(32, "-7", 8));
+ EXPECT_EQ(APInt(32, uint64_t(-8LL)), APInt(32, "-10", 8));
+ EXPECT_EQ(APInt(32, uint64_t(-15LL)), APInt(32, "-17", 8));
+ EXPECT_EQ(APInt(32, uint64_t(-16LL)), APInt(32, "-20", 8));
+
+
+ EXPECT_EQ(APInt(32, 0), APInt(32, "0", 10));
+ EXPECT_EQ(APInt(32, 1), APInt(32, "1", 10));
+ EXPECT_EQ(APInt(32, 9), APInt(32, "9", 10));
+ EXPECT_EQ(APInt(32, 10), APInt(32, "10", 10));
+ EXPECT_EQ(APInt(32, 19), APInt(32, "19", 10));
+ EXPECT_EQ(APInt(32, 20), APInt(32, "20", 10));
+
+ EXPECT_EQ(APInt(32, uint64_t(-0LL)), APInt(32, "-0", 10));
+ EXPECT_EQ(APInt(32, uint64_t(-1LL)), APInt(32, "-1", 10));
+ EXPECT_EQ(APInt(32, uint64_t(-9LL)), APInt(32, "-9", 10));
+ EXPECT_EQ(APInt(32, uint64_t(-10LL)), APInt(32, "-10", 10));
+ EXPECT_EQ(APInt(32, uint64_t(-19LL)), APInt(32, "-19", 10));
+ EXPECT_EQ(APInt(32, uint64_t(-20LL)), APInt(32, "-20", 10));
+
+
+ EXPECT_EQ(APInt(32, 0), APInt(32, "0", 16));
+ EXPECT_EQ(APInt(32, 1), APInt(32, "1", 16));
+ EXPECT_EQ(APInt(32, 15), APInt(32, "F", 16));
+ EXPECT_EQ(APInt(32, 16), APInt(32, "10", 16));
+ EXPECT_EQ(APInt(32, 31), APInt(32, "1F", 16));
+ EXPECT_EQ(APInt(32, 32), APInt(32, "20", 16));
+
+ EXPECT_EQ(APInt(32, uint64_t(-0LL)), APInt(32, "-0", 16));
+ EXPECT_EQ(APInt(32, uint64_t(-1LL)), APInt(32, "-1", 16));
+ EXPECT_EQ(APInt(32, uint64_t(-15LL)), APInt(32, "-F", 16));
+ EXPECT_EQ(APInt(32, uint64_t(-16LL)), APInt(32, "-10", 16));
+ EXPECT_EQ(APInt(32, uint64_t(-31LL)), APInt(32, "-1F", 16));
+ EXPECT_EQ(APInt(32, uint64_t(-32LL)), APInt(32, "-20", 16));
+}
+
+TEST(APIntTest, StringBitsNeeded2) {
+ EXPECT_EQ(1U, APInt::getBitsNeeded( "0", 2));
+ EXPECT_EQ(1U, APInt::getBitsNeeded( "1", 2));
+ EXPECT_EQ(2U, APInt::getBitsNeeded( "10", 2));
+ EXPECT_EQ(2U, APInt::getBitsNeeded( "11", 2));
+ EXPECT_EQ(3U, APInt::getBitsNeeded("100", 2));
+
+ EXPECT_EQ(1U, APInt::getBitsNeeded( "+0", 2));
+ EXPECT_EQ(1U, APInt::getBitsNeeded( "+1", 2));
+ EXPECT_EQ(2U, APInt::getBitsNeeded( "+10", 2));
+ EXPECT_EQ(2U, APInt::getBitsNeeded( "+11", 2));
+ EXPECT_EQ(3U, APInt::getBitsNeeded("+100", 2));
+
+ EXPECT_EQ(2U, APInt::getBitsNeeded( "-0", 2));
+ EXPECT_EQ(2U, APInt::getBitsNeeded( "-1", 2));
+ EXPECT_EQ(3U, APInt::getBitsNeeded( "-10", 2));
+ EXPECT_EQ(3U, APInt::getBitsNeeded( "-11", 2));
+ EXPECT_EQ(4U, APInt::getBitsNeeded("-100", 2));
+}
+
+TEST(APIntTest, StringBitsNeeded8) {
+ EXPECT_EQ(3U, APInt::getBitsNeeded( "0", 8));
+ EXPECT_EQ(3U, APInt::getBitsNeeded( "7", 8));
+ EXPECT_EQ(6U, APInt::getBitsNeeded("10", 8));
+ EXPECT_EQ(6U, APInt::getBitsNeeded("17", 8));
+ EXPECT_EQ(6U, APInt::getBitsNeeded("20", 8));
+
+ EXPECT_EQ(3U, APInt::getBitsNeeded( "+0", 8));
+ EXPECT_EQ(3U, APInt::getBitsNeeded( "+7", 8));
+ EXPECT_EQ(6U, APInt::getBitsNeeded("+10", 8));
+ EXPECT_EQ(6U, APInt::getBitsNeeded("+17", 8));
+ EXPECT_EQ(6U, APInt::getBitsNeeded("+20", 8));
+
+ EXPECT_EQ(4U, APInt::getBitsNeeded( "-0", 8));
+ EXPECT_EQ(4U, APInt::getBitsNeeded( "-7", 8));
+ EXPECT_EQ(7U, APInt::getBitsNeeded("-10", 8));
+ EXPECT_EQ(7U, APInt::getBitsNeeded("-17", 8));
+ EXPECT_EQ(7U, APInt::getBitsNeeded("-20", 8));
+}
+
+TEST(APIntTest, StringBitsNeeded10) {
+ EXPECT_EQ(1U, APInt::getBitsNeeded( "0", 10));
+ EXPECT_EQ(2U, APInt::getBitsNeeded( "3", 10));
+ EXPECT_EQ(4U, APInt::getBitsNeeded( "9", 10));
+ EXPECT_EQ(4U, APInt::getBitsNeeded("10", 10));
+ EXPECT_EQ(5U, APInt::getBitsNeeded("19", 10));
+ EXPECT_EQ(5U, APInt::getBitsNeeded("20", 10));
+
+ EXPECT_EQ(1U, APInt::getBitsNeeded( "+0", 10));
+ EXPECT_EQ(4U, APInt::getBitsNeeded( "+9", 10));
+ EXPECT_EQ(4U, APInt::getBitsNeeded("+10", 10));
+ EXPECT_EQ(5U, APInt::getBitsNeeded("+19", 10));
+ EXPECT_EQ(5U, APInt::getBitsNeeded("+20", 10));
+
+ EXPECT_EQ(2U, APInt::getBitsNeeded( "-0", 10));
+ EXPECT_EQ(5U, APInt::getBitsNeeded( "-9", 10));
+ EXPECT_EQ(5U, APInt::getBitsNeeded("-10", 10));
+ EXPECT_EQ(6U, APInt::getBitsNeeded("-19", 10));
+ EXPECT_EQ(6U, APInt::getBitsNeeded("-20", 10));
+}
+
+TEST(APIntTest, StringBitsNeeded16) {
+ EXPECT_EQ(4U, APInt::getBitsNeeded( "0", 16));
+ EXPECT_EQ(4U, APInt::getBitsNeeded( "F", 16));
+ EXPECT_EQ(8U, APInt::getBitsNeeded("10", 16));
+ EXPECT_EQ(8U, APInt::getBitsNeeded("1F", 16));
+ EXPECT_EQ(8U, APInt::getBitsNeeded("20", 16));
+
+ EXPECT_EQ(4U, APInt::getBitsNeeded( "+0", 16));
+ EXPECT_EQ(4U, APInt::getBitsNeeded( "+F", 16));
+ EXPECT_EQ(8U, APInt::getBitsNeeded("+10", 16));
+ EXPECT_EQ(8U, APInt::getBitsNeeded("+1F", 16));
+ EXPECT_EQ(8U, APInt::getBitsNeeded("+20", 16));
+
+ EXPECT_EQ(5U, APInt::getBitsNeeded( "-0", 16));
+ EXPECT_EQ(5U, APInt::getBitsNeeded( "-F", 16));
+ EXPECT_EQ(9U, APInt::getBitsNeeded("-10", 16));
+ EXPECT_EQ(9U, APInt::getBitsNeeded("-1F", 16));
+ EXPECT_EQ(9U, APInt::getBitsNeeded("-20", 16));
+}
+
+TEST(APIntTest, Log2) {
+ EXPECT_EQ(APInt(15, 7).logBase2(), 2U);
+ EXPECT_EQ(APInt(15, 7).ceilLogBase2(), 3U);
+ EXPECT_EQ(APInt(15, 7).exactLogBase2(), -1);
+ EXPECT_EQ(APInt(15, 8).logBase2(), 3U);
+ EXPECT_EQ(APInt(15, 8).ceilLogBase2(), 3U);
+ EXPECT_EQ(APInt(15, 8).exactLogBase2(), 3);
+ EXPECT_EQ(APInt(15, 9).logBase2(), 3U);
+ EXPECT_EQ(APInt(15, 9).ceilLogBase2(), 4U);
+ EXPECT_EQ(APInt(15, 9).exactLogBase2(), -1);
+}
+
+#ifdef GTEST_HAS_DEATH_TEST
+TEST(APIntTest, StringDeath) {
+ EXPECT_DEATH(APInt(0, "", 0), "Bitwidth too small");
+ EXPECT_DEATH(APInt(32, "", 0), "Invalid string length");
+ EXPECT_DEATH(APInt(32, "0", 0), "Radix should be 2, 8, 10, or 16!");
+ EXPECT_DEATH(APInt(32, "", 10), "Invalid string length");
+ EXPECT_DEATH(APInt(32, "-", 10), "String is only a sign, needs a value.");
+ EXPECT_DEATH(APInt(1, "1234", 10), "Insufficient bit width");
+ EXPECT_DEATH(APInt(32, "\0", 10), "Invalid string length");
+ EXPECT_DEATH(APInt(32, StringRef("1\02", 3), 10), "Invalid character in digit string");
+ EXPECT_DEATH(APInt(32, "1L", 10), "Invalid character in digit string");
}
+#endif
}
diff --git a/unittests/ADT/SmallStringTest.cpp b/unittests/ADT/SmallStringTest.cpp
new file mode 100644
index 0000000..099d815
--- /dev/null
+++ b/unittests/ADT/SmallStringTest.cpp
@@ -0,0 +1,48 @@
+//===- llvm/unittest/ADT/SmallStringTest.cpp ------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// SmallString unit tests.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/ADT/SmallString.h"
+#include <stdarg.h>
+#include <climits>
+#include <cstring>
+
+using namespace llvm;
+
+namespace {
+
+// Test fixture class
+class SmallStringTest : public testing::Test {
+protected:
+ typedef SmallString<40> StringType;
+
+ StringType theString;
+
+ void assertEmpty(StringType & v) {
+ // Size tests
+ EXPECT_EQ(0u, v.size());
+ EXPECT_TRUE(v.empty());
+ // Iterator tests
+ EXPECT_TRUE(v.begin() == v.end());
+ }
+};
+
+// New string test.
+TEST_F(SmallStringTest, EmptyStringTest) {
+ SCOPED_TRACE("EmptyStringTest");
+ assertEmpty(theString);
+ EXPECT_TRUE(theString.rbegin() == theString.rend());
+}
+
+}
+
diff --git a/unittests/ADT/SmallVectorTest.cpp b/unittests/ADT/SmallVectorTest.cpp
index 19ef099..8a81796 100644
--- a/unittests/ADT/SmallVectorTest.cpp
+++ b/unittests/ADT/SmallVectorTest.cpp
@@ -196,7 +196,8 @@ TEST_F(SmallVectorTest, ResizeGrowTest) {
theVector.resize(2);
- // XXX: I don't know where the extra construct/destruct is coming from.
+ // The extra constructor/destructor calls come from the temporary object used
+ // to initialize the contents of the resized array (via copy construction).
EXPECT_EQ(3, Constructable::getNumConstructorCalls());
EXPECT_EQ(1, Constructable::getNumDestructorCalls());
EXPECT_EQ(2u, theVector.size());
@@ -214,16 +215,16 @@ TEST_F(SmallVectorTest, ResizeFillTest) {
TEST_F(SmallVectorTest, OverflowTest) {
SCOPED_TRACE("OverflowTest");
- // Push more elements than the fixed size
+ // Push more elements than the fixed size.
makeSequence(theVector, 1, 10);
- // test size and values
+ // Test size and values.
EXPECT_EQ(10u, theVector.size());
for (int i = 0; i < 10; ++i) {
EXPECT_EQ(i+1, theVector[i].getValue());
}
- // Now resize back to fixed size
+ // Now resize back to fixed size.
theVector.resize(1);
assertValuesInOrder(theVector, 1u, 1);
@@ -380,4 +381,22 @@ TEST_F(SmallVectorTest, ConstVectorTest) {
EXPECT_TRUE(constVector.begin() == constVector.end());
}
+// Direct array access.
+TEST_F(SmallVectorTest, DirectVectorTest) {
+ EXPECT_EQ(0u, theVector.size());
+ EXPECT_EQ(4u, theVector.capacity());
+ EXPECT_EQ(0, Constructable::getNumConstructorCalls());
+ theVector.end()[0] = 1;
+ theVector.end()[1] = 2;
+ theVector.end()[2] = 3;
+ theVector.end()[3] = 4;
+ theVector.set_size(4);
+ EXPECT_EQ(4u, theVector.size());
+ EXPECT_EQ(4, Constructable::getNumConstructorCalls());
+ EXPECT_EQ(1, theVector[0].getValue());
+ EXPECT_EQ(2, theVector[1].getValue());
+ EXPECT_EQ(3, theVector[2].getValue());
+ EXPECT_EQ(4, theVector[3].getValue());
+}
+
}
diff --git a/unittests/ADT/SparseBitVectorTest.cpp b/unittests/ADT/SparseBitVectorTest.cpp
new file mode 100644
index 0000000..d8fc5ce
--- /dev/null
+++ b/unittests/ADT/SparseBitVectorTest.cpp
@@ -0,0 +1,36 @@
+//===- llvm/unittest/ADT/SparseBitVectorTest.cpp - SparseBitVector tests --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SparseBitVector.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(SparseBitVectorTest, TrivialOperation) {
+ SparseBitVector<> Vec;
+ EXPECT_EQ(0U, Vec.count());
+ EXPECT_FALSE(Vec.test(17));
+ Vec.set(5);
+ EXPECT_TRUE(Vec.test(5));
+ EXPECT_FALSE(Vec.test(17));
+ Vec.reset(6);
+ EXPECT_TRUE(Vec.test(5));
+ EXPECT_FALSE(Vec.test(6));
+ Vec.reset(5);
+ EXPECT_FALSE(Vec.test(5));
+ EXPECT_TRUE(Vec.test_and_set(17));
+ EXPECT_FALSE(Vec.test_and_set(17));
+ EXPECT_TRUE(Vec.test(17));
+ Vec.clear();
+ EXPECT_FALSE(Vec.test(17));
+}
+
+}
diff --git a/unittests/ADT/StringMapTest.cpp b/unittests/ADT/StringMapTest.cpp
index 9f9f2e4..8ee166b 100644
--- a/unittests/ADT/StringMapTest.cpp
+++ b/unittests/ADT/StringMapTest.cpp
@@ -9,6 +9,7 @@
#include "gtest/gtest.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/DataTypes.h"
using namespace llvm;
namespace {
@@ -21,7 +22,7 @@ protected:
static const char testKey[];
static const uint32_t testValue;
static const char* testKeyFirst;
- static const char* testKeyLast;
+ static size_t testKeyLength;
static const std::string testKeyStr;
void assertEmptyMap() {
@@ -34,10 +35,11 @@ protected:
// Lookup tests
EXPECT_EQ(0u, testMap.count(testKey));
- EXPECT_EQ(0u, testMap.count(testKeyFirst, testKeyLast));
+ EXPECT_EQ(0u, testMap.count(StringRef(testKeyFirst, testKeyLength)));
EXPECT_EQ(0u, testMap.count(testKeyStr));
EXPECT_TRUE(testMap.find(testKey) == testMap.end());
- EXPECT_TRUE(testMap.find(testKeyFirst, testKeyLast) == testMap.end());
+ EXPECT_TRUE(testMap.find(StringRef(testKeyFirst, testKeyLength)) ==
+ testMap.end());
EXPECT_TRUE(testMap.find(testKeyStr) == testMap.end());
}
@@ -56,10 +58,11 @@ protected:
// Lookup tests
EXPECT_EQ(1u, testMap.count(testKey));
- EXPECT_EQ(1u, testMap.count(testKeyFirst, testKeyLast));
+ EXPECT_EQ(1u, testMap.count(StringRef(testKeyFirst, testKeyLength)));
EXPECT_EQ(1u, testMap.count(testKeyStr));
EXPECT_TRUE(testMap.find(testKey) == testMap.begin());
- EXPECT_TRUE(testMap.find(testKeyFirst, testKeyLast) == testMap.begin());
+ EXPECT_TRUE(testMap.find(StringRef(testKeyFirst, testKeyLength)) ==
+ testMap.begin());
EXPECT_TRUE(testMap.find(testKeyStr) == testMap.begin());
}
};
@@ -67,7 +70,7 @@ protected:
const char StringMapTest::testKey[] = "key";
const uint32_t StringMapTest::testValue = 1u;
const char* StringMapTest::testKeyFirst = testKey;
-const char* StringMapTest::testKeyLast = testKey + sizeof(testKey) - 1;
+size_t StringMapTest::testKeyLength = sizeof(testKey) - 1;
const std::string StringMapTest::testKeyStr(testKey);
// Empty map tests.
@@ -89,10 +92,10 @@ TEST_F(StringMapTest, ConstEmptyMapTest) {
// Lookup tests
EXPECT_EQ(0u, constTestMap.count(testKey));
- EXPECT_EQ(0u, constTestMap.count(testKeyFirst, testKeyLast));
+ EXPECT_EQ(0u, constTestMap.count(StringRef(testKeyFirst, testKeyLength)));
EXPECT_EQ(0u, constTestMap.count(testKeyStr));
EXPECT_TRUE(constTestMap.find(testKey) == constTestMap.end());
- EXPECT_TRUE(constTestMap.find(testKeyFirst, testKeyLast) ==
+ EXPECT_TRUE(constTestMap.find(StringRef(testKeyFirst, testKeyLength)) ==
constTestMap.end());
EXPECT_TRUE(constTestMap.find(testKeyStr) == constTestMap.end());
}
@@ -185,7 +188,7 @@ namespace {
TEST_F(StringMapTest, StringMapEntryTest) {
StringMap<uint32_t>::value_type* entry =
StringMap<uint32_t>::value_type::Create(
- testKeyFirst, testKeyLast, 1u);
+ testKeyFirst, testKeyFirst + testKeyLength, 1u);
EXPECT_STREQ(testKey, entry->first());
EXPECT_EQ(1u, entry->second);
}
@@ -195,7 +198,8 @@ TEST_F(StringMapTest, InsertTest) {
SCOPED_TRACE("InsertTest");
testMap.insert(
StringMap<uint32_t>::value_type::Create(
- testKeyFirst, testKeyLast, testMap.getAllocator(), 1u));
+ testKeyFirst, testKeyFirst + testKeyLength,
+ testMap.getAllocator(), 1u));
assertSingleItemMap();
}
diff --git a/unittests/ADT/StringRefTest.cpp b/unittests/ADT/StringRefTest.cpp
new file mode 100644
index 0000000..cdc476e
--- /dev/null
+++ b/unittests/ADT/StringRefTest.cpp
@@ -0,0 +1,155 @@
+//===- llvm/unittest/ADT/StringRefTest.cpp - StringRef unit tests ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+namespace {
+
+std::ostream &operator<<(std::ostream &OS, const StringRef &S) {
+ OS << S;
+ return OS;
+}
+
+std::ostream &operator<<(std::ostream &OS,
+ const std::pair<StringRef, StringRef> &P) {
+ OS << "(" << P.first << ", " << P.second << ")";
+ return OS;
+}
+
+TEST(StringRefTest, Construction) {
+ EXPECT_EQ("", StringRef());
+ EXPECT_EQ("hello", StringRef("hello"));
+ EXPECT_EQ("hello", StringRef("hello world", 5));
+ EXPECT_EQ("hello", StringRef(std::string("hello")));
+}
+
+TEST(StringRefTest, Iteration) {
+ StringRef S("hello");
+ const char *p = "hello";
+ for (const char *it = S.begin(), *ie = S.end(); it != ie; ++it, ++p)
+ EXPECT_EQ(*it, *p);
+}
+
+TEST(StringRefTest, StringOps) {
+ const char *p = "hello";
+ EXPECT_EQ(p, StringRef(p, 0).data());
+ EXPECT_TRUE(StringRef().empty());
+ EXPECT_EQ((size_t) 5, StringRef("hello").size());
+ EXPECT_EQ(-1, StringRef("aab").compare("aad"));
+ EXPECT_EQ( 0, StringRef("aab").compare("aab"));
+ EXPECT_EQ( 1, StringRef("aab").compare("aaa"));
+ EXPECT_EQ(-1, StringRef("aab").compare("aabb"));
+ EXPECT_EQ( 1, StringRef("aab").compare("aa"));
+}
+
+TEST(StringRefTest, Operators) {
+ EXPECT_EQ("", StringRef());
+ EXPECT_TRUE(StringRef("aab") < StringRef("aad"));
+ EXPECT_FALSE(StringRef("aab") < StringRef("aab"));
+ EXPECT_TRUE(StringRef("aab") <= StringRef("aab"));
+ EXPECT_FALSE(StringRef("aab") <= StringRef("aaa"));
+ EXPECT_TRUE(StringRef("aad") > StringRef("aab"));
+ EXPECT_FALSE(StringRef("aab") > StringRef("aab"));
+ EXPECT_TRUE(StringRef("aab") >= StringRef("aab"));
+ EXPECT_FALSE(StringRef("aaa") >= StringRef("aab"));
+ EXPECT_EQ(StringRef("aab"), StringRef("aab"));
+ EXPECT_FALSE(StringRef("aab") == StringRef("aac"));
+ EXPECT_FALSE(StringRef("aab") != StringRef("aab"));
+ EXPECT_TRUE(StringRef("aab") != StringRef("aac"));
+ EXPECT_EQ('a', StringRef("aab")[1]);
+}
+
+TEST(StringRefTest, Substr) {
+ StringRef Str("hello");
+ EXPECT_EQ("lo", Str.substr(3));
+ EXPECT_EQ("", Str.substr(100));
+ EXPECT_EQ("hello", Str.substr(0, 100));
+ EXPECT_EQ("o", Str.substr(4, 10));
+}
+
+TEST(StringRefTest, Slice) {
+ StringRef Str("hello");
+ EXPECT_EQ("l", Str.slice(2, 3));
+ EXPECT_EQ("ell", Str.slice(1, 4));
+ EXPECT_EQ("llo", Str.slice(2, 100));
+ EXPECT_EQ("", Str.slice(2, 1));
+ EXPECT_EQ("", Str.slice(10, 20));
+}
+
+TEST(StringRefTest, Split) {
+ StringRef Str("hello");
+ EXPECT_EQ(std::make_pair(StringRef("hello"), StringRef("")),
+ Str.split('X'));
+ EXPECT_EQ(std::make_pair(StringRef("h"), StringRef("llo")),
+ Str.split('e'));
+ EXPECT_EQ(std::make_pair(StringRef(""), StringRef("ello")),
+ Str.split('h'));
+ EXPECT_EQ(std::make_pair(StringRef("he"), StringRef("lo")),
+ Str.split('l'));
+ EXPECT_EQ(std::make_pair(StringRef("hell"), StringRef("")),
+ Str.split('o'));
+
+ EXPECT_EQ(std::make_pair(StringRef("hello"), StringRef("")),
+ Str.rsplit('X'));
+ EXPECT_EQ(std::make_pair(StringRef("h"), StringRef("llo")),
+ Str.rsplit('e'));
+ EXPECT_EQ(std::make_pair(StringRef(""), StringRef("ello")),
+ Str.rsplit('h'));
+ EXPECT_EQ(std::make_pair(StringRef("hel"), StringRef("o")),
+ Str.rsplit('l'));
+ EXPECT_EQ(std::make_pair(StringRef("hell"), StringRef("")),
+ Str.rsplit('o'));
+}
+
+TEST(StringRefTest, StartsWith) {
+ StringRef Str("hello");
+ EXPECT_TRUE(Str.startswith("he"));
+ EXPECT_FALSE(Str.startswith("helloworld"));
+ EXPECT_FALSE(Str.startswith("hi"));
+}
+
+TEST(StringRefTest, Find) {
+ StringRef Str("hello");
+ EXPECT_EQ(2U, Str.find('l'));
+ EXPECT_EQ(StringRef::npos, Str.find('z'));
+ EXPECT_EQ(StringRef::npos, Str.find("helloworld"));
+ EXPECT_EQ(0U, Str.find("hello"));
+ EXPECT_EQ(1U, Str.find("ello"));
+ EXPECT_EQ(StringRef::npos, Str.find("zz"));
+
+ EXPECT_EQ(3U, Str.rfind('l'));
+ EXPECT_EQ(StringRef::npos, Str.rfind('z'));
+ EXPECT_EQ(StringRef::npos, Str.rfind("helloworld"));
+ EXPECT_EQ(0U, Str.rfind("hello"));
+ EXPECT_EQ(1U, Str.rfind("ello"));
+ EXPECT_EQ(StringRef::npos, Str.rfind("zz"));
+}
+
+TEST(StringRefTest, Count) {
+ StringRef Str("hello");
+ EXPECT_EQ(2U, Str.count('l'));
+ EXPECT_EQ(1U, Str.count('o'));
+ EXPECT_EQ(0U, Str.count('z'));
+ EXPECT_EQ(0U, Str.count("helloworld"));
+ EXPECT_EQ(1U, Str.count("hello"));
+ EXPECT_EQ(1U, Str.count("ello"));
+ EXPECT_EQ(0U, Str.count("zz"));
+}
+
+TEST(StringRefTest, Misc) {
+ std::string Storage;
+ raw_string_ostream OS(Storage);
+ OS << StringRef("hello");
+ EXPECT_EQ("hello", OS.str());
+}
+
+} // end anonymous namespace
diff --git a/unittests/ADT/TripleTest.cpp b/unittests/ADT/TripleTest.cpp
index dee09f4..1a9e81a 100644
--- a/unittests/ADT/TripleTest.cpp
+++ b/unittests/ADT/TripleTest.cpp
@@ -18,58 +18,58 @@ TEST(TripleTest, BasicParsing) {
Triple T;
T = Triple("");
- EXPECT_EQ("", T.getArchName());
- EXPECT_EQ("", T.getVendorName());
- EXPECT_EQ("", T.getOSName());
- EXPECT_EQ("", T.getEnvironmentName());
+ EXPECT_EQ("", T.getArchName().str());
+ EXPECT_EQ("", T.getVendorName().str());
+ EXPECT_EQ("", T.getOSName().str());
+ EXPECT_EQ("", T.getEnvironmentName().str());
T = Triple("-");
- EXPECT_EQ("", T.getArchName());
- EXPECT_EQ("", T.getVendorName());
- EXPECT_EQ("", T.getOSName());
- EXPECT_EQ("", T.getEnvironmentName());
+ EXPECT_EQ("", T.getArchName().str());
+ EXPECT_EQ("", T.getVendorName().str());
+ EXPECT_EQ("", T.getOSName().str());
+ EXPECT_EQ("", T.getEnvironmentName().str());
T = Triple("--");
- EXPECT_EQ("", T.getArchName());
- EXPECT_EQ("", T.getVendorName());
- EXPECT_EQ("", T.getOSName());
- EXPECT_EQ("", T.getEnvironmentName());
+ EXPECT_EQ("", T.getArchName().str());
+ EXPECT_EQ("", T.getVendorName().str());
+ EXPECT_EQ("", T.getOSName().str());
+ EXPECT_EQ("", T.getEnvironmentName().str());
T = Triple("---");
- EXPECT_EQ("", T.getArchName());
- EXPECT_EQ("", T.getVendorName());
- EXPECT_EQ("", T.getOSName());
- EXPECT_EQ("", T.getEnvironmentName());
+ EXPECT_EQ("", T.getArchName().str());
+ EXPECT_EQ("", T.getVendorName().str());
+ EXPECT_EQ("", T.getOSName().str());
+ EXPECT_EQ("", T.getEnvironmentName().str());
T = Triple("----");
- EXPECT_EQ("", T.getArchName());
- EXPECT_EQ("", T.getVendorName());
- EXPECT_EQ("", T.getOSName());
- EXPECT_EQ("-", T.getEnvironmentName());
+ EXPECT_EQ("", T.getArchName().str());
+ EXPECT_EQ("", T.getVendorName().str());
+ EXPECT_EQ("", T.getOSName().str());
+ EXPECT_EQ("-", T.getEnvironmentName().str());
T = Triple("a");
- EXPECT_EQ("a", T.getArchName());
- EXPECT_EQ("", T.getVendorName());
- EXPECT_EQ("", T.getOSName());
- EXPECT_EQ("", T.getEnvironmentName());
+ EXPECT_EQ("a", T.getArchName().str());
+ EXPECT_EQ("", T.getVendorName().str());
+ EXPECT_EQ("", T.getOSName().str());
+ EXPECT_EQ("", T.getEnvironmentName().str());
T = Triple("a-b");
- EXPECT_EQ("a", T.getArchName());
- EXPECT_EQ("b", T.getVendorName());
- EXPECT_EQ("", T.getOSName());
- EXPECT_EQ("", T.getEnvironmentName());
+ EXPECT_EQ("a", T.getArchName().str());
+ EXPECT_EQ("b", T.getVendorName().str());
+ EXPECT_EQ("", T.getOSName().str());
+ EXPECT_EQ("", T.getEnvironmentName().str());
T = Triple("a-b-c");
- EXPECT_EQ("a", T.getArchName());
- EXPECT_EQ("b", T.getVendorName());
- EXPECT_EQ("c", T.getOSName());
- EXPECT_EQ("", T.getEnvironmentName());
+ EXPECT_EQ("a", T.getArchName().str());
+ EXPECT_EQ("b", T.getVendorName().str());
+ EXPECT_EQ("c", T.getOSName().str());
+ EXPECT_EQ("", T.getEnvironmentName().str());
T = Triple("a-b-c-d");
- EXPECT_EQ("a", T.getArchName());
- EXPECT_EQ("b", T.getVendorName());
- EXPECT_EQ("c", T.getOSName());
- EXPECT_EQ("d", T.getEnvironmentName());
+ EXPECT_EQ("a", T.getArchName().str());
+ EXPECT_EQ("b", T.getVendorName().str());
+ EXPECT_EQ("c", T.getOSName().str());
+ EXPECT_EQ("d", T.getEnvironmentName().str());
}
TEST(TripleTest, ParsedIDs) {
@@ -92,6 +92,18 @@ TEST(TripleTest, ParsedIDs) {
T = Triple("huh");
EXPECT_EQ(Triple::UnknownArch, T.getArch());
+
+ // Two exceptional cases.
+
+ T = Triple("i386-mingw32");
+ EXPECT_EQ(Triple::x86, T.getArch());
+ EXPECT_EQ(Triple::PC, T.getVendor());
+ EXPECT_EQ(Triple::MinGW32, T.getOS());
+
+ T = Triple("arm-elf");
+ EXPECT_EQ(Triple::arm, T.getArch());
+ EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+ EXPECT_EQ(Triple::UnknownOS, T.getOS());
}
TEST(TripleTest, MutateName) {
diff --git a/unittests/ADT/TwineTest.cpp b/unittests/ADT/TwineTest.cpp
new file mode 100644
index 0000000..61e8a0a
--- /dev/null
+++ b/unittests/ADT/TwineTest.cpp
@@ -0,0 +1,75 @@
+//===- TwineTest.cpp - Twine unit tests -----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+namespace {
+
+std::string repr(const Twine &Value) {
+ std::string res;
+ llvm::raw_string_ostream OS(res);
+ Value.printRepr(OS);
+ return OS.str();
+}
+
+TEST(TwineTest, Construction) {
+ EXPECT_EQ("", Twine().str());
+ EXPECT_EQ("hi", Twine("hi").str());
+ EXPECT_EQ("hi", Twine(std::string("hi")).str());
+ EXPECT_EQ("hi", Twine(StringRef("hi")).str());
+ EXPECT_EQ("hi", Twine(StringRef(std::string("hi"))).str());
+ EXPECT_EQ("hi", Twine(StringRef("hithere", 2)).str());
+}
+
+TEST(TwineTest, Numbers) {
+ EXPECT_EQ("123", Twine(123U).str());
+ EXPECT_EQ("123", Twine(123).str());
+ EXPECT_EQ("-123", Twine(-123).str());
+ EXPECT_EQ("123", Twine(123).str());
+ EXPECT_EQ("-123", Twine(-123).str());
+ EXPECT_EQ("123", Twine((char) 123).str());
+ EXPECT_EQ("-123", Twine((signed char) -123).str());
+
+ EXPECT_EQ("7b", Twine::utohexstr(123).str());
+}
+
+TEST(TwineTest, Concat) {
+ // Check verse repr, since we care about the actual representation not just
+ // the result.
+
+ // Concat with null.
+ EXPECT_EQ("(Twine null empty)",
+ repr(Twine("hi").concat(Twine::createNull())));
+ EXPECT_EQ("(Twine null empty)",
+ repr(Twine::createNull().concat(Twine("hi"))));
+
+ // Concat with empty.
+ EXPECT_EQ("(Twine cstring:\"hi\" empty)",
+ repr(Twine("hi").concat(Twine())));
+ EXPECT_EQ("(Twine cstring:\"hi\" empty)",
+ repr(Twine().concat(Twine("hi"))));
+
+ // Concatenation of unary ropes.
+ EXPECT_EQ("(Twine cstring:\"a\" cstring:\"b\")",
+ repr(Twine("a").concat(Twine("b"))));
+
+ // Concatenation of other ropes.
+ EXPECT_EQ("(Twine rope:(Twine cstring:\"a\" cstring:\"b\") cstring:\"c\")",
+ repr(Twine("a").concat(Twine("b")).concat(Twine("c"))));
+ EXPECT_EQ("(Twine cstring:\"a\" rope:(Twine cstring:\"b\" cstring:\"c\"))",
+ repr(Twine("a").concat(Twine("b").concat(Twine("c")))));
+}
+
+ // I suppose linking in the entire code generator to add a unit test to check
+ // the code size of the concat operation is overkill... :)
+
+} // end anonymous namespace
diff --git a/unittests/ExecutionEngine/ExecutionEngineTest.cpp b/unittests/ExecutionEngine/ExecutionEngineTest.cpp
new file mode 100644
index 0000000..904ee2b
--- /dev/null
+++ b/unittests/ExecutionEngine/ExecutionEngineTest.cpp
@@ -0,0 +1,129 @@
+//===- ExecutionEngineTest.cpp - Unit tests for ExecutionEngine -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DerivedTypes.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ExecutionEngine/Interpreter.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+class ExecutionEngineTest : public testing::Test {
+protected:
+ ExecutionEngineTest()
+ : M(new Module("<main>", getGlobalContext())),
+ Engine(EngineBuilder(M).create()) {
+ }
+
+ virtual void SetUp() {
+ ASSERT_TRUE(Engine.get() != NULL);
+ }
+
+ GlobalVariable *NewExtGlobal(const Type *T, const Twine &Name) {
+ return new GlobalVariable(*M, T, false, // Not constant.
+ GlobalValue::ExternalLinkage, NULL, Name);
+ }
+
+ Module *const M;
+ const OwningPtr<ExecutionEngine> Engine;
+};
+
+TEST_F(ExecutionEngineTest, ForwardGlobalMapping) {
+ GlobalVariable *G1 =
+ NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
+ int32_t Mem1 = 3;
+ Engine->addGlobalMapping(G1, &Mem1);
+ EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable(G1));
+ int32_t Mem2 = 4;
+ Engine->updateGlobalMapping(G1, &Mem2);
+ EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1));
+ Engine->updateGlobalMapping(G1, NULL);
+ EXPECT_EQ(NULL, Engine->getPointerToGlobalIfAvailable(G1));
+ Engine->updateGlobalMapping(G1, &Mem2);
+ EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1));
+
+ GlobalVariable *G2 =
+ NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
+ EXPECT_EQ(NULL, Engine->getPointerToGlobalIfAvailable(G2))
+ << "The NULL return shouldn't depend on having called"
+ << " updateGlobalMapping(..., NULL)";
+ // Check that update...() can be called before add...().
+ Engine->updateGlobalMapping(G2, &Mem1);
+ EXPECT_EQ(&Mem1, Engine->getPointerToGlobalIfAvailable(G2));
+ EXPECT_EQ(&Mem2, Engine->getPointerToGlobalIfAvailable(G1))
+ << "A second mapping shouldn't affect the first.";
+}
+
+TEST_F(ExecutionEngineTest, ReverseGlobalMapping) {
+ GlobalVariable *G1 =
+ NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
+
+ int32_t Mem1 = 3;
+ Engine->addGlobalMapping(G1, &Mem1);
+ EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
+ int32_t Mem2 = 4;
+ Engine->updateGlobalMapping(G1, &Mem2);
+ EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));
+ EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem2));
+
+ GlobalVariable *G2 =
+ NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global2");
+ Engine->updateGlobalMapping(G2, &Mem1);
+ EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1));
+ EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem2));
+ Engine->updateGlobalMapping(G1, NULL);
+ EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1))
+ << "Removing one mapping doesn't affect a different one.";
+ EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem2));
+ Engine->updateGlobalMapping(G2, &Mem2);
+ EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));
+ EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem2))
+ << "Once a mapping is removed, we can point another GV at the"
+ << " now-free address.";
+}
+
+TEST_F(ExecutionEngineTest, ClearModuleMappings) {
+ GlobalVariable *G1 =
+ NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
+
+ int32_t Mem1 = 3;
+ Engine->addGlobalMapping(G1, &Mem1);
+ EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
+
+ Engine->clearGlobalMappingsFromModule(M);
+
+ EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));
+
+ GlobalVariable *G2 =
+ NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global2");
+ // After clearing the module mappings, we can assign a new GV to the
+ // same address.
+ Engine->addGlobalMapping(G2, &Mem1);
+ EXPECT_EQ(G2, Engine->getGlobalValueAtAddress(&Mem1));
+}
+
+TEST_F(ExecutionEngineTest, DestructionRemovesGlobalMapping) {
+ GlobalVariable *G1 =
+ NewExtGlobal(Type::getInt32Ty(getGlobalContext()), "Global1");
+ int32_t Mem1 = 3;
+ Engine->addGlobalMapping(G1, &Mem1);
+ // Make sure the reverse mapping is enabled.
+ EXPECT_EQ(G1, Engine->getGlobalValueAtAddress(&Mem1));
+ // When the GV goes away, the ExecutionEngine should remove any
+ // mappings that refer to it.
+ G1->eraseFromParent();
+ EXPECT_EQ(NULL, Engine->getGlobalValueAtAddress(&Mem1));
+}
+
+}
diff --git a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
index 1007ae1..87e3280 100644
--- a/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
+++ b/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
@@ -65,8 +65,10 @@ struct RecordingJITEventListener : public JITEventListener {
class JITEventListenerTest : public testing::Test {
protected:
JITEventListenerTest()
- : M(new Module("module", *new LLVMContext())),
- EE(ExecutionEngine::createJIT(new ExistingModuleProvider(M))) {
+ : M(new Module("module", getGlobalContext())),
+ EE(EngineBuilder(M)
+ .setEngineKind(EngineKind::JIT)
+ .create()) {
}
Module *M;
@@ -75,11 +77,11 @@ class JITEventListenerTest : public testing::Test {
Function *buildFunction(Module *M) {
Function *Result = Function::Create(
- TypeBuilder<int32_t(int32_t), false>::get(),
+ TypeBuilder<int32_t(int32_t), false>::get(getGlobalContext()),
GlobalValue::ExternalLinkage, "id", M);
Value *Arg = Result->arg_begin();
- BasicBlock *BB = BasicBlock::Create("entry", Result);
- ReturnInst::Create(Arg, BB);
+ BasicBlock *BB = BasicBlock::Create(M->getContext(), "entry", Result);
+ ReturnInst::Create(M->getContext(), Arg, BB);
return Result;
}
@@ -232,7 +234,7 @@ TEST_F(JITEventListenerTest, MatchesMachineCodeInfo) {
class JITEnvironment : public testing::Environment {
virtual void SetUp() {
- // Required for ExecutionEngine::createJIT to create a JIT.
+ // Required to create a JIT.
InitializeNativeTarget();
}
};
diff --git a/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp b/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp
new file mode 100644
index 0000000..89a4be7
--- /dev/null
+++ b/unittests/ExecutionEngine/JIT/JITMemoryManagerTest.cpp
@@ -0,0 +1,277 @@
+//===- JITMemoryManagerTest.cpp - Unit tests for the JIT memory manager ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ExecutionEngine/JITMemoryManager.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/GlobalValue.h"
+
+using namespace llvm;
+
+namespace {
+
+Function *makeFakeFunction() {
+ std::vector<const Type*> params;
+ const FunctionType *FTy =
+ FunctionType::get(Type::getVoidTy(getGlobalContext()), params, false);
+ return Function::Create(FTy, GlobalValue::ExternalLinkage);
+}
+
+// Allocate three simple functions that fit in the initial slab. This exercises
+// the code in the case that we don't have to allocate more memory to store the
+// function bodies.
+TEST(JITMemoryManagerTest, NoAllocations) {
+ OwningPtr<JITMemoryManager> MemMgr(
+ JITMemoryManager::CreateDefaultMemManager());
+ uintptr_t size;
+ uint8_t *start;
+ std::string Error;
+
+ // Allocate the functions.
+ OwningPtr<Function> F1(makeFakeFunction());
+ size = 1024;
+ start = MemMgr->startFunctionBody(F1.get(), size);
+ memset(start, 0xFF, 1024);
+ MemMgr->endFunctionBody(F1.get(), start, start + 1024);
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+
+ OwningPtr<Function> F2(makeFakeFunction());
+ size = 1024;
+ start = MemMgr->startFunctionBody(F2.get(), size);
+ memset(start, 0xFF, 1024);
+ MemMgr->endFunctionBody(F2.get(), start, start + 1024);
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+
+ OwningPtr<Function> F3(makeFakeFunction());
+ size = 1024;
+ start = MemMgr->startFunctionBody(F3.get(), size);
+ memset(start, 0xFF, 1024);
+ MemMgr->endFunctionBody(F3.get(), start, start + 1024);
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+
+ // Deallocate them out of order, in case that matters.
+ MemMgr->deallocateMemForFunction(F2.get());
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+ MemMgr->deallocateMemForFunction(F1.get());
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+ MemMgr->deallocateMemForFunction(F3.get());
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+}
+
+// Make three large functions that take up most of the space in the slab. Then
+// try allocating three smaller functions that don't require additional slabs.
+TEST(JITMemoryManagerTest, TestCodeAllocation) {
+ OwningPtr<JITMemoryManager> MemMgr(
+ JITMemoryManager::CreateDefaultMemManager());
+ uintptr_t size;
+ uint8_t *start;
+ std::string Error;
+
+ // Big functions are a little less than the largest block size.
+ const uintptr_t smallFuncSize = 1024;
+ const uintptr_t bigFuncSize = (MemMgr->GetDefaultCodeSlabSize() -
+ smallFuncSize * 2);
+
+ // Allocate big functions
+ OwningPtr<Function> F1(makeFakeFunction());
+ size = bigFuncSize;
+ start = MemMgr->startFunctionBody(F1.get(), size);
+ ASSERT_LE(bigFuncSize, size);
+ memset(start, 0xFF, bigFuncSize);
+ MemMgr->endFunctionBody(F1.get(), start, start + bigFuncSize);
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+
+ OwningPtr<Function> F2(makeFakeFunction());
+ size = bigFuncSize;
+ start = MemMgr->startFunctionBody(F2.get(), size);
+ ASSERT_LE(bigFuncSize, size);
+ memset(start, 0xFF, bigFuncSize);
+ MemMgr->endFunctionBody(F2.get(), start, start + bigFuncSize);
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+
+ OwningPtr<Function> F3(makeFakeFunction());
+ size = bigFuncSize;
+ start = MemMgr->startFunctionBody(F3.get(), size);
+ ASSERT_LE(bigFuncSize, size);
+ memset(start, 0xFF, bigFuncSize);
+ MemMgr->endFunctionBody(F3.get(), start, start + bigFuncSize);
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+
+ // Check that each large function took it's own slab.
+ EXPECT_EQ(3U, MemMgr->GetNumCodeSlabs());
+
+ // Allocate small functions
+ OwningPtr<Function> F4(makeFakeFunction());
+ size = smallFuncSize;
+ start = MemMgr->startFunctionBody(F4.get(), size);
+ ASSERT_LE(smallFuncSize, size);
+ memset(start, 0xFF, smallFuncSize);
+ MemMgr->endFunctionBody(F4.get(), start, start + smallFuncSize);
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+
+ OwningPtr<Function> F5(makeFakeFunction());
+ size = smallFuncSize;
+ start = MemMgr->startFunctionBody(F5.get(), size);
+ ASSERT_LE(smallFuncSize, size);
+ memset(start, 0xFF, smallFuncSize);
+ MemMgr->endFunctionBody(F5.get(), start, start + smallFuncSize);
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+
+ OwningPtr<Function> F6(makeFakeFunction());
+ size = smallFuncSize;
+ start = MemMgr->startFunctionBody(F6.get(), size);
+ ASSERT_LE(smallFuncSize, size);
+ memset(start, 0xFF, smallFuncSize);
+ MemMgr->endFunctionBody(F6.get(), start, start + smallFuncSize);
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+
+ // Check that the small functions didn't allocate any new slabs.
+ EXPECT_EQ(3U, MemMgr->GetNumCodeSlabs());
+
+ // Deallocate them out of order, in case that matters.
+ MemMgr->deallocateMemForFunction(F2.get());
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+ MemMgr->deallocateMemForFunction(F1.get());
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+ MemMgr->deallocateMemForFunction(F4.get());
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+ MemMgr->deallocateMemForFunction(F3.get());
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+ MemMgr->deallocateMemForFunction(F5.get());
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+ MemMgr->deallocateMemForFunction(F6.get());
+ EXPECT_TRUE(MemMgr->CheckInvariants(Error)) << Error;
+}
+
+// Allocate five global ints of varying widths and alignment, and check their
+// alignment and overlap.
+TEST(JITMemoryManagerTest, TestSmallGlobalInts) {
+ OwningPtr<JITMemoryManager> MemMgr(
+ JITMemoryManager::CreateDefaultMemManager());
+ uint8_t *a = (uint8_t *)MemMgr->allocateGlobal(8, 0);
+ uint16_t *b = (uint16_t*)MemMgr->allocateGlobal(16, 2);
+ uint32_t *c = (uint32_t*)MemMgr->allocateGlobal(32, 4);
+ uint64_t *d = (uint64_t*)MemMgr->allocateGlobal(64, 8);
+
+ // Check the alignment.
+ EXPECT_EQ(0U, ((uintptr_t)b) & 0x1);
+ EXPECT_EQ(0U, ((uintptr_t)c) & 0x3);
+ EXPECT_EQ(0U, ((uintptr_t)d) & 0x7);
+
+ // Initialize them each one at a time and make sure they don't overlap.
+ *a = 0xff;
+ *b = 0U;
+ *c = 0U;
+ *d = 0U;
+ EXPECT_EQ(0xffU, *a);
+ EXPECT_EQ(0U, *b);
+ EXPECT_EQ(0U, *c);
+ EXPECT_EQ(0U, *d);
+ *a = 0U;
+ *b = 0xffffU;
+ EXPECT_EQ(0U, *a);
+ EXPECT_EQ(0xffffU, *b);
+ EXPECT_EQ(0U, *c);
+ EXPECT_EQ(0U, *d);
+ *b = 0U;
+ *c = 0xffffffffU;
+ EXPECT_EQ(0U, *a);
+ EXPECT_EQ(0U, *b);
+ EXPECT_EQ(0xffffffffU, *c);
+ EXPECT_EQ(0U, *d);
+ *c = 0U;
+ *d = 0xffffffffffffffffULL;
+ EXPECT_EQ(0U, *a);
+ EXPECT_EQ(0U, *b);
+ EXPECT_EQ(0U, *c);
+ EXPECT_EQ(0xffffffffffffffffULL, *d);
+
+ // Make sure we didn't allocate any extra slabs for this tiny amount of data.
+ EXPECT_EQ(1U, MemMgr->GetNumDataSlabs());
+}
+
+// Allocate a small global, a big global, and a third global, and make sure we
+// only use two slabs for that.
+TEST(JITMemoryManagerTest, TestLargeGlobalArray) {
+ OwningPtr<JITMemoryManager> MemMgr(
+ JITMemoryManager::CreateDefaultMemManager());
+ size_t Size = 4 * MemMgr->GetDefaultDataSlabSize();
+ uint64_t *a = (uint64_t*)MemMgr->allocateGlobal(64, 8);
+ uint8_t *g = MemMgr->allocateGlobal(Size, 8);
+ uint64_t *b = (uint64_t*)MemMgr->allocateGlobal(64, 8);
+
+ // Check the alignment.
+ EXPECT_EQ(0U, ((uintptr_t)a) & 0x7);
+ EXPECT_EQ(0U, ((uintptr_t)g) & 0x7);
+ EXPECT_EQ(0U, ((uintptr_t)b) & 0x7);
+
+ // Initialize them to make sure we don't segfault and make sure they don't
+ // overlap.
+ memset(a, 0x1, 8);
+ memset(g, 0x2, Size);
+ memset(b, 0x3, 8);
+ EXPECT_EQ(0x0101010101010101ULL, *a);
+ // Just check the edges.
+ EXPECT_EQ(0x02U, g[0]);
+ EXPECT_EQ(0x02U, g[Size - 1]);
+ EXPECT_EQ(0x0303030303030303ULL, *b);
+
+ // Check the number of slabs.
+ EXPECT_EQ(2U, MemMgr->GetNumDataSlabs());
+}
+
+// Allocate lots of medium globals so that we can test moving the bump allocator
+// to a new slab.
+TEST(JITMemoryManagerTest, TestManyGlobals) {
+ OwningPtr<JITMemoryManager> MemMgr(
+ JITMemoryManager::CreateDefaultMemManager());
+ size_t SlabSize = MemMgr->GetDefaultDataSlabSize();
+ size_t Size = 128;
+ int Iters = (SlabSize / Size) + 1;
+
+ // We should start with one slab.
+ EXPECT_EQ(1U, MemMgr->GetNumDataSlabs());
+
+ // After allocating a bunch of globals, we should have two.
+ for (int I = 0; I < Iters; ++I)
+ MemMgr->allocateGlobal(Size, 8);
+ EXPECT_EQ(2U, MemMgr->GetNumDataSlabs());
+
+ // And after much more, we should have three.
+ for (int I = 0; I < Iters; ++I)
+ MemMgr->allocateGlobal(Size, 8);
+ EXPECT_EQ(3U, MemMgr->GetNumDataSlabs());
+}
+
+// Allocate lots of function stubs so that we can test moving the stub bump
+// allocator to a new slab.
+TEST(JITMemoryManagerTest, TestManyStubs) {
+ OwningPtr<JITMemoryManager> MemMgr(
+ JITMemoryManager::CreateDefaultMemManager());
+ size_t SlabSize = MemMgr->GetDefaultStubSlabSize();
+ size_t Size = 128;
+ int Iters = (SlabSize / Size) + 1;
+
+ // We should start with one slab.
+ EXPECT_EQ(1U, MemMgr->GetNumStubSlabs());
+
+ // After allocating a bunch of stubs, we should have two.
+ for (int I = 0; I < Iters; ++I)
+ MemMgr->allocateStub(NULL, Size, 8);
+ EXPECT_EQ(2U, MemMgr->GetNumStubSlabs());
+
+ // And after much more, we should have three.
+ for (int I = 0; I < Iters; ++I)
+ MemMgr->allocateStub(NULL, Size, 8);
+ EXPECT_EQ(3U, MemMgr->GetNumStubSlabs());
+}
+
+}
diff --git a/unittests/ExecutionEngine/JIT/JITTest.cpp b/unittests/ExecutionEngine/JIT/JITTest.cpp
new file mode 100644
index 0000000..55d3749
--- /dev/null
+++ b/unittests/ExecutionEngine/JIT/JITTest.cpp
@@ -0,0 +1,277 @@
+//===- JITTest.cpp - Unit tests for the JIT -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Constant.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/ExecutionEngine/JIT.h"
+#include "llvm/ExecutionEngine/JITMemoryManager.h"
+#include "llvm/Function.h"
+#include "llvm/GlobalValue.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/ModuleProvider.h"
+#include "llvm/Support/IRBuilder.h"
+#include "llvm/Support/TypeBuilder.h"
+#include "llvm/Target/TargetSelect.h"
+#include "llvm/Type.h"
+
+using namespace llvm;
+
+namespace {
+
+Function *makeReturnGlobal(std::string Name, GlobalVariable *G, Module *M) {
+ std::vector<const Type*> params;
+ const FunctionType *FTy = FunctionType::get(G->getType()->getElementType(),
+ params, false);
+ Function *F = Function::Create(FTy, GlobalValue::ExternalLinkage, Name, M);
+ BasicBlock *Entry = BasicBlock::Create(M->getContext(), "entry", F);
+ IRBuilder<> builder(Entry);
+ Value *Load = builder.CreateLoad(G);
+ const Type *GTy = G->getType()->getElementType();
+ Value *Add = builder.CreateAdd(Load, ConstantInt::get(GTy, 1LL));
+ builder.CreateStore(Add, G);
+ builder.CreateRet(Add);
+ return F;
+}
+
+class JITTest : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ M = new Module("<main>", Context);
+ std::string Error;
+ TheJIT.reset(EngineBuilder(M).setEngineKind(EngineKind::JIT)
+ .setErrorStr(&Error).create());
+ ASSERT_TRUE(TheJIT.get() != NULL) << Error;
+ }
+
+ LLVMContext Context;
+ Module *M; // Owned by ExecutionEngine.
+ OwningPtr<ExecutionEngine> TheJIT;
+};
+
+// Regression test for a bug. The JIT used to allocate globals inside the same
+// memory block used for the function, and when the function code was freed,
+// the global was left in the same place. This test allocates a function
+// that uses and global, deallocates it, and then makes sure that the global
+// stays alive after that.
+TEST(JIT, GlobalInFunction) {
+ LLVMContext context;
+ Module *M = new Module("<main>", context);
+ ExistingModuleProvider *MP = new ExistingModuleProvider(M);
+
+ JITMemoryManager *MemMgr = JITMemoryManager::CreateDefaultMemManager();
+ // Tell the memory manager to poison freed memory so that accessing freed
+ // memory is more easily tested.
+ MemMgr->setPoisonMemory(true);
+ std::string Error;
+ OwningPtr<ExecutionEngine> JIT(EngineBuilder(MP)
+ .setEngineKind(EngineKind::JIT)
+ .setErrorStr(&Error)
+ .setJITMemoryManager(MemMgr)
+ // The next line enables the fix:
+ .setAllocateGVsWithCode(false)
+ .create());
+ ASSERT_EQ(Error, "");
+
+ // Create a global variable.
+ const Type *GTy = Type::getInt32Ty(context);
+ GlobalVariable *G = new GlobalVariable(
+ *M,
+ GTy,
+ false, // Not constant.
+ GlobalValue::InternalLinkage,
+ Constant::getNullValue(GTy),
+ "myglobal");
+
+ // Make a function that points to a global.
+ Function *F1 = makeReturnGlobal("F1", G, M);
+
+ // Get the pointer to the native code to force it to JIT the function and
+ // allocate space for the global.
+ void (*F1Ptr)() =
+ reinterpret_cast<void(*)()>((intptr_t)JIT->getPointerToFunction(F1));
+
+ // Since F1 was codegen'd, a pointer to G should be available.
+ int32_t *GPtr = (int32_t*)JIT->getPointerToGlobalIfAvailable(G);
+ ASSERT_NE((int32_t*)NULL, GPtr);
+ EXPECT_EQ(0, *GPtr);
+
+ // F1() should increment G.
+ F1Ptr();
+ EXPECT_EQ(1, *GPtr);
+
+ // Make a second function identical to the first, referring to the same
+ // global.
+ Function *F2 = makeReturnGlobal("F2", G, M);
+ void (*F2Ptr)() =
+ reinterpret_cast<void(*)()>((intptr_t)JIT->getPointerToFunction(F2));
+
+ // F2() should increment G.
+ F2Ptr();
+ EXPECT_EQ(2, *GPtr);
+
+ // Deallocate F1.
+ JIT->freeMachineCodeForFunction(F1);
+
+ // F2() should *still* increment G.
+ F2Ptr();
+ EXPECT_EQ(3, *GPtr);
+}
+
+int PlusOne(int arg) {
+ return arg + 1;
+}
+
+TEST_F(JITTest, FarCallToKnownFunction) {
+ // x86-64 can only make direct calls to functions within 32 bits of
+ // the current PC. To call anything farther away, we have to load
+ // the address into a register and call through the register. The
+ // current JIT does this by allocating a stub for any far call.
+ // There was a bug in which the JIT tried to emit a direct call when
+ // the target was already in the JIT's global mappings and lazy
+ // compilation was disabled.
+
+ Function *KnownFunction = Function::Create(
+ TypeBuilder<int(int), false>::get(Context),
+ GlobalValue::ExternalLinkage, "known", M);
+ TheJIT->addGlobalMapping(KnownFunction, (void*)(intptr_t)PlusOne);
+
+ // int test() { return known(7); }
+ Function *TestFunction = Function::Create(
+ TypeBuilder<int(), false>::get(Context),
+ GlobalValue::ExternalLinkage, "test", M);
+ BasicBlock *Entry = BasicBlock::Create(Context, "entry", TestFunction);
+ IRBuilder<> Builder(Entry);
+ Value *result = Builder.CreateCall(
+ KnownFunction,
+ ConstantInt::get(TypeBuilder<int, false>::get(Context), 7));
+ Builder.CreateRet(result);
+
+ TheJIT->EnableDlsymStubs(false);
+ TheJIT->DisableLazyCompilation();
+ int (*TestFunctionPtr)() = reinterpret_cast<int(*)()>(
+ (intptr_t)TheJIT->getPointerToFunction(TestFunction));
+ // This used to crash in trying to call PlusOne().
+ EXPECT_EQ(8, TestFunctionPtr());
+}
+
+// Test a function C which calls A and B which call each other.
+TEST_F(JITTest, NonLazyCompilationStillNeedsStubs) {
+ TheJIT->DisableLazyCompilation();
+
+ const FunctionType *Func1Ty =
+ cast<FunctionType>(TypeBuilder<void(void), false>::get(Context));
+ std::vector<const Type*> arg_types;
+ arg_types.push_back(Type::getInt1Ty(Context));
+ const FunctionType *FuncTy = FunctionType::get(
+ Type::getVoidTy(Context), arg_types, false);
+ Function *Func1 = Function::Create(Func1Ty, Function::ExternalLinkage,
+ "func1", M);
+ Function *Func2 = Function::Create(FuncTy, Function::InternalLinkage,
+ "func2", M);
+ Function *Func3 = Function::Create(FuncTy, Function::InternalLinkage,
+ "func3", M);
+ BasicBlock *Block1 = BasicBlock::Create(Context, "block1", Func1);
+ BasicBlock *Block2 = BasicBlock::Create(Context, "block2", Func2);
+ BasicBlock *True2 = BasicBlock::Create(Context, "cond_true", Func2);
+ BasicBlock *False2 = BasicBlock::Create(Context, "cond_false", Func2);
+ BasicBlock *Block3 = BasicBlock::Create(Context, "block3", Func3);
+ BasicBlock *True3 = BasicBlock::Create(Context, "cond_true", Func3);
+ BasicBlock *False3 = BasicBlock::Create(Context, "cond_false", Func3);
+
+ // Make Func1 call Func2(0) and Func3(0).
+ IRBuilder<> Builder(Block1);
+ Builder.CreateCall(Func2, ConstantInt::getTrue(Context));
+ Builder.CreateCall(Func3, ConstantInt::getTrue(Context));
+ Builder.CreateRetVoid();
+
+ // void Func2(bool b) { if (b) { Func3(false); return; } return; }
+ Builder.SetInsertPoint(Block2);
+ Builder.CreateCondBr(Func2->arg_begin(), True2, False2);
+ Builder.SetInsertPoint(True2);
+ Builder.CreateCall(Func3, ConstantInt::getFalse(Context));
+ Builder.CreateRetVoid();
+ Builder.SetInsertPoint(False2);
+ Builder.CreateRetVoid();
+
+ // void Func3(bool b) { if (b) { Func2(false); return; } return; }
+ Builder.SetInsertPoint(Block3);
+ Builder.CreateCondBr(Func3->arg_begin(), True3, False3);
+ Builder.SetInsertPoint(True3);
+ Builder.CreateCall(Func2, ConstantInt::getFalse(Context));
+ Builder.CreateRetVoid();
+ Builder.SetInsertPoint(False3);
+ Builder.CreateRetVoid();
+
+ // Compile the function to native code
+ void (*F1Ptr)() =
+ reinterpret_cast<void(*)()>((intptr_t)TheJIT->getPointerToFunction(Func1));
+
+ F1Ptr();
+}
+
+// Regression test for PR5162. This used to trigger an AssertingVH inside the
+// JIT's Function to stub mapping.
+TEST_F(JITTest, NonLazyLeaksNoStubs) {
+ TheJIT->DisableLazyCompilation();
+
+ // Create two functions with a single basic block each.
+ const FunctionType *FuncTy =
+ cast<FunctionType>(TypeBuilder<int(), false>::get(Context));
+ Function *Func1 = Function::Create(FuncTy, Function::ExternalLinkage,
+ "func1", M);
+ Function *Func2 = Function::Create(FuncTy, Function::InternalLinkage,
+ "func2", M);
+ BasicBlock *Block1 = BasicBlock::Create(Context, "block1", Func1);
+ BasicBlock *Block2 = BasicBlock::Create(Context, "block2", Func2);
+
+ // The first function calls the second and returns the result
+ IRBuilder<> Builder(Block1);
+ Value *Result = Builder.CreateCall(Func2);
+ Builder.CreateRet(Result);
+
+ // The second function just returns a constant
+ Builder.SetInsertPoint(Block2);
+ Builder.CreateRet(ConstantInt::get(TypeBuilder<int, false>::get(Context),42));
+
+ // Compile the function to native code
+ (void)TheJIT->getPointerToFunction(Func1);
+
+ // Free the JIT state for the functions
+ TheJIT->freeMachineCodeForFunction(Func1);
+ TheJIT->freeMachineCodeForFunction(Func2);
+
+ // Delete the first function (and show that is has no users)
+ EXPECT_EQ(Func1->getNumUses(), 0u);
+ Func1->eraseFromParent();
+
+ // Delete the second function (and show that it has no users - it had one,
+ // func1 but that's gone now)
+ EXPECT_EQ(Func2->getNumUses(), 0u);
+ Func2->eraseFromParent();
+}
+
+// This code is copied from JITEventListenerTest, but it only runs once for all
+// the tests in this directory. Everything seems fine, but that's strange
+// behavior.
+class JITEnvironment : public testing::Environment {
+ virtual void SetUp() {
+ // Required to create a JIT.
+ InitializeNativeTarget();
+ }
+};
+testing::Environment* const jit_env =
+ testing::AddGlobalTestEnvironment(new JITEnvironment);
+
+}
diff --git a/unittests/ExecutionEngine/Makefile b/unittests/ExecutionEngine/Makefile
index e837a7d..d4ef92f 100644
--- a/unittests/ExecutionEngine/Makefile
+++ b/unittests/ExecutionEngine/Makefile
@@ -8,12 +8,11 @@
##===----------------------------------------------------------------------===##
LEVEL = ../..
+TESTNAME = ExecutionEngine
+LINK_COMPONENTS := engine interpreter
include $(LEVEL)/Makefile.config
PARALLEL_DIRS = JIT
-include $(LEVEL)/Makefile.common
-
-clean::
- $(Verb) $(RM) -f *Tests
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/Makefile b/unittests/Makefile
index 1eb69ab..9f377cd 100644
--- a/unittests/Makefile
+++ b/unittests/Makefile
@@ -9,14 +9,7 @@
LEVEL = ..
-include $(LEVEL)/Makefile.config
-
-LIBRARYNAME = UnitTestMain
-BUILD_ARCHIVE = 1
-CPP.Flags += -I$(LLVM_SRC_ROOT)/utils/unittest/googletest/include/
-CPP.Flags += -Wno-variadic-macros
-
-PARALLEL_DIRS = ADT ExecutionEngine Support VMCore MC
+PARALLEL_DIRS = ADT ExecutionEngine Support Transforms VMCore
include $(LEVEL)/Makefile.common
diff --git a/unittests/Makefile.unittest b/unittests/Makefile.unittest
index 1c75e44..76051e4 100644
--- a/unittests/Makefile.unittest
+++ b/unittests/Makefile.unittest
@@ -20,16 +20,18 @@ LLVMUnitTestExe = $(BuildMode)/$(TESTNAME)Tests$(EXEEXT)
CPP.Flags += -I$(LLVM_SRC_ROOT)/utils/unittest/googletest/include/
CPP.Flags += -Wno-variadic-macros
-LIBS += -lGoogleTest -lUnitTestMain
+TESTLIBS = -lGoogleTest -lUnitTestMain
$(LLVMUnitTestExe): $(ObjectsO) $(ProjLibsPaths) $(LLVMLibsPaths)
$(Echo) Linking $(BuildMode) unit test $(TESTNAME) $(StripWarnMsg)
$(Verb) $(Link) -o $@ $(TOOLLINKOPTS) $(ObjectsO) $(ProjLibsOptions) \
- $(LLVMLibsOptions) $(ExtraLibs) $(TOOLLINKOPTSB) $(LIBS)
+ $(TESTLIBS) $(LLVMLibsOptions) $(ExtraLibs) $(TOOLLINKOPTSB) $(LIBS)
$(Echo) ======= Finished Linking $(BuildMode) Unit test $(TESTNAME) \
$(StripWarnMsg)
all:: $(LLVMUnitTestExe)
+
+unitcheck:: $(LLVMUnitTestExe)
$(LLVMUnitTestExe)
endif
diff --git a/unittests/Support/AllocatorTest.cpp b/unittests/Support/AllocatorTest.cpp
new file mode 100644
index 0000000..2a01f3a
--- /dev/null
+++ b/unittests/Support/AllocatorTest.cpp
@@ -0,0 +1,143 @@
+//===- llvm/unittest/Support/AllocatorTest.cpp - BumpPtrAllocator tests ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Allocator.h"
+
+#include "gtest/gtest.h"
+#include <cstdlib>
+
+using namespace llvm;
+
+namespace {
+
+TEST(AllocatorTest, Basics) {
+ BumpPtrAllocator Alloc;
+ int *a = (int*)Alloc.Allocate(sizeof(int), 0);
+ int *b = (int*)Alloc.Allocate(sizeof(int) * 10, 0);
+ int *c = (int*)Alloc.Allocate(sizeof(int), 0);
+ *a = 1;
+ b[0] = 2;
+ b[9] = 2;
+ *c = 3;
+ EXPECT_EQ(1, *a);
+ EXPECT_EQ(2, b[0]);
+ EXPECT_EQ(2, b[9]);
+ EXPECT_EQ(3, *c);
+ EXPECT_EQ(1U, Alloc.GetNumSlabs());
+}
+
+// Allocate enough bytes to create three slabs.
+TEST(AllocatorTest, ThreeSlabs) {
+ BumpPtrAllocator Alloc(4096, 4096);
+ Alloc.Allocate(3000, 0);
+ EXPECT_EQ(1U, Alloc.GetNumSlabs());
+ Alloc.Allocate(3000, 0);
+ EXPECT_EQ(2U, Alloc.GetNumSlabs());
+ Alloc.Allocate(3000, 0);
+ EXPECT_EQ(3U, Alloc.GetNumSlabs());
+}
+
+// Allocate enough bytes to create two slabs, reset the allocator, and do it
+// again.
+TEST(AllocatorTest, TestReset) {
+ BumpPtrAllocator Alloc(4096, 4096);
+ Alloc.Allocate(3000, 0);
+ EXPECT_EQ(1U, Alloc.GetNumSlabs());
+ Alloc.Allocate(3000, 0);
+ EXPECT_EQ(2U, Alloc.GetNumSlabs());
+ Alloc.Reset();
+ EXPECT_EQ(1U, Alloc.GetNumSlabs());
+ Alloc.Allocate(3000, 0);
+ EXPECT_EQ(1U, Alloc.GetNumSlabs());
+ Alloc.Allocate(3000, 0);
+ EXPECT_EQ(2U, Alloc.GetNumSlabs());
+}
+
+// Test some allocations at varying alignments.
+TEST(AllocatorTest, TestAlignment) {
+ BumpPtrAllocator Alloc;
+ uintptr_t a;
+ a = (uintptr_t)Alloc.Allocate(1, 2);
+ EXPECT_EQ(0U, a & 1);
+ a = (uintptr_t)Alloc.Allocate(1, 4);
+ EXPECT_EQ(0U, a & 3);
+ a = (uintptr_t)Alloc.Allocate(1, 8);
+ EXPECT_EQ(0U, a & 7);
+ a = (uintptr_t)Alloc.Allocate(1, 16);
+ EXPECT_EQ(0U, a & 15);
+ a = (uintptr_t)Alloc.Allocate(1, 32);
+ EXPECT_EQ(0U, a & 31);
+ a = (uintptr_t)Alloc.Allocate(1, 64);
+ EXPECT_EQ(0U, a & 63);
+ a = (uintptr_t)Alloc.Allocate(1, 128);
+ EXPECT_EQ(0U, a & 127);
+}
+
+// Test allocating just over the slab size. This tests a bug where before the
+// allocator incorrectly calculated the buffer end pointer.
+TEST(AllocatorTest, TestOverflow) {
+ BumpPtrAllocator Alloc(4096, 4096);
+
+ // Fill the slab right up until the end pointer.
+ Alloc.Allocate(4096 - sizeof(MemSlab), 0);
+ EXPECT_EQ(1U, Alloc.GetNumSlabs());
+
+ // If we dont't allocate a new slab, then we will have overflowed.
+ Alloc.Allocate(1, 0);
+ EXPECT_EQ(2U, Alloc.GetNumSlabs());
+}
+
+// Mock slab allocator that returns slabs aligned on 4096 bytes. There is no
+// easy portable way to do this, so this is kind of a hack.
+class MockSlabAllocator : public SlabAllocator {
+ MemSlab *LastSlab;
+
+public:
+ virtual ~MockSlabAllocator() { }
+
+ virtual MemSlab *Allocate(size_t Size) {
+ // Allocate space for the alignment, the slab, and a void* that goes right
+ // before the slab.
+ size_t Alignment = 4096;
+ void *MemBase = malloc(Size + Alignment - 1 + sizeof(void*));
+
+ // Make the slab.
+ MemSlab *Slab = (MemSlab*)(((uintptr_t)MemBase+sizeof(void*)+Alignment-1) &
+ ~(uintptr_t)(Alignment - 1));
+ Slab->Size = Size;
+ Slab->NextPtr = 0;
+
+ // Hold a pointer to the base so we can free the whole malloced block.
+ ((void**)Slab)[-1] = MemBase;
+
+ LastSlab = Slab;
+ return Slab;
+ }
+
+ virtual void Deallocate(MemSlab *Slab) {
+ free(((void**)Slab)[-1]);
+ }
+
+ MemSlab *GetLastSlab() {
+ return LastSlab;
+ }
+};
+
+// Allocate a large-ish block with a really large alignment so that the
+// allocator will think that it has space, but after it does the alignment it
+// will not.
+TEST(AllocatorTest, TestBigAlignment) {
+ MockSlabAllocator SlabAlloc;
+ BumpPtrAllocator Alloc(4096, 4096, SlabAlloc);
+ uintptr_t Ptr = (uintptr_t)Alloc.Allocate(3000, 2048);
+ MemSlab *Slab = SlabAlloc.GetLastSlab();
+ EXPECT_LE(Ptr + 3000, ((uintptr_t)Slab) + Slab->Size);
+}
+
+} // anonymous namespace
diff --git a/unittests/Support/CommandLineTest.cpp b/unittests/Support/CommandLineTest.cpp
new file mode 100644
index 0000000..72fa24a
--- /dev/null
+++ b/unittests/Support/CommandLineTest.cpp
@@ -0,0 +1,60 @@
+//===- llvm/unittest/Support/CommandLineTest.cpp - CommandLine tests ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Config/config.h"
+
+#include "gtest/gtest.h"
+
+#include <string>
+#include <stdlib.h>
+
+using namespace llvm;
+
+namespace {
+
+class TempEnvVar {
+ public:
+ TempEnvVar(const char *name, const char *value)
+ : name(name) {
+ const char *old_value = getenv(name);
+ EXPECT_EQ(NULL, old_value) << old_value;
+#if HAVE_SETENV
+ setenv(name, value, true);
+#else
+# define SKIP_ENVIRONMENT_TESTS
+#endif
+ }
+
+ ~TempEnvVar() {
+#if HAVE_SETENV
+ // Assume setenv and unsetenv come together.
+ unsetenv(name);
+#endif
+ }
+
+ private:
+ const char *const name;
+};
+
+#ifndef SKIP_ENVIRONMENT_TESTS
+
+const char test_env_var[] = "LLVM_TEST_COMMAND_LINE_FLAGS";
+
+cl::opt<std::string> EnvironmentTestOption("env-test-opt");
+TEST(CommandLineTest, ParseEnvironment) {
+ TempEnvVar TEV(test_env_var, "-env-test-opt=hello");
+ EXPECT_EQ("", EnvironmentTestOption);
+ cl::ParseEnvironmentOptions("CommandLineTest", test_env_var);
+ EXPECT_EQ("hello", EnvironmentTestOption);
+}
+
+#endif // SKIP_ENVIRONMENT_TESTS
+
+} // anonymous namespace
diff --git a/unittests/Support/ConstantRangeTest.cpp b/unittests/Support/ConstantRangeTest.cpp
new file mode 100644
index 0000000..6b8d01d
--- /dev/null
+++ b/unittests/Support/ConstantRangeTest.cpp
@@ -0,0 +1,351 @@
+//===- llvm/unittest/Support/ConstantRangeTest.cpp - ConstantRange tests --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/ConstantRange.h"
+
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+class ConstantRangeTest : public ::testing::Test {
+protected:
+ static ConstantRange Full;
+ static ConstantRange Empty;
+ static ConstantRange One;
+ static ConstantRange Some;
+ static ConstantRange Wrap;
+};
+
+ConstantRange ConstantRangeTest::Full(16);
+ConstantRange ConstantRangeTest::Empty(16, false);
+ConstantRange ConstantRangeTest::One(APInt(16, 0xa));
+ConstantRange ConstantRangeTest::Some(APInt(16, 0xa), APInt(16, 0xaaa));
+ConstantRange ConstantRangeTest::Wrap(APInt(16, 0xaaa), APInt(16, 0xa));
+
+TEST_F(ConstantRangeTest, Basics) {
+ EXPECT_TRUE(Full.isFullSet());
+ EXPECT_FALSE(Full.isEmptySet());
+ EXPECT_FALSE(Full.isWrappedSet());
+ EXPECT_TRUE(Full.contains(APInt(16, 0x0)));
+ EXPECT_TRUE(Full.contains(APInt(16, 0x9)));
+ EXPECT_TRUE(Full.contains(APInt(16, 0xa)));
+ EXPECT_TRUE(Full.contains(APInt(16, 0xaa9)));
+ EXPECT_TRUE(Full.contains(APInt(16, 0xaaa)));
+
+ EXPECT_FALSE(Empty.isFullSet());
+ EXPECT_TRUE(Empty.isEmptySet());
+ EXPECT_FALSE(Empty.isWrappedSet());
+ EXPECT_FALSE(Empty.contains(APInt(16, 0x0)));
+ EXPECT_FALSE(Empty.contains(APInt(16, 0x9)));
+ EXPECT_FALSE(Empty.contains(APInt(16, 0xa)));
+ EXPECT_FALSE(Empty.contains(APInt(16, 0xaa9)));
+ EXPECT_FALSE(Empty.contains(APInt(16, 0xaaa)));
+
+ EXPECT_FALSE(One.isFullSet());
+ EXPECT_FALSE(One.isEmptySet());
+ EXPECT_FALSE(One.isWrappedSet());
+ EXPECT_FALSE(One.contains(APInt(16, 0x0)));
+ EXPECT_FALSE(One.contains(APInt(16, 0x9)));
+ EXPECT_TRUE(One.contains(APInt(16, 0xa)));
+ EXPECT_FALSE(One.contains(APInt(16, 0xaa9)));
+ EXPECT_FALSE(One.contains(APInt(16, 0xaaa)));
+
+ EXPECT_FALSE(Some.isFullSet());
+ EXPECT_FALSE(Some.isEmptySet());
+ EXPECT_FALSE(Some.isWrappedSet());
+ EXPECT_FALSE(Some.contains(APInt(16, 0x0)));
+ EXPECT_FALSE(Some.contains(APInt(16, 0x9)));
+ EXPECT_TRUE(Some.contains(APInt(16, 0xa)));
+ EXPECT_TRUE(Some.contains(APInt(16, 0xaa9)));
+ EXPECT_FALSE(Some.contains(APInt(16, 0xaaa)));
+
+ EXPECT_FALSE(Wrap.isFullSet());
+ EXPECT_FALSE(Wrap.isEmptySet());
+ EXPECT_TRUE(Wrap.isWrappedSet());
+ EXPECT_TRUE(Wrap.contains(APInt(16, 0x0)));
+ EXPECT_TRUE(Wrap.contains(APInt(16, 0x9)));
+ EXPECT_FALSE(Wrap.contains(APInt(16, 0xa)));
+ EXPECT_FALSE(Wrap.contains(APInt(16, 0xaa9)));
+ EXPECT_TRUE(Wrap.contains(APInt(16, 0xaaa)));
+}
+
+TEST_F(ConstantRangeTest, Equality) {
+ EXPECT_EQ(Full, Full);
+ EXPECT_EQ(Empty, Empty);
+ EXPECT_EQ(One, One);
+ EXPECT_EQ(Some, Some);
+ EXPECT_EQ(Wrap, Wrap);
+ EXPECT_NE(Full, Empty);
+ EXPECT_NE(Full, One);
+ EXPECT_NE(Full, Some);
+ EXPECT_NE(Full, Wrap);
+ EXPECT_NE(Empty, One);
+ EXPECT_NE(Empty, Some);
+ EXPECT_NE(Empty, Wrap);
+ EXPECT_NE(One, Some);
+ EXPECT_NE(One, Wrap);
+ EXPECT_NE(Some, Wrap);
+}
+
+TEST_F(ConstantRangeTest, SingleElement) {
+ EXPECT_EQ(Full.getSingleElement(), static_cast<APInt *>(NULL));
+ EXPECT_EQ(Empty.getSingleElement(), static_cast<APInt *>(NULL));
+ EXPECT_EQ(*One.getSingleElement(), APInt(16, 0xa));
+ EXPECT_EQ(Some.getSingleElement(), static_cast<APInt *>(NULL));
+ EXPECT_EQ(Wrap.getSingleElement(), static_cast<APInt *>(NULL));
+
+ EXPECT_FALSE(Full.isSingleElement());
+ EXPECT_FALSE(Empty.isSingleElement());
+ EXPECT_TRUE(One.isSingleElement());
+ EXPECT_FALSE(Some.isSingleElement());
+ EXPECT_FALSE(Wrap.isSingleElement());
+}
+
+TEST_F(ConstantRangeTest, GetSetSize) {
+ EXPECT_EQ(Full.getSetSize(), APInt(16, 0));
+ EXPECT_EQ(Empty.getSetSize(), APInt(16, 0));
+ EXPECT_EQ(One.getSetSize(), APInt(16, 1));
+ EXPECT_EQ(Some.getSetSize(), APInt(16, 0xaa0));
+ EXPECT_EQ(Wrap.getSetSize(), APInt(16, 0x10000 - 0xaa0));
+}
+
+TEST_F(ConstantRangeTest, GetMinsAndMaxes) {
+ EXPECT_EQ(Full.getUnsignedMax(), APInt(16, UINT16_MAX));
+ EXPECT_EQ(One.getUnsignedMax(), APInt(16, 0xa));
+ EXPECT_EQ(Some.getUnsignedMax(), APInt(16, 0xaa9));
+ EXPECT_EQ(Wrap.getUnsignedMax(), APInt(16, UINT16_MAX));
+
+ EXPECT_EQ(Full.getUnsignedMin(), APInt(16, 0));
+ EXPECT_EQ(One.getUnsignedMin(), APInt(16, 0xa));
+ EXPECT_EQ(Some.getUnsignedMin(), APInt(16, 0xa));
+ EXPECT_EQ(Wrap.getUnsignedMin(), APInt(16, 0));
+
+ EXPECT_EQ(Full.getSignedMax(), APInt(16, INT16_MAX));
+ EXPECT_EQ(One.getSignedMax(), APInt(16, 0xa));
+ EXPECT_EQ(Some.getSignedMax(), APInt(16, 0xaa9));
+ EXPECT_EQ(Wrap.getSignedMax(), APInt(16, INT16_MAX));
+
+ EXPECT_EQ(Full.getSignedMin(), APInt(16, (uint64_t)INT16_MIN));
+ EXPECT_EQ(One.getSignedMin(), APInt(16, 0xa));
+ EXPECT_EQ(Some.getSignedMin(), APInt(16, 0xa));
+ EXPECT_EQ(Wrap.getSignedMin(), APInt(16, (uint64_t)INT16_MIN));
+
+ // Found by Klee
+ EXPECT_EQ(ConstantRange(APInt(4, 7), APInt(4, 0)).getSignedMax(),
+ APInt(4, 7));
+}
+
+TEST_F(ConstantRangeTest, Trunc) {
+ ConstantRange TFull = Full.truncate(10);
+ ConstantRange TEmpty = Empty.truncate(10);
+ ConstantRange TOne = One.truncate(10);
+ ConstantRange TSome = Some.truncate(10);
+ ConstantRange TWrap = Wrap.truncate(10);
+ EXPECT_TRUE(TFull.isFullSet());
+ EXPECT_TRUE(TEmpty.isEmptySet());
+ EXPECT_EQ(TOne, ConstantRange(APInt(One.getLower()).trunc(10),
+ APInt(One.getUpper()).trunc(10)));
+ EXPECT_TRUE(TSome.isFullSet());
+}
+
+TEST_F(ConstantRangeTest, ZExt) {
+ ConstantRange ZFull = Full.zeroExtend(20);
+ ConstantRange ZEmpty = Empty.zeroExtend(20);
+ ConstantRange ZOne = One.zeroExtend(20);
+ ConstantRange ZSome = Some.zeroExtend(20);
+ ConstantRange ZWrap = Wrap.zeroExtend(20);
+ EXPECT_EQ(ZFull, ConstantRange(APInt(20, 0), APInt(20, 0x10000)));
+ EXPECT_TRUE(ZEmpty.isEmptySet());
+ EXPECT_EQ(ZOne, ConstantRange(APInt(One.getLower()).zext(20),
+ APInt(One.getUpper()).zext(20)));
+ EXPECT_EQ(ZSome, ConstantRange(APInt(Some.getLower()).zext(20),
+ APInt(Some.getUpper()).zext(20)));
+ EXPECT_EQ(ZWrap, ConstantRange(APInt(Wrap.getLower()).zext(20),
+ APInt(Wrap.getUpper()).zext(20)));
+}
+
+TEST_F(ConstantRangeTest, SExt) {
+ ConstantRange SFull = Full.signExtend(20);
+ ConstantRange SEmpty = Empty.signExtend(20);
+ ConstantRange SOne = One.signExtend(20);
+ ConstantRange SSome = Some.signExtend(20);
+ ConstantRange SWrap = Wrap.signExtend(20);
+ EXPECT_EQ(SFull, ConstantRange(APInt(20, (uint64_t)INT16_MIN, true),
+ APInt(20, INT16_MAX + 1, true)));
+ EXPECT_TRUE(SEmpty.isEmptySet());
+ EXPECT_EQ(SOne, ConstantRange(APInt(One.getLower()).sext(20),
+ APInt(One.getUpper()).sext(20)));
+ EXPECT_EQ(SSome, ConstantRange(APInt(Some.getLower()).sext(20),
+ APInt(Some.getUpper()).sext(20)));
+ EXPECT_EQ(SWrap, ConstantRange(APInt(Wrap.getLower()).sext(20),
+ APInt(Wrap.getUpper()).sext(20)));
+}
+
+TEST_F(ConstantRangeTest, IntersectWith) {
+ EXPECT_EQ(Empty.intersectWith(Full), Empty);
+ EXPECT_EQ(Empty.intersectWith(Empty), Empty);
+ EXPECT_EQ(Empty.intersectWith(One), Empty);
+ EXPECT_EQ(Empty.intersectWith(Some), Empty);
+ EXPECT_EQ(Empty.intersectWith(Wrap), Empty);
+ EXPECT_EQ(Full.intersectWith(Full), Full);
+ EXPECT_EQ(Some.intersectWith(Some), Some);
+ EXPECT_EQ(Some.intersectWith(One), One);
+ EXPECT_EQ(Full.intersectWith(One), One);
+ EXPECT_EQ(Full.intersectWith(Some), Some);
+ EXPECT_EQ(Some.intersectWith(Wrap), Empty);
+ EXPECT_EQ(One.intersectWith(Wrap), Empty);
+ EXPECT_EQ(One.intersectWith(Wrap), Wrap.intersectWith(One));
+
+ // Klee generated testcase from PR4545.
+ // The intersection of i16 [4, 2) and [6, 5) is disjoint, looking like
+ // 01..4.6789ABCDEF where the dots represent values not in the intersection.
+ ConstantRange LHS(APInt(16, 4), APInt(16, 2));
+ ConstantRange RHS(APInt(16, 6), APInt(16, 5));
+ EXPECT_TRUE(LHS.intersectWith(RHS) == LHS);
+}
+
+TEST_F(ConstantRangeTest, UnionWith) {
+ EXPECT_EQ(Wrap.unionWith(One),
+ ConstantRange(APInt(16, 0xaaa), APInt(16, 0xb)));
+ EXPECT_EQ(One.unionWith(Wrap), Wrap.unionWith(One));
+ EXPECT_EQ(Empty.unionWith(Empty), Empty);
+ EXPECT_EQ(Full.unionWith(Full), Full);
+ EXPECT_EQ(Some.unionWith(Wrap), Full);
+
+ // PR4545
+ EXPECT_EQ(ConstantRange(APInt(16, 14), APInt(16, 1)).unionWith(
+ ConstantRange(APInt(16, 0), APInt(16, 8))),
+ ConstantRange(APInt(16, 14), APInt(16, 8)));
+ EXPECT_EQ(ConstantRange(APInt(16, 6), APInt(16, 4)).unionWith(
+ ConstantRange(APInt(16, 4), APInt(16, 0))),
+ ConstantRange(16));
+ EXPECT_EQ(ConstantRange(APInt(16, 1), APInt(16, 0)).unionWith(
+ ConstantRange(APInt(16, 2), APInt(16, 1))),
+ ConstantRange(16));
+}
+
+TEST_F(ConstantRangeTest, SubtractAPInt) {
+ EXPECT_EQ(Full.subtract(APInt(16, 4)), Full);
+ EXPECT_EQ(Empty.subtract(APInt(16, 4)), Empty);
+ EXPECT_EQ(Some.subtract(APInt(16, 4)),
+ ConstantRange(APInt(16, 0x6), APInt(16, 0xaa6)));
+ EXPECT_EQ(Wrap.subtract(APInt(16, 4)),
+ ConstantRange(APInt(16, 0xaa6), APInt(16, 0x6)));
+ EXPECT_EQ(One.subtract(APInt(16, 4)),
+ ConstantRange(APInt(16, 0x6)));
+}
+
+TEST_F(ConstantRangeTest, Add) {
+ EXPECT_EQ(Full.add(APInt(16, 4)), Full);
+ EXPECT_EQ(Full.add(Full), Full);
+ EXPECT_EQ(Full.add(Empty), Empty);
+ EXPECT_EQ(Full.add(One), Full);
+ EXPECT_EQ(Full.add(Some), Full);
+ EXPECT_EQ(Full.add(Wrap), Full);
+ EXPECT_EQ(Empty.add(Empty), Empty);
+ EXPECT_EQ(Empty.add(One), Empty);
+ EXPECT_EQ(Empty.add(Some), Empty);
+ EXPECT_EQ(Empty.add(Wrap), Empty);
+ EXPECT_EQ(Empty.add(APInt(16, 4)), Empty);
+ EXPECT_EQ(Some.add(APInt(16, 4)),
+ ConstantRange(APInt(16, 0xe), APInt(16, 0xaae)));
+ EXPECT_EQ(Wrap.add(APInt(16, 4)),
+ ConstantRange(APInt(16, 0xaae), APInt(16, 0xe)));
+ EXPECT_EQ(One.add(APInt(16, 4)),
+ ConstantRange(APInt(16, 0xe)));
+}
+
+TEST_F(ConstantRangeTest, Multiply) {
+ EXPECT_EQ(Full.multiply(Full), Full);
+ EXPECT_EQ(Full.multiply(Empty), Empty);
+ EXPECT_EQ(Full.multiply(One), Full);
+ EXPECT_EQ(Full.multiply(Some), Full);
+ EXPECT_EQ(Full.multiply(Wrap), Full);
+ EXPECT_EQ(Empty.multiply(Empty), Empty);
+ EXPECT_EQ(Empty.multiply(One), Empty);
+ EXPECT_EQ(Empty.multiply(Some), Empty);
+ EXPECT_EQ(Empty.multiply(Wrap), Empty);
+ EXPECT_EQ(One.multiply(One), ConstantRange(APInt(16, 0xa*0xa),
+ APInt(16, 0xa*0xa + 1)));
+ EXPECT_EQ(One.multiply(Some), ConstantRange(APInt(16, 0xa*0xa),
+ APInt(16, 0xa*0xaa9 + 1)));
+ EXPECT_EQ(One.multiply(Wrap), Full);
+ EXPECT_EQ(Some.multiply(Some), Full);
+ EXPECT_EQ(Some.multiply(Wrap), Full);
+ EXPECT_EQ(Wrap.multiply(Wrap), Full);
+
+ // http://llvm.org/PR4545
+ EXPECT_EQ(ConstantRange(APInt(4, 1), APInt(4, 6)).multiply(
+ ConstantRange(APInt(4, 6), APInt(4, 2))),
+ ConstantRange(4, /*isFullSet=*/true));
+}
+
+TEST_F(ConstantRangeTest, UMax) {
+ EXPECT_EQ(Full.umax(Full), Full);
+ EXPECT_EQ(Full.umax(Empty), Empty);
+ EXPECT_EQ(Full.umax(Some), ConstantRange(APInt(16, 0xa), APInt(16, 0)));
+ EXPECT_EQ(Full.umax(Wrap), Full);
+ EXPECT_EQ(Full.umax(Some), ConstantRange(APInt(16, 0xa), APInt(16, 0)));
+ EXPECT_EQ(Empty.umax(Empty), Empty);
+ EXPECT_EQ(Empty.umax(Some), Empty);
+ EXPECT_EQ(Empty.umax(Wrap), Empty);
+ EXPECT_EQ(Empty.umax(One), Empty);
+ EXPECT_EQ(Some.umax(Some), Some);
+ EXPECT_EQ(Some.umax(Wrap), ConstantRange(APInt(16, 0xa), APInt(16, 0)));
+ EXPECT_EQ(Some.umax(One), Some);
+ // TODO: ConstantRange is currently over-conservative here.
+ EXPECT_EQ(Wrap.umax(Wrap), Full);
+ EXPECT_EQ(Wrap.umax(One), ConstantRange(APInt(16, 0xa), APInt(16, 0)));
+ EXPECT_EQ(One.umax(One), One);
+}
+
+TEST_F(ConstantRangeTest, SMax) {
+ EXPECT_EQ(Full.smax(Full), Full);
+ EXPECT_EQ(Full.smax(Empty), Empty);
+ EXPECT_EQ(Full.smax(Some), ConstantRange(APInt(16, 0xa),
+ APInt::getSignedMinValue(16)));
+ EXPECT_EQ(Full.smax(Wrap), Full);
+ EXPECT_EQ(Full.smax(One), ConstantRange(APInt(16, 0xa),
+ APInt::getSignedMinValue(16)));
+ EXPECT_EQ(Empty.smax(Empty), Empty);
+ EXPECT_EQ(Empty.smax(Some), Empty);
+ EXPECT_EQ(Empty.smax(Wrap), Empty);
+ EXPECT_EQ(Empty.smax(One), Empty);
+ EXPECT_EQ(Some.smax(Some), Some);
+ EXPECT_EQ(Some.smax(Wrap), ConstantRange(APInt(16, 0xa),
+ APInt(16, (uint64_t)INT16_MIN)));
+ EXPECT_EQ(Some.smax(One), Some);
+ EXPECT_EQ(Wrap.smax(One), ConstantRange(APInt(16, 0xa),
+ APInt(16, (uint64_t)INT16_MIN)));
+ EXPECT_EQ(One.smax(One), One);
+}
+
+TEST_F(ConstantRangeTest, UDiv) {
+ EXPECT_EQ(Full.udiv(Full), Full);
+ EXPECT_EQ(Full.udiv(Empty), Empty);
+ EXPECT_EQ(Full.udiv(One), ConstantRange(APInt(16, 0),
+ APInt(16, 0xffff / 0xa + 1)));
+ EXPECT_EQ(Full.udiv(Some), ConstantRange(APInt(16, 0),
+ APInt(16, 0xffff / 0xa + 1)));
+ EXPECT_EQ(Full.udiv(Wrap), Full);
+ EXPECT_EQ(Empty.udiv(Empty), Empty);
+ EXPECT_EQ(Empty.udiv(One), Empty);
+ EXPECT_EQ(Empty.udiv(Some), Empty);
+ EXPECT_EQ(Empty.udiv(Wrap), Empty);
+ EXPECT_EQ(One.udiv(One), ConstantRange(APInt(16, 1)));
+ EXPECT_EQ(One.udiv(Some), ConstantRange(APInt(16, 0), APInt(16, 2)));
+ EXPECT_EQ(One.udiv(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xb)));
+ EXPECT_EQ(Some.udiv(Some), ConstantRange(APInt(16, 0), APInt(16, 0x111)));
+ EXPECT_EQ(Some.udiv(Wrap), ConstantRange(APInt(16, 0), APInt(16, 0xaaa)));
+ EXPECT_EQ(Wrap.udiv(Wrap), Full);
+}
+
+} // anonymous namespace
diff --git a/unittests/Support/MathExtrasTest.cpp b/unittests/Support/MathExtrasTest.cpp
index 1f19468..3db1f77 100644
--- a/unittests/Support/MathExtrasTest.cpp
+++ b/unittests/Support/MathExtrasTest.cpp
@@ -1,4 +1,4 @@
-//===- llvm/unittest/Support/MathExtrasTest.cpp - math utils tests --------===//
+//===- unittests/Support/MathExtrasTest.cpp - math utils tests ------------===//
//
// The LLVM Compiler Infrastructure
//
diff --git a/unittests/Support/RegexTest.cpp b/unittests/Support/RegexTest.cpp
new file mode 100644
index 0000000..44c7e55
--- /dev/null
+++ b/unittests/Support/RegexTest.cpp
@@ -0,0 +1,65 @@
+//===- llvm/unittest/Support/RegexTest.cpp - Regex tests --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/ADT/SmallVector.h"
+#include <cstring>
+
+using namespace llvm;
+namespace {
+
+class RegexTest : public ::testing::Test {
+};
+
+TEST_F(RegexTest, Basics) {
+ Regex r1("^[0-9]+$");
+ EXPECT_TRUE(r1.match("916"));
+ EXPECT_TRUE(r1.match("9"));
+ EXPECT_FALSE(r1.match("9a"));
+
+ SmallVector<StringRef, 1> Matches;
+ Regex r2("[0-9]+");
+ EXPECT_TRUE(r2.match("aa216b", &Matches));
+ EXPECT_EQ(1u, Matches.size());
+ EXPECT_EQ("216", Matches[0].str());
+
+ Regex r3("[0-9]+([a-f])?:([0-9]+)");
+ EXPECT_TRUE(r3.match("9a:513b", &Matches));
+ EXPECT_EQ(3u, Matches.size());
+ EXPECT_EQ("9a:513", Matches[0].str());
+ EXPECT_EQ("a", Matches[1].str());
+ EXPECT_EQ("513", Matches[2].str());
+
+ EXPECT_TRUE(r3.match("9:513b", &Matches));
+ EXPECT_EQ(3u, Matches.size());
+ EXPECT_EQ("9:513", Matches[0].str());
+ EXPECT_EQ("", Matches[1].str());
+ EXPECT_EQ("513", Matches[2].str());
+
+ Regex r4("a[^b]+b");
+ std::string String="axxb";
+ String[2] = '\0';
+ EXPECT_FALSE(r4.match("abb"));
+ EXPECT_TRUE(r4.match(String, &Matches));
+ EXPECT_EQ(1u, Matches.size());
+ EXPECT_EQ(String, Matches[0].str());
+
+
+ std::string NulPattern="X[0-9]+X([a-f])?:([0-9]+)";
+ String="YX99a:513b";
+ NulPattern[7] = '\0';
+ Regex r5(NulPattern);
+ EXPECT_FALSE(r5.match(String));
+ EXPECT_FALSE(r5.match("X9"));
+ String[3]='\0';
+ EXPECT_TRUE(r5.match(String));
+}
+
+}
diff --git a/unittests/Support/TypeBuilderTest.cpp b/unittests/Support/TypeBuilderTest.cpp
index 425ee6b..a5c5e67 100644
--- a/unittests/Support/TypeBuilderTest.cpp
+++ b/unittests/Support/TypeBuilderTest.cpp
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/TypeBuilder.h"
+#include "llvm/LLVMContext.h"
#include "gtest/gtest.h"
@@ -16,134 +17,146 @@ using namespace llvm;
namespace {
TEST(TypeBuilderTest, Void) {
- EXPECT_EQ(Type::VoidTy, (TypeBuilder<void, true>::get()));
- EXPECT_EQ(Type::VoidTy, (TypeBuilder<void, false>::get()));
+ EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, true>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getVoidTy(getGlobalContext()), (TypeBuilder<void, false>::get(getGlobalContext())));
// Special case for C compatibility:
- EXPECT_EQ(PointerType::getUnqual(Type::Int8Ty),
- (TypeBuilder<void*, false>::get()));
+ EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
+ (TypeBuilder<void*, false>::get(getGlobalContext())));
}
TEST(TypeBuilderTest, HostIntegers) {
- EXPECT_EQ(Type::Int8Ty, (TypeBuilder<int8_t, false>::get()));
- EXPECT_EQ(Type::Int8Ty, (TypeBuilder<uint8_t, false>::get()));
- EXPECT_EQ(Type::Int16Ty, (TypeBuilder<int16_t, false>::get()));
- EXPECT_EQ(Type::Int16Ty, (TypeBuilder<uint16_t, false>::get()));
- EXPECT_EQ(Type::Int32Ty, (TypeBuilder<int32_t, false>::get()));
- EXPECT_EQ(Type::Int32Ty, (TypeBuilder<uint32_t, false>::get()));
- EXPECT_EQ(Type::Int64Ty, (TypeBuilder<int64_t, false>::get()));
- EXPECT_EQ(Type::Int64Ty, (TypeBuilder<uint64_t, false>::get()));
-
- EXPECT_EQ(IntegerType::get(sizeof(size_t) * CHAR_BIT),
- (TypeBuilder<size_t, false>::get()));
- EXPECT_EQ(IntegerType::get(sizeof(ptrdiff_t) * CHAR_BIT),
- (TypeBuilder<ptrdiff_t, false>::get()));
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), (TypeBuilder<int8_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()), (TypeBuilder<uint8_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt16Ty(getGlobalContext()), (TypeBuilder<int16_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt16Ty(getGlobalContext()), (TypeBuilder<uint16_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (TypeBuilder<int32_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (TypeBuilder<uint32_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt64Ty(getGlobalContext()), (TypeBuilder<int64_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt64Ty(getGlobalContext()), (TypeBuilder<uint64_t, false>::get(getGlobalContext())));
+
+ EXPECT_EQ(IntegerType::get(getGlobalContext(), sizeof(size_t) * CHAR_BIT),
+ (TypeBuilder<size_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(IntegerType::get(getGlobalContext(), sizeof(ptrdiff_t) * CHAR_BIT),
+ (TypeBuilder<ptrdiff_t, false>::get(getGlobalContext())));
}
TEST(TypeBuilderTest, CrossCompilableIntegers) {
- EXPECT_EQ(IntegerType::get(1), (TypeBuilder<types::i<1>, true>::get()));
- EXPECT_EQ(IntegerType::get(1), (TypeBuilder<types::i<1>, false>::get()));
- EXPECT_EQ(IntegerType::get(72), (TypeBuilder<types::i<72>, true>::get()));
- EXPECT_EQ(IntegerType::get(72), (TypeBuilder<types::i<72>, false>::get()));
+ EXPECT_EQ(IntegerType::get(getGlobalContext(), 1), (TypeBuilder<types::i<1>, true>::get(getGlobalContext())));
+ EXPECT_EQ(IntegerType::get(getGlobalContext(), 1), (TypeBuilder<types::i<1>, false>::get(getGlobalContext())));
+ EXPECT_EQ(IntegerType::get(getGlobalContext(), 72), (TypeBuilder<types::i<72>, true>::get(getGlobalContext())));
+ EXPECT_EQ(IntegerType::get(getGlobalContext(), 72), (TypeBuilder<types::i<72>, false>::get(getGlobalContext())));
}
TEST(TypeBuilderTest, Float) {
- EXPECT_EQ(Type::FloatTy, (TypeBuilder<float, false>::get()));
- EXPECT_EQ(Type::DoubleTy, (TypeBuilder<double, false>::get()));
+ EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<float, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<double, false>::get(getGlobalContext())));
// long double isn't supported yet.
- EXPECT_EQ(Type::FloatTy, (TypeBuilder<types::ieee_float, true>::get()));
- EXPECT_EQ(Type::FloatTy, (TypeBuilder<types::ieee_float, false>::get()));
- EXPECT_EQ(Type::DoubleTy, (TypeBuilder<types::ieee_double, true>::get()));
- EXPECT_EQ(Type::DoubleTy, (TypeBuilder<types::ieee_double, false>::get()));
- EXPECT_EQ(Type::X86_FP80Ty, (TypeBuilder<types::x86_fp80, true>::get()));
- EXPECT_EQ(Type::X86_FP80Ty, (TypeBuilder<types::x86_fp80, false>::get()));
- EXPECT_EQ(Type::FP128Ty, (TypeBuilder<types::fp128, true>::get()));
- EXPECT_EQ(Type::FP128Ty, (TypeBuilder<types::fp128, false>::get()));
- EXPECT_EQ(Type::PPC_FP128Ty, (TypeBuilder<types::ppc_fp128, true>::get()));
- EXPECT_EQ(Type::PPC_FP128Ty, (TypeBuilder<types::ppc_fp128, false>::get()));
+ EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<types::ieee_float, true>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getFloatTy(getGlobalContext()), (TypeBuilder<types::ieee_float, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<types::ieee_double, true>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getDoubleTy(getGlobalContext()), (TypeBuilder<types::ieee_double, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getX86_FP80Ty(getGlobalContext()), (TypeBuilder<types::x86_fp80, true>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getX86_FP80Ty(getGlobalContext()), (TypeBuilder<types::x86_fp80, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getFP128Ty(getGlobalContext()), (TypeBuilder<types::fp128, true>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getFP128Ty(getGlobalContext()), (TypeBuilder<types::fp128, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getPPC_FP128Ty(getGlobalContext()), (TypeBuilder<types::ppc_fp128, true>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getPPC_FP128Ty(getGlobalContext()), (TypeBuilder<types::ppc_fp128, false>::get(getGlobalContext())));
}
TEST(TypeBuilderTest, Derived) {
- EXPECT_EQ(PointerType::getUnqual(PointerType::getUnqual(Type::Int8Ty)),
- (TypeBuilder<int8_t**, false>::get()));
- EXPECT_EQ(ArrayType::get(Type::Int8Ty, 7),
- (TypeBuilder<int8_t[7], false>::get()));
- EXPECT_EQ(ArrayType::get(Type::Int8Ty, 0),
- (TypeBuilder<int8_t[], false>::get()));
-
- EXPECT_EQ(PointerType::getUnqual(PointerType::getUnqual(Type::Int8Ty)),
- (TypeBuilder<types::i<8>**, false>::get()));
- EXPECT_EQ(ArrayType::get(Type::Int8Ty, 7),
- (TypeBuilder<types::i<8>[7], false>::get()));
- EXPECT_EQ(ArrayType::get(Type::Int8Ty, 0),
- (TypeBuilder<types::i<8>[], false>::get()));
-
- EXPECT_EQ(PointerType::getUnqual(PointerType::getUnqual(Type::Int8Ty)),
- (TypeBuilder<types::i<8>**, true>::get()));
- EXPECT_EQ(ArrayType::get(Type::Int8Ty, 7),
- (TypeBuilder<types::i<8>[7], true>::get()));
- EXPECT_EQ(ArrayType::get(Type::Int8Ty, 0),
- (TypeBuilder<types::i<8>[], true>::get()));
-
-
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<const int8_t, false>::get()));
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<volatile int8_t, false>::get()));
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<const volatile int8_t, false>::get()));
-
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<const types::i<8>, false>::get()));
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<volatile types::i<8>, false>::get()));
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<const volatile types::i<8>, false>::get()));
-
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<const types::i<8>, true>::get()));
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<volatile types::i<8>, true>::get()));
- EXPECT_EQ(Type::Int8Ty,
- (TypeBuilder<const volatile types::i<8>, true>::get()));
-
- EXPECT_EQ(PointerType::getUnqual(Type::Int8Ty),
- (TypeBuilder<const volatile int8_t*const volatile, false>::get()));
+ EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())),
+ (TypeBuilder<int8_t**, false>::get(getGlobalContext())));
+ EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7),
+ (TypeBuilder<int8_t[7], false>::get(getGlobalContext())));
+ EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0),
+ (TypeBuilder<int8_t[], false>::get(getGlobalContext())));
+
+ EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())),
+ (TypeBuilder<types::i<8>**, false>::get(getGlobalContext())));
+ EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7),
+ (TypeBuilder<types::i<8>[7], false>::get(getGlobalContext())));
+ EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0),
+ (TypeBuilder<types::i<8>[], false>::get(getGlobalContext())));
+
+ EXPECT_EQ(PointerType::getUnqual(Type::getInt8PtrTy(getGlobalContext())),
+ (TypeBuilder<types::i<8>**, true>::get(getGlobalContext())));
+ EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 7),
+ (TypeBuilder<types::i<8>[7], true>::get(getGlobalContext())));
+ EXPECT_EQ(ArrayType::get(Type::getInt8Ty(getGlobalContext()), 0),
+ (TypeBuilder<types::i<8>[], true>::get(getGlobalContext())));
+
+
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<const int8_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<volatile int8_t, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<const volatile int8_t, false>::get(getGlobalContext())));
+
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<const types::i<8>, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<volatile types::i<8>, false>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<const volatile types::i<8>, false>::get(getGlobalContext())));
+
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<const types::i<8>, true>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<volatile types::i<8>, true>::get(getGlobalContext())));
+ EXPECT_EQ(Type::getInt8Ty(getGlobalContext()),
+ (TypeBuilder<const volatile types::i<8>, true>::get(getGlobalContext())));
+
+ EXPECT_EQ(Type::getInt8PtrTy(getGlobalContext()),
+ (TypeBuilder<const volatile int8_t*const volatile, false>::get(getGlobalContext())));
}
TEST(TypeBuilderTest, Functions) {
std::vector<const Type*> params;
- EXPECT_EQ(FunctionType::get(Type::VoidTy, params, false),
- (TypeBuilder<void(), true>::get()));
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true),
- (TypeBuilder<int8_t(...), false>::get()));
- params.push_back(TypeBuilder<int32_t*, false>::get());
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, false),
- (TypeBuilder<int8_t(const int32_t*), false>::get()));
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true),
- (TypeBuilder<int8_t(const int32_t*, ...), false>::get()));
- params.push_back(TypeBuilder<char*, false>::get());
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, false),
- (TypeBuilder<int8_t(int32_t*, void*), false>::get()));
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true),
- (TypeBuilder<int8_t(int32_t*, char*, ...), false>::get()));
- params.push_back(TypeBuilder<char, false>::get());
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, false),
- (TypeBuilder<int8_t(int32_t*, void*, char), false>::get()));
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true),
- (TypeBuilder<int8_t(int32_t*, char*, char, ...), false>::get()));
- params.push_back(TypeBuilder<char, false>::get());
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, false),
- (TypeBuilder<int8_t(int32_t*, void*, char, char), false>::get()));
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true),
+ EXPECT_EQ(FunctionType::get(Type::getVoidTy(getGlobalContext()), params, false),
+ (TypeBuilder<void(), true>::get(getGlobalContext())));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
+ (TypeBuilder<int8_t(...), false>::get(getGlobalContext())));
+ params.push_back(TypeBuilder<int32_t*, false>::get(getGlobalContext()));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
+ (TypeBuilder<int8_t(const int32_t*), false>::get(getGlobalContext())));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
+ (TypeBuilder<int8_t(const int32_t*, ...), false>::get(getGlobalContext())));
+ params.push_back(TypeBuilder<char*, false>::get(getGlobalContext()));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
+ (TypeBuilder<int8_t(int32_t*, void*), false>::get(getGlobalContext())));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
+ (TypeBuilder<int8_t(int32_t*, char*, ...), false>::get(getGlobalContext())));
+ params.push_back(TypeBuilder<char, false>::get(getGlobalContext()));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
+ (TypeBuilder<int8_t(int32_t*, void*, char), false>::get(getGlobalContext())));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
+ (TypeBuilder<int8_t(int32_t*, char*, char, ...), false>::get(getGlobalContext())));
+ params.push_back(TypeBuilder<char, false>::get(getGlobalContext()));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
+ (TypeBuilder<int8_t(int32_t*, void*, char, char), false>::get(getGlobalContext())));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
(TypeBuilder<int8_t(int32_t*, char*, char, char, ...),
- false>::get()));
- params.push_back(TypeBuilder<char, false>::get());
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, false),
+ false>::get(getGlobalContext())));
+ params.push_back(TypeBuilder<char, false>::get(getGlobalContext()));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, false),
(TypeBuilder<int8_t(int32_t*, void*, char, char, char),
- false>::get()));
- EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true),
+ false>::get(getGlobalContext())));
+ EXPECT_EQ(FunctionType::get(Type::getInt8Ty(getGlobalContext()), params, true),
(TypeBuilder<int8_t(int32_t*, char*, char, char, char, ...),
- false>::get()));
+ false>::get(getGlobalContext())));
+}
+
+TEST(TypeBuilderTest, Context) {
+ // We used to cache TypeBuilder results in static local variables. This
+ // produced the same type for different contexts, which of course broke
+ // things.
+ LLVMContext context1;
+ EXPECT_EQ(&context1,
+ &(TypeBuilder<types::i<1>, true>::get(context1))->getContext());
+ LLVMContext context2;
+ EXPECT_EQ(&context2,
+ &(TypeBuilder<types::i<1>, true>::get(context2))->getContext());
}
class MyType {
@@ -163,14 +176,14 @@ class MyPortableType {
namespace llvm {
template<bool cross> class TypeBuilder<MyType, cross> {
public:
- static const StructType *get() {
+ static const StructType *get(LLVMContext &Context) {
// Using the static result variable ensures that the type is
// only looked up once.
- static const StructType *const result = StructType::get(
- TypeBuilder<int, cross>::get(),
- TypeBuilder<int*, cross>::get(),
- TypeBuilder<void*[], cross>::get(),
- NULL);
+ std::vector<const Type*> st;
+ st.push_back(TypeBuilder<int, cross>::get(Context));
+ st.push_back(TypeBuilder<int*, cross>::get(Context));
+ st.push_back(TypeBuilder<void*[], cross>::get(Context));
+ static const StructType *const result = StructType::get(Context, st);
return result;
}
@@ -186,14 +199,14 @@ public:
template<bool cross> class TypeBuilder<MyPortableType, cross> {
public:
- static const StructType *get() {
+ static const StructType *get(LLVMContext &Context) {
// Using the static result variable ensures that the type is
// only looked up once.
- static const StructType *const result = StructType::get(
- TypeBuilder<types::i<32>, cross>::get(),
- TypeBuilder<types::i<32>*, cross>::get(),
- TypeBuilder<types::i<8>*[], cross>::get(),
- NULL);
+ std::vector<const Type*> st;
+ st.push_back(TypeBuilder<types::i<32>, cross>::get(Context));
+ st.push_back(TypeBuilder<types::i<32>*, cross>::get(Context));
+ st.push_back(TypeBuilder<types::i<8>*[], cross>::get(Context));
+ static const StructType *const result = StructType::get(Context, st);
return result;
}
@@ -210,24 +223,24 @@ public:
namespace {
TEST(TypeBuilderTest, Extensions) {
- EXPECT_EQ(PointerType::getUnqual(StructType::get(
- TypeBuilder<int, false>::get(),
- TypeBuilder<int*, false>::get(),
- TypeBuilder<void*[], false>::get(),
+ EXPECT_EQ(PointerType::getUnqual(StructType::get(getGlobalContext(),
+ TypeBuilder<int, false>::get(getGlobalContext()),
+ TypeBuilder<int*, false>::get(getGlobalContext()),
+ TypeBuilder<void*[], false>::get(getGlobalContext()),
NULL)),
- (TypeBuilder<MyType*, false>::get()));
- EXPECT_EQ(PointerType::getUnqual(StructType::get(
- TypeBuilder<types::i<32>, false>::get(),
- TypeBuilder<types::i<32>*, false>::get(),
- TypeBuilder<types::i<8>*[], false>::get(),
+ (TypeBuilder<MyType*, false>::get(getGlobalContext())));
+ EXPECT_EQ(PointerType::getUnqual(StructType::get(getGlobalContext(),
+ TypeBuilder<types::i<32>, false>::get(getGlobalContext()),
+ TypeBuilder<types::i<32>*, false>::get(getGlobalContext()),
+ TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()),
NULL)),
- (TypeBuilder<MyPortableType*, false>::get()));
- EXPECT_EQ(PointerType::getUnqual(StructType::get(
- TypeBuilder<types::i<32>, false>::get(),
- TypeBuilder<types::i<32>*, false>::get(),
- TypeBuilder<types::i<8>*[], false>::get(),
+ (TypeBuilder<MyPortableType*, false>::get(getGlobalContext())));
+ EXPECT_EQ(PointerType::getUnqual(StructType::get(getGlobalContext(),
+ TypeBuilder<types::i<32>, false>::get(getGlobalContext()),
+ TypeBuilder<types::i<32>*, false>::get(getGlobalContext()),
+ TypeBuilder<types::i<8>*[], false>::get(getGlobalContext()),
NULL)),
- (TypeBuilder<MyPortableType*, true>::get()));
+ (TypeBuilder<MyPortableType*, true>::get(getGlobalContext())));
}
} // anonymous namespace
diff --git a/unittests/Support/ValueHandleTest.cpp b/unittests/Support/ValueHandleTest.cpp
index 336e7d9..c89a7af 100644
--- a/unittests/Support/ValueHandleTest.cpp
+++ b/unittests/Support/ValueHandleTest.cpp
@@ -11,6 +11,7 @@
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
+#include "llvm/ADT/OwningPtr.h"
#include "gtest/gtest.h"
@@ -25,8 +26,9 @@ protected:
Constant *ConstantV;
std::auto_ptr<BitCastInst> BitcastV;
- ValueHandle() : ConstantV(ConstantInt::get(Type::Int32Ty, 0)),
- BitcastV(new BitCastInst(ConstantV, Type::Int32Ty)) {
+ ValueHandle() :
+ ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)),
+ BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(getGlobalContext()))) {
}
};
@@ -44,8 +46,8 @@ TEST_F(ValueHandle, WeakVH_BasicOperation) {
// Make sure I can call a method on the underlying Value. It
// doesn't matter which method.
- EXPECT_EQ(Type::Int32Ty, WVH->getType());
- EXPECT_EQ(Type::Int32Ty, (*WVH).getType());
+ EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), WVH->getType());
+ EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*WVH).getType());
}
TEST_F(ValueHandle, WeakVH_Comparisons) {
@@ -119,6 +121,13 @@ TEST_F(ValueHandle, AssertingVH_BasicOperation) {
EXPECT_FALSE((*AVH).mayWriteToMemory());
}
+TEST_F(ValueHandle, AssertingVH_Const) {
+ const CastInst *ConstBitcast = BitcastV.get();
+ AssertingVH<const CastInst> AVH(ConstBitcast);
+ const CastInst *implicit_to_exact_type = AVH;
+ implicit_to_exact_type = implicit_to_exact_type; // Avoid warning.
+}
+
TEST_F(ValueHandle, AssertingVH_Comparisons) {
AssertingVH<Value> BitcastAVH(BitcastV.get());
AssertingVH<Value> ConstantAVH(ConstantV);
@@ -192,8 +201,8 @@ TEST_F(ValueHandle, CallbackVH_BasicOperation) {
// Make sure I can call a method on the underlying Value. It
// doesn't matter which method.
- EXPECT_EQ(Type::Int32Ty, CVH->getType());
- EXPECT_EQ(Type::Int32Ty, (*CVH).getType());
+ EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), CVH->getType());
+ EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*CVH).getType());
}
TEST_F(ValueHandle, CallbackVH_Comparisons) {
@@ -284,14 +293,17 @@ TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
public:
int DeletedCalls;
Value *AURWArgument;
+ LLVMContext *Context;
- RecoveringVH() : DeletedCalls(0), AURWArgument(NULL) {}
+ RecoveringVH() : DeletedCalls(0), AURWArgument(NULL),
+ Context(&getGlobalContext()) {}
RecoveringVH(Value *V)
- : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL) {}
+ : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL),
+ Context(&getGlobalContext()) {}
private:
virtual void deleted() {
- getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::Int32Ty));
+ getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())));
setValPtr(NULL);
}
virtual void allUsesReplacedWith(Value *new_value) {
@@ -307,11 +319,93 @@ TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
RecoveringVH RVH;
RVH = BitcastV.get();
std::auto_ptr<BinaryOperator> BitcastUser(
- BinaryOperator::CreateAdd(RVH, Constant::getNullValue(Type::Int32Ty)));
+ BinaryOperator::CreateAdd(RVH,
+ Constant::getNullValue(Type::getInt32Ty(getGlobalContext()))));
EXPECT_EQ(BitcastV.get(), BitcastUser->getOperand(0));
BitcastV.reset(); // Would crash without the ValueHandler.
- EXPECT_EQ(Constant::getNullValue(Type::Int32Ty), RVH.AURWArgument);
- EXPECT_EQ(Constant::getNullValue(Type::Int32Ty), BitcastUser->getOperand(0));
+ EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())), RVH.AURWArgument);
+ EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())),
+ BitcastUser->getOperand(0));
+}
+
+TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) {
+ // When a CallbackVH modifies other ValueHandles in its callbacks,
+ // that shouldn't interfere with non-modified ValueHandles receiving
+ // their appropriate callbacks.
+ //
+ // We create the active CallbackVH in the middle of a palindromic
+ // arrangement of other VHs so that the bad behavior would be
+ // triggered in whichever order callbacks run.
+
+ class DestroyingVH : public CallbackVH {
+ public:
+ OwningPtr<WeakVH> ToClear[2];
+ DestroyingVH(Value *V) {
+ ToClear[0].reset(new WeakVH(V));
+ setValPtr(V);
+ ToClear[1].reset(new WeakVH(V));
+ }
+ virtual void deleted() {
+ ToClear[0].reset();
+ ToClear[1].reset();
+ CallbackVH::deleted();
+ }
+ virtual void allUsesReplacedWith(Value *) {
+ ToClear[0].reset();
+ ToClear[1].reset();
+ }
+ };
+
+ {
+ WeakVH ShouldBeVisited1(BitcastV.get());
+ DestroyingVH C(BitcastV.get());
+ WeakVH ShouldBeVisited2(BitcastV.get());
+
+ BitcastV->replaceAllUsesWith(ConstantV);
+ EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited1));
+ EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited2));
+ }
+
+ {
+ WeakVH ShouldBeVisited1(BitcastV.get());
+ DestroyingVH C(BitcastV.get());
+ WeakVH ShouldBeVisited2(BitcastV.get());
+
+ BitcastV.reset();
+ EXPECT_EQ(NULL, static_cast<Value*>(ShouldBeVisited1));
+ EXPECT_EQ(NULL, static_cast<Value*>(ShouldBeVisited2));
+ }
+}
+
+TEST_F(ValueHandle, AssertingVHCheckedLast) {
+ // If a CallbackVH exists to clear out a group of AssertingVHs on
+ // Value deletion, the CallbackVH should get a chance to do so
+ // before the AssertingVHs assert.
+
+ class ClearingVH : public CallbackVH {
+ public:
+ AssertingVH<Value> *ToClear[2];
+ ClearingVH(Value *V,
+ AssertingVH<Value> &A0, AssertingVH<Value> &A1)
+ : CallbackVH(V) {
+ ToClear[0] = &A0;
+ ToClear[1] = &A1;
+ }
+
+ virtual void deleted() {
+ *ToClear[0] = 0;
+ *ToClear[1] = 0;
+ CallbackVH::deleted();
+ }
+ };
+
+ AssertingVH<Value> A1, A2;
+ A1 = BitcastV.get();
+ ClearingVH C(BitcastV.get(), A1, A2);
+ A2 = BitcastV.get();
+ // C.deleted() should run first, clearing the two AssertingVHs,
+ // which should prevent them from asserting.
+ BitcastV.reset();
}
}
diff --git a/unittests/Support/raw_ostream_test.cpp b/unittests/Support/raw_ostream_test.cpp
index feb0152..bd2e95c 100644
--- a/unittests/Support/raw_ostream_test.cpp
+++ b/unittests/Support/raw_ostream_test.cpp
@@ -8,6 +8,8 @@
//===----------------------------------------------------------------------===//
#include "gtest/gtest.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -20,6 +22,23 @@ template<typename T> std::string printToString(const T &Value) {
return res;
}
+/// printToString - Print the given value to a stream which only has \arg
+/// BytesLeftInBuffer bytes left in the buffer. This is useful for testing edge
+/// cases in the buffer handling logic.
+template<typename T> std::string printToString(const T &Value,
+ unsigned BytesLeftInBuffer) {
+ // FIXME: This is relying on internal knowledge of how raw_ostream works to
+ // get the buffer position right.
+ SmallString<256> SVec;
+ assert(BytesLeftInBuffer < 256 && "Invalid buffer count!");
+ llvm::raw_svector_ostream OS(SVec);
+ unsigned StartIndex = 256 - BytesLeftInBuffer;
+ for (unsigned i = 0; i != StartIndex; ++i)
+ OS << '?';
+ OS << Value;
+ return OS.str().substr(StartIndex);
+}
+
template<typename T> std::string printToStringUnbuffered(const T &Value) {
std::string res;
llvm::raw_string_ostream OS(res);
@@ -53,6 +72,10 @@ TEST(raw_ostreamTest, Types_Buffered) {
EXPECT_EQ("0x0", printToString((void*) 0));
EXPECT_EQ("0xbeef", printToString((void*) 0xbeef));
EXPECT_EQ("0xdeadbeef", printToString((void*) 0xdeadbeef));
+
+ // Min and max.
+ EXPECT_EQ("18446744073709551615", printToString(UINT64_MAX));
+ EXPECT_EQ("-9223372036854775808", printToString(INT64_MIN));
}
TEST(raw_ostreamTest, Types_Unbuffered) {
@@ -80,6 +103,28 @@ TEST(raw_ostreamTest, Types_Unbuffered) {
EXPECT_EQ("0x0", printToStringUnbuffered((void*) 0));
EXPECT_EQ("0xbeef", printToStringUnbuffered((void*) 0xbeef));
EXPECT_EQ("0xdeadbeef", printToStringUnbuffered((void*) 0xdeadbeef));
+
+ // Min and max.
+ EXPECT_EQ("18446744073709551615", printToStringUnbuffered(UINT64_MAX));
+ EXPECT_EQ("-9223372036854775808", printToStringUnbuffered(INT64_MIN));
+}
+
+TEST(raw_ostreamTest, BufferEdge) {
+ EXPECT_EQ("1.20", printToString(format("%.2f", 1.2), 1));
+ EXPECT_EQ("1.20", printToString(format("%.2f", 1.2), 2));
+ EXPECT_EQ("1.20", printToString(format("%.2f", 1.2), 3));
+ EXPECT_EQ("1.20", printToString(format("%.2f", 1.2), 4));
+ EXPECT_EQ("1.20", printToString(format("%.2f", 1.2), 10));
+}
+
+TEST(raw_ostreamTest, TinyBuffer) {
+ std::string Str;
+ raw_string_ostream OS(Str);
+ OS.SetBufferSize(1);
+ OS << "hello";
+ OS << 1;
+ OS << 'w' << 'o' << 'r' << 'l' << 'd';
+ EXPECT_EQ("hello1world", OS.str());
}
}
diff --git a/unittests/Transforms/Makefile b/unittests/Transforms/Makefile
new file mode 100644
index 0000000..599b18a
--- /dev/null
+++ b/unittests/Transforms/Makefile
@@ -0,0 +1,17 @@
+##===- unittests/Transforms/Makefile -----------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+
+PARALLEL_DIRS = Utils
+
+include $(LEVEL)/Makefile.common
+
+clean::
+ $(Verb) $(RM) -f *Tests
diff --git a/unittests/Transforms/Utils/Cloning.cpp b/unittests/Transforms/Utils/Cloning.cpp
new file mode 100644
index 0000000..b14114a
--- /dev/null
+++ b/unittests/Transforms/Utils/Cloning.cpp
@@ -0,0 +1,87 @@
+//===- Cloning.cpp - Unit tests for the Cloner ----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "gtest/gtest.h"
+#include "llvm/Argument.h"
+#include "llvm/Instructions.h"
+
+using namespace llvm;
+
+TEST(CloneInstruction, OverflowBits) {
+ LLVMContext context;
+ Value *V = new Argument(Type::getInt32Ty(context));
+
+ BinaryOperator *Add = BinaryOperator::Create(Instruction::Add, V, V);
+ BinaryOperator *Sub = BinaryOperator::Create(Instruction::Sub, V, V);
+ BinaryOperator *Mul = BinaryOperator::Create(Instruction::Mul, V, V);
+
+ EXPECT_FALSE(Add->clone()->hasNoUnsignedWrap());
+ EXPECT_FALSE(Add->clone()->hasNoSignedWrap());
+ EXPECT_FALSE(Sub->clone()->hasNoUnsignedWrap());
+ EXPECT_FALSE(Sub->clone()->hasNoSignedWrap());
+ EXPECT_FALSE(Mul->clone()->hasNoUnsignedWrap());
+ EXPECT_FALSE(Mul->clone()->hasNoSignedWrap());
+
+ Add->setHasNoUnsignedWrap();
+ Sub->setHasNoUnsignedWrap();
+ Mul->setHasNoUnsignedWrap();
+
+ EXPECT_TRUE(Add->clone()->hasNoUnsignedWrap());
+ EXPECT_FALSE(Add->clone()->hasNoSignedWrap());
+ EXPECT_TRUE(Sub->clone()->hasNoUnsignedWrap());
+ EXPECT_FALSE(Sub->clone()->hasNoSignedWrap());
+ EXPECT_TRUE(Mul->clone()->hasNoUnsignedWrap());
+ EXPECT_FALSE(Mul->clone()->hasNoSignedWrap());
+
+ Add->setHasNoSignedWrap();
+ Sub->setHasNoSignedWrap();
+ Mul->setHasNoSignedWrap();
+
+ EXPECT_TRUE(Add->clone()->hasNoUnsignedWrap());
+ EXPECT_TRUE(Add->clone()->hasNoSignedWrap());
+ EXPECT_TRUE(Sub->clone()->hasNoUnsignedWrap());
+ EXPECT_TRUE(Sub->clone()->hasNoSignedWrap());
+ EXPECT_TRUE(Mul->clone()->hasNoUnsignedWrap());
+ EXPECT_TRUE(Mul->clone()->hasNoSignedWrap());
+
+ Add->setHasNoUnsignedWrap(false);
+ Sub->setHasNoUnsignedWrap(false);
+ Mul->setHasNoUnsignedWrap(false);
+
+ EXPECT_FALSE(Add->clone()->hasNoUnsignedWrap());
+ EXPECT_TRUE(Add->clone()->hasNoSignedWrap());
+ EXPECT_FALSE(Sub->clone()->hasNoUnsignedWrap());
+ EXPECT_TRUE(Sub->clone()->hasNoSignedWrap());
+ EXPECT_FALSE(Mul->clone()->hasNoUnsignedWrap());
+ EXPECT_TRUE(Mul->clone()->hasNoSignedWrap());
+}
+
+TEST(CloneInstruction, Inbounds) {
+ LLVMContext context;
+ Value *V = new Argument(Type::getInt32PtrTy(context));
+ Constant *Z = Constant::getNullValue(Type::getInt32Ty(context));
+ std::vector<Value *> ops;
+ ops.push_back(Z);
+ GetElementPtrInst *GEP = GetElementPtrInst::Create(V, ops.begin(), ops.end());
+ EXPECT_FALSE(GEP->clone()->isInBounds());
+
+ GEP->setIsInBounds();
+ EXPECT_TRUE(GEP->clone()->isInBounds());
+}
+
+TEST(CloneInstruction, Exact) {
+ LLVMContext context;
+ Value *V = new Argument(Type::getInt32Ty(context));
+
+ BinaryOperator *SDiv = BinaryOperator::Create(Instruction::SDiv, V, V);
+ EXPECT_FALSE(SDiv->clone()->isExact());
+
+ SDiv->setIsExact(true);
+ EXPECT_TRUE(SDiv->clone()->isExact());
+}
diff --git a/unittests/Transforms/Utils/Makefile b/unittests/Transforms/Utils/Makefile
new file mode 100644
index 0000000..fdf4be0
--- /dev/null
+++ b/unittests/Transforms/Utils/Makefile
@@ -0,0 +1,15 @@
+##===- unittests/Transforms/Utils/Makefile -----------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+TESTNAME = Utils
+LINK_COMPONENTS := core support transformutils
+
+include $(LEVEL)/Makefile.config
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/VMCore/ConstantsTest.cpp b/unittests/VMCore/ConstantsTest.cpp
index 519d928..8f28407 100644
--- a/unittests/VMCore/ConstantsTest.cpp
+++ b/unittests/VMCore/ConstantsTest.cpp
@@ -9,13 +9,14 @@
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/LLVMContext.h"
#include "gtest/gtest.h"
namespace llvm {
namespace {
TEST(ConstantsTest, Integer_i1) {
- const IntegerType* Int1 = IntegerType::get(1);
+ const IntegerType* Int1 = IntegerType::get(getGlobalContext(), 1);
Constant* One = ConstantInt::get(Int1, 1, true);
Constant* Zero = ConstantInt::get(Int1, 0);
Constant* NegOne = ConstantInt::get(Int1, static_cast<uint64_t>(-1), true);
@@ -96,7 +97,7 @@ TEST(ConstantsTest, Integer_i1) {
}
TEST(ConstantsTest, IntSigns) {
- const IntegerType* Int8Ty = Type::Int8Ty;
+ const IntegerType* Int8Ty = Type::getInt8Ty(getGlobalContext());
EXPECT_EQ(100, ConstantInt::get(Int8Ty, 100, false)->getSExtValue());
EXPECT_EQ(100, ConstantInt::get(Int8Ty, 100, true)->getSExtValue());
EXPECT_EQ(100, ConstantInt::getSigned(Int8Ty, 100)->getSExtValue());
diff --git a/unittests/VMCore/MetadataTest.cpp b/unittests/VMCore/MetadataTest.cpp
index 2de3a92..b92b068 100644
--- a/unittests/VMCore/MetadataTest.cpp
+++ b/unittests/VMCore/MetadataTest.cpp
@@ -10,22 +10,24 @@
#include "gtest/gtest.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
-#include "llvm/MDNode.h"
+#include "llvm/Metadata.h"
+#include "llvm/Module.h"
#include "llvm/Type.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ValueHandle.h"
-#include <sstream>
-
using namespace llvm;
namespace {
+LLVMContext &Context = getGlobalContext();
+
// Test that construction of MDString with different value produces different
// MDString objects, even with the same string pointer and nulls in the string.
TEST(MDStringTest, CreateDifferent) {
char x[3] = { 'f', 0, 'A' };
- MDString *s1 = MDString::get(&x[0], &x[3]);
+ MDString *s1 = MDString::get(Context, StringRef(&x[0], 3));
x[2] = 'B';
- MDString *s2 = MDString::get(&x[0], &x[3]);
+ MDString *s2 = MDString::get(Context, StringRef(&x[0], 3));
EXPECT_NE(s1, s2);
}
@@ -35,8 +37,8 @@ TEST(MDStringTest, CreateSame) {
char x[4] = { 'a', 'b', 'c', 'X' };
char y[4] = { 'a', 'b', 'c', 'Y' };
- MDString *s1 = MDString::get(&x[0], &x[3]);
- MDString *s2 = MDString::get(&y[0], &y[3]);
+ MDString *s1 = MDString::get(Context, StringRef(&x[0], 3));
+ MDString *s2 = MDString::get(Context, StringRef(&y[0], 3));
EXPECT_EQ(s1, s2);
}
@@ -44,11 +46,12 @@ TEST(MDStringTest, CreateSame) {
TEST(MDStringTest, PrintingSimple) {
char *str = new char[13];
strncpy(str, "testing 1 2 3", 13);
- MDString *s = MDString::get(str, str+13);
+ MDString *s = MDString::get(Context, StringRef(str, 13));
strncpy(str, "aaaaaaaaaaaaa", 13);
delete[] str;
- std::ostringstream oss;
+ std::string Str;
+ raw_string_ostream oss(Str);
s->print(oss);
EXPECT_STREQ("metadata !\"testing 1 2 3\"", oss.str().c_str());
}
@@ -56,8 +59,9 @@ TEST(MDStringTest, PrintingSimple) {
// Test printing of MDString with non-printable characters.
TEST(MDStringTest, PrintingComplex) {
char str[5] = {0, '\n', '"', '\\', -1};
- MDString *s = MDString::get(str+0, str+5);
- std::ostringstream oss;
+ MDString *s = MDString::get(Context, StringRef(str+0, 5));
+ std::string Str;
+ raw_string_ostream oss(Str);
s->print(oss);
EXPECT_STREQ("metadata !\"\\00\\0A\\22\\5C\\FF\"", oss.str().c_str());
}
@@ -67,21 +71,25 @@ TEST(MDNodeTest, Simple) {
char x[3] = { 'a', 'b', 'c' };
char y[3] = { '1', '2', '3' };
- MDString *s1 = MDString::get(&x[0], &x[3]);
- MDString *s2 = MDString::get(&y[0], &y[3]);
- ConstantInt *CI = ConstantInt::get(APInt(8, 0));
+ MDString *s1 = MDString::get(Context, StringRef(&x[0], 3));
+ MDString *s2 = MDString::get(Context, StringRef(&y[0], 3));
+ ConstantInt *CI = ConstantInt::get(getGlobalContext(), APInt(8, 0));
std::vector<Value *> V;
V.push_back(s1);
V.push_back(CI);
V.push_back(s2);
- MDNode *n1 = MDNode::get(&V[0], 3);
+ MDNode *n1 = MDNode::get(Context, &V[0], 3);
Value *const c1 = n1;
- MDNode *n2 = MDNode::get(&c1, 1);
- MDNode *n3 = MDNode::get(&V[0], 3);
+ MDNode *n2 = MDNode::get(Context, &c1, 1);
+ MDNode *n3 = MDNode::get(Context, &V[0], 3);
EXPECT_NE(n1, n2);
+#ifdef ENABLE_MDNODE_UNIQUING
EXPECT_EQ(n1, n3);
+#else
+ (void) n3;
+#endif
EXPECT_EQ(3u, n1->getNumElements());
EXPECT_EQ(s1, n1->getElement(0));
@@ -91,49 +99,55 @@ TEST(MDNodeTest, Simple) {
EXPECT_EQ(1u, n2->getNumElements());
EXPECT_EQ(n1, n2->getElement(0));
- std::ostringstream oss1, oss2;
- n1->print(oss1);
- n2->print(oss2);
- EXPECT_STREQ("metadata !{metadata !\"abc\", i8 0, metadata !\"123\"}",
- oss1.str().c_str());
- EXPECT_STREQ("metadata !{metadata !{metadata !\"abc\", i8 0, "
- "metadata !\"123\"}}",
- oss2.str().c_str());
-}
-
-TEST(MDNodeTest, RAUW) {
- Constant *C = ConstantInt::get(Type::Int32Ty, 1);
- Instruction *I = new BitCastInst(C, Type::Int32Ty);
-
- Value *const V1 = I;
- MDNode *n1 = MDNode::get(&V1, 1);
- WeakVH wn1 = n1;
-
- Value *const V2 = C;
- MDNode *n2 = MDNode::get(&V2, 1);
- WeakVH wn2 = n2;
-
- EXPECT_NE(wn1, wn2);
-
- I->replaceAllUsesWith(C);
-
- EXPECT_EQ(wn1, wn2);
+ std::string Str;
+ raw_string_ostream oss(Str);
+ n1->print(oss);
+ EXPECT_STREQ("!0 = metadata !{metadata !\"abc\", i8 0, metadata !\"123\"}\n",
+ oss.str().c_str());
+ Str.clear();
+ n2->print(oss);
+ EXPECT_STREQ("!0 = metadata !{metadata !1}\n"
+ "!1 = metadata !{metadata !\"abc\", i8 0, metadata !\"123\"}\n",
+ oss.str().c_str());
}
TEST(MDNodeTest, Delete) {
- Constant *C = ConstantInt::get(Type::Int32Ty, 1);
- Instruction *I = new BitCastInst(C, Type::Int32Ty);
+ Constant *C = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 1);
+ Instruction *I = new BitCastInst(C, Type::getInt32Ty(getGlobalContext()));
Value *const V = I;
- MDNode *n = MDNode::get(&V, 1);
+ MDNode *n = MDNode::get(Context, &V, 1);
WeakVH wvh = n;
EXPECT_EQ(n, wvh);
delete I;
- std::ostringstream oss;
+ std::string Str;
+ raw_string_ostream oss(Str);
wvh->print(oss);
- EXPECT_STREQ("metadata !{null}", oss.str().c_str());
+ EXPECT_STREQ("!0 = metadata !{null}\n", oss.str().c_str());
+}
+
+TEST(NamedMDNodeTest, Search) {
+ Constant *C = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 1);
+ Constant *C2 = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 2);
+
+ Value *const V = C;
+ Value *const V2 = C2;
+ MDNode *n = MDNode::get(Context, &V, 1);
+ MDNode *n2 = MDNode::get(Context, &V2, 1);
+
+ MetadataBase *Nodes[2] = { n, n2 };
+
+ Module *M = new Module("MyModule", getGlobalContext());
+ const char *Name = "llvm.NMD1";
+ NamedMDNode *NMD = NamedMDNode::Create(getGlobalContext(), Name, &Nodes[0], 2, M);
+ std::string Str;
+ raw_string_ostream oss(Str);
+ NMD->print(oss);
+ EXPECT_STREQ("!llvm.NMD1 = !{!0, !1}\n!0 = metadata !{i32 1}\n"
+ "!1 = metadata !{i32 2}\n",
+ oss.str().c_str());
}
}
diff --git a/unittests/VMCore/PassManagerTest.cpp b/unittests/VMCore/PassManagerTest.cpp
index 8122e2c..cb8f9eb 100644
--- a/unittests/VMCore/PassManagerTest.cpp
+++ b/unittests/VMCore/PassManagerTest.cpp
@@ -154,7 +154,7 @@ namespace llvm {
struct CGPass : public PassTest<CallGraph, CallGraphSCCPass> {
public:
- virtual bool runOnSCC(const std::vector<CallGraphNode*> &SCMM) {
+ virtual bool runOnSCC(std::vector<CallGraphNode*> &SCMM) {
EXPECT_TRUE(getAnalysisIfAvailable<TargetData>());
run();
return false;
@@ -272,7 +272,7 @@ namespace llvm {
char OnTheFlyTest::ID=0;
TEST(PassManager, RunOnce) {
- Module M("test-once", *new LLVMContext());
+ Module M("test-once", getGlobalContext());
struct ModuleNDNM *mNDNM = new ModuleNDNM();
struct ModuleDNM *mDNM = new ModuleDNM();
struct ModuleNDM *mNDM = new ModuleNDM();
@@ -296,7 +296,7 @@ namespace llvm {
}
TEST(PassManager, ReRun) {
- Module M("test-rerun", *new LLVMContext());
+ Module M("test-rerun", getGlobalContext());
struct ModuleNDNM *mNDNM = new ModuleNDNM();
struct ModuleDNM *mDNM = new ModuleDNM();
struct ModuleNDM *mNDM = new ModuleNDM();
@@ -387,7 +387,7 @@ namespace llvm {
Module* makeLLVMModule() {
// Module Construction
- Module* mod = new Module("test-mem", *new LLVMContext());
+ Module* mod = new Module("test-mem", getGlobalContext());
mod->setDataLayout("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
"a0:0:64-s0:64:64-f80:128:128");
@@ -396,14 +396,14 @@ namespace llvm {
// Type Definitions
std::vector<const Type*>FuncTy_0_args;
FunctionType* FuncTy_0 = FunctionType::get(
- /*Result=*/IntegerType::get(32),
+ /*Result=*/IntegerType::get(getGlobalContext(), 32),
/*Params=*/FuncTy_0_args,
/*isVarArg=*/false);
std::vector<const Type*>FuncTy_2_args;
- FuncTy_2_args.push_back(IntegerType::get(1));
+ FuncTy_2_args.push_back(IntegerType::get(getGlobalContext(), 1));
FunctionType* FuncTy_2 = FunctionType::get(
- /*Result=*/Type::VoidTy,
+ /*Result=*/Type::getVoidTy(getGlobalContext()),
/*Params=*/FuncTy_2_args,
/*isVarArg=*/false);
@@ -454,7 +454,7 @@ namespace llvm {
// Function: test1 (func_test1)
{
- BasicBlock* label_entry = BasicBlock::Create("entry",func_test1,0);
+ BasicBlock* label_entry = BasicBlock::Create(getGlobalContext(), "entry",func_test1,0);
// Block entry (label_entry)
CallInst* int32_3 = CallInst::Create(func_test2, "", label_entry);
@@ -462,14 +462,14 @@ namespace llvm {
int32_3->setTailCall(false);AttrListPtr int32_3_PAL;
int32_3->setAttributes(int32_3_PAL);
- ReturnInst::Create(int32_3, label_entry);
+ ReturnInst::Create(getGlobalContext(), int32_3, label_entry);
}
// Function: test2 (func_test2)
{
- BasicBlock* label_entry_5 = BasicBlock::Create("entry",func_test2,0);
+ BasicBlock* label_entry_5 = BasicBlock::Create(getGlobalContext(), "entry",func_test2,0);
// Block entry (label_entry_5)
CallInst* int32_6 = CallInst::Create(func_test3, "", label_entry_5);
@@ -477,14 +477,14 @@ namespace llvm {
int32_6->setTailCall(false);AttrListPtr int32_6_PAL;
int32_6->setAttributes(int32_6_PAL);
- ReturnInst::Create(int32_6, label_entry_5);
+ ReturnInst::Create(getGlobalContext(), int32_6, label_entry_5);
}
// Function: test3 (func_test3)
{
- BasicBlock* label_entry_8 = BasicBlock::Create("entry",func_test3,0);
+ BasicBlock* label_entry_8 = BasicBlock::Create(getGlobalContext(), "entry",func_test3,0);
// Block entry (label_entry_8)
CallInst* int32_9 = CallInst::Create(func_test1, "", label_entry_8);
@@ -492,7 +492,7 @@ namespace llvm {
int32_9->setTailCall(false);AttrListPtr int32_9_PAL;
int32_9->setAttributes(int32_9_PAL);
- ReturnInst::Create(int32_9, label_entry_8);
+ ReturnInst::Create(getGlobalContext(), int32_9, label_entry_8);
}
@@ -502,10 +502,10 @@ namespace llvm {
Value* int1_f = args++;
int1_f->setName("f");
- BasicBlock* label_entry_11 = BasicBlock::Create("entry",func_test4,0);
- BasicBlock* label_bb = BasicBlock::Create("bb",func_test4,0);
- BasicBlock* label_bb1 = BasicBlock::Create("bb1",func_test4,0);
- BasicBlock* label_return = BasicBlock::Create("return",func_test4,0);
+ BasicBlock* label_entry_11 = BasicBlock::Create(getGlobalContext(), "entry",func_test4,0);
+ BasicBlock* label_bb = BasicBlock::Create(getGlobalContext(), "bb",func_test4,0);
+ BasicBlock* label_bb1 = BasicBlock::Create(getGlobalContext(), "bb1",func_test4,0);
+ BasicBlock* label_return = BasicBlock::Create(getGlobalContext(), "return",func_test4,0);
// Block entry (label_entry_11)
BranchInst::Create(label_bb, label_entry_11);
@@ -517,7 +517,7 @@ namespace llvm {
BranchInst::Create(label_bb1, label_return, int1_f, label_bb1);
// Block return (label_return)
- ReturnInst::Create(label_return);
+ ReturnInst::Create(getGlobalContext(), label_return);
}
return mod;
OpenPOWER on IntegriCloud