PointerIntPair.h revision b9cf75a15f6738be99a98f15cb6c2669f06d0ddf
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 <cassert>
18
19namespace llvm {
20
21template<typename T>
22struct DenseMapInfo;
23
24/// PointerIntPair - This class implements a pair of a pointer and small
25/// integer.  It is designed to represent this in the space required by one
26/// pointer by bitmangling the integer into the low part of the pointer.  This
27/// can only be done for small integers: typically up to 3 bits, but it depends
28/// on the alignment returned by the allocator in use.
29///
30template <typename PointerTy, unsigned IntBits, typename IntType=unsigned>
31class PointerIntPair {
32  intptr_t Value;
33public:
34  PointerIntPair() : Value(0) {}
35  PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) {
36    setPointer(Ptr);
37    setInt(Int);
38  }
39
40  PointerTy getPointer() const {
41    return reinterpret_cast<PointerTy>(Value & ~((1 << IntBits)-1));
42  }
43
44  IntType getInt() const {
45    return (IntType)(Value & ((1 << IntBits)-1));
46  }
47
48  void setPointer(PointerTy Ptr) {
49    intptr_t PtrVal = reinterpret_cast<intptr_t>(Ptr);
50    assert((PtrVal & ((1 << IntBits)-1)) == 0 &&
51           "Pointer is not sufficiently aligned");
52    Value = PtrVal | (intptr_t)getInt();
53  }
54
55  void setInt(IntType Int) {
56    assert(Int < (1 << IntBits) && "Integer too large for field");
57    Value = reinterpret_cast<intptr_t>(getPointer()) | (intptr_t)Int;
58  }
59
60  void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); }
61  void setFromOpaqueValue(void *Val) { Value = reinterpret_cast<intptr_t>(Val);}
62
63  bool operator==(const PointerIntPair &RHS) const {
64    return Value == RHS.Value;
65  }
66  bool operator!=(const PointerIntPair &RHS) const {
67    return Value != RHS.Value;
68  }
69};
70
71// Provide specialization of DenseMapInfo for PointerIntPair.
72template<typename PointerTy, unsigned IntBits, typename IntType>
73struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
74  typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
75  static Ty getEmptyKey() {
76    return Ty(reinterpret_cast<PointerTy>(-1 << IntBits),
77              IntType((1 << IntBits)-1));
78  }
79  static Ty getTombstoneKey() {
80    return Ty(reinterpret_cast<PointerTy>(-2 << IntBits), IntType(0));
81  }
82  static unsigned getHashValue(Ty V) {
83    uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
84    return unsigned(IV) ^ unsigned(IV >> 9);
85  }
86  static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
87  static bool isPod() { return true; }
88};
89
90} // end namespace llvm
91#endif
92