robk-dev wrote:

Two pre-existing issues turned up while implementing the `DeclVendor` on this 
branch.
Neither is introduced here and neither is fixed here, but both shape what this 
PR can
claim, so they seem worth recording. Line numbers are against `c45f19e967de`.

### 1. The GNUstep v2 ABI ivar list omits struct field names

`ASTContext::getObjCEncodingForType` documents that *"if `Field` is specified 
then record
field names are also encoded"*. Three call sites emit ivar type encodings, and 
one of them
does not pass it:

| | call | field names |
|---|---|---|
| `CGObjCMac.cpp:6547` | `getObjCEncodingForType(Field->getType(), TypeStr, 
Field)` | yes |
| `CGObjCGNU.cpp:3802` (older ABI) | `getObjCEncodingForType(IVD->getType(), 
TypeStr, IVD)` | yes |
| `CGObjCGNU.cpp:1884` (v2 ABI) | 
`getObjCEncodingForMethodParameter(Decl::OBJC_TQ_None, ivarTy, TypeStr, true)` 
| **no** |

`getObjCEncodingForMethodParameter` has no `FieldDecl` parameter to pass. 
Directly above
it, line 1883 is a commented-out `//Context.getObjCEncodingForType(ivarTy, 
TypeStr, IVD, true);`.

Observable in the shipped library, via the ivar offset symbol that embeds the 
encoding:

```
__objc_ivar_offset_NSURLComponents._rangeOfFragment.{_NSRange=QQ}
```

i.e. `{_NSRange=QQ}` rather than `{_NSRange="location"Q"length"Q}`.

The consequence for a debugger is narrow but real: a class's own ivars are 
reachable by
name from runtime metadata, but members *inside* a struct-typed ivar are not. 
That is why
the `NSDictionary` and `NSSet` formatters in this PR still require DWARF — they 
walk
`GSIMapTable_t` by member name — while the string, number, array, data, date, 
`NSURL` and
`NSException` formatters work from runtime metadata alone.

I have not sent a patch because I do not know whether the omission is 
deliberate. The
encoding is part of the ABI surface libobjc2 consumes, and 
`GetIVarOffsetVariableName`
(`CGObjCGNU.cpp:1709`) puts it in a symbol name specifically so the linker 
rejects
mismatched types, so lengthening it changes those symbols. Happy to send one if 
a
GNUstep-runtime owner thinks it should match the other two paths.

### 2. `AppleObjCDeclVendor` drops an ivar whose encoding will not realize

`AppleObjCDeclVendor.cpp:482` guards decl creation with `if 
(ivar_type.IsValid())`, so an
ivar whose encoding fails to realize is skipped. Clang then lays the interface 
out from the
ivars that remain, which silently shifts the offset of every ivar after it — 
the debugger
reports wrong values rather than declining to answer.

The callback already receives the ivar's size (`AppleObjCDeclVendor.cpp:469`) 
and does not
use it, so the information needed to avoid this is in hand.

The GNUstep vendor in this PR started out with the same shape, since it was 
modelled on the
Apple one. It now emits an opaque `char[size]` ivar instead of dropping the 
entry, which
keeps every later offset correct and shows the unrealizable ivar as bytes. The 
equivalent
change looks applicable to `AppleObjCDeclVendor`, but I have no Apple-runtime 
setup to test
it on, so I have not touched it. Honouring the runtime-supplied offset 
directly, rather than
letting clang compute the layout at all, would be the more complete fix for 
both.

---

*Written with AI assistance, as noted in the PR description.*


https://github.com/llvm/llvm-project/pull/216709
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to