@@ -18,8 +18,7 @@ namespace interp {
18
18
std::optional<Pointer> MemberPointer::toPointer (const Context &Ctx) const {
19
19
if (!Dcl || isa<FunctionDecl>(Dcl))
20
20
return Base;
21
- const FieldDecl *FD = cast<FieldDecl>(Dcl);
22
- assert (FD);
21
+ assert ((isa<FieldDecl, IndirectFieldDecl>(Dcl)));
23
22
24
23
if (!Base.isBlockPointer ())
25
24
return std::nullopt;
@@ -31,24 +30,36 @@ std::optional<Pointer> MemberPointer::toPointer(const Context &Ctx) const {
31
30
if (!BaseRecord)
32
31
return std::nullopt;
33
32
34
- assert (BaseRecord);
35
- if (FD->getParent () == BaseRecord->getDecl ())
36
- return CastedBase.atField (BaseRecord->getField (FD)->Offset );
37
-
38
- const RecordDecl *FieldParent = FD->getParent ();
39
- const Record *FieldRecord = Ctx.getRecord (FieldParent);
40
-
41
33
unsigned Offset = 0 ;
42
- Offset += FieldRecord->getField (FD)->Offset ;
43
34
Offset += CastedBase.block ()->getDescriptor ()->getMetadataSize ();
44
35
45
- if (Offset > CastedBase.block ()->getSize ())
46
- return std::nullopt;
36
+ if (const auto *FD = dyn_cast<FieldDecl>(Dcl)) {
37
+ if (FD->getParent () == BaseRecord->getDecl ())
38
+ return CastedBase.atField (BaseRecord->getField (FD)->Offset );
47
39
48
- if (const RecordDecl *BaseDecl = Base.getDeclPtr ().getRecord ()->getDecl ();
49
- BaseDecl != FieldParent)
50
- Offset += Ctx.collectBaseOffset (FieldParent, BaseDecl);
40
+ const RecordDecl *FieldParent = FD->getParent ();
41
+ const Record *FieldRecord = Ctx.getRecord (FieldParent);
51
42
43
+ Offset += FieldRecord->getField (FD)->Offset ;
44
+ if (Offset > CastedBase.block ()->getSize ())
45
+ return std::nullopt;
46
+
47
+ if (const RecordDecl *BaseDecl = Base.getDeclPtr ().getRecord ()->getDecl ();
48
+ BaseDecl != FieldParent)
49
+ Offset += Ctx.collectBaseOffset (FieldParent, BaseDecl);
50
+
51
+ } else {
52
+ const auto *IFD = cast<IndirectFieldDecl>(Dcl);
53
+
54
+ for (const NamedDecl *ND : IFD->chain ()) {
55
+ const FieldDecl *F = cast<FieldDecl>(ND);
56
+ const RecordDecl *FieldParent = F->getParent ();
57
+ const Record *FieldRecord = Ctx.getRecord (FieldParent);
58
+ Offset += FieldRecord->getField (F)->Offset ;
59
+ }
60
+ }
61
+
62
+ assert (BaseRecord);
52
63
if (Offset > CastedBase.block ()->getSize ())
53
64
return std::nullopt;
54
65
0 commit comments