================
@@ -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