136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===- llvm/unittest/ADT/PointerIntPairTest.cpp - Unit tests --------------===//
236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//                     The LLVM Compiler Infrastructure
436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// This file is distributed under the University of Illinois Open Source
636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// License. See LICENSE.TXT for details.
736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//
836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines//===----------------------------------------------------------------------===//
936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "gtest/gtest.h"
1136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/PointerIntPair.h"
1236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include <limits>
1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesusing namespace llvm;
1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesnamespace {
1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// Test fixture
1836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass PointerIntPairTest : public testing::Test {
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines};
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesTEST_F(PointerIntPairTest, GetSet) {
2236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  PointerIntPair<PointerIntPairTest *, 2> Pair(this, 1U);
2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_EQ(this, Pair.getPointer());
2436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_EQ(1U, Pair.getInt());
2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Pair.setInt(2);
2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_EQ(this, Pair.getPointer());
2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_EQ(2U, Pair.getInt());
2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Pair.setPointer(nullptr);
3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_EQ(nullptr, Pair.getPointer());
3236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_EQ(2U, Pair.getInt());
3336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Pair.setPointerAndInt(this, 3U);
3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_EQ(this, Pair.getPointer());
3636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_EQ(3U, Pair.getInt());
3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesTEST_F(PointerIntPairTest, DefaultInitialize) {
4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  PointerIntPair<PointerIntPairTest *, 2> Pair;
4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_EQ(nullptr, Pair.getPointer());
4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_EQ(0U, Pair.getInt());
4336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#if !(defined(_MSC_VER) && _MSC_VER==1700)
4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesTEST_F(PointerIntPairTest, ManyUnusedBits) {
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // In real code this would be a word-sized integer limited to 31 bits.
4836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct Fixnum31 {
4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uintptr_t Value;
5036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  class FixnumPointerTraits {
5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  public:
5336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    static inline void *getAsVoidPointer(Fixnum31 Num) {
5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return reinterpret_cast<void *>(Num.Value << NumLowBitsAvailable);
5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    static inline Fixnum31 getFromVoidPointer(void *P) {
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // In real code this would assert that the value is in range.
5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return { reinterpret_cast<uintptr_t>(P) >> NumLowBitsAvailable };
5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    enum { NumLowBitsAvailable = std::numeric_limits<uintptr_t>::digits - 31 };
6136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  PointerIntPair<Fixnum31, 1, bool, FixnumPointerTraits> pair;
6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_EQ((uintptr_t)0, pair.getPointer().Value);
6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_FALSE(pair.getInt());
6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  pair.setPointerAndInt({ 0x7FFFFFFF }, true );
6836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_EQ((uintptr_t)0x7FFFFFFF, pair.getPointer().Value);
6936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_TRUE(pair.getInt());
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  EXPECT_EQ(FixnumPointerTraits::NumLowBitsAvailable - 1,
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            PointerLikeTypeTraits<decltype(pair)>::NumLowBitsAvailable);
7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
7436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#endif
7536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
7636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} // end anonymous namespace
77