https://github.com/Michael137 commented:
I have the suspicion that this could be done simpler.
`CXXRecordDecl::lookupInBases` is already perfectly capable of finding field in
anonymous structures in bases. That's why the expression evaluator is able to
find them just fine.
I think the actual problem lies in our logic that iterates the `CXXBasePaths`
after the `lookupInBases` lookup.
The field of the anonymous structure *is found* by `lookupInBases`. It is an
`IndirectFieldDecl`. But we fail to extract it in:
```
for (clang::DeclContext::lookup_iterator I = path->Decls, E;
I != E; ++I) {
child_idx = GetIndexForRecordChild(
parent_record_decl, *I, omit_empty_base_classes);
if (child_idx == UINT32_MAX) {
child_indexes.clear();
return 0;
```
Here `GetIndexForRecordChild` doesn't correctly get the index of the
`IndirectFieldDecl`:
```
6702 clang::RecordDecl::field_iterator field, field_end;
6703 for (field = record_decl->field_begin(), field_end =
record_decl->field_end();
6704 field != field_end; ++field, ++child_idx) {
-> 6705 if (field->getCanonicalDecl() == canonical_decl)
6706 return child_idx;
6707 }
6708
6709 return UINT32_MAX;
6710 }
6711
6712 // Look for a child member (doesn't include base classes, but it does
include
6713 // their members) in the type hierarchy. Returns an index path into
6714 // "clang_type" on how to reach the appropriate member.
6715 //
Target 0: (lldb) stopped.
(lldb) p field->getCanonicalDecl()->dump()
FieldDecl 0x7e9f01418 <<invalid sloc>> <invalid sloc> implicit
'Base::(anonymous struct)'
(lldb) p canonical_decl->dump()
IndirectFieldDecl 0x7e9f014c8 <<invalid sloc>> <invalid sloc> implicit x 'int'
|-Field 0x7e9f01418 field_index 0 'Base::(anonymous struct)'
`-Field 0x7e9f013c0 'x' 'int'
```
I haven't fully thought this through, but could we adjust
`GetIndexForRecordChild` to look into unwrap the anonymous union?
We can fish out the underlying `FieldDecl`s in both cases:
```
(lldb) p ((clang::IndirectFieldDecl*)canonical_decl)->getAnonField()
(clang::FieldDecl *) 0x0000000c563293c0
(lldb) p field->getType()->getAsCXXRecordDecl()->field_begin()
(clang::RecordDecl::field_iterator) {
Current = {
Current = 0x0000000c563293c0
}
}
(lldb) p field->getType()->getAsCXXRecordDecl()->field_begin()->dump()
FieldDecl 0xc563293c0 <<invalid sloc>> <invalid sloc> x 'int'
```
So in pseudo-code, maybe the function could look something like:
```
uint32_t TypeSystemClang::GetIndexForRecordChild(
const clang::RecordDecl *record_decl, clang::NamedDecl *canonical_decl,
bool omit_empty_base_classes) {
uint32_t child_idx = TypeSystemClang::GetNumBaseClasses(
llvm::dyn_cast<clang::CXXRecordDecl>(record_decl),
omit_empty_base_classes);
clang::RecordDecl::field_iterator field, field_end;
for (field = record_decl->field_begin(), field_end = record_decl->field_end();
field != field_end; ++field, ++child_idx) {
IndirectFieldDecl * indirect_decl =
llvm::dyn_cast<IndirectFieldDecl>(canonical_decl);
if (field is unnamed && indirect_decl) {
for (anon_field : fields of anonymous structure)
if (anon_field == canonical_decl->getAnonField())
return child_idx;
} else if (field == canonical_decl)
return child_idx;
}
return UINT32_MAX;
}
```
Might need to adjust the `child_idx` calculation here. But hopefully that
conveys the overall idea.
Let me know if you have any questions or if you think this doesn't work
https://github.com/llvm/llvm-project/pull/158256
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits