Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- llvm/ADT/PointerIntPair.h - Pair for pointer and int -----*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. ///
  9. /// \file
  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 "llvm/Support/Compiler.h"
  18. #include "llvm/Support/PointerLikeTypeTraits.h"
  19. #include "llvm/Support/type_traits.h"
  20. #include <cassert>
  21. #include <cstdint>
  22. #include <limits>
  23.  
  24. namespace llvm {
  25.  
  26. template <typename T, typename Enable> struct DenseMapInfo;
  27. template <typename PointerT, unsigned IntBits, typename PtrTraits>
  28. struct PointerIntPairInfo;
  29.  
  30. /// PointerIntPair - This class implements a pair of a pointer and small
  31. /// integer.  It is designed to represent this in the space required by one
  32. /// pointer by bitmangling the integer into the low part of the pointer.  This
  33. /// can only be done for small integers: typically up to 3 bits, but it depends
  34. /// on the number of bits available according to PointerLikeTypeTraits for the
  35. /// type.
  36. ///
  37. /// Note that PointerIntPair always puts the IntVal part in the highest bits
  38. /// possible.  For example, PointerIntPair<void*, 1, bool> will put the bit for
  39. /// the bool into bit #2, not bit #0, which allows the low two bits to be used
  40. /// for something else.  For example, this allows:
  41. ///   PointerIntPair<PointerIntPair<void*, 1, bool>, 1, bool>
  42. /// ... and the two bools will land in different bits.
  43. template <typename PointerTy, unsigned IntBits, typename IntType = unsigned,
  44.           typename PtrTraits = PointerLikeTypeTraits<PointerTy>,
  45.           typename Info = PointerIntPairInfo<PointerTy, IntBits, PtrTraits>>
  46. class PointerIntPair {
  47.   // Used by MSVC visualizer and generally helpful for debugging/visualizing.
  48.   using InfoTy = Info;
  49.   intptr_t Value = 0;
  50.  
  51. public:
  52.   constexpr PointerIntPair() = default;
  53.  
  54.   PointerIntPair(PointerTy PtrVal, IntType IntVal) {
  55.     setPointerAndInt(PtrVal, IntVal);
  56.   }
  57.  
  58.   explicit PointerIntPair(PointerTy PtrVal) { initWithPointer(PtrVal); }
  59.  
  60.   PointerTy getPointer() const { return Info::getPointer(Value); }
  61.  
  62.   IntType getInt() const { return (IntType)Info::getInt(Value); }
  63.  
  64.   void setPointer(PointerTy PtrVal) & {
  65.     Value = Info::updatePointer(Value, PtrVal);
  66.   }
  67.  
  68.   void setInt(IntType IntVal) & {
  69.     Value = Info::updateInt(Value, static_cast<intptr_t>(IntVal));
  70.   }
  71.  
  72.   void initWithPointer(PointerTy PtrVal) & {
  73.     Value = Info::updatePointer(0, PtrVal);
  74.   }
  75.  
  76.   void setPointerAndInt(PointerTy PtrVal, IntType IntVal) & {
  77.     Value = Info::updateInt(Info::updatePointer(0, PtrVal),
  78.                             static_cast<intptr_t>(IntVal));
  79.   }
  80.  
  81.   PointerTy const *getAddrOfPointer() const {
  82.     return const_cast<PointerIntPair *>(this)->getAddrOfPointer();
  83.   }
  84.  
  85.   PointerTy *getAddrOfPointer() {
  86.     assert(Value == reinterpret_cast<intptr_t>(getPointer()) &&
  87.            "Can only return the address if IntBits is cleared and "
  88.            "PtrTraits doesn't change the pointer");
  89.     return reinterpret_cast<PointerTy *>(&Value);
  90.   }
  91.  
  92.   void *getOpaqueValue() const { return reinterpret_cast<void *>(Value); }
  93.  
  94.   void setFromOpaqueValue(void *Val) & {
  95.     Value = reinterpret_cast<intptr_t>(Val);
  96.   }
  97.  
  98.   static PointerIntPair getFromOpaqueValue(void *V) {
  99.     PointerIntPair P;
  100.     P.setFromOpaqueValue(V);
  101.     return P;
  102.   }
  103.  
  104.   // Allow PointerIntPairs to be created from const void * if and only if the
  105.   // pointer type could be created from a const void *.
  106.   static PointerIntPair getFromOpaqueValue(const void *V) {
  107.     (void)PtrTraits::getFromVoidPointer(V);
  108.     return getFromOpaqueValue(const_cast<void *>(V));
  109.   }
  110.  
  111.   bool operator==(const PointerIntPair &RHS) const {
  112.     return Value == RHS.Value;
  113.   }
  114.  
  115.   bool operator!=(const PointerIntPair &RHS) const {
  116.     return Value != RHS.Value;
  117.   }
  118.  
  119.   bool operator<(const PointerIntPair &RHS) const { return Value < RHS.Value; }
  120.   bool operator>(const PointerIntPair &RHS) const { return Value > RHS.Value; }
  121.  
  122.   bool operator<=(const PointerIntPair &RHS) const {
  123.     return Value <= RHS.Value;
  124.   }
  125.  
  126.   bool operator>=(const PointerIntPair &RHS) const {
  127.     return Value >= RHS.Value;
  128.   }
  129. };
  130.  
  131. template <typename PointerT, unsigned IntBits, typename PtrTraits>
  132. struct PointerIntPairInfo {
  133.   static_assert(PtrTraits::NumLowBitsAvailable <
  134.                     std::numeric_limits<uintptr_t>::digits,
  135.                 "cannot use a pointer type that has all bits free");
  136.   static_assert(IntBits <= PtrTraits::NumLowBitsAvailable,
  137.                 "PointerIntPair with integer size too large for pointer");
  138.   enum MaskAndShiftConstants : uintptr_t {
  139.     /// PointerBitMask - The bits that come from the pointer.
  140.     PointerBitMask =
  141.         ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable) - 1),
  142.  
  143.     /// IntShift - The number of low bits that we reserve for other uses, and
  144.     /// keep zero.
  145.     IntShift = (uintptr_t)PtrTraits::NumLowBitsAvailable - IntBits,
  146.  
  147.     /// IntMask - This is the unshifted mask for valid bits of the int type.
  148.     IntMask = (uintptr_t)(((intptr_t)1 << IntBits) - 1),
  149.  
  150.     // ShiftedIntMask - This is the bits for the integer shifted in place.
  151.     ShiftedIntMask = (uintptr_t)(IntMask << IntShift)
  152.   };
  153.  
  154.   static PointerT getPointer(intptr_t Value) {
  155.     return PtrTraits::getFromVoidPointer(
  156.         reinterpret_cast<void *>(Value & PointerBitMask));
  157.   }
  158.  
  159.   static intptr_t getInt(intptr_t Value) {
  160.     return (Value >> IntShift) & IntMask;
  161.   }
  162.  
  163.   static intptr_t updatePointer(intptr_t OrigValue, PointerT Ptr) {
  164.     intptr_t PtrWord =
  165.         reinterpret_cast<intptr_t>(PtrTraits::getAsVoidPointer(Ptr));
  166.     assert((PtrWord & ~PointerBitMask) == 0 &&
  167.            "Pointer is not sufficiently aligned");
  168.     // Preserve all low bits, just update the pointer.
  169.     return PtrWord | (OrigValue & ~PointerBitMask);
  170.   }
  171.  
  172.   static intptr_t updateInt(intptr_t OrigValue, intptr_t Int) {
  173.     intptr_t IntWord = static_cast<intptr_t>(Int);
  174.     assert((IntWord & ~IntMask) == 0 && "Integer too large for field");
  175.  
  176.     // Preserve all bits other than the ones we are updating.
  177.     return (OrigValue & ~ShiftedIntMask) | IntWord << IntShift;
  178.   }
  179. };
  180.  
  181. // Provide specialization of DenseMapInfo for PointerIntPair.
  182. template <typename PointerTy, unsigned IntBits, typename IntType>
  183. struct DenseMapInfo<PointerIntPair<PointerTy, IntBits, IntType>, void> {
  184.   using Ty = PointerIntPair<PointerTy, IntBits, IntType>;
  185.  
  186.   static Ty getEmptyKey() {
  187.     uintptr_t Val = static_cast<uintptr_t>(-1);
  188.     Val <<= PointerLikeTypeTraits<Ty>::NumLowBitsAvailable;
  189.     return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
  190.   }
  191.  
  192.   static Ty getTombstoneKey() {
  193.     uintptr_t Val = static_cast<uintptr_t>(-2);
  194.     Val <<= PointerLikeTypeTraits<PointerTy>::NumLowBitsAvailable;
  195.     return Ty::getFromOpaqueValue(reinterpret_cast<void *>(Val));
  196.   }
  197.  
  198.   static unsigned getHashValue(Ty V) {
  199.     uintptr_t IV = reinterpret_cast<uintptr_t>(V.getOpaqueValue());
  200.     return unsigned(IV) ^ unsigned(IV >> 9);
  201.   }
  202.  
  203.   static bool isEqual(const Ty &LHS, const Ty &RHS) { return LHS == RHS; }
  204. };
  205.  
  206. // Teach SmallPtrSet that PointerIntPair is "basically a pointer".
  207. template <typename PointerTy, unsigned IntBits, typename IntType,
  208.           typename PtrTraits>
  209. struct PointerLikeTypeTraits<
  210.     PointerIntPair<PointerTy, IntBits, IntType, PtrTraits>> {
  211.   static inline void *
  212.   getAsVoidPointer(const PointerIntPair<PointerTy, IntBits, IntType> &P) {
  213.     return P.getOpaqueValue();
  214.   }
  215.  
  216.   static inline PointerIntPair<PointerTy, IntBits, IntType>
  217.   getFromVoidPointer(void *P) {
  218.     return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
  219.   }
  220.  
  221.   static inline PointerIntPair<PointerTy, IntBits, IntType>
  222.   getFromVoidPointer(const void *P) {
  223.     return PointerIntPair<PointerTy, IntBits, IntType>::getFromOpaqueValue(P);
  224.   }
  225.  
  226.   static constexpr int NumLowBitsAvailable =
  227.       PtrTraits::NumLowBitsAvailable - IntBits;
  228. };
  229.  
  230. // Allow structured bindings on PointerIntPair.
  231. template <std::size_t I, typename PointerTy, unsigned IntBits, typename IntType,
  232.           typename PtrTraits, typename Info>
  233. decltype(auto)
  234. get(const PointerIntPair<PointerTy, IntBits, IntType, PtrTraits, Info> &Pair) {
  235.   static_assert(I < 2);
  236.   if constexpr (I == 0)
  237.     return Pair.getPointer();
  238.   else
  239.     return Pair.getInt();
  240. }
  241.  
  242. } // end namespace llvm
  243.  
  244. namespace std {
  245. template <typename PointerTy, unsigned IntBits, typename IntType,
  246.           typename PtrTraits, typename Info>
  247. struct tuple_size<
  248.     llvm::PointerIntPair<PointerTy, IntBits, IntType, PtrTraits, Info>>
  249.     : std::integral_constant<std::size_t, 2> {};
  250.  
  251. template <std::size_t I, typename PointerTy, unsigned IntBits, typename IntType,
  252.           typename PtrTraits, typename Info>
  253. struct tuple_element<
  254.     I, llvm::PointerIntPair<PointerTy, IntBits, IntType, PtrTraits, Info>>
  255.     : std::conditional<I == 0, PointerTy, IntType> {};
  256. } // namespace std
  257.  
  258. #endif // LLVM_ADT_POINTERINTPAIR_H
  259.