Allow PointerIntPairs to be created from const void *.
[oota-llvm.git] / include / llvm / ADT / PointerIntPair.h
1 //===- llvm/ADT/PointerIntPair.h - Pair for pointer and int -----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the PointerIntPair class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_ADT_POINTERINTPAIR_H
15 #define LLVM_ADT_POINTERINTPAIR_H
16
17 #include "llvm/Support/PointerLikeTypeTraits.h"
18 #include <cassert>
19
20 namespace llvm {
21
22 template<typename T>
23 struct DenseMapInfo;
24
25 /// PointerIntPair - This class implements a pair of a pointer and small
26 /// integer.  It is designed to represent this in the space required by one
27 /// pointer by bitmangling the integer into the low part of the pointer.  This
28 /// can only be done for small integers: typically up to 3 bits, but it depends
29 /// on the number of bits available according to PointerLikeTypeTraits for the
30 /// type.
31 ///
32 /// Note that PointerIntPair always puts the Int part in the highest bits
33 /// possible.  For example, PointerIntPair<void*, 1, bool> will put the bit for
34 /// the bool into bit #2, not bit #0, which allows the low two bits to be used
35 /// for something else.  For example, this allows:
36 ///   PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool>
37 /// ... and the two bools will land in different bits.
38 ///
39 template <typename PointerTy, unsigned IntBits, typename IntType=unsigned,
40           typename PtrTraits = PointerLikeTypeTraits<PointerTy> >
41 class PointerIntPair {
42   intptr_t Value;
43   enum {
44     /// PointerBitMask - The bits that come from the pointer.
45     PointerBitMask =
46       ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable)-1),
47
48     /// IntShift - The number of low bits that we reserve for other uses, and
49     /// keep zero.
50     IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable-IntBits,
51     
52     /// IntMask - This is the unshifted mask for valid bits of the int type.
53     IntMask = (uintptr_t)(((intptr_t)1 << IntBits)-1),
54     
55     // ShiftedIntMask - This is the bits for the integer shifted in place.
56     ShiftedIntMask = (uintptr_t)(IntMask << IntShift)
57   };
58 public:
59   PointerIntPair() : Value(0) {}
60   PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) {
61     assert(IntBits <= PtrTraits::NumLowBitsAvailable &&
62            "PointerIntPair formed with integer size too large for pointer");
63     setPointer(Ptr);
64     setInt(Int);
65   }
66
67   PointerTy getPointer() const {
68     return PtrTraits::getFromVoidPointer(
69                          reinterpret_cast<void*>(Value & PointerBitMask));
70   }
71
72   IntType getInt() const {
73     return (IntType)((Value >> IntShift) & IntMask);
74   }
75
76   void setPointer(PointerTy Ptr) {
77     intptr_t PtrVal
78       = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
79     assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 &&
80            "Pointer is not sufficiently aligned");
81     // Preserve all low bits, just update the pointer.
82     Value = PtrVal | (Value & ~PointerBitMask);
83   }
84
85   void setInt(IntType Int) {
86     intptr_t IntVal = Int;
87     assert(IntVal < (1 << IntBits) && "Integer too large for field");
88     
89     // Preserve all bits other than the ones we are updating.
90     Value &= ~ShiftedIntMask;     // Remove integer field.
91     Value |= IntVal << IntShift;  // Set new integer.
92   }
93
94   PointerTy const *getAddrOfPointer() const {
95     return const_cast<PointerIntPair *>(this)->getAddrOfPointer();
96   }
97
98   PointerTy *getAddrOfPointer() {
99     assert(Value == reinterpret_cast<intptr_t>(getPointer()) &&
100            "Can only return the address if IntBits is cleared and "
101            "PtrTraits doesn't change the pointer");
102     return reinterpret_cast<PointerTy *>(&Value);
103   }
104
105   void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); }
106   void setFromOpaqueValue(void *Val) { Value = reinterpret_cast<intptr_t>(Val);}
107
108   static PointerIntPair getFromOpaqueValue(void *V) {
109     PointerIntPair P; P.setFromOpaqueValue(V); return P; 
110   }
111
112   // Allow PointerIntPairs to be created from const void * if and only if the
113   // pointer type could be created from a const void *.
114   static PointerIntPair getFromOpaqueValue(const void *V) {
115     (void)PtrTraits::getFromVoidPointer(V);
116     return getFromOpaqueValue(const_cast<void *>(V));
117   }
118
119   bool operator==(const PointerIntPair &RHS) const {return Value == RHS.Value;}
120   bool operator!=(const PointerIntPair &RHS) const {return Value != RHS.Value;}
121   bool operator<(const PointerIntPair &RHS) const {return Value < RHS.Value;}
122   bool operator>(const PointerIntPair &RHS) const {return Value > RHS.Value;}
123   bool operator<=(const PointerIntPair &RHS) const {return Value <= RHS.Value;}
124   bool operator>=(const PointerIntPair &RHS) const {return Value >= RHS.Value;}
125 };
126
127 template <typename T> struct isPodLike;
128 template<typename PointerTy, unsigned IntBits, typename IntType>
129 struct isPodLike<PointerIntPair<PointerTy, IntBits, IntType> > {
130    static const bool value = true;
131 };
132   
133 // Provide specialization of DenseMapInfo for PointerIntPair.
134 template<typename PointerTy, unsigned IntBits, typename IntType>
135 struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
136   typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
137   static Ty getEmptyKey() {
138     intptr_t Val = -1;
139     Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
140     return Ty(reinterpret_cast<PointerTy>(Val), IntType((1 << IntBits)-1));
141   }
142   static Ty getTombstoneKey() {
143     intptr_t Val = -2;
144     Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
145     return Ty(reinterpret_cast<PointerTy>(Val), IntType(0));
146   }
147   static unsigned getHashValue(Ty V) {
148     uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
149     return unsigned(IV) ^ unsigned(IV >> 9);
150   }
151   static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
152 };
153
154 // Teach SmallPtrSet that PointerIntPair is "basically a pointer".
155 template<typename PointerTy, unsigned IntBits, typename IntType,
156          typename PtrTraits>
157 class PointerLikeTypeTraits<PointerIntPair<PointerTy, IntBits, IntType,
158                                            PtrTraits> > {
159 public:
160   static inline void *
161   getAsVoidPointer(const PointerIntPair<PointerTy, IntBits, IntType> &P) {
162     return P.getOpaqueValue();
163   }
164   static inline PointerIntPair<PointerTy, IntBits, IntType>
165   getFromVoidPointer(void *P) {
166     return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
167   }
168   static inline PointerIntPair<PointerTy, IntBits, IntType>
169   getFromVoidPointer(const void *P) {
170     return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
171   }
172   enum {
173     NumLowBitsAvailable = PtrTraits::NumLowBitsAvailable - IntBits
174   };
175 };
176
177 } // end namespace llvm
178 #endif