================
@@ -479,24 +479,109 @@ til::SExpr *SExprBuilder::translateDeclRefExpr(const 
DeclRefExpr *DRE,
   if (const auto *VarD = dyn_cast<VarDecl>(VD))
     return translateVariable(VarD, Ctx);
 
+  // A member named through anonymous structs/unions is an IndirectFieldDecl;
+  // name it by its field.
+  const auto *IFD = dyn_cast<IndirectFieldDecl>(VD);
+  if (IFD)
+    VD = IFD->getAnonField();
+
   // FIXME: A FieldDecl reached via a DeclRefExpr should ideally be modelled as
   // a MemberExpr with an artificial self in the AST (e.g. ImplicitThisExpr as 
a
   // C equivalent of CXXThisExpr). Until such AST support is available, project
   // the field on the current SelfArg, so implicit member references in C and 
in
-  // parameter attributes are not lost.
-  if (const auto *FD = dyn_cast<FieldDecl>(VD); FD && Ctx && Ctx->SelfArg) {
-    til::SExpr *BE = translateCXXThisExpr(nullptr, Ctx);
-    til::SExpr *E = new (Arena) til::SApply(BE);
-    til::Project *P = new (Arena) til::Project(E, FD);
-    if (hasAnyPointerType(BE))
-      P->setArrow(true);
-    return P;
+  // parameter attributes are not lost. (A chain rooted in a VarDecl, from a
----------------
melver wrote:

In Sema::BuildDeclarationNameExpr, any non-member IndirectFieldDecl 
(!IndirectField->isCXXClassMember(), which is the exact case where 
IFD->getVarDecl() is non-null, such as a namespace- or block-scope anonymous 
union) is lowered immediately via BuildAnonymousStructUnionMemberReference into 
a MemberExpr chain rooted at the implicit VarDecl; it never forms a 
DeclRefExpr(IndirectFieldDecl). Also, since FD is already IFD->getAnonField() 
(i.e. IFD->chain().back()), we can project IFD->chain().drop_back() directly 
followed by FD and avoid the SmallVector copy:

```
    -  // parameter attributes are not lost. (A chain rooted in a VarDecl, from 
a
    -  // namespace-scope anonymous union, is a named object instead.)
    -  if (const auto *FD = dyn_cast<FieldDecl>(VD);
    -      FD && Ctx && Ctx->SelfArg && !(IFD && IFD->getVarDecl())) {
    -    // Project each anonymous member of the chain in turn.
    -    SmallVector<const FieldDecl *> Chain;
    -    if (IFD)
    -      for (const NamedDecl *ND : IFD->chain())
    -        Chain.push_back(cast<FieldDecl>(ND));
    -    else
    -      Chain.push_back(FD);
    +  // parameter attributes are not lost.
    +  if (const auto *FD = dyn_cast<FieldDecl>(VD); FD && Ctx && Ctx->SelfArg) 
{
    +    assert((!IFD || !IFD->getVarDecl()) &&
    +           "non-member IndirectFieldDecl should be a MemberExpr");
         bool Found;
    -    til::SExpr *E = translateFieldOwner(Chain.front()->getParent(), Ctx, 
Found);
    -    til::Project *P = nullptr;
    -    for (const FieldDecl *Member : Chain)
    -      E = P = translateProject(E, Member);
    -    assert(P && "a field or a non-empty chain");
    +    const auto *Owner =
    +        cast<FieldDecl>(IFD ? IFD->chain().front() : FD)->getParent();
    +    til::SExpr *E = translateFieldOwner(Owner, Ctx, Found);
    +    if (IFD)
    +      for (const NamedDecl *ND : IFD->chain().drop_back())
    +        E = translateProject(E, cast<FieldDecl>(ND));
    +    til::Project *P = translateProject(E, FD);
         // Say whose field this is when self does not have it.
         P->setQualified(!Found);
    -    return E;
    +    return P;
       }
```

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

Reply via email to