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