[clang] 89d2d7a - [clang][bytecode] Avoid classifying struct fields in `Pointer::toRValue` (#185903)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 13 01:14:04 PDT 2026
Author: Timm Baeder
Date: 2026-03-13T09:13:59+01:00
New Revision: 89d2d7aa87e271ea00aa621f7937dacd4ed90aa4
URL: https://github.com/llvm/llvm-project/commit/89d2d7aa87e271ea00aa621f7937dacd4ed90aa4
DIFF: https://github.com/llvm/llvm-project/commit/89d2d7aa87e271ea00aa621f7937dacd4ed90aa4.diff
LOG: [clang][bytecode] Avoid classifying struct fields in `Pointer::toRValue` (#185903)
We already did that when creating the fields. Look at the `PrimType`
saved in the `Descriptor` instead.
Added:
Modified:
clang/lib/AST/ByteCode/Pointer.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp
index f4352e7edf5f8..740a72ca241a8 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -803,11 +803,8 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
Ptr.isPastEnd())
return false;
- // Primitive values.
- if (OptPrimType T = Ctx.classify(Ty)) {
- TYPE_SWITCH(*T, R = Ptr.deref<T>().toAPValue(ASTCtx));
- return true;
- }
+ // Primitives should never end up here.
+ assert(!Ctx.canClassify(Ty));
if (const auto *RT = Ty->getAsCanonical<RecordType>()) {
const auto *Record = Ptr.getRecord();
@@ -819,11 +816,13 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
APValue Value;
for (const auto &F : Record->fields()) {
const Pointer &FP = Ptr.atField(F.Offset);
- QualType FieldTy = F.Decl->getType();
if (FP.isActive()) {
- if (OptPrimType T = Ctx.classify(FieldTy)) {
- TYPE_SWITCH(*T, Value = FP.deref<T>().toAPValue(ASTCtx));
+ const Descriptor *Desc = F.Desc;
+ if (Desc->isPrimitive()) {
+ TYPE_SWITCH(Desc->getPrimType(),
+ Value = FP.deref<T>().toAPValue(ASTCtx));
} else {
+ QualType FieldTy = F.Decl->getType();
Ok &= Composite(FieldTy, FP, Value);
}
ActiveField = FP.getFieldDesc()->asFieldDecl();
@@ -838,27 +837,28 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
R = APValue(APValue::UninitStruct(), NB, NF);
- for (unsigned I = 0; I < NF; ++I) {
+ for (unsigned I = 0; I != NF; ++I) {
const Record::Field *FD = Record->getField(I);
- QualType FieldTy = FD->Decl->getType();
+ const Descriptor *Desc = FD->Desc;
const Pointer &FP = Ptr.atField(FD->Offset);
APValue &Value = R.getStructField(I);
-
- if (OptPrimType T = Ctx.classify(FieldTy)) {
- TYPE_SWITCH(*T, Value = FP.deref<T>().toAPValue(ASTCtx));
+ if (Desc->isPrimitive()) {
+ TYPE_SWITCH(Desc->getPrimType(),
+ Value = FP.deref<T>().toAPValue(ASTCtx));
} else {
+ QualType FieldTy = FD->Decl->getType();
Ok &= Composite(FieldTy, FP, Value);
}
}
- for (unsigned I = 0; I < NB; ++I) {
+ for (unsigned I = 0; I != NB; ++I) {
const Record::Base *BD = Record->getBase(I);
QualType BaseTy = Ctx.getASTContext().getCanonicalTagType(BD->Decl);
const Pointer &BP = Ptr.atField(BD->Offset);
Ok &= Composite(BaseTy, BP, R.getStructBase(I));
}
- for (unsigned I = 0; I < NV; ++I) {
+ for (unsigned I = 0; I != NV; ++I) {
const Record::Base *VD = Record->getVirtualBase(I);
QualType VirtBaseTy =
Ctx.getASTContext().getCanonicalTagType(VD->Decl);
@@ -893,22 +893,22 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
}
// Complex types.
- if (const auto *CT = Ty->getAs<ComplexType>()) {
+ if (Ty->isAnyComplexType()) {
+ const Descriptor *Desc = Ptr.getFieldDesc();
// Can happen via C casts.
- if (!Ptr.getFieldDesc()->isPrimitiveArray())
+ if (!Desc->isPrimitiveArray())
return false;
- QualType ElemTy = CT->getElementType();
- if (ElemTy->isIntegerType()) {
- OptPrimType ElemT = Ctx.classify(ElemTy);
- assert(ElemT);
- INT_TYPE_SWITCH(*ElemT, {
+ PrimType ElemT = Desc->getPrimType();
+ if (isIntegerOrBoolType(ElemT)) {
+ PrimType ElemT = Desc->getPrimType();
+ INT_TYPE_SWITCH(ElemT, {
auto V1 = Ptr.elem<T>(0);
auto V2 = Ptr.elem<T>(1);
R = APValue(V1.toAPSInt(), V2.toAPSInt());
return true;
});
- } else if (ElemTy->isFloatingType()) {
+ } else if (ElemT == PT_Float) {
R = APValue(Ptr.elem<Floating>(0).getAPFloat(),
Ptr.elem<Floating>(1).getAPFloat());
return true;
@@ -918,9 +918,9 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
// Vector types.
if (const auto *VT = Ty->getAs<VectorType>()) {
+ const Descriptor *Desc = Ptr.getFieldDesc();
assert(Ptr.getFieldDesc()->isPrimitiveArray());
- QualType ElemTy = VT->getElementType();
- PrimType ElemT = *Ctx.classify(ElemTy);
+ PrimType ElemT = Desc->getPrimType();
SmallVector<APValue> Values;
Values.reserve(VT->getNumElements());
@@ -937,8 +937,8 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
// Constant Matrix types.
if (const auto *MT = Ty->getAs<ConstantMatrixType>()) {
assert(Ptr.getFieldDesc()->isPrimitiveArray());
- QualType ElemTy = MT->getElementType();
- PrimType ElemT = *Ctx.classify(ElemTy);
+ const Descriptor *Desc = Ptr.getFieldDesc();
+ PrimType ElemT = Desc->getPrimType();
unsigned NumElems = MT->getNumElementsFlattened();
SmallVector<APValue> Values;
More information about the cfe-commits
mailing list