[clang] [clang][bytecode] Simplify Pointer (PR #155170)

Timm Baeder via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 25 05:46:35 PDT 2025


https://github.com/tbaederr updated https://github.com/llvm/llvm-project/pull/155170

>From 6accebd531bf512f1f281522922eb568e6920d25 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Sun, 24 Aug 2025 16:36:17 +0200
Subject: [PATCH] [clang][bytecode] Simplify Pointer

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.
---
 clang/lib/AST/ByteCode/Pointer.h | 195 ++++++++++++++-----------------
 1 file changed, 90 insertions(+), 105 deletions(-)

diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h
index 4ac913f5b74cc..ce288808687b2 100644
--- a/clang/lib/AST/ByteCode/Pointer.h
+++ b/clang/lib/AST/ByteCode/Pointer.h
@@ -120,17 +120,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;
   }
 
@@ -144,10 +141,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.
@@ -157,27 +154,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
@@ -185,7 +180,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.
@@ -197,15 +192,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.
@@ -213,7 +208,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
@@ -224,7 +219,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.
@@ -233,19 +228,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()
@@ -258,19 +252,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 {
@@ -283,13 +277,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(); }
 
@@ -298,37 +292,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();
@@ -340,9 +333,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())
@@ -355,19 +348,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();
   }
@@ -381,24 +372,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 {
@@ -407,7 +396,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;
   };
@@ -429,7 +418,7 @@ class Pointer {
     if (!isBlockPointer())
       return false;
 
-    const BlockPointer &BP = asBlockPointer();
+    const BlockPointer &BP = BS;
     if (inArray() && BP.Base != Offset)
       return true;
 
@@ -444,16 +433,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 {
@@ -495,29 +483,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;
   }
@@ -533,12 +521,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;
@@ -558,7 +546,7 @@ class Pointer {
     if (!isBlockPointer())
       return false;
 
-    if (const Block *Pointee = asBlockPointer().Pointee)
+    if (const Block *Pointee = BS.Pointee)
       return Pointee->isDummy();
     return false;
   }
@@ -585,8 +573,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;
   }
@@ -594,9 +582,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;
@@ -609,13 +597,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.
@@ -627,8 +615,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())
@@ -641,7 +628,7 @@ class Pointer {
     if (!isBlockPointer())
       return false;
 
-    if (!asBlockPointer().Pointee)
+    if (!BS.Pointee)
       return false;
 
     if (isUnknownSizeArray())
@@ -674,16 +661,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.
@@ -691,7 +677,7 @@ 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());
     assert(I < getFieldDesc()->getNumElems());
@@ -735,7 +721,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;
   }
@@ -743,7 +729,7 @@ class Pointer {
   void endLifetime() const {
     if (!isBlockPointer())
       return;
-    if (asBlockPointer().Base < sizeof(InlineDescriptor))
+    if (BS.Base < sizeof(InlineDescriptor))
       return;
     getInlineDesc()->LifeState = Lifetime::Ended;
   }
@@ -751,7 +737,7 @@ class Pointer {
   void startLifetime() const {
     if (!isBlockPointer())
       return;
-    if (asBlockPointer().Base < sizeof(InlineDescriptor))
+    if (BS.Base < sizeof(InlineDescriptor))
       return;
     getInlineDesc()->LifeState = Lifetime::Started;
   }
@@ -804,10 +790,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.
@@ -815,8 +801,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;
   }
 
@@ -824,8 +810,7 @@ class Pointer {
   InitMapPtr &getInitMap() const {
     assert(isBlockPointer());
     assert(!isZero());
-    return *reinterpret_cast<InitMapPtr *>(asBlockPointer().Pointee->rawData() +
-                                           asBlockPointer().Base);
+    return *reinterpret_cast<InitMapPtr *>(BS.Pointee->rawData() + BS.Base);
   }
 
   /// Offset into the storage.



More information about the cfe-commits mailing list