[clang] [Clang] support friend declarations with a dependent nested-name-specifier (PR #191268)

Oleksandr Tarasiuk via cfe-commits cfe-commits at lists.llvm.org
Wed Apr 29 07:24:09 PDT 2026


================
@@ -18158,25 +18185,41 @@ DeclResult Sema::ActOnTemplatedFriendTag(
     }
   }
 
-  // Handle the case of a templated-scope friend class.  e.g.
-  //   template <class T> class A<T>::B;
-  // FIXME: we don't support these right now.
-  Diag(NameLoc, diag::warn_template_qualified_friend_unsupported)
-    << SS.getScopeRep() << SS.getRange() << cast<CXXRecordDecl>(CurContext);
+  NestedNameSpecifier NNS = SS.getScopeRep();
+  if (EllipsisLoc.isInvalid() &&
+      CheckDependentFriend(TagLoc, NNS, TempParamLists.front()))
+    return true;
+
   ElaboratedTypeKeyword ETK = TypeWithKeyword::getKeywordForTagTypeKind(Kind);
-  QualType T = Context.getDependentNameType(ETK, SS.getScopeRep(), Name);
+  QualType T = Context.getDependentNameType(ETK, NNS, Name);
   TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T);
+
   DependentNameTypeLoc TL = TSI->getTypeLoc().castAs<DependentNameTypeLoc>();
   TL.setElaboratedKeywordLoc(TagLoc);
   TL.setQualifierLoc(SS.getWithLocInContext(Context));
   TL.setNameLoc(NameLoc);
 
-  FriendDecl *Friend =
-      FriendDecl::Create(Context, CurContext, NameLoc, TSI, FriendLoc,
-                         EllipsisLoc, TempParamLists);
+  Decl *Friend;
+  if (TempParamLists.empty())
+    Friend = FriendDecl::Create(Context, CurContext, NameLoc, TSI, FriendLoc,
+                                EllipsisLoc);
+  else {
+    if (CheckTemplateDeclScope(S, TempParamLists.back()))
+      return true;
+
+    Friend = FriendTemplateDecl::Create(Context, CurContext, NameLoc, TSI,
+                                        FriendLoc, TempParamLists, EllipsisLoc);
+  }
+
+  if (EllipsisLoc.isValid() && NNS.isDependent()) {
+    Diag(NameLoc, diag::warn_template_qualified_friend_unsupported)
+        << SS.getScopeRep() << SS.getRange() << cast<CXXRecordDecl>(CurContext);
+    cast<FriendDecl>(Friend)->setUnsupportedFriend(true);
+  }
+
----------------
a-tarasyuk wrote:

@cor3ntin, we need this because the current changes don’t fully cover the following cases

https://github.com/llvm/llvm-project/blob/3dd75651e5d6d369fb94a22efb4af15368b0511a/clang/test/Parser/cxx2c-variadic-friends.cpp#L59-L65

I can proceed and add support for them, but it would be better to handle this in a separate PR. WDYT?


https://github.com/llvm/llvm-project/pull/191268


More information about the cfe-commits mailing list