================ @@ -3048,6 +3087,66 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclaration( if (DS.hasTagDefinition()) Actions.ActOnDefinedDeclarationSpecifier(DS.getRepAsDecl()); + // Handle C++26's variadic friend declarations. These don't even have + // declarators, so we get them out of the way early here. + if (DS.isFriendSpecifiedFirst() && Tok.isOneOf(tok::comma, tok::ellipsis)) { + SourceLocation FriendLoc = DS.getFriendSpecLoc(); + SmallVector<Decl *> Decls; + auto DiagnoseCompat = [&, Diagnosed = false]() mutable { + if (Diagnosed) + return; + Diagnosed = true; + Diag(Tok.getLocation(), getLangOpts().CPlusPlus26 + ? diag::warn_cxx23_variadic_friends + : diag::ext_variadic_friends); + }; + + // Handles a single friend-type-specifier. + auto ParsedFriendDecl = [&](ParsingDeclSpec &DeclSpec) { + bool Variadic = Tok.is(tok::ellipsis); + RecordDecl *AnonRecord = nullptr; + Decl *D = Actions.ParsedFreeStandingDeclSpec( + getCurScope(), AS, DeclSpec, DeclAttrs, TemplateParams, false, + AnonRecord, Variadic ? Tok.getLocation() : SourceLocation()); + DeclSpec.complete(D); + if (!D) { + SkipUntil(tok::semi, tok::r_brace); + return true; + } + + // Eat the '...'. + if (Variadic) { + DiagnoseCompat(); + ConsumeToken(); + } + + Decls.push_back(D); + return false; + }; + + if (ParsedFriendDecl(DS)) + return nullptr; + + if (Tok.is(tok::comma)) + DiagnoseCompat(); + + while (TryConsumeToken(tok::comma)) { + ParsingDeclSpec DeclSpec(*this, TemplateDiags); + const char *PrevSpec = nullptr; + unsigned DiagId = 0; + DeclSpec.SetFriendSpec(FriendLoc, PrevSpec, DiagId); + ParseDeclarationSpecifiers(DeclSpec, TemplateInfo, AS, + DeclSpecContext::DSC_class, nullptr); + if (ParsedFriendDecl(DeclSpec)) + return nullptr; + } ---------------- cor3ntin wrote:
Oh well, good enough! https://github.com/llvm/llvm-project/pull/101448 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits