LLVM API Documentation

PointerIntPair.h

Go to the documentation of this file.
00001 //===- llvm/ADT/PointerIntPair.h - Pair for pointer and int -----*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the PointerIntPair class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #ifndef LLVM_ADT_POINTERINTPAIR_H
00015 #define LLVM_ADT_POINTERINTPAIR_H
00016 
00017 #include "llvm/Support/DataTypes.h"
00018 #include <cassert>
00019 
00020 namespace llvm {
00021 
00022 template<typename T>
00023 struct DenseMapInfo;
00024 
00025 /// PointerIntPair - This class implements a pair of a pointer and small
00026 /// integer.  It is designed to represent this in the space required by one
00027 /// pointer by bitmangling the integer into the low part of the pointer.  This
00028 /// can only be done for small integers: typically up to 3 bits, but it depends
00029 /// on the alignment returned by the allocator in use.
00030 ///
00031 template <typename PointerTy, unsigned IntBits, typename IntType=unsigned>
00032 class PointerIntPair {
00033   intptr_t Value;
00034 public:
00035   PointerIntPair() : Value(0) {}
00036   PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) {
00037     setPointer(Ptr);
00038     setInt(Int);
00039   }
00040 
00041   PointerTy getPointer() const {
00042     return reinterpret_cast<PointerTy>(Value & ~((1 << IntBits)-1));
00043   }
00044 
00045   IntType getInt() const {
00046     return (IntType)(Value & ((1 << IntBits)-1));
00047   }
00048 
00049   void setPointer(PointerTy Ptr) {
00050     intptr_t PtrVal = reinterpret_cast<intptr_t>(Ptr);
00051     assert((PtrVal & ((1 << IntBits)-1)) == 0 &&
00052            "Pointer is not sufficiently aligned");
00053     Value = PtrVal | (intptr_t)getInt();
00054   }
00055 
00056   void setInt(IntType Int) {
00057     intptr_t IntVal = Int;
00058     assert(IntVal < (1 << IntBits) && "Integer too large for field");
00059     Value = reinterpret_cast<intptr_t>(getPointer()) | IntVal;
00060   }
00061 
00062   void *getOpaqueValue() const { return reinterpret_cast<void*>(Value); }
00063   void setFromOpaqueValue(void *Val) { Value = reinterpret_cast<intptr_t>(Val);}
00064 
00065   bool operator==(const PointerIntPair &RHS) const {return Value == RHS.Value;}
00066   bool operator!=(const PointerIntPair &RHS) const {return Value != RHS.Value;}
00067   bool operator<(const PointerIntPair &RHS) const {return Value < RHS.Value;}
00068   bool operator>(const PointerIntPair &RHS) const {return Value > RHS.Value;}
00069   bool operator<=(const PointerIntPair &RHS) const {return Value <= RHS.Value;}
00070   bool operator>=(const PointerIntPair &RHS) const {return Value >= RHS.Value;}
00071 };
00072 
00073 // Provide specialization of DenseMapInfo for PointerIntPair.
00074 template<typename PointerTy, unsigned IntBits, typename IntType>
00075 struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType> > {
00076   typedef PointerIntPair<PointerTy, IntBits, IntType> Ty;
00077   static Ty getEmptyKey() {
00078     return Ty(reinterpret_cast<PointerTy>(-1 << IntBits),
00079               IntType((1 << IntBits)-1));
00080   }
00081   static Ty getTombstoneKey() {
00082     return Ty(reinterpret_cast<PointerTy>(-2 << IntBits), IntType(0));
00083   }
00084   static unsigned getHashValue(Ty V) {
00085     uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
00086     return unsigned(IV) ^ unsigned(IV >> 9);
00087   }
00088   static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
00089   static bool isPod() { return true; }
00090 };
00091 
00092 } // end namespace llvm
00093 #endif