[llvm] [llvm][ADT] Refactor PointerUnion to use PunnedPointer. NFC. (PR #187950)

Markus Böck via llvm-commits llvm-commits at lists.llvm.org
Sun Mar 22 14:25:35 PDT 2026


================
@@ -102,63 +93,80 @@ namespace pointer_union_detail {
 ///    PointerUnion<int*, int*> Q; // compile time failure.
 template <typename... PTs>
 class PointerUnion
-    : public pointer_union_detail::PointerUnionMembers<
-          PointerUnion<PTs...>,
-          PointerIntPair<
-              void *, pointer_union_detail::bitsRequired(sizeof...(PTs)), int,
-              pointer_union_detail::PointerUnionUIntTraits<PTs...>>,
-          0, PTs...> {
+    : public pointer_union_detail::PointerUnionMembers<PointerUnion<PTs...>, 0,
+                                                       PTs...> {
   static_assert(TypesAreDistinct<PTs...>::value,
                 "PointerUnion alternative types cannot be repeated");
-  // The first type is special because we want to directly cast a pointer to a
-  // default-initialized union to a pointer to the first type. But we don't
-  // want PointerUnion to be a 'template <typename First, typename ...Rest>'
-  // because it's much more convenient to have a name for the whole pack. So
-  // split off the first type here.
-  using First = TypeAtIndex<0, PTs...>;
+
   using Base = typename PointerUnion::PointerUnionMembers;
+  using First = TypeAtIndex<0, PTs...>;
 
-  // Give the CastInfo specialization below access to protected members.
-  //
-  // This makes all of CastInfo a friend, which is more than strictly
-  // necessary. It's a workaround for C++'s inability to friend a
-  // partial template specialization.
+  template <typename, int, typename...>
+  friend class pointer_union_detail::PointerUnionMembers;
   template <typename To, typename From, typename Enable> friend struct CastInfo;
+  template <typename> friend struct PointerLikeTypeTraits;
+
+  // Lazy constexpr functions so that alignof() on potentially incomplete
+  // types is not evaluated at class-definition time.
+  static constexpr int minBits() {
+    return pointer_union_detail::lowBitsAvailable<PTs...>();
+  }
+
+  static constexpr int tagBits() {
+    return pointer_union_detail::bitsRequired(sizeof...(PTs));
+  }
+
+  /// The tag is shifted to the high end of the available low bits so that
+  /// the lowest bits remain free for nesting in PointerIntPair or SmallPtrSet.
+  static constexpr int tagShift() { return minBits() - tagBits(); }
+
+  static constexpr uintptr_t tagMask() {
+    return (uintptr_t(1) << tagBits()) - 1;
+  }
+
+  template <typename T> static uintptr_t encode(T V) {
+    constexpr int Shift = tagShift();
+    constexpr uintptr_t Tag = uintptr_t(FirstIndexOfType<T, PTs...>::value);
----------------
zero9178 wrote:

```suggestion
    constexpr auto Tag = uintptr_t(FirstIndexOfType<T, PTs...>::value);
```
nit: don't repeat the typename twice (ditto below)

https://github.com/llvm/llvm-project/pull/187950


More information about the llvm-commits mailing list