PointerIntPair.h revision b79a01111d1ed14ec92b969fb995906268733c12
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 intptr_t IntVal = Int; 57 assert(IntVal < (1 << IntBits) && "Integer too large for field"); 58 Value = reinterpret_cast<intptr_t>(getPointer()) | IntVal; 59 } 60 61 void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); } 62 void setFromOpaqueValue(void *Val) { Value = reinterpret_cast<intptr_t>(Val);} 63 64 bool operator==(const PointerIntPair &RHS) const {return Value == RHS.Value;} 65 bool operator!=(const PointerIntPair &RHS) const {return Value != RHS.Value;} 66 bool operator<(const PointerIntPair &RHS) const {return Value < RHS.Value;} 67 bool operator>(const PointerIntPair &RHS) const {return Value > RHS.Value;} 68 bool operator<=(const PointerIntPair &RHS) const {return Value <= RHS.Value;} 69 bool operator>=(const PointerIntPair &RHS) const {return Value >= RHS.Value;} 70}; 71 72// Provide specialization of DenseMapInfo for PointerIntPair. 73template<typename PointerTy, unsigned IntBits, typename IntType> 74struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > { 75 typedef PointerIntPair<PointerTy, IntBits, IntType> Ty; 76 static Ty getEmptyKey() { 77 return Ty(reinterpret_cast<PointerTy>(-1 << IntBits), 78 IntType((1 << IntBits)-1)); 79 } 80 static Ty getTombstoneKey() { 81 return Ty(reinterpret_cast<PointerTy>(-2 << IntBits), IntType(0)); 82 } 83 static unsigned getHashValue(Ty V) { 84 uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue()); 85 return unsigned(IV) ^ unsigned(IV >> 9); 86 } 87 static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; } 88 static bool isPod() { return true; } 89}; 90 91} // end namespace llvm 92#endif 93