diff options
Diffstat (limited to 'contrib/llvm/include/llvm/ADT/PointerIntPair.h')
-rw-r--r-- | contrib/llvm/include/llvm/ADT/PointerIntPair.h | 47 |
1 files changed, 34 insertions, 13 deletions
diff --git a/contrib/llvm/include/llvm/ADT/PointerIntPair.h b/contrib/llvm/include/llvm/ADT/PointerIntPair.h index 71c379bad5a4..0299a83c4411 100644 --- a/contrib/llvm/include/llvm/ADT/PointerIntPair.h +++ b/contrib/llvm/include/llvm/ADT/PointerIntPair.h @@ -29,7 +29,7 @@ struct DenseMapInfo; /// on the number of bits available according to PointerLikeTypeTraits for the /// type. /// -/// Note that PointerIntPair always puts the Int part in the highest bits +/// Note that PointerIntPair always puts the IntVal part in the highest bits /// possible. For example, PointerIntPair<void*, 1, bool> will put the bit for /// the bool into bit #2, not bit #0, which allows the low two bits to be used /// for something else. For example, this allows: @@ -57,11 +57,13 @@ class PointerIntPair { }; public: PointerIntPair() : Value(0) {} - PointerIntPair(PointerTy Ptr, IntType Int) : Value(0) { + PointerIntPair(PointerTy PtrVal, IntType IntVal) { assert(IntBits <= PtrTraits::NumLowBitsAvailable && "PointerIntPair formed with integer size too large for pointer"); - setPointer(Ptr); - setInt(Int); + setPointerAndInt(PtrVal, IntVal); + } + explicit PointerIntPair(PointerTy PtrVal) { + initWithPointer(PtrVal); } PointerTy getPointer() const { @@ -73,22 +75,41 @@ public: return (IntType)((Value >> IntShift) & IntMask); } - void setPointer(PointerTy Ptr) { - intptr_t PtrVal - = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr)); - assert((PtrVal & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 && + void setPointer(PointerTy PtrVal) { + intptr_t PtrWord + = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal)); + assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 && "Pointer is not sufficiently aligned"); // Preserve all low bits, just update the pointer. - Value = PtrVal | (Value & ~PointerBitMask); + Value = PtrWord | (Value & ~PointerBitMask); } - void setInt(IntType Int) { - intptr_t IntVal = Int; - assert(IntVal < (1 << IntBits) && "Integer too large for field"); + void setInt(IntType IntVal) { + intptr_t IntWord = static_cast<intptr_t>(IntVal); + assert(IntWord < (1 << IntBits) && "Integer too large for field"); // Preserve all bits other than the ones we are updating. Value &= ~ShiftedIntMask; // Remove integer field. - Value |= IntVal << IntShift; // Set new integer. + Value |= IntWord << IntShift; // Set new integer. + } + + void initWithPointer(PointerTy PtrVal) { + intptr_t PtrWord + = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal)); + assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 && + "Pointer is not sufficiently aligned"); + Value = PtrWord; + } + + void setPointerAndInt(PointerTy PtrVal, IntType IntVal) { + intptr_t PtrWord + = reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(PtrVal)); + assert((PtrWord & ((1 << PtrTraits::NumLowBitsAvailable)-1)) == 0 && + "Pointer is not sufficiently aligned"); + intptr_t IntWord = static_cast<intptr_t>(IntVal); + assert(IntWord < (1 << IntBits) && "Integer too large for field"); + + Value = PtrWord | (IntWord << IntShift); } PointerTy const *getAddrOfPointer() const { |