Skip to content

Conversation

@tbaederr
Copy link
Contributor

Now that we don't have the PointeeStorage pointer anymore, it's simpler to access the members of the anonymous union directly instead of using asBlockPointer(), etc.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:bytecode Issues for the clang bytecode constexpr interpreter labels Aug 24, 2025
@llvmbot
Copy link
Member

llvmbot commented Aug 24, 2025

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

Changes

Now that we don't have the PointeeStorage pointer anymore, it's simpler to access the members of the anonymous union directly instead of using asBlockPointer(), etc.


Patch is 20.12 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/155170.diff

1 Files Affected:

  • (modified) clang/lib/AST/ByteCode/Pointer.h (+93-109)
diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h
index 0ce54ab0a17df..55cfdae4d0926 100644
--- a/clang/lib/AST/ByteCode/Pointer.h
+++ b/clang/lib/AST/ByteCode/Pointer.h
@@ -122,17 +122,14 @@ class Pointer {
     if (P.StorageKind != StorageKind)
       return false;
     if (isIntegralPointer())
-      return P.asIntPointer().Value == asIntPointer().Value &&
-             P.asIntPointer().Desc == asIntPointer().Desc && P.Offset == Offset;
+      return P.Int.Value == Int.Value && P.Int.Desc == Int.Desc &&
+             P.Offset == Offset;
 
     if (isFunctionPointer())
-      return P.asFunctionPointer().getFunction() ==
-                 asFunctionPointer().getFunction() &&
-             P.Offset == Offset;
+      return P.Fn.getFunction() == Fn.getFunction() && P.Offset == Offset;
 
     assert(isBlockPointer());
-    return P.asBlockPointer().Pointee == asBlockPointer().Pointee &&
-           P.asBlockPointer().Base == asBlockPointer().Base &&
+    return P.BS.Pointee == BS.Pointee && P.BS.Base == BS.Base &&
            P.Offset == Offset;
   }
 
@@ -146,10 +143,10 @@ class Pointer {
 
   uint64_t getIntegerRepresentation() const {
     if (isIntegralPointer())
-      return asIntPointer().Value + (Offset * elemSize());
+      return Int.Value + (Offset * elemSize());
     if (isFunctionPointer())
-      return asFunctionPointer().getIntegerRepresentation() + Offset;
-    return reinterpret_cast<uint64_t>(asBlockPointer().Pointee) + Offset;
+      return Fn.getIntegerRepresentation() + Offset;
+    return reinterpret_cast<uint64_t>(BS.Pointee) + Offset;
   }
 
   /// Converts the pointer to an APValue that is an rvalue.
@@ -159,27 +156,25 @@ class Pointer {
   /// Offsets a pointer inside an array.
   [[nodiscard]] Pointer atIndex(uint64_t Idx) const {
     if (isIntegralPointer())
-      return Pointer(asIntPointer().Value, asIntPointer().Desc, Idx);
+      return Pointer(Int.Value, Int.Desc, Idx);
     if (isFunctionPointer())
-      return Pointer(asFunctionPointer().getFunction(), Idx);
+      return Pointer(Fn.getFunction(), Idx);
 
-    if (asBlockPointer().Base == RootPtrMark)
-      return Pointer(asBlockPointer().Pointee, RootPtrMark,
-                     getDeclDesc()->getSize());
+    if (BS.Base == RootPtrMark)
+      return Pointer(BS.Pointee, RootPtrMark, getDeclDesc()->getSize());
     uint64_t Off = Idx * elemSize();
     if (getFieldDesc()->ElemDesc)
       Off += sizeof(InlineDescriptor);
     else
       Off += sizeof(InitMapPtr);
-    return Pointer(asBlockPointer().Pointee, asBlockPointer().Base,
-                   asBlockPointer().Base + Off);
+    return Pointer(BS.Pointee, BS.Base, BS.Base + Off);
   }
 
   /// Creates a pointer to a field.
   [[nodiscard]] Pointer atField(unsigned Off) const {
     assert(isBlockPointer());
     unsigned Field = Offset + Off;
-    return Pointer(asBlockPointer().Pointee, Field, Field);
+    return Pointer(BS.Pointee, Field, Field);
   }
 
   /// Subtract the given offset from the current Base and Offset
@@ -187,7 +182,7 @@ class Pointer {
   [[nodiscard]] Pointer atFieldSub(unsigned Off) const {
     assert(Offset >= Off);
     unsigned O = Offset - Off;
-    return Pointer(asBlockPointer().Pointee, O, O);
+    return Pointer(BS.Pointee, O, O);
   }
 
   /// Restricts the scope of an array element pointer.
@@ -199,15 +194,15 @@ class Pointer {
     if (isZero() || isUnknownSizeArray())
       return *this;
 
-    unsigned Base = asBlockPointer().Base;
+    unsigned Base = BS.Base;
     // Pointer to an array of base types - enter block.
     if (Base == RootPtrMark)
-      return Pointer(asBlockPointer().Pointee, sizeof(InlineDescriptor),
+      return Pointer(BS.Pointee, sizeof(InlineDescriptor),
                      Offset == 0 ? Offset : PastEndMark);
 
     // Pointer is one past end - magic offset marks that.
     if (isOnePastEnd())
-      return Pointer(asBlockPointer().Pointee, Base, PastEndMark);
+      return Pointer(BS.Pointee, Base, PastEndMark);
 
     if (Offset != Base) {
       // If we're pointing to a primitive array element, there's nothing to do.
@@ -215,7 +210,7 @@ class Pointer {
         return *this;
       // Pointer is to a composite array element - enter it.
       if (Offset != Base)
-        return Pointer(asBlockPointer().Pointee, Offset, Offset);
+        return Pointer(BS.Pointee, Offset, Offset);
     }
 
     // Otherwise, we're pointing to a non-array element or
@@ -226,7 +221,7 @@ class Pointer {
   /// Expands a pointer to the containing array, undoing narrowing.
   [[nodiscard]] Pointer expand() const {
     assert(isBlockPointer());
-    Block *Pointee = asBlockPointer().Pointee;
+    Block *Pointee = BS.Pointee;
 
     if (isElementPastEnd()) {
       // Revert to an outer one-past-end pointer.
@@ -235,19 +230,18 @@ class Pointer {
         Adjust = sizeof(InitMapPtr);
       else
         Adjust = sizeof(InlineDescriptor);
-      return Pointer(Pointee, asBlockPointer().Base,
-                     asBlockPointer().Base + getSize() + Adjust);
+      return Pointer(Pointee, BS.Base, BS.Base + getSize() + Adjust);
     }
 
     // Do not step out of array elements.
-    if (asBlockPointer().Base != Offset)
+    if (BS.Base != Offset)
       return *this;
 
     if (isRoot())
-      return Pointer(Pointee, asBlockPointer().Base, asBlockPointer().Base);
+      return Pointer(Pointee, BS.Base, BS.Base);
 
     // Step into the containing array, if inside one.
-    unsigned Next = asBlockPointer().Base - getInlineDesc()->Offset;
+    unsigned Next = BS.Base - getInlineDesc()->Offset;
     const Descriptor *Desc =
         (Next == Pointee->getDescriptor()->getMetadataSize())
             ? getDeclDesc()
@@ -260,19 +254,19 @@ class Pointer {
   /// Checks if the pointer is null.
   bool isZero() const {
     if (isBlockPointer())
-      return asBlockPointer().Pointee == nullptr;
+      return BS.Pointee == nullptr;
     if (isFunctionPointer())
-      return asFunctionPointer().isZero();
+      return Fn.isZero();
     if (isTypeidPointer())
       return false;
     assert(isIntegralPointer());
-    return asIntPointer().Value == 0 && Offset == 0;
+    return Int.Value == 0 && Offset == 0;
   }
   /// Checks if the pointer is live.
   bool isLive() const {
     if (!isBlockPointer())
       return true;
-    return asBlockPointer().Pointee && !asBlockPointer().Pointee->isDead();
+    return BS.Pointee && !BS.Pointee->isDead();
   }
   /// Checks if the item is a field in an object.
   bool isField() const {
@@ -285,13 +279,13 @@ class Pointer {
   /// Accessor for information about the declaration site.
   const Descriptor *getDeclDesc() const {
     if (isIntegralPointer())
-      return asIntPointer().Desc;
+      return Int.Desc;
     if (isFunctionPointer() || isTypeidPointer())
       return nullptr;
 
     assert(isBlockPointer());
-    assert(asBlockPointer().Pointee);
-    return asBlockPointer().Pointee->Desc;
+    assert(BS.Pointee);
+    return BS.Pointee->Desc;
   }
   SourceLocation getDeclLoc() const { return getDeclDesc()->getLocation(); }
 
@@ -300,37 +294,36 @@ class Pointer {
     if (isBlockPointer())
       return getDeclDesc()->getSource();
     if (isFunctionPointer()) {
-      const Function *F = asFunctionPointer().getFunction();
+      const Function *F = Fn.getFunction();
       return F ? F->getDecl() : DeclTy();
     }
     assert(isIntegralPointer());
-    return asIntPointer().Desc ? asIntPointer().Desc->getSource() : DeclTy();
+    return Int.Desc ? Int.Desc->getSource() : DeclTy();
   }
 
   /// Returns a pointer to the object of which this pointer is a field.
   [[nodiscard]] Pointer getBase() const {
-    if (asBlockPointer().Base == RootPtrMark) {
+    if (BS.Base == RootPtrMark) {
       assert(Offset == PastEndMark && "cannot get base of a block");
-      return Pointer(asBlockPointer().Pointee, asBlockPointer().Base, 0);
+      return Pointer(BS.Pointee, BS.Base, 0);
     }
-    unsigned NewBase = asBlockPointer().Base - getInlineDesc()->Offset;
-    return Pointer(asBlockPointer().Pointee, NewBase, NewBase);
+    unsigned NewBase = BS.Base - getInlineDesc()->Offset;
+    return Pointer(BS.Pointee, NewBase, NewBase);
   }
   /// Returns the parent array.
   [[nodiscard]] Pointer getArray() const {
-    if (asBlockPointer().Base == RootPtrMark) {
+    if (BS.Base == RootPtrMark) {
       assert(Offset != 0 && Offset != PastEndMark && "not an array element");
-      return Pointer(asBlockPointer().Pointee, asBlockPointer().Base, 0);
+      return Pointer(BS.Pointee, BS.Base, 0);
     }
-    assert(Offset != asBlockPointer().Base && "not an array element");
-    return Pointer(asBlockPointer().Pointee, asBlockPointer().Base,
-                   asBlockPointer().Base);
+    assert(Offset != BS.Base && "not an array element");
+    return Pointer(BS.Pointee, BS.Base, BS.Base);
   }
 
   /// Accessors for information about the innermost field.
   const Descriptor *getFieldDesc() const {
     if (isIntegralPointer())
-      return asIntPointer().Desc;
+      return Int.Desc;
 
     if (isRoot())
       return getDeclDesc();
@@ -342,9 +335,9 @@ class Pointer {
     if (isTypeidPointer())
       return QualType(Typeid.TypeInfoType, 0);
     if (isFunctionPointer())
-      return asFunctionPointer().getFunction()->getDecl()->getType();
+      return Fn.getFunction()->getDecl()->getType();
 
-    if (inPrimitiveArray() && Offset != asBlockPointer().Base) {
+    if (inPrimitiveArray() && Offset != BS.Base) {
       // Unfortunately, complex and vector types are not array types in clang,
       // but they are for us.
       if (const auto *AT = getFieldDesc()->getType()->getAsArrayTypeUnsafe())
@@ -357,19 +350,17 @@ class Pointer {
     return getFieldDesc()->getType();
   }
 
-  [[nodiscard]] Pointer getDeclPtr() const {
-    return Pointer(asBlockPointer().Pointee);
-  }
+  [[nodiscard]] Pointer getDeclPtr() const { return Pointer(BS.Pointee); }
 
   /// Returns the element size of the innermost field.
   size_t elemSize() const {
     if (isIntegralPointer()) {
-      if (!asIntPointer().Desc)
+      if (!Int.Desc)
         return 1;
-      return asIntPointer().Desc->getElemSize();
+      return Int.Desc->getElemSize();
     }
 
-    if (asBlockPointer().Base == RootPtrMark)
+    if (BS.Base == RootPtrMark)
       return getDeclDesc()->getSize();
     return getFieldDesc()->getElemSize();
   }
@@ -383,24 +374,22 @@ class Pointer {
   unsigned getOffset() const {
     assert(Offset != PastEndMark && "invalid offset");
     assert(isBlockPointer());
-    if (asBlockPointer().Base == RootPtrMark)
+    if (BS.Base == RootPtrMark)
       return Offset;
 
     unsigned Adjust = 0;
-    if (Offset != asBlockPointer().Base) {
+    if (Offset != BS.Base) {
       if (getFieldDesc()->ElemDesc)
         Adjust = sizeof(InlineDescriptor);
       else
         Adjust = sizeof(InitMapPtr);
     }
-    return Offset - asBlockPointer().Base - Adjust;
+    return Offset - BS.Base - Adjust;
   }
 
   /// Whether this array refers to an array, but not
   /// to the first element.
-  bool isArrayRoot() const {
-    return inArray() && Offset == asBlockPointer().Base;
-  }
+  bool isArrayRoot() const { return inArray() && Offset == BS.Base; }
 
   /// Checks if the innermost field is an array.
   bool inArray() const {
@@ -409,7 +398,7 @@ class Pointer {
     return false;
   }
   bool inUnion() const {
-    if (isBlockPointer() && asBlockPointer().Base >= sizeof(InlineDescriptor))
+    if (isBlockPointer() && BS.Base >= sizeof(InlineDescriptor))
       return getInlineDesc()->InUnion;
     return false;
   };
@@ -431,7 +420,7 @@ class Pointer {
     if (!isBlockPointer())
       return false;
 
-    const BlockPointer &BP = asBlockPointer();
+    const BlockPointer &BP = BS;
     if (inArray() && BP.Base != Offset)
       return true;
 
@@ -446,16 +435,15 @@ class Pointer {
   bool isRoot() const {
     if (isZero() || !isBlockPointer())
       return true;
-    return (asBlockPointer().Base ==
-                asBlockPointer().Pointee->getDescriptor()->getMetadataSize() ||
-            asBlockPointer().Base == 0);
+    return (BS.Base == BS.Pointee->getDescriptor()->getMetadataSize() ||
+            BS.Base == 0);
   }
   /// If this pointer has an InlineDescriptor we can use to initialize.
   bool canBeInitialized() const {
     if (!isBlockPointer())
       return false;
 
-    return asBlockPointer().Pointee && asBlockPointer().Base > 0;
+    return BS.Pointee && BS.Base > 0;
   }
 
   [[nodiscard]] const BlockPointer &asBlockPointer() const {
@@ -497,29 +485,29 @@ class Pointer {
   /// Checks if the storage is extern.
   bool isExtern() const {
     if (isBlockPointer())
-      return asBlockPointer().Pointee && asBlockPointer().Pointee->isExtern();
+      return BS.Pointee && BS.Pointee->isExtern();
     return false;
   }
   /// Checks if the storage is static.
   bool isStatic() const {
     if (!isBlockPointer())
       return true;
-    assert(asBlockPointer().Pointee);
-    return asBlockPointer().Pointee->isStatic();
+    assert(BS.Pointee);
+    return BS.Pointee->isStatic();
   }
   /// Checks if the storage is temporary.
   bool isTemporary() const {
     if (isBlockPointer()) {
-      assert(asBlockPointer().Pointee);
-      return asBlockPointer().Pointee->isTemporary();
+      assert(BS.Pointee);
+      return BS.Pointee->isTemporary();
     }
     return false;
   }
   /// Checks if the storage has been dynamically allocated.
   bool isDynamic() const {
     if (isBlockPointer()) {
-      assert(asBlockPointer().Pointee);
-      return asBlockPointer().Pointee->isDynamic();
+      assert(BS.Pointee);
+      return BS.Pointee->isDynamic();
     }
     return false;
   }
@@ -535,12 +523,12 @@ class Pointer {
 
   bool isWeak() const {
     if (isFunctionPointer())
-      return asFunctionPointer().isWeak();
+      return Fn.isWeak();
     if (!isBlockPointer())
       return false;
 
     assert(isBlockPointer());
-    return asBlockPointer().Pointee->isWeak();
+    return BS.Pointee->isWeak();
   }
   /// Checks if an object was initialized.
   bool isInitialized() const;
@@ -560,7 +548,7 @@ class Pointer {
     if (!isBlockPointer())
       return false;
 
-    if (const Block *Pointee = asBlockPointer().Pointee)
+    if (const Block *Pointee = BS.Pointee)
       return Pointee->isDummy();
     return false;
   }
@@ -587,8 +575,8 @@ class Pointer {
   /// Returns the declaration ID.
   UnsignedOrNone getDeclID() const {
     if (isBlockPointer()) {
-      assert(asBlockPointer().Pointee);
-      return asBlockPointer().Pointee->getDeclID();
+      assert(BS.Pointee);
+      return BS.Pointee->getDeclID();
     }
     return std::nullopt;
   }
@@ -596,9 +584,9 @@ class Pointer {
   /// Returns the byte offset from the start.
   uint64_t getByteOffset() const {
     if (isIntegralPointer())
-      return asIntPointer().Value + Offset;
+      return Int.Value + Offset;
     if (isTypeidPointer())
-      return reinterpret_cast<uintptr_t>(asTypeidPointer().TypePtr) + Offset;
+      return reinterpret_cast<uintptr_t>(Typeid.TypePtr) + Offset;
     if (isOnePastEnd())
       return PastEndMark;
     return Offset;
@@ -611,13 +599,13 @@ class Pointer {
     return getSize() / elemSize();
   }
 
-  const Block *block() const { return asBlockPointer().Pointee; }
+  const Block *block() const { return BS.Pointee; }
 
   /// If backed by actual data (i.e. a block pointer), return
   /// an address to that data.
   const std::byte *getRawAddress() const {
     assert(isBlockPointer());
-    return asBlockPointer().Pointee->rawData() + Offset;
+    return BS.Pointee->rawData() + Offset;
   }
 
   /// Returns the index into an array.
@@ -629,8 +617,7 @@ class Pointer {
       return 0;
 
     // narrow()ed element in a composite array.
-    if (asBlockPointer().Base > sizeof(InlineDescriptor) &&
-        asBlockPointer().Base == Offset)
+    if (BS.Base > sizeof(InlineDescriptor) && BS.Base == Offset)
       return 0;
 
     if (auto ElemSize = elemSize())
@@ -643,7 +630,7 @@ class Pointer {
     if (!isBlockPointer())
       return false;
 
-    if (!asBlockPointer().Pointee)
+    if (!BS.Pointee)
       return false;
 
     if (isUnknownSizeArray())
@@ -676,16 +663,15 @@ class Pointer {
   template <typename T> T &deref() const {
     assert(isLive() && "Invalid pointer");
     assert(isBlockPointer());
-    assert(asBlockPointer().Pointee);
+    assert(BS.Pointee);
     assert(isDereferencable());
-    assert(Offset + sizeof(T) <=
-           asBlockPointer().Pointee->getDescriptor()->getAllocSize());
+    assert(Offset + sizeof(T) <= BS.Pointee->getDescriptor()->getAllocSize());
 
     if (isArrayRoot())
-      return *reinterpret_cast<T *>(asBlockPointer().Pointee->rawData() +
-                                    asBlockPointer().Base + sizeof(InitMapPtr));
+      return *reinterpret_cast<T *>(BS.Pointee->rawData() + BS.Base +
+                                    sizeof(InitMapPtr));
 
-    return *reinterpret_cast<T *>(asBlockPointer().Pointee->rawData() + Offset);
+    return *reinterpret_cast<T *>(BS.Pointee->rawData() + Offset);
   }
 
   /// Dereferences the element at index \p I.
@@ -693,17 +679,16 @@ class Pointer {
   template <typename T> T &elem(unsigned I) const {
     assert(isLive() && "Invalid pointer");
     assert(isBlockPointer());
-    assert(asBlockPointer().Pointee);
+    assert(BS.Pointee);
     assert(isDereferencable());
     assert(getFieldDesc()->isPrimitiveArray());
 
     unsigned ElemByteOffset = I * getFieldDesc()->getElemSize();
     if (isArrayRoot())
-      return *reinterpret_cast<T *>(asBlockPointer().Pointee->rawData() +
-                                    asBlockPointer().Base + sizeof(InitMapPtr) +
-                                    ElemByteOffset);
+      return *reinterpret_cast<T *>(BS.Pointee->rawData() + BS.Base +
+                                    sizeof(InitMapPtr) + ElemByteOffset);
 
-    return *reinterpret_cast<T *>(asBlockPointer().Pointee->rawData() + Offset +
+    return *reinterpret_cast<T *>(BS.Pointee->rawData() + Offset +
                                   ElemByteOffset);
   }
 
@@ -732,7 +717,7 @@ class Pointer {
   Lifetime getLifetime() const {
     if (!isBlockPointer())
       return Lifetime::Started;
-    if (asBlockPointer().Base < sizeof(InlineDescriptor))
+    if (BS.Base < sizeof(InlineDescriptor))
       return Lifetime::Started;
     return getInlineDesc()->LifeState;
   }
@@ -740,7 +725,7 @@ class Pointer {
   void endLifetime() const {
     if (!isBlockPointer())
       return;
-    if (asBlockPointer().Base < sizeof(InlineDescriptor))
+    if (BS.Base < sizeof(InlineDescriptor))
       return;
     getInlineDesc()->LifeState = Lifetime::Ended;
   }
@@ -748,7 +733,7 @@ class Pointer {
   void startLifetime() const {
     if (!isBlockPointer())
       return;
-    if (asBlockPointer().Base < sizeof(InlineDescriptor))
+    if (BS.Base < sizeof(InlineDescriptor))
       return;
     getInlineDesc()->LifeState = Lifetime::Started;
   }
@@ -801,10 +786,10 @@ class Pointer {
   /// Returns the embedded descriptor preceding a field.
   InlineDescriptor *getInlineDesc() const {
     assert(isBlockPointer());
-    assert(asBlockPointer().Base != sizeof(GlobalInlineDescriptor));
-    assert(asBlockPointer().Base <= asBlockPointer().Pointee->getSize());
-    assert(asBlockPointer().Base >= sizeof(InlineDescriptor));
-    return getDescriptor(asBlockPointer().Base);
+    assert(BS.Base != sizeof(GlobalInlineDescriptor));
+    assert(BS.Base <= BS.Pointee->getSize());
+    assert(BS.Base >= sizeof(InlineDescriptor));
+    return getDescriptor(BS.Base);
   }
 
   /// Returns a descriptor at a given offset.
@@ -812,8 +797,8 @@ class Pointer {
     assert(Offset != 0 && "Not a nested pointer");
     assert(isBlockPointer());
     assert(!isZero());
-    return reinterpret_cast<InlineDescriptor *>(
-               asBlockPointer().Pointee->rawData() + Offset) -
+    return reinterpret_cast<InlineDescriptor *>(BS.Pointee->rawData() +
+                                                Offset) -
            1;
   }
 
@@ -821,8 +806,7 @@ class Pointer {
   InitMapPtr &getInitMap() const {
     assert(isBlockPointer());
     assert(!isZero());
-    return *reinterpret_cast<InitMapPtr *>(asBlockPointer().Pointee->rawData() +
-                                           asBlockPointer...
[truncated]

@tbaederr tbaederr force-pushed the pointer-simplify branch 2 times, most recently from bcfb423 to 6accebd Compare August 25, 2025 12:46
Now that we don't have the PointeeStorage pointer anymore, it's simpler
to access the members of the anonymous union directly instead of using
asBlockPointer(), etc.
@tbaederr tbaederr merged commit 9cc89bb into llvm:main Aug 26, 2025
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:bytecode Issues for the clang bytecode constexpr interpreter clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants