[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