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

Reply via email to