fix a bug in post-order iterators with external storage, patch by
[oota-llvm.git] / include / llvm / ADT / PointerIntPair.h
index f189a3285820f1f736cb5468a8d4558f77596a95..0aa478b1ff61cd7117d06ce780d319f11e7959e7 100644 (file)
@@ -30,10 +30,10 @@ struct DenseMapInfo;
 /// type.
 ///
 /// Note that PointerIntPair always puts the Int part in the highest bits
-/// possible.  For example, PointerIntPair<void*, 1,bool> will put the bit for
+/// possible.  For example, PointerIntPair<void*, 1, bool> will put the bit for
 /// the bool into bit #2, not bit #0, which allows the low two bits to be used
 /// for something else.  For example, this allows:
-///   PointerIntPair<PointerIntPair<void*, 1,bool>, 1, bool>
+///   PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool>
 /// ... and the two bools will land in different bits.
 ///
 template <typename PointerTy, unsigned IntBits, typename IntType=unsigned,
@@ -42,16 +42,18 @@ class PointerIntPair {
   intptr_t Value;
   enum {
     /// PointerBitMask - The bits that come from the pointer.
-    PointerBitMask = ~(((intptr_t)1 << PtrTraits::NumLowBitsAvailable)-1),
+    PointerBitMask =
+      ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable)-1),
+
     /// IntShift - The number of low bits that we reserve for other uses, and
     /// keep zero.
-    IntShift = PtrTraits::NumLowBitsAvailable-IntBits,
+    IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable-IntBits,
     
     /// IntMask - This is the unshifted mask for valid bits of the int type.
-    IntMask = ((intptr_t)1 << IntBits)-1,
+    IntMask = (uintptr_t)(((intptr_t)1 << IntBits)-1),
     
     // ShiftedIntMask - This is the bits for the integer shifted in place.
-    ShiftedIntMask = IntMask << IntShift
+    ShiftedIntMask = (uintptr_t)(IntMask << IntShift)
   };
 public:
   PointerIntPair() : Value(0) {}
@@ -107,11 +109,14 @@ template<typename PointerTy, unsigned IntBits, typename IntType>
 struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
   typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
   static Ty getEmptyKey() {
-    return Ty(reinterpret_cast<PointerTy>(-1 << IntBits),
-              IntType((1 << IntBits)-1));
+    intptr_t Val = -1;
+    Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
+    return Ty(reinterpret_cast<PointerTy>(Val), IntType((1 << IntBits)-1));
   }
   static Ty getTombstoneKey() {
-    return Ty(reinterpret_cast<PointerTy>(-2 << IntBits), IntType(0));
+    intptr_t Val = -2;
+    Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
+    return Ty(reinterpret_cast<PointerTy>(Val), IntType(0));
   }
   static unsigned getHashValue(Ty V) {
     uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
@@ -122,8 +127,10 @@ struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
 };
 
 // Teach SmallPtrSet that PointerIntPair is "basically a pointer".
-template<typename PointerTy, unsigned IntBits, typename IntType>
-class PointerLikeTypeTraits<PointerIntPair<PointerTy, IntBits, IntType> > {
+template<typename PointerTy, unsigned IntBits, typename IntType,
+         typename PtrTraits>
+class PointerLikeTypeTraits<PointerIntPair<PointerTy, IntBits, IntType,
+                                           PtrTraits> > {
 public:
   static inline void *
   getAsVoidPointer(const PointerIntPair<PointerTy, IntBits, IntType> &P) {