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; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
