[clang] [Clang] Implement C++26’s P2893R3 ‘Variadic friends’ (PR #101448)
Aaron Ballman via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 14 06:34:07 PDT 2024
================
@@ -1442,8 +1442,49 @@ Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) {
if (D->isUnsupportedFriend()) {
InstTy = Ty;
} else {
- InstTy = SemaRef.SubstType(Ty, TemplateArgs,
- D->getLocation(), DeclarationName());
+ if (D->isVariadic()) {
+ SmallVector<UnexpandedParameterPack, 2> Unexpanded;
+ SemaRef.collectUnexpandedParameterPacks(Ty->getTypeLoc(), Unexpanded);
+ assert(!Unexpanded.empty() && "Pack expansion without packs");
+
+ bool ShouldExpand = true;
+ bool RetainExpansion = false;
+ std::optional<unsigned> NumExpansions;
+ if (SemaRef.CheckParameterPacksForExpansion(
+ D->getEllipsisLoc(), D->getSourceRange(), Unexpanded,
+ TemplateArgs, ShouldExpand, RetainExpansion, NumExpansions))
+ return nullptr;
+
+ assert(!RetainExpansion &&
+ "should never retain an expansion for a FriendPackDecl");
+
+ if (ShouldExpand) {
+ SmallVector<FriendDecl *> Decls;
+ for (unsigned I = 0; I != *NumExpansions; I++) {
+ Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
+ TypeSourceInfo *TSI = SemaRef.SubstType(
+ Ty, TemplateArgs, D->getEllipsisLoc(), DeclarationName());
+ if (!TSI)
+ return nullptr;
+
+ auto FD =
+ FriendDecl::Create(SemaRef.Context, Owner, D->getLocation(),
+ TSI, D->getFriendLoc());
+
+ FD->setAccess(AS_public);
+ Owner->addDecl(FD);
----------------
AaronBallman wrote:
I *think* that is not a bug (I think this gets called on the thing that is being friended, not on the friend itself), but I'd appreciate a second opinion from @zygoloid or @rjmccall
https://github.com/llvm/llvm-project/pull/101448
More information about the cfe-commits
mailing list