martinboehme wrote:

> Another possibility to consider: when [transforming a member 
> access](https://github.com/llvm/llvm-project/blob/ff210b94d449de8ebe1f32cf0d7763ba63b27b39/clang/lib/Sema/TreeTransform.h#L11950),
>  strip off any implicit member accesses from the base expression before 
> transforming the base. That way, we'll rebuild the implicit member access 
> from scratch, which might be a little more work, but should get details like 
> this one right. (We can then probably also remove the logic to deal with an 
> absent `DeclName` in `RebuildMemberExpr` since that shouldn't happen any 
> more.)

This sounds enticing, but after experimenting with this a bit, I’ve concluded 
that it’s unfortunately not so simple to get this working (unless there’s 
something I’m overlooking).

Looking at the relevant part of the AST:

```cxx
    `-MemberExpr <col:10, col:14> 'int' xvalue .i 0xbdcb3c0
      `-MemberExpr <col:10, col:14> 'S::(anonymous struct at line:2:3)' xvalue 
.S::(anonymous struct at line:2:3) 0xbdcb488
        `-MaterializeTemporaryExpr <col:10, col:12> 'S' xvalue
          `-CXXTemporaryObjectExpr <col:10, col:12> 'S' 'void () noexcept' 
zeroing
```

What I think you’re suggesting is that while processing the base for the outer 
`MemberExpr` (the one for `.i`), we strip the inner `MemberExpr` (the one for 
the anonymous field). The idea would be that the `MemberExpr` for the anonymous 
field should get recreated within `Sema::BuildMemberReferenceExpr()` when it’s 
called with the field declaration for `i`.

This _would_ work if we handed an `IndirectFieldDecl` to 
`BuildMemberReferenceExpr()`, but the problem is that we have no easy way of 
getting to the `IndirectFieldDecl`. The `getMemberDecl()` for the outer 
`MemberExpr` is a plain `FieldDecl`; the `getFoundDecl()` is, too.

The `getFoundDecl()` for the _inner_ `MemberExpr` does refer to the 
`IndirectFieldDecl` we want. So we could try to retain only this `MemberExpr` 
and strip the others – but then we run into the issue that there may not even 
_be_ an inner `MemberExpr` if the anonymous union is declared inside a function 
rather than inside a class ([example](https://godbolt.org/z/s1qqj5rY3)).

My feeling is that rather than trying to deal with all of the various cases 
involved in stripping, then recreating the implicit `MemberExpr`s, we retain 
them and merely recreate the `MaterializeTemporaryExpr` if needed.

https://github.com/llvm/llvm-project/pull/90842
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to