summaryrefslogtreecommitdiffstats
path: root/unittests/Support
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/Support')
-rw-r--r--unittests/Support/Makefile15
-rw-r--r--unittests/Support/MathExtrasTest.cpp104
-rw-r--r--unittests/Support/TypeBuilderTest.cpp233
-rw-r--r--unittests/Support/ValueHandleTest.cpp317
-rw-r--r--unittests/Support/raw_ostream_test.cpp85
5 files changed, 754 insertions, 0 deletions
diff --git a/unittests/Support/Makefile b/unittests/Support/Makefile
new file mode 100644
index 0000000..815bdd2
--- /dev/null
+++ b/unittests/Support/Makefile
@@ -0,0 +1,15 @@
+##===- unittests/ADT/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 = Support
+LINK_COMPONENTS := core support
+
+include $(LEVEL)/Makefile.config
+include $(LLVM_SRC_ROOT)/unittests/Makefile.unittest
diff --git a/unittests/Support/MathExtrasTest.cpp b/unittests/Support/MathExtrasTest.cpp
new file mode 100644
index 0000000..1f19468
--- /dev/null
+++ b/unittests/Support/MathExtrasTest.cpp
@@ -0,0 +1,104 @@
+//===- llvm/unittest/Support/MathExtrasTest.cpp - math utils 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/MathExtras.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(MathExtras, isPowerOf2_32) {
+ EXPECT_TRUE(isPowerOf2_32(1 << 6));
+ EXPECT_TRUE(isPowerOf2_32(1 << 12));
+ EXPECT_FALSE(isPowerOf2_32((1 << 19) + 3));
+ EXPECT_FALSE(isPowerOf2_32(0xABCDEF0));
+}
+
+TEST(MathExtras, isPowerOf2_64) {
+ EXPECT_TRUE(isPowerOf2_64(1LL << 46));
+ EXPECT_TRUE(isPowerOf2_64(1LL << 12));
+ EXPECT_FALSE(isPowerOf2_64((1LL << 53) + 3));
+ EXPECT_FALSE(isPowerOf2_64(0xABCDEF0ABCDEF0LL));
+}
+
+TEST(MathExtras, ByteSwap_32) {
+ EXPECT_EQ(0x44332211u, ByteSwap_32(0x11223344));
+ EXPECT_EQ(0xDDCCBBAAu, ByteSwap_32(0xAABBCCDD));
+}
+
+TEST(MathExtras, ByteSwap_64) {
+ EXPECT_EQ(0x8877665544332211ULL, ByteSwap_64(0x1122334455667788LL));
+ EXPECT_EQ(0x1100FFEEDDCCBBAAULL, ByteSwap_64(0xAABBCCDDEEFF0011LL));
+}
+
+TEST(MathExtras, CountLeadingZeros_32) {
+ EXPECT_EQ(8u, CountLeadingZeros_32(0x00F000FF));
+ EXPECT_EQ(8u, CountLeadingZeros_32(0x00F12345));
+ for (unsigned i = 0; i <= 30; ++i) {
+ EXPECT_EQ(31 - i, CountLeadingZeros_32(1 << i));
+ }
+}
+
+TEST(MathExtras, CountLeadingZeros_64) {
+ EXPECT_EQ(8u, CountLeadingZeros_64(0x00F1234500F12345LL));
+ EXPECT_EQ(1u, CountLeadingZeros_64(1LL << 62));
+ for (unsigned i = 0; i <= 62; ++i) {
+ EXPECT_EQ(63 - i, CountLeadingZeros_64(1LL << i));
+ }
+}
+
+TEST(MathExtras, CountLeadingOnes_32) {
+ for (int i = 30; i >= 0; --i) {
+ // Start with all ones and unset some bit.
+ EXPECT_EQ(31u - i, CountLeadingOnes_32(0xFFFFFFFF ^ (1 << i)));
+ }
+}
+
+TEST(MathExtras, CountLeadingOnes_64) {
+ for (int i = 62; i >= 0; --i) {
+ // Start with all ones and unset some bit.
+ EXPECT_EQ(63u - i, CountLeadingOnes_64(0xFFFFFFFFFFFFFFFFLL ^ (1LL << i)));
+ }
+ for (int i = 30; i >= 0; --i) {
+ // Start with all ones and unset some bit.
+ EXPECT_EQ(31u - i, CountLeadingOnes_32(0xFFFFFFFF ^ (1 << i)));
+ }
+}
+
+TEST(MathExtras, FloatBits) {
+ static const float kValue = 5632.34;
+ EXPECT_FLOAT_EQ(kValue, BitsToFloat(FloatToBits(kValue)));
+}
+
+TEST(MathExtras, DoubleBits) {
+ static const double kValue = 87987234.983498;
+ EXPECT_FLOAT_EQ(kValue, BitsToDouble(DoubleToBits(kValue)));
+}
+
+TEST(MathExtras, MinAlign) {
+ EXPECT_EQ(1u, MinAlign(2, 3));
+ EXPECT_EQ(2u, MinAlign(2, 4));
+ EXPECT_EQ(1u, MinAlign(17, 64));
+ EXPECT_EQ(256u, MinAlign(256, 512));
+}
+
+TEST(MathExtras, NextPowerOf2) {
+ EXPECT_EQ(4u, NextPowerOf2(3));
+ EXPECT_EQ(16u, NextPowerOf2(15));
+ EXPECT_EQ(256u, NextPowerOf2(128));
+}
+
+TEST(MathExtras, RoundUpToAlignment) {
+ EXPECT_EQ(8u, RoundUpToAlignment(5, 8));
+ EXPECT_EQ(24u, RoundUpToAlignment(17, 8));
+ EXPECT_EQ(0u, RoundUpToAlignment(~0LL, 8));
+}
+
+}
diff --git a/unittests/Support/TypeBuilderTest.cpp b/unittests/Support/TypeBuilderTest.cpp
new file mode 100644
index 0000000..425ee6b
--- /dev/null
+++ b/unittests/Support/TypeBuilderTest.cpp
@@ -0,0 +1,233 @@
+//===- llvm/unittest/Support/TypeBuilderTest.cpp - TypeBuilder 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/TypeBuilder.h"
+
+#include "gtest/gtest.h"
+
+using namespace llvm;
+
+namespace {
+
+TEST(TypeBuilderTest, Void) {
+ EXPECT_EQ(Type::VoidTy, (TypeBuilder<void, true>::get()));
+ EXPECT_EQ(Type::VoidTy, (TypeBuilder<void, false>::get()));
+ // Special case for C compatibility:
+ EXPECT_EQ(PointerType::getUnqual(Type::Int8Ty),
+ (TypeBuilder<void*, false>::get()));
+}
+
+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()));
+}
+
+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()));
+}
+
+TEST(TypeBuilderTest, Float) {
+ EXPECT_EQ(Type::FloatTy, (TypeBuilder<float, false>::get()));
+ EXPECT_EQ(Type::DoubleTy, (TypeBuilder<double, false>::get()));
+ // 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()));
+}
+
+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()));
+}
+
+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),
+ (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),
+ (TypeBuilder<int8_t(int32_t*, void*, char, char, char),
+ false>::get()));
+ EXPECT_EQ(FunctionType::get(Type::Int8Ty, params, true),
+ (TypeBuilder<int8_t(int32_t*, char*, char, char, char, ...),
+ false>::get()));
+}
+
+class MyType {
+ int a;
+ int *b;
+ void *array[1];
+};
+
+class MyPortableType {
+ int32_t a;
+ int32_t *b;
+ void *array[1];
+};
+
+} // anonymous namespace
+
+namespace llvm {
+template<bool cross> class TypeBuilder<MyType, cross> {
+public:
+ static const StructType *get() {
+ // 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);
+ return result;
+ }
+
+ // You may find this a convenient place to put some constants
+ // to help with getelementptr. They don't have any effect on
+ // the operation of TypeBuilder.
+ enum Fields {
+ FIELD_A,
+ FIELD_B,
+ FIELD_ARRAY
+ };
+};
+
+template<bool cross> class TypeBuilder<MyPortableType, cross> {
+public:
+ static const StructType *get() {
+ // 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);
+ return result;
+ }
+
+ // You may find this a convenient place to put some constants
+ // to help with getelementptr. They don't have any effect on
+ // the operation of TypeBuilder.
+ enum Fields {
+ FIELD_A,
+ FIELD_B,
+ FIELD_ARRAY
+ };
+};
+} // namespace llvm
+namespace {
+
+TEST(TypeBuilderTest, Extensions) {
+ EXPECT_EQ(PointerType::getUnqual(StructType::get(
+ TypeBuilder<int, false>::get(),
+ TypeBuilder<int*, false>::get(),
+ TypeBuilder<void*[], false>::get(),
+ 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(),
+ 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(),
+ NULL)),
+ (TypeBuilder<MyPortableType*, true>::get()));
+}
+
+} // anonymous namespace
diff --git a/unittests/Support/ValueHandleTest.cpp b/unittests/Support/ValueHandleTest.cpp
new file mode 100644
index 0000000..336e7d9
--- /dev/null
+++ b/unittests/Support/ValueHandleTest.cpp
@@ -0,0 +1,317 @@
+//===- llvm/unittest/Support/ValueHandleTest.cpp - ValueHandle 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/ValueHandle.h"
+
+#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
+
+#include "gtest/gtest.h"
+
+#include <memory>
+
+using namespace llvm;
+
+namespace {
+
+class ValueHandle : public testing::Test {
+protected:
+ Constant *ConstantV;
+ std::auto_ptr<BitCastInst> BitcastV;
+
+ ValueHandle() : ConstantV(ConstantInt::get(Type::Int32Ty, 0)),
+ BitcastV(new BitCastInst(ConstantV, Type::Int32Ty)) {
+ }
+};
+
+class ConcreteCallbackVH : public CallbackVH {
+public:
+ ConcreteCallbackVH() : CallbackVH() {}
+ ConcreteCallbackVH(Value *V) : CallbackVH(V) {}
+};
+
+TEST_F(ValueHandle, WeakVH_BasicOperation) {
+ WeakVH WVH(BitcastV.get());
+ EXPECT_EQ(BitcastV.get(), WVH);
+ WVH = ConstantV;
+ EXPECT_EQ(ConstantV, WVH);
+
+ // 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());
+}
+
+TEST_F(ValueHandle, WeakVH_Comparisons) {
+ WeakVH BitcastWVH(BitcastV.get());
+ WeakVH ConstantWVH(ConstantV);
+
+ EXPECT_TRUE(BitcastWVH == BitcastWVH);
+ EXPECT_TRUE(BitcastV.get() == BitcastWVH);
+ EXPECT_TRUE(BitcastWVH == BitcastV.get());
+ EXPECT_FALSE(BitcastWVH == ConstantWVH);
+
+ EXPECT_TRUE(BitcastWVH != ConstantWVH);
+ EXPECT_TRUE(BitcastV.get() != ConstantWVH);
+ EXPECT_TRUE(BitcastWVH != ConstantV);
+ EXPECT_FALSE(BitcastWVH != BitcastWVH);
+
+ // Cast to Value* so comparisons work.
+ Value *BV = BitcastV.get();
+ Value *CV = ConstantV;
+ EXPECT_EQ(BV < CV, BitcastWVH < ConstantWVH);
+ EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantWVH);
+ EXPECT_EQ(BV > CV, BitcastWVH > ConstantWVH);
+ EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantWVH);
+
+ EXPECT_EQ(BV < CV, BitcastV.get() < ConstantWVH);
+ EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantWVH);
+ EXPECT_EQ(BV > CV, BitcastV.get() > ConstantWVH);
+ EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantWVH);
+
+ EXPECT_EQ(BV < CV, BitcastWVH < ConstantV);
+ EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantV);
+ EXPECT_EQ(BV > CV, BitcastWVH > ConstantV);
+ EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantV);
+}
+
+TEST_F(ValueHandle, WeakVH_FollowsRAUW) {
+ WeakVH WVH(BitcastV.get());
+ WeakVH WVH_Copy(WVH);
+ WeakVH WVH_Recreated(BitcastV.get());
+ BitcastV->replaceAllUsesWith(ConstantV);
+ EXPECT_EQ(ConstantV, WVH);
+ EXPECT_EQ(ConstantV, WVH_Copy);
+ EXPECT_EQ(ConstantV, WVH_Recreated);
+}
+
+TEST_F(ValueHandle, WeakVH_NullOnDeletion) {
+ WeakVH WVH(BitcastV.get());
+ WeakVH WVH_Copy(WVH);
+ WeakVH WVH_Recreated(BitcastV.get());
+ BitcastV.reset();
+ Value *null_value = NULL;
+ EXPECT_EQ(null_value, WVH);
+ EXPECT_EQ(null_value, WVH_Copy);
+ EXPECT_EQ(null_value, WVH_Recreated);
+}
+
+
+TEST_F(ValueHandle, AssertingVH_BasicOperation) {
+ AssertingVH<CastInst> AVH(BitcastV.get());
+ CastInst *implicit_to_exact_type = AVH;
+ implicit_to_exact_type = implicit_to_exact_type; // Avoid warning.
+
+ AssertingVH<Value> GenericAVH(BitcastV.get());
+ EXPECT_EQ(BitcastV.get(), GenericAVH);
+ GenericAVH = ConstantV;
+ EXPECT_EQ(ConstantV, GenericAVH);
+
+ // Make sure I can call a method on the underlying CastInst. It
+ // doesn't matter which method.
+ EXPECT_FALSE(AVH->mayWriteToMemory());
+ EXPECT_FALSE((*AVH).mayWriteToMemory());
+}
+
+TEST_F(ValueHandle, AssertingVH_Comparisons) {
+ AssertingVH<Value> BitcastAVH(BitcastV.get());
+ AssertingVH<Value> ConstantAVH(ConstantV);
+
+ EXPECT_TRUE(BitcastAVH == BitcastAVH);
+ EXPECT_TRUE(BitcastV.get() == BitcastAVH);
+ EXPECT_TRUE(BitcastAVH == BitcastV.get());
+ EXPECT_FALSE(BitcastAVH == ConstantAVH);
+
+ EXPECT_TRUE(BitcastAVH != ConstantAVH);
+ EXPECT_TRUE(BitcastV.get() != ConstantAVH);
+ EXPECT_TRUE(BitcastAVH != ConstantV);
+ EXPECT_FALSE(BitcastAVH != BitcastAVH);
+
+ // Cast to Value* so comparisons work.
+ Value *BV = BitcastV.get();
+ Value *CV = ConstantV;
+ EXPECT_EQ(BV < CV, BitcastAVH < ConstantAVH);
+ EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantAVH);
+ EXPECT_EQ(BV > CV, BitcastAVH > ConstantAVH);
+ EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantAVH);
+
+ EXPECT_EQ(BV < CV, BitcastV.get() < ConstantAVH);
+ EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantAVH);
+ EXPECT_EQ(BV > CV, BitcastV.get() > ConstantAVH);
+ EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantAVH);
+
+ EXPECT_EQ(BV < CV, BitcastAVH < ConstantV);
+ EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantV);
+ EXPECT_EQ(BV > CV, BitcastAVH > ConstantV);
+ EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantV);
+}
+
+TEST_F(ValueHandle, AssertingVH_DoesNotFollowRAUW) {
+ AssertingVH<Value> AVH(BitcastV.get());
+ BitcastV->replaceAllUsesWith(ConstantV);
+ EXPECT_EQ(BitcastV.get(), AVH);
+}
+
+#ifdef NDEBUG
+
+TEST_F(ValueHandle, AssertingVH_ReducesToPointer) {
+ EXPECT_EQ(sizeof(CastInst *), sizeof(AssertingVH<CastInst>));
+}
+
+#else // !NDEBUG
+
+#ifdef GTEST_HAS_DEATH_TEST
+
+TEST_F(ValueHandle, AssertingVH_Asserts) {
+ AssertingVH<Value> AVH(BitcastV.get());
+ EXPECT_DEATH({BitcastV.reset();},
+ "An asserting value handle still pointed to this value!");
+ AssertingVH<Value> Copy(AVH);
+ AVH = NULL;
+ EXPECT_DEATH({BitcastV.reset();},
+ "An asserting value handle still pointed to this value!");
+ Copy = NULL;
+ BitcastV.reset();
+}
+
+#endif // GTEST_HAS_DEATH_TEST
+
+#endif // NDEBUG
+
+TEST_F(ValueHandle, CallbackVH_BasicOperation) {
+ ConcreteCallbackVH CVH(BitcastV.get());
+ EXPECT_EQ(BitcastV.get(), CVH);
+ CVH = ConstantV;
+ EXPECT_EQ(ConstantV, CVH);
+
+ // 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());
+}
+
+TEST_F(ValueHandle, CallbackVH_Comparisons) {
+ ConcreteCallbackVH BitcastCVH(BitcastV.get());
+ ConcreteCallbackVH ConstantCVH(ConstantV);
+
+ EXPECT_TRUE(BitcastCVH == BitcastCVH);
+ EXPECT_TRUE(BitcastV.get() == BitcastCVH);
+ EXPECT_TRUE(BitcastCVH == BitcastV.get());
+ EXPECT_FALSE(BitcastCVH == ConstantCVH);
+
+ EXPECT_TRUE(BitcastCVH != ConstantCVH);
+ EXPECT_TRUE(BitcastV.get() != ConstantCVH);
+ EXPECT_TRUE(BitcastCVH != ConstantV);
+ EXPECT_FALSE(BitcastCVH != BitcastCVH);
+
+ // Cast to Value* so comparisons work.
+ Value *BV = BitcastV.get();
+ Value *CV = ConstantV;
+ EXPECT_EQ(BV < CV, BitcastCVH < ConstantCVH);
+ EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantCVH);
+ EXPECT_EQ(BV > CV, BitcastCVH > ConstantCVH);
+ EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantCVH);
+
+ EXPECT_EQ(BV < CV, BitcastV.get() < ConstantCVH);
+ EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantCVH);
+ EXPECT_EQ(BV > CV, BitcastV.get() > ConstantCVH);
+ EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantCVH);
+
+ EXPECT_EQ(BV < CV, BitcastCVH < ConstantV);
+ EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantV);
+ EXPECT_EQ(BV > CV, BitcastCVH > ConstantV);
+ EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantV);
+}
+
+TEST_F(ValueHandle, CallbackVH_CallbackOnDeletion) {
+ class RecordingVH : public CallbackVH {
+ public:
+ int DeletedCalls;
+ int AURWCalls;
+
+ RecordingVH() : DeletedCalls(0), AURWCalls(0) {}
+ RecordingVH(Value *V) : CallbackVH(V), DeletedCalls(0), AURWCalls(0) {}
+
+ private:
+ virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
+ virtual void allUsesReplacedWith(Value *) { AURWCalls++; }
+ };
+
+ RecordingVH RVH;
+ RVH = BitcastV.get();
+ EXPECT_EQ(0, RVH.DeletedCalls);
+ EXPECT_EQ(0, RVH.AURWCalls);
+ BitcastV.reset();
+ EXPECT_EQ(1, RVH.DeletedCalls);
+ EXPECT_EQ(0, RVH.AURWCalls);
+}
+
+TEST_F(ValueHandle, CallbackVH_CallbackOnRAUW) {
+ class RecordingVH : public CallbackVH {
+ public:
+ int DeletedCalls;
+ Value *AURWArgument;
+
+ RecordingVH() : DeletedCalls(0), AURWArgument(NULL) {}
+ RecordingVH(Value *V)
+ : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL) {}
+
+ private:
+ virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
+ virtual void allUsesReplacedWith(Value *new_value) {
+ EXPECT_EQ(NULL, AURWArgument);
+ AURWArgument = new_value;
+ }
+ };
+
+ RecordingVH RVH;
+ RVH = BitcastV.get();
+ EXPECT_EQ(0, RVH.DeletedCalls);
+ EXPECT_EQ(NULL, RVH.AURWArgument);
+ BitcastV->replaceAllUsesWith(ConstantV);
+ EXPECT_EQ(0, RVH.DeletedCalls);
+ EXPECT_EQ(ConstantV, RVH.AURWArgument);
+}
+
+TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
+ class RecoveringVH : public CallbackVH {
+ public:
+ int DeletedCalls;
+ Value *AURWArgument;
+
+ RecoveringVH() : DeletedCalls(0), AURWArgument(NULL) {}
+ RecoveringVH(Value *V)
+ : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL) {}
+
+ private:
+ virtual void deleted() {
+ getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::Int32Ty));
+ setValPtr(NULL);
+ }
+ virtual void allUsesReplacedWith(Value *new_value) {
+ ASSERT_TRUE(NULL != getValPtr());
+ EXPECT_EQ(1U, getValPtr()->getNumUses());
+ EXPECT_EQ(NULL, AURWArgument);
+ AURWArgument = new_value;
+ }
+ };
+
+ // Normally, if a value has uses, deleting it will crash. However, we can use
+ // a CallbackVH to remove the uses before the check for no uses.
+ RecoveringVH RVH;
+ RVH = BitcastV.get();
+ std::auto_ptr<BinaryOperator> BitcastUser(
+ BinaryOperator::CreateAdd(RVH, Constant::getNullValue(Type::Int32Ty)));
+ 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));
+}
+
+}
diff --git a/unittests/Support/raw_ostream_test.cpp b/unittests/Support/raw_ostream_test.cpp
new file mode 100644
index 0000000..feb0152
--- /dev/null
+++ b/unittests/Support/raw_ostream_test.cpp
@@ -0,0 +1,85 @@
+//===- llvm/unittest/Support/raw_ostream_test.cpp - raw_ostream 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/raw_ostream.h"
+
+using namespace llvm;
+
+namespace {
+
+template<typename T> std::string printToString(const T &Value) {
+ std::string res;
+ llvm::raw_string_ostream(res) << Value;
+ return res;
+}
+
+template<typename T> std::string printToStringUnbuffered(const T &Value) {
+ std::string res;
+ llvm::raw_string_ostream OS(res);
+ OS.SetUnbuffered();
+ OS << Value;
+ return res;
+}
+
+TEST(raw_ostreamTest, Types_Buffered) {
+ // Char
+ EXPECT_EQ("c", printToString('c'));
+
+ // String
+ EXPECT_EQ("hello", printToString("hello"));
+ EXPECT_EQ("hello", printToString(std::string("hello")));
+
+ // Int
+ EXPECT_EQ("0", printToString(0));
+ EXPECT_EQ("2425", printToString(2425));
+ EXPECT_EQ("-2425", printToString(-2425));
+
+ // Long long
+ EXPECT_EQ("0", printToString(0LL));
+ EXPECT_EQ("257257257235709", printToString(257257257235709LL));
+ EXPECT_EQ("-257257257235709", printToString(-257257257235709LL));
+
+ // Double
+ EXPECT_EQ("1.100000e+00", printToString(1.1));
+
+ // void*
+ EXPECT_EQ("0x0", printToString((void*) 0));
+ EXPECT_EQ("0xbeef", printToString((void*) 0xbeef));
+ EXPECT_EQ("0xdeadbeef", printToString((void*) 0xdeadbeef));
+}
+
+TEST(raw_ostreamTest, Types_Unbuffered) {
+ // Char
+ EXPECT_EQ("c", printToStringUnbuffered('c'));
+
+ // String
+ EXPECT_EQ("hello", printToStringUnbuffered("hello"));
+ EXPECT_EQ("hello", printToStringUnbuffered(std::string("hello")));
+
+ // Int
+ EXPECT_EQ("0", printToStringUnbuffered(0));
+ EXPECT_EQ("2425", printToStringUnbuffered(2425));
+ EXPECT_EQ("-2425", printToStringUnbuffered(-2425));
+
+ // Long long
+ EXPECT_EQ("0", printToStringUnbuffered(0LL));
+ EXPECT_EQ("257257257235709", printToStringUnbuffered(257257257235709LL));
+ EXPECT_EQ("-257257257235709", printToStringUnbuffered(-257257257235709LL));
+
+ // Double
+ EXPECT_EQ("1.100000e+00", printToStringUnbuffered(1.1));
+
+ // void*
+ EXPECT_EQ("0x0", printToStringUnbuffered((void*) 0));
+ EXPECT_EQ("0xbeef", printToStringUnbuffered((void*) 0xbeef));
+ EXPECT_EQ("0xdeadbeef", printToStringUnbuffered((void*) 0xdeadbeef));
+}
+
+}
OpenPOWER on IntegriCloud