[clang] [clang][bytecode] Move Descriptor::{ElemDesc, ElemRecord} into a PointerUnion (PR #217324)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 19 05:23:41 PDT 2026
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/217324
We only ever need one of them. Also reorder the Descriptor members a bit to reduce the size of `Desciptor` from 72 to 64 bytes.
>From ee2c59e5b6094360d2f3dcf60580309c61336abf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Wed, 19 Aug 2026 10:28:23 +0200
Subject: [PATCH] elemdesc/elemrecord
---
clang/lib/AST/ByteCode/Compiler.cpp | 10 +-
clang/lib/AST/ByteCode/Descriptor.cpp | 106 +++++++++---------
clang/lib/AST/ByteCode/Descriptor.h | 47 +++++---
clang/lib/AST/ByteCode/Disasm.cpp | 12 +-
clang/lib/AST/ByteCode/EvaluationResult.cpp | 12 +-
clang/lib/AST/ByteCode/Interp.cpp | 8 +-
clang/lib/AST/ByteCode/InterpBuiltin.cpp | 8 +-
.../lib/AST/ByteCode/InterpBuiltinBitCast.cpp | 2 +-
clang/lib/AST/ByteCode/Pointer.cpp | 2 +-
clang/lib/AST/ByteCode/Pointer.h | 12 +-
clang/lib/AST/ByteCode/Program.cpp | 2 +-
11 files changed, 119 insertions(+), 102 deletions(-)
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index cbfd067bfbdd4..9c6fdc70e9300 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -5087,7 +5087,7 @@ bool Compiler<Emitter>::visitZeroRecordInitializer(const Record *R,
if (!this->visitZeroArrayInitializer(D->getType(), E))
return false;
} else if (D->isRecord()) {
- if (!this->visitZeroRecordInitializer(D->ElemRecord, E))
+ if (!this->visitZeroRecordInitializer(D->getElemRecord(), E))
return false;
} else
return false;
@@ -8676,7 +8676,7 @@ bool Compiler<Emitter>::emitDestructionPop(const Descriptor *Desc,
// Arrays.
if (Desc->isArray()) {
- const Descriptor *ElemDesc = Desc->ElemDesc;
+ const Descriptor *ElemDesc = Desc->getElemDesc();
assert(ElemDesc);
unsigned N = Desc->getNumElems();
@@ -8699,9 +8699,9 @@ bool Compiler<Emitter>::emitDestructionPop(const Descriptor *Desc,
return this->emitDestructionPop(ElemDesc, Loc);
}
- assert(Desc->ElemRecord);
- assert(!Desc->ElemRecord->hasTrivialDtor());
- return this->emitRecordDestructionPop(Desc->ElemRecord, Loc);
+ assert(Desc->isRecord());
+ assert(!Desc->getElemRecord()->hasTrivialDtor());
+ return this->emitRecordDestructionPop(Desc->getElemRecord(), Loc);
}
/// Create a dummy pointer for the given decl (or expr) and
diff --git a/clang/lib/AST/ByteCode/Descriptor.cpp b/clang/lib/AST/ByteCode/Descriptor.cpp
index d0435d4684875..be5d42967059f 100644
--- a/clang/lib/AST/ByteCode/Descriptor.cpp
+++ b/clang/lib/AST/ByteCode/Descriptor.cpp
@@ -83,13 +83,13 @@ static void ctorArrayDesc(Block *B, std::byte *Ptr, bool IsConst,
bool InUnion, const Descriptor *D) {
const unsigned NumElems = D->getNumElems();
const unsigned ElemSize =
- D->ElemDesc->getAllocSize() + sizeof(InlineDescriptor);
+ D->getElemDesc()->getAllocSize() + sizeof(InlineDescriptor);
unsigned ElemOffset = 0;
for (unsigned I = 0; I != NumElems; ++I, ElemOffset += ElemSize) {
auto *ElemPtr = Ptr + ElemOffset;
auto *Desc = reinterpret_cast<InlineDescriptor *>(ElemPtr);
- auto *SD = D->ElemDesc;
+ auto *SD = D->getElemDesc();
Desc->Offset = ElemOffset + sizeof(InlineDescriptor);
Desc->Desc = SD;
@@ -102,10 +102,10 @@ static void ctorArrayDesc(Block *B, std::byte *Ptr, bool IsConst,
Desc->IsArrayElement = true;
Desc->IsVolatile = IsVolatile;
- if (auto Fn = D->ElemDesc->CtorFn) {
+ if (auto Fn = D->getElemDesc()->CtorFn) {
auto *ElemLoc = reinterpret_cast<std::byte *>(Desc + 1);
Fn(B, ElemLoc, Desc->IsConst, Desc->IsFieldMutable, IsVolatile, IsActive,
- Desc->InUnion || SD->isUnion(), D->ElemDesc);
+ Desc->InUnion || SD->isUnion(), D->getElemDesc());
}
}
}
@@ -113,17 +113,17 @@ static void ctorArrayDesc(Block *B, std::byte *Ptr, bool IsConst,
static void dtorArrayDesc(Block *B, std::byte *Ptr, const Descriptor *D) {
const unsigned NumElems = D->getNumElems();
const unsigned ElemSize =
- D->ElemDesc->getAllocSize() + sizeof(InlineDescriptor);
+ D->getElemDesc()->getAllocSize() + sizeof(InlineDescriptor);
unsigned ElemOffset = 0;
- auto Dtor = D->ElemDesc->DtorFn;
+ auto Dtor = D->getElemDesc()->DtorFn;
assert(Dtor &&
"a composite array without an elem dtor shouldn't have a dtor itself");
for (unsigned I = 0; I != NumElems; ++I, ElemOffset += ElemSize) {
auto *ElemPtr = Ptr + ElemOffset;
auto *Desc = reinterpret_cast<InlineDescriptor *>(ElemPtr);
auto *ElemLoc = reinterpret_cast<std::byte *>(Desc + 1);
- Dtor(B, ElemLoc, D->ElemDesc);
+ Dtor(B, ElemLoc, D->getElemDesc());
}
}
@@ -157,8 +157,8 @@ static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
const Descriptor *D, unsigned FieldOffset,
bool IsVirtualBase) {
assert(D);
- assert(D->ElemRecord);
- assert(!D->ElemRecord->isUnion()); // Unions cannot be base classes.
+ assert(D->getElemRecord());
+ assert(!D->getElemRecord()->isUnion()); // Unions cannot be base classes.
auto *Desc = reinterpret_cast<InlineDescriptor *>(Ptr + FieldOffset) - 1;
Desc->Offset = FieldOffset;
@@ -172,10 +172,10 @@ static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
Desc->InUnion = InUnion;
Desc->IsVolatile = false;
- for (const auto &V : D->ElemRecord->bases())
+ for (const auto &V : D->getElemRecord()->bases())
initBase(B, Ptr + FieldOffset, IsConst, IsMutable, IsVolatile, IsActive,
InUnion, V.Desc, V.Offset, false);
- for (const auto &F : D->ElemRecord->fields())
+ for (const auto &F : D->getElemRecord()->fields())
initField(B, Ptr + FieldOffset, IsConst, IsMutable, IsVolatile, IsActive,
InUnion, InUnion, F.Desc, F.Offset);
}
@@ -183,16 +183,16 @@ static void initBase(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
static void ctorRecord(Block *B, std::byte *Ptr, bool IsConst, bool IsMutable,
bool IsVolatile, bool IsActive, bool InUnion,
const Descriptor *D) {
- for (const auto &V : D->ElemRecord->bases())
+ for (const auto &V : D->getElemRecord()->bases())
initBase(B, Ptr, IsConst, IsMutable, IsVolatile, IsActive, InUnion, V.Desc,
V.Offset,
/*IsVirtualBase=*/false);
- for (const auto &F : D->ElemRecord->fields()) {
+ for (const auto &F : D->getElemRecord()->fields()) {
bool IsUnionField = D->isUnion();
initField(B, Ptr, IsConst, IsMutable, IsVolatile, IsActive, IsUnionField,
InUnion || IsUnionField, F.Desc, F.Offset);
}
- for (const auto &V : D->ElemRecord->virtual_bases())
+ for (const auto &V : D->getElemRecord()->virtual_bases())
initBase(B, Ptr, IsConst, IsMutable, IsVolatile, IsActive, InUnion, V.Desc,
V.Offset,
/*IsVirtualBase=*/true);
@@ -207,20 +207,20 @@ static void destroyField(Block *B, std::byte *Ptr, const Descriptor *D,
static void destroyBase(Block *B, std::byte *Ptr, const Descriptor *D,
unsigned FieldOffset) {
assert(D);
- assert(D->ElemRecord);
+ assert(D->getElemRecord());
- for (const auto &V : D->ElemRecord->bases())
+ for (const auto &V : D->getElemRecord()->bases())
destroyBase(B, Ptr + FieldOffset, V.Desc, V.Offset);
- for (const auto &F : D->ElemRecord->fields())
+ for (const auto &F : D->getElemRecord()->fields())
destroyField(B, Ptr + FieldOffset, F.Desc, F.Offset);
}
static void dtorRecord(Block *B, std::byte *Ptr, const Descriptor *D) {
- for (const auto &F : D->ElemRecord->bases())
+ for (const auto &F : D->getElemRecord()->bases())
destroyBase(B, Ptr, F.Desc, F.Offset);
- for (const auto &F : D->ElemRecord->fields())
+ for (const auto &F : D->getElemRecord()->fields())
destroyField(B, Ptr, F.Desc, F.Offset);
- for (const auto &F : D->ElemRecord->virtual_bases())
+ for (const auto &F : D->getElemRecord()->virtual_bases())
destroyBase(B, Ptr, F.Desc, F.Offset);
}
@@ -282,10 +282,10 @@ static BlockDtorFn getDtorArrayPrim(PrimType Type) {
Descriptor::Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type,
bool IsConst, bool IsTemporary, bool IsMutable,
bool IsVolatile)
- : Source(D), SourceType(SourceTy), ElemSize(primSize(Type)), Size(ElemSize),
+ : Source(D), SourceType(SourceTy), CtorFn(getCtorPrim(Type)),
+ DtorFn(getDtorPrim(Type)), ElemSize(primSize(Type)), Size(ElemSize),
AllocSize(align(ElemSize)), PrimT(Type), IsConst(IsConst),
- IsMutable(IsMutable), IsTemporary(IsTemporary), IsVolatile(IsVolatile),
- CtorFn(getCtorPrim(Type)), DtorFn(getDtorPrim(Type)) {
+ IsMutable(IsMutable), IsTemporary(IsTemporary), IsVolatile(IsVolatile) {
assert(Source && "Missing source");
}
@@ -293,11 +293,11 @@ Descriptor::Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type,
Descriptor::Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type,
size_t NumElems, bool IsConst, bool IsTemporary,
bool IsMutable, bool IsVolatile)
- : Source(D), SourceType(SourceTy), ElemSize(primSize(Type)),
+ : Source(D), SourceType(SourceTy), CtorFn(getCtorArrayPrim(Type)),
+ DtorFn(getDtorArrayPrim(Type)), ElemSize(primSize(Type)),
Size(ElemSize * NumElems), AllocSize(align(Size) + sizeof(InitMapPtr)),
PrimT(Type), IsConst(IsConst), IsMutable(IsMutable),
- IsTemporary(IsTemporary), IsVolatile(IsVolatile), IsArray(true),
- CtorFn(getCtorArrayPrim(Type)), DtorFn(getDtorArrayPrim(Type)) {
+ IsTemporary(IsTemporary), IsVolatile(IsVolatile), IsArray(true) {
assert(Source && "Missing source");
assert(NumElems <= (MaxArrayElemBytes / ElemSize));
}
@@ -305,11 +305,11 @@ Descriptor::Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type,
/// Primitive unknown-size arrays.
Descriptor::Descriptor(DeclOrExpr D, PrimType Type, bool IsConst,
bool IsTemporary, UnknownSize)
- : Source(D), ElemSize(primSize(Type)), Size(UnknownSizeMark),
+ : Source(D), CtorFn(getCtorArrayPrim(Type)), DtorFn(getDtorArrayPrim(Type)),
+ ElemSize(primSize(Type)), Size(UnknownSizeMark),
AllocSize(sizeof(InitMapPtr) + alignof(void *)), PrimT(Type),
IsConst(IsConst), IsMutable(false), IsTemporary(IsTemporary),
- IsArray(true), CtorFn(getCtorArrayPrim(Type)),
- DtorFn(getDtorArrayPrim(Type)) {
+ IsArray(true) {
assert(Source && "Missing source");
}
@@ -317,40 +317,41 @@ Descriptor::Descriptor(DeclOrExpr D, PrimType Type, bool IsConst,
Descriptor::Descriptor(DeclOrExpr D, const Type *SourceTy,
const Descriptor *Elem, unsigned NumElems, bool IsConst,
bool IsTemporary, bool IsMutable)
- : Source(D), SourceType(SourceTy),
+ : Source(D), SourceType(SourceTy), ElemDescOrRecord(Elem),
+ CtorFn(ctorArrayDesc), DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr),
ElemSize(Elem->getAllocSize() + sizeof(InlineDescriptor)),
Size(ElemSize * NumElems),
- AllocSize(std::max<size_t>(alignof(void *), Size)), ElemDesc(Elem),
- IsConst(IsConst), IsMutable(IsMutable), IsTemporary(IsTemporary),
- IsArray(true), CtorFn(ctorArrayDesc),
- DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr) {
+ AllocSize(std::max<size_t>(alignof(void *), Size)), IsConst(IsConst),
+ IsMutable(IsMutable), IsTemporary(IsTemporary), IsArray(true) {
assert(Source && "Missing source");
}
/// Unknown-size arrays of composite elements.
Descriptor::Descriptor(DeclOrExpr D, const Descriptor *Elem, bool IsTemporary,
UnknownSize)
- : Source(D), ElemSize(Elem->getAllocSize() + sizeof(InlineDescriptor)),
- Size(UnknownSizeMark), AllocSize(alignof(void *)), ElemDesc(Elem),
- IsConst(true), IsMutable(false), IsTemporary(IsTemporary), IsArray(true),
- CtorFn(ctorArrayDesc), DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr) {
+ : Source(D), ElemDescOrRecord(Elem), CtorFn(ctorArrayDesc),
+ DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr),
+ ElemSize(Elem->getAllocSize() + sizeof(InlineDescriptor)),
+ Size(UnknownSizeMark), AllocSize(alignof(void *)), IsConst(true),
+ IsMutable(false), IsTemporary(IsTemporary), IsArray(true) {
assert(Source && "Missing source");
}
/// Composite records.
Descriptor::Descriptor(DeclOrExpr D, const Record *R, bool IsConst,
bool IsTemporary, bool IsMutable, bool IsVolatile)
- : Source(D), ElemSize(std::max<size_t>(alignof(void *), R->getFullSize())),
- Size(ElemSize), AllocSize(Size), ElemRecord(R), IsConst(IsConst),
- IsMutable(IsMutable), IsTemporary(IsTemporary), IsVolatile(IsVolatile),
- CtorFn(ctorRecord), DtorFn(needsRecordDtor(R) ? dtorRecord : nullptr) {
+ : Source(D), ElemDescOrRecord(R), CtorFn(ctorRecord),
+ DtorFn(needsRecordDtor(R) ? dtorRecord : nullptr),
+ ElemSize(std::max<size_t>(alignof(void *), R->getFullSize())),
+ Size(ElemSize), AllocSize(Size), IsConst(IsConst), IsMutable(IsMutable),
+ IsTemporary(IsTemporary), IsVolatile(IsVolatile) {
assert(Source && "Missing source");
}
/// Dummy.
Descriptor::Descriptor(DeclOrExpr D)
- : Source(D), ElemSize(1), Size(1), AllocSize(0), ElemDesc(nullptr),
- IsConst(true), IsMutable(false), IsTemporary(false) {
+ : Source(D), ElemSize(1), Size(1), AllocSize(0), IsConst(true),
+ IsMutable(false), IsTemporary(false) {
assert(Source && "Missing source");
}
@@ -364,7 +365,7 @@ QualType Descriptor::getType() const {
// The Source sometimes has a different type than the once
// we really save. Try to consult the Record first.
if (isRecord()) {
- const RecordDecl *RD = ElemRecord->getDecl();
+ const RecordDecl *RD = getElemRecord()->getDecl();
QualType T = RD->getASTContext().getTagType(ElaboratedTypeKeyword::None,
std::nullopt, RD, false);
if (IsConst)
@@ -399,7 +400,7 @@ QualType Descriptor::getElemQualType() const {
} else if (const auto *TDecl = dyn_cast_if_present<TypeDecl>(asDecl())) {
T = TDecl->getASTContext().getTypeDeclType(TDecl);
} else if (isRecord()) {
- const RecordDecl *RD = ElemRecord->getDecl();
+ const RecordDecl *RD = getElemRecord()->getDecl();
T = RD->getASTContext().getTagType(ElaboratedTypeKeyword::None,
std::nullopt, RD, false);
if (IsConst)
@@ -480,17 +481,18 @@ bool Descriptor::hasTrivialDtor() const {
return true;
if (isRecord()) {
- assert(ElemRecord);
- return ElemRecord->hasTrivialDtor();
+ return getElemRecord()->hasTrivialDtor();
}
- if (!ElemDesc)
- return true;
+ if (const Descriptor *ElemDesc = getElemDescOrNull())
+ return ElemDesc->hasTrivialDtor();
// Composite arrays.
- return ElemDesc->hasTrivialDtor();
+ return true;
}
-bool Descriptor::isUnion() const { return isRecord() && ElemRecord->isUnion(); }
+bool Descriptor::isUnion() const {
+ return isRecord() && getElemRecord()->isUnion();
+}
unsigned Descriptor::getElemDataSize() const {
if ((isPrimitive() || isPrimitiveArray()) &&
diff --git a/clang/lib/AST/ByteCode/Descriptor.h b/clang/lib/AST/ByteCode/Descriptor.h
index ee88b8bad3aee..466dddaf5b0bf 100644
--- a/clang/lib/AST/ByteCode/Descriptor.h
+++ b/clang/lib/AST/ByteCode/Descriptor.h
@@ -16,13 +16,14 @@
#include "DeclOrExpr.h"
#include "InitMap.h"
#include "PrimType.h"
+#include "Record.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
+#include <unistd.h>
namespace clang {
namespace interp {
class Block;
-class Record;
class SourceInfo;
struct Descriptor;
enum PrimType : uint8_t;
@@ -124,6 +125,15 @@ struct Descriptor final {
/// Original declaration, used to emit the error message.
const DeclOrExpr Source;
const Type *SourceType = nullptr;
+ const llvm::PointerUnion<const Record *, const Descriptor *>
+ ElemDescOrRecord = nullptr;
+
+public:
+ /// Storage management methods.
+ const BlockCtorFn CtorFn = nullptr;
+ const BlockDtorFn DtorFn = nullptr;
+
+private:
/// Size of an element, in host bytes.
const unsigned ElemSize;
/// Size of the storage, in host bytes.
@@ -142,10 +152,6 @@ struct Descriptor final {
static constexpr unsigned MaxArrayElemBytes =
std::numeric_limits<decltype(AllocSize)>::max() - sizeof(InitMapPtr);
- /// Pointer to the record, if block contains records.
- const Record *const ElemRecord = nullptr;
- /// Descriptor of the array element.
- const Descriptor *const ElemDesc = nullptr;
/// The primitive type this descriptor was created for,
/// or the primitive element type in case this is
/// a primitive array.
@@ -161,10 +167,6 @@ struct Descriptor final {
const bool IsArray = false;
bool IsConstexprUnknown = false;
- /// Storage management methods.
- const BlockCtorFn CtorFn = nullptr;
- const BlockDtorFn DtorFn = nullptr;
-
/// Allocates a descriptor for a primitive.
Descriptor(DeclOrExpr D, const Type *SourceTy, PrimType Type, bool IsConst,
bool IsTemporary, bool IsMutable, bool IsVolatile);
@@ -192,6 +194,19 @@ struct Descriptor final {
/// Allocates a dummy descriptor.
Descriptor(DeclOrExpr D);
+ const Descriptor *getElemDesc() const {
+ return cast<const Descriptor *>(ElemDescOrRecord);
+ }
+ const Descriptor *getElemDescOrNull() const {
+ return dyn_cast_if_present<const Descriptor *>(ElemDescOrRecord);
+ }
+ const Record *getElemRecord() const {
+ return cast<const Record *>(ElemDescOrRecord);
+ }
+ const Record *getElemRecordOrNull() const {
+ return dyn_cast_if_present<const Record *>(ElemDescOrRecord);
+ }
+
QualType getType() const;
QualType getElemQualType() const;
QualType getDataType(const ASTContext &Ctx) const;
@@ -218,10 +233,6 @@ struct Descriptor final {
return dyn_cast_if_present<RecordDecl>(asDecl());
}
- template <typename T> const T *getAs() const {
- return dyn_cast_if_present<T>(asDecl());
- }
-
/// Returns the size of the object without metadata.
unsigned getSize() const {
assert(!isUnknownSizeArray() && "Array of unknown size");
@@ -248,21 +259,23 @@ struct Descriptor final {
}
/// Checks if the descriptor is of an array of primitives.
- bool isPrimitiveArray() const { return IsArray && !ElemDesc; }
+ bool isPrimitiveArray() const { return IsArray && !getElemDescOrNull(); }
/// Checks if the descriptor is of an array of composites.
- bool isCompositeArray() const { return IsArray && ElemDesc; }
+ bool isCompositeArray() const { return IsArray && getElemDescOrNull(); }
/// Checks if the descriptor is of an array of zero size.
bool isZeroSizeArray() const { return Size == 0; }
/// Checks if the descriptor is of an array of unknown size.
bool isUnknownSizeArray() const { return Size == UnknownSizeMark; }
/// Checks if the descriptor is of a primitive.
- bool isPrimitive() const { return !IsArray && !ElemRecord && PrimT; }
+ bool isPrimitive() const {
+ return !IsArray && !getElemRecordOrNull() && PrimT;
+ }
/// Checks if the descriptor is of an array.
bool isArray() const { return IsArray; }
/// Checks if the descriptor is of a record.
- bool isRecord() const { return !IsArray && ElemRecord; }
+ bool isRecord() const { return !IsArray && getElemRecordOrNull(); }
/// Checks if the descriptor is of a union.
bool isUnion() const;
diff --git a/clang/lib/AST/ByteCode/Disasm.cpp b/clang/lib/AST/ByteCode/Disasm.cpp
index 9499d3a246706..f2b466171744d 100644
--- a/clang/lib/AST/ByteCode/Disasm.cpp
+++ b/clang/lib/AST/ByteCode/Disasm.cpp
@@ -453,9 +453,9 @@ LLVM_DUMP_METHOD void Descriptor::dump(llvm::raw_ostream &OS) const {
else if (isCompositeArray())
OS << " composite-array " << getNumElems();
else if (isUnion())
- OS << " union(" << ElemRecord->getName() << ")";
+ OS << " union(" << getElemRecord()->getName() << ")";
else if (isRecord())
- OS << " record(" << ElemRecord->getName() << ")";
+ OS << " record(" << getElemRecord()->getName() << ")";
else if (isPrimitive())
OS << " primitive " << primTypeToString(getPrimType());
@@ -484,9 +484,9 @@ LLVM_DUMP_METHOD void Descriptor::dumpFull(unsigned Offset,
for (unsigned I = 0; I != getNumElems(); ++I) {
FO += sizeof(InlineDescriptor);
OS.indent(Spaces) << "Element " << I << " offset: " << FO << '\n';
- ElemDesc->dumpFull(FO, Indent + 1);
+ getElemDesc()->dumpFull(FO, Indent + 1);
- FO += ElemDesc->getAllocSize();
+ FO += getElemDesc()->getAllocSize();
}
} else if (isPrimitiveArray()) {
OS.indent(Spaces) << "Elements: " << getNumElems() << '\n';
@@ -498,9 +498,9 @@ LLVM_DUMP_METHOD void Descriptor::dumpFull(unsigned Offset,
FO += getElemSize();
}
} else if (isRecord()) {
- ElemRecord->dump(OS, Indent + 1, Offset);
+ getElemRecord()->dump(OS, Indent + 1, Offset);
unsigned I = 0;
- for (const Record::Field &F : ElemRecord->fields()) {
+ for (const Record::Field &F : getElemRecord()->fields()) {
OS.indent(Spaces) << "- Field " << I << ": ";
{
ColorScope SC(OS, true, {llvm::raw_ostream::BRIGHT_RED, true});
diff --git a/clang/lib/AST/ByteCode/EvaluationResult.cpp b/clang/lib/AST/ByteCode/EvaluationResult.cpp
index 19a2744f73f15..d5b65e5a7868e 100644
--- a/clang/lib/AST/ByteCode/EvaluationResult.cpp
+++ b/clang/lib/AST/ByteCode/EvaluationResult.cpp
@@ -47,10 +47,10 @@ static bool CheckArrayInitialized(InterpState &S, SourceLocation Loc,
DiagnoseUninitializedSubobject(S, Loc, BasePtr.getField());
return false;
}
- const Descriptor *ElemDesc = BaseDesc->ElemDesc;
+ const Descriptor *ElemDesc = BaseDesc->getElemDesc();
if (ElemDesc->isRecord()) {
- const Record *R = ElemDesc->ElemRecord;
+ const Record *R = ElemDesc->getElemRecord();
for (size_t I = 0; I != NumElems; ++I) {
PtrView ElemPtr = BasePtr.atIndex(I).narrow();
Result &= CheckFieldsInitialized(S, Loc, ElemPtr, R);
@@ -166,8 +166,8 @@ static bool isOrHasPtr(const Descriptor *D) {
if ((D->isPrimitive() || D->isPrimitiveArray()) && D->getPrimType() == PT_Ptr)
return true;
- if (D->ElemRecord)
- return D->ElemRecord->hasPtrField();
+ if (D->isRecord())
+ return D->getElemRecord()->hasPtrField();
return false;
}
@@ -188,7 +188,7 @@ static void collectBlocks(PtrView Ptr, llvm::SetVector<const Block *> &Blocks,
if (!Desc)
return;
- if (const Record *R = Desc->ElemRecord) {
+ if (const Record *R = Desc->getElemRecordOrNull()) {
if (!R->hasPtrField())
return;
@@ -235,7 +235,7 @@ static void collectBlocks(PtrView Ptr, llvm::SetVector<const Block *> &Blocks,
return;
}
- if (Desc->isCompositeArray() && isOrHasPtr(Desc->ElemDesc)) {
+ if (Desc->isCompositeArray() && isOrHasPtr(Desc->getElemDesc())) {
for (unsigned I = 0; I != Desc->getNumElems(); ++I) {
PtrView ElemPtr = Ptr.atIndex(I).narrow();
collectBlocks(ElemPtr, Blocks);
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 7704550a12d82..2b6758edfc873 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1351,7 +1351,7 @@ static bool runRecordDestructor(InterpState &S, CodePtr OpPC,
const Pointer &BasePtr,
const Descriptor *Desc) {
assert(Desc->isRecord());
- const Record *R = Desc->ElemRecord;
+ const Record *R = Desc->getElemRecord();
assert(R);
if (!S.Current->isBottomFrame() && S.Current->hasThisPointer() &&
@@ -1390,7 +1390,7 @@ static bool RunDestructors(InterpState &S, CodePtr OpPC, const Block *B) {
unsigned N = Desc->getNumElems();
if (N == 0)
return true;
- const Descriptor *ElemDesc = Desc->ElemDesc;
+ const Descriptor *ElemDesc = Desc->getElemDesc();
assert(ElemDesc->isRecord());
Pointer RP(const_cast<Block *>(B));
@@ -1729,13 +1729,13 @@ static bool checkConstructor(InterpState &S, CodePtr OpPC, const Function *Func,
const Descriptor *D = ThisPtr.getFieldDesc();
// FIXME: I think this case is not 100% correct. E.g. a pointer into a
// subobject of a composite array.
- if (!D->ElemRecord)
+ if (!D->isRecord())
return true;
if (S.getLangOpts().CPlusPlus26)
return true;
- if (D->ElemRecord->getNumVirtualBases() == 0)
+ if (D->getElemRecord()->getNumVirtualBases() == 0)
return true;
S.FFDiag(S.Current->getLocation(OpPC), diag::note_constexpr_virtual_base)
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 54b2b4bb1b16d..f2b9b22ae773d 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -2310,7 +2310,7 @@ static std::optional<unsigned> computeFullDescSize(const ASTContext &ASTCtx,
// at the decl directly.
return ASTCtx
.getTypeSizeInChars(
- ASTCtx.getCanonicalTagType(Desc->ElemRecord->getDecl()))
+ ASTCtx.getCanonicalTagType(Desc->getElemRecord()->getDecl()))
.getQuantity();
}
@@ -6902,7 +6902,7 @@ static void zeroAll(PtrView Dest) {
}
if (Desc->isRecord()) {
- const Record *R = Desc->ElemRecord;
+ const Record *R = Desc->getElemRecord();
for (const Record::Field &F : R->fields()) {
PtrView FieldPtr = Dest.atField(F.Offset);
zeroAll(FieldPtr);
@@ -6953,8 +6953,8 @@ static bool copyRecord(InterpState &S, CodePtr OpPC, PtrView Src, PtrView Dest,
};
assert(SrcDesc->isRecord());
- assert(SrcDesc->ElemRecord == DestDesc->ElemRecord);
- const Record *R = DestDesc->ElemRecord;
+ assert(SrcDesc->getElemRecord() == DestDesc->getElemRecord());
+ const Record *R = DestDesc->getElemRecord();
for (const Record::Field &F : R->fields()) {
PtrView FP = Src.atField(F.Offset);
diff --git a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
index 2529bfc6c1cbd..59bb40b22a602 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp
@@ -130,7 +130,7 @@ static Result enumerateData(PtrView P, const Context &Ctx, Bits Offset,
// Records.
if (FieldDesc->isRecord()) {
- const Record *R = FieldDesc->ElemRecord;
+ const Record *R = FieldDesc->getElemRecord();
if (R->getDecl()->isInvalidDecl())
return Result::Failure;
const ASTRecordLayout &Layout =
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp
index 46f658f7cef64..46eab1b6ee747 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -1216,7 +1216,7 @@ IntPointer IntPointer::baseCast(const interp::Context &Ctx,
CharUnits BaseLayoutOffset =
Layout.getBaseClassOffset(cast<CXXRecordDecl>(BaseDesc->asDecl()));
- const RecordDecl *RD = BaseDesc->ElemRecord->getDecl();
+ const RecordDecl *RD = BaseDesc->getElemRecord()->getDecl();
QualType T = RD->getASTContext().getTagType(ElaboratedTypeKeyword::None,
std::nullopt, RD, false);
return {T.getTypePtr(), Value + BaseLayoutOffset.getQuantity()};
diff --git a/clang/lib/AST/ByteCode/Pointer.h b/clang/lib/AST/ByteCode/Pointer.h
index 78768929f3487..2cc10dad7aac2 100644
--- a/clang/lib/AST/ByteCode/Pointer.h
+++ b/clang/lib/AST/ByteCode/Pointer.h
@@ -150,10 +150,12 @@ struct PtrView {
return PtrView{Pointee, Base, Base};
}
- const Record *getRecord() const { return getFieldDesc()->ElemRecord; }
+ const Record *getRecord() const {
+ return getFieldDesc()->getElemRecordOrNull();
+ }
const Record *getElemRecord() const {
- const Descriptor *ElemDesc = getFieldDesc()->ElemDesc;
- return ElemDesc ? ElemDesc->ElemRecord : nullptr;
+ const Descriptor *ElemDesc = getFieldDesc()->getElemDescOrNull();
+ return ElemDesc ? ElemDesc->getElemRecord() : nullptr;
}
const FieldDecl *getField() const { return getFieldDesc()->asFieldDecl(); }
@@ -176,7 +178,7 @@ struct PtrView {
unsigned Adjust = 0;
if (Offset != Base) {
- if (getFieldDesc()->ElemDesc)
+ if (getFieldDesc()->getElemDescOrNull())
Adjust = sizeof(InlineDescriptor);
else
Adjust = sizeof(InitMapPtr);
@@ -196,7 +198,7 @@ struct PtrView {
PtrView atIndex(unsigned Idx) const {
unsigned Off = Idx * elemSize();
- if (getFieldDesc()->ElemDesc)
+ if (getFieldDesc()->getElemDescOrNull())
Off += sizeof(InlineDescriptor);
else
Off += sizeof(InitMapPtr);
diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp
index c838729fb599d..2b6aaab021d1e 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -396,7 +396,7 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
HasPtrField =
HasPtrField ||
(Desc->isPrimitiveArray() && Desc->getPrimType() == PT_Ptr) ||
- (Desc->ElemRecord && Desc->ElemRecord->hasPtrField());
+ (Desc->isRecord() && Desc->getElemRecord()->hasPtrField());
} else {
Desc = allocateDescriptor(FD);
}
More information about the cfe-commits
mailing list