[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