llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-tools-extra

Author: Oleksandr Tarasiuk (a-tarasyuk)

<details>
<summary>Changes</summary>

Reverts llvm/llvm-project#<!-- -->208345

---

Revert dependent friend support due to GCC build failure

---

Patch is 234.68 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/216549.diff


64 Files Affected:

- (modified) clang-tools-extra/clang-doc/Serialize.cpp (+3) 
- (modified) clang/docs/ReleaseNotes.md (-1) 
- (modified) clang/include/clang/AST/ASTNodeTraverser.h (-8) 
- (modified) clang/include/clang/AST/DeclFriend.h (+100-25) 
- (modified) clang/include/clang/AST/DeclTemplate.h (+49-52) 
- (modified) clang/include/clang/AST/JSONNodeDumper.h (-1) 
- (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+7-5) 
- (modified) clang/include/clang/AST/TextNodeDumper.h (-1) 
- (modified) clang/include/clang/Basic/DeclNodes.td (+1-1) 
- (modified) clang/include/clang/Basic/DiagnosticGroups.td (+1) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+10-15) 
- (modified) clang/include/clang/Sema/Sema.h (+2-28) 
- (modified) clang/include/clang/Sema/Template.h (+1-7) 
- (modified) clang/include/clang/Sema/TemplateDeduction.h (+3-14) 
- (modified) clang/include/clang/Serialization/ASTBitCodes.h (-8) 
- (modified) clang/lib/AST/ASTImporter.cpp (+34-99) 
- (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+4-48) 
- (modified) clang/lib/AST/DeclFriend.cpp (+26-39) 
- (modified) clang/lib/AST/DeclPrinter.cpp (+12-27) 
- (modified) clang/lib/AST/DeclTemplate.cpp (+13-44) 
- (modified) clang/lib/AST/JSONNodeDumper.cpp (-14) 
- (modified) clang/lib/AST/ODRHash.cpp (-28) 
- (modified) clang/lib/AST/TextNodeDumper.cpp (-12) 
- (modified) clang/lib/Index/IndexDecl.cpp (-9) 
- (modified) clang/lib/Parse/ParseDeclCXX.cpp (+6-11) 
- (modified) clang/lib/Sema/Sema.cpp (+2-3) 
- (modified) clang/lib/Sema/SemaAccess.cpp (+99-679) 
- (modified) clang/lib/Sema/SemaCodeComplete.cpp (-1) 
- (modified) clang/lib/Sema/SemaConcept.cpp (+3-4) 
- (modified) clang/lib/Sema/SemaDecl.cpp (+3-6) 
- (modified) clang/lib/Sema/SemaDeclCXX.cpp (+128-304) 
- (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+2-3) 
- (modified) clang/lib/Sema/SemaOverload.cpp (+8-16) 
- (modified) clang/lib/Sema/SemaTemplate.cpp (+7-17) 
- (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+37-191) 
- (modified) clang/lib/Sema/SemaTemplateDeductionGuide.cpp (+3-4) 
- (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+73-335) 
- (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+12-24) 
- (modified) clang/lib/Serialization/ASTWriterDecl.cpp (+14-32) 
- (removed) clang/test/AST/friend-template-decl.cpp (-37) 
- (modified) clang/test/CXX/class.access/class.friend/p3-cxx0x.cpp (+2-2) 
- (modified) clang/test/CXX/drs/cwg18xx.cpp (+9-9) 
- (modified) clang/test/CXX/drs/cwg19xx.cpp (+8-7) 
- (modified) clang/test/CXX/drs/cwg28xx.cpp (+4-8) 
- (modified) clang/test/CXX/drs/cwg6xx.cpp (+9-12) 
- (modified) clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp (-26) 
- (modified) clang/test/CXX/temp/temp.decls/temp.friend/p5.cpp (+13-1089) 
- (removed) clang/test/CXX/temp/temp.decls/temp.friend/p6.cpp (-27) 
- (removed) clang/test/Index/load-dependent-friend-template.cpp (-15) 
- (modified) clang/test/Modules/odr_hash.cpp (-26) 
- (modified) clang/test/Parser/cxx2c-variadic-friends.cpp (+4-7) 
- (modified) clang/test/SemaCXX/cxx2c-variadic-friends.cpp (-57) 
- (modified) clang/test/SemaCXX/many-template-parameter-lists.cpp (+7-8) 
- (modified) clang/test/SemaTemplate/GH71595.cpp (+2-6) 
- (modified) clang/test/SemaTemplate/concepts-friends.cpp (-58) 
- (modified) clang/test/SemaTemplate/ctad.cpp (+10-14) 
- (removed) clang/test/SemaTemplate/dependent-friend-constraints.cpp (-263) 
- (modified) clang/test/SemaTemplate/friend-template.cpp (+5-29) 
- (modified) clang/test/SemaTemplate/nested-template.cpp (-14) 
- (modified) clang/tools/libclang/CIndex.cpp (-8) 
- (modified) clang/tools/libclang/CursorVisitor.h (-1) 
- (modified) clang/unittests/AST/DeclTest.cpp (-120) 
- (modified) clang/unittests/AST/StructuralEquivalenceTest.cpp (-19) 
- (modified) clang/www/cxx_dr_status.html (+4-4) 


``````````diff
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp 
b/clang-tools-extra/clang-doc/Serialize.cpp
index 5fa23416949c4..50118e0472075 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -1029,6 +1029,9 @@ void Serializer::parseFriends(RecordInfo &RI, const 
CXXRecordDecl *D) {
   llvm::SmallVector<FriendInfo, 4> LocalFriends;
 
   for (const FriendDecl *FD : D->friends()) {
+    if (FD->isUnsupportedFriend())
+      continue;
+
     FriendInfo F(InfoType::IT_friend, getUSRForDecl(FD));
     const auto *ActualDecl = FD->getFriendDecl();
     if (!ActualDecl) {
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 59ebcc4444b28..70ea2e35090c6 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -123,7 +123,6 @@ features cannot lower the translation-unit ABI level;
 ## What's New in Clang {{env.config.release}}?
 
 ### C++ Language Changes
-- Clang now supports friend declarations with a dependent nested name 
specifier. (#GH104057)
 
 #### C++2d Feature Support
 
diff --git a/clang/include/clang/AST/ASTNodeTraverser.h 
b/clang/include/clang/AST/ASTNodeTraverser.h
index e00c3dd537b0d..a8a73c5b72d33 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -791,14 +791,6 @@ class ASTNodeTraverser
     }
   }
 
-  void VisitFriendTemplateDecl(const FriendTemplateDecl *D) {
-    for (const TemplateParameterList *TPL : D->getTemplateParameterLists())
-      dumpTemplateParameters(TPL);
-    if (D->getFriendKind() !=
-        FriendTemplateDecl::FriendTemplateEntityKind::Template)
-      VisitFriendDecl(D);
-  }
-
   void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
     if (D->isThisDeclarationADefinition())
       dumpDeclContext(D);
diff --git a/clang/include/clang/AST/DeclFriend.h 
b/clang/include/clang/AST/DeclFriend.h
index 6d2659337a9c8..1f8c210263677 100644
--- a/clang/include/clang/AST/DeclFriend.h
+++ b/clang/include/clang/AST/DeclFriend.h
@@ -15,12 +15,18 @@
 #define LLVM_CLANG_AST_DECLFRIEND_H
 
 #include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/ExternalASTSource.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/PointerUnion.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/TrailingObjects.h"
 #include <cassert>
 #include <iterator>
 
@@ -43,7 +49,9 @@ class ASTContext;
 /// @endcode
 ///
 /// The semantic context of a friend decl is its declaring class.
-class FriendDecl : public Decl {
+class FriendDecl final
+    : public Decl,
+      private llvm::TrailingObjects<FriendDecl, TemplateParameterList *> {
   LLVM_DECLARE_VIRTUAL_ANCHOR_FUNCTION();
 
 public:
@@ -53,28 +61,46 @@ class FriendDecl : public Decl {
   friend class CXXRecordDecl;
   friend class CXXRecordDecl::friend_iterator;
 
-  // Location of the '...', if present.
-  SourceLocation EllipsisLoc;
-
-  SourceLocation FriendLoc;
-
-protected:
   // The declaration that's a friend of this class.
   FriendUnion Friend;
 
+  // A pointer to the next friend in the sequence.
   LazyDeclPtr NextFriend;
 
-  FriendDecl(Kind K, DeclContext *DC, SourceLocation L, FriendUnion Friend,
-             SourceLocation FL, SourceLocation EllipsisLoc = {})
-      : Decl(K, DC, L), EllipsisLoc(EllipsisLoc), FriendLoc(FL), 
Friend(Friend),
-        NextFriend() {}
+  // Location of the 'friend' specifier.
+  SourceLocation FriendLoc;
+
+  // Location of the '...', if present.
+  SourceLocation EllipsisLoc;
+
+  /// True if this 'friend' declaration is unsupported.  Eventually we
+  /// will support every possible friend declaration, but for now we
+  /// silently ignore some and set this flag to authorize all access.
+  LLVM_PREFERRED_TYPE(bool)
+  unsigned UnsupportedFriend : 1;
+
+  // The number of "outer" template parameter lists in non-templatic
+  // (currently unsupported) friend type declarations, such as
+  //     template <class T> friend class A<T>::B;
+  unsigned NumTPLists : 31;
+
+  FriendDecl(DeclContext *DC, SourceLocation L, FriendUnion Friend,
+             SourceLocation FriendL, SourceLocation EllipsisLoc,
+             ArrayRef<TemplateParameterList *> FriendTypeTPLists)
+      : Decl(Decl::Friend, DC, L), Friend(Friend), FriendLoc(FriendL),
+        EllipsisLoc(EllipsisLoc), UnsupportedFriend(false),
+        NumTPLists(FriendTypeTPLists.size()) {
+    llvm::copy(FriendTypeTPLists, getTrailingObjects());
+  }
 
-  FriendDecl(Kind K, EmptyShell Empty) : Decl(K, Empty) {}
+  FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists)
+      : Decl(Decl::Friend, Empty), UnsupportedFriend(false),
+        NumTPLists(NumFriendTypeTPLists) {}
 
   FriendDecl *getNextFriend() {
-    if (NextFriend.isOffset())
-      return getNextFriendSlowCase();
-    return cast_or_null<FriendDecl>(NextFriend.get(nullptr));
+    if (!NextFriend.isOffset())
+      return cast_or_null<FriendDecl>(NextFriend.get(nullptr));
+    return getNextFriendSlowCase();
   }
 
   FriendDecl *getNextFriendSlowCase();
@@ -83,11 +109,14 @@ class FriendDecl : public Decl {
   friend class ASTDeclReader;
   friend class ASTDeclWriter;
   friend class ASTNodeImporter;
+  friend TrailingObjects;
 
-  static FriendDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
-                            FriendUnion Friend, SourceLocation FriendL,
-                            SourceLocation EllipsisLoc = {});
-  static FriendDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
+  static FriendDecl *
+  Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_,
+         SourceLocation FriendL, SourceLocation EllipsisLoc = {},
+         ArrayRef<TemplateParameterList *> FriendTypeTPLists = {});
+  static FriendDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
+                                        unsigned FriendTypeNumTPLists);
 
   /// If this friend declaration names an (untemplated but possibly
   /// dependent) type, return the type; otherwise return null.  This
@@ -97,26 +126,72 @@ class FriendDecl : public Decl {
     return Friend.dyn_cast<TypeSourceInfo*>();
   }
 
+  unsigned getFriendTypeNumTemplateParameterLists() const {
+    return NumTPLists;
+  }
+
+  TemplateParameterList *getFriendTypeTemplateParameterList(unsigned N) const {
+    return getTrailingObjects(NumTPLists)[N];
+  }
+
   /// If this friend declaration doesn't name a type, return the inner
   /// declaration.
-  virtual NamedDecl *getFriendDecl() const {
+  NamedDecl *getFriendDecl() const {
     return Friend.dyn_cast<NamedDecl *>();
   }
 
+  /// Retrieves the location of the 'friend' keyword.
+  SourceLocation getFriendLoc() const {
+    return FriendLoc;
+  }
+
   /// Retrieves the location of the '...', if present.
   SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
 
-  SourceLocation getFriendLoc() const { return FriendLoc; }
+  /// Retrieves the source range for the friend declaration.
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    if (TypeSourceInfo *TInfo = getFriendType()) {
+      SourceLocation StartL = (NumTPLists == 0)
+                                  ? getFriendLoc()
+                                  : getTrailingObjects()[0]->getTemplateLoc();
+      SourceLocation EndL = isPackExpansion() ? getEllipsisLoc()
+                                              : 
TInfo->getTypeLoc().getEndLoc();
+      return SourceRange(StartL, EndL);
+    }
+
+    if (isPackExpansion())
+      return SourceRange(getFriendLoc(), getEllipsisLoc());
+
+    if (NamedDecl *ND = getFriendDecl()) {
+      if (const auto *FD = dyn_cast<FunctionDecl>(ND))
+        return FD->getSourceRange();
+      if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
+        return FTD->getSourceRange();
+      if (const auto *CTD = dyn_cast<ClassTemplateDecl>(ND))
+        return CTD->getSourceRange();
+      if (const auto *DD = dyn_cast<DeclaratorDecl>(ND)) {
+        if (DD->getOuterLocStart() != DD->getInnerLocStart())
+          return DD->getSourceRange();
+      }
+      return SourceRange(getFriendLoc(), ND->getEndLoc());
+    }
+
+    return SourceRange(getFriendLoc(), getLocation());
+  }
 
-  SourceRange getSourceRange() const override LLVM_READONLY;
+  /// Determines if this friend kind is unsupported.
+  bool isUnsupportedFriend() const {
+    return UnsupportedFriend;
+  }
+  void setUnsupportedFriend(bool Unsupported) {
+    UnsupportedFriend = Unsupported;
+  }
 
   bool isPackExpansion() const { return EllipsisLoc.isValid(); }
 
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
-  static bool classofKind(Kind K) {
-    return K >= firstFriend && K <= lastFriend;
-  }
+  static bool classofKind(Kind K) { return K == Decl::Friend; }
 };
 
 /// An iterator over the friend declarations of a class.
diff --git a/clang/include/clang/AST/DeclTemplate.h 
b/clang/include/clang/AST/DeclTemplate.h
index f5b26b0aab9ba..ed1a517247943 100644
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -19,7 +19,6 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclFriend.h"
 #include "clang/AST/DeclarationName.h"
 #include "clang/AST/Redeclarable.h"
 #include "clang/AST/TemplateBase.h"
@@ -2458,78 +2457,76 @@ class ClassTemplateDecl : public 
RedeclarableTemplateDecl {
 /// \code
 /// template \<typename T> class A {
 ///   friend class MyVector<T>; // not a friend template
-///   template \<typename U> friend class B; // friend class template
+///   template \<typename U> friend class B; // not a friend template
 ///   template \<typename U> friend class Foo<T>::Nested; // friend template
 /// };
 /// \endcode
-class FriendTemplateDecl final
-    : public FriendDecl,
-      private llvm::TrailingObjects<FriendTemplateDecl,
-                                    TemplateParameterList *> {
-  void anchor() override;
+///
+/// \note This class is not currently in use.  All of the above
+/// will yield a FriendDecl, not a FriendTemplateDecl.
+class FriendTemplateDecl : public Decl {
+  virtual void anchor();
+
+public:
+  using FriendUnion = llvm::PointerUnion<NamedDecl *,TypeSourceInfo *>;
 
 private:
-  unsigned NumTPLists = 0;
-  TemplateName Template;
+  // The number of template parameters;  always non-zero.
+  unsigned NumParams = 0;
 
-  FriendTemplateDecl(DeclContext *DC, SourceLocation Loc, FriendUnion Friend,
-                     SourceLocation FriendLoc, SourceLocation EllipsisLoc,
-                     ArrayRef<TemplateParameterList *> FriendTPLists,
-                     TemplateName Template = {})
-      : FriendDecl(Decl::FriendTemplate, DC, Loc, Friend, FriendLoc,
-                   EllipsisLoc),
-        NumTPLists(FriendTPLists.size()), Template(Template) {
-    assert(!FriendTPLists.empty());
-    llvm::copy(FriendTPLists, getTrailingObjects());
-  }
+  // The parameter list.
+  TemplateParameterList **Params = nullptr;
 
-  FriendTemplateDecl(EmptyShell Empty, unsigned NumFriendTPLists)
-      : FriendDecl(Decl::FriendTemplate, Empty), NumTPLists(NumFriendTPLists) {
-    assert(NumFriendTPLists != 0);
-  }
+  // The declaration that's a friend of this class.
+  FriendUnion Friend;
 
-public:
-  friend class ASTDeclReader;
-  friend class ASTDeclWriter;
-  friend TrailingObjects;
+  // Location of the 'friend' specifier.
+  SourceLocation FriendLoc;
 
-  enum class FriendTemplateEntityKind { Type, Template, Decl };
+  FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
+                     TemplateParameterList **Params, unsigned NumParams,
+                     FriendUnion Friend, SourceLocation FriendLoc)
+      : Decl(Decl::FriendTemplate, DC, Loc), NumParams(NumParams),
+        Params(Params), Friend(Friend), FriendLoc(FriendLoc) {}
 
-  static FriendTemplateDecl *
-  Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
-         FriendUnion Friend, SourceLocation FriendLoc,
-         ArrayRef<TemplateParameterList *> FriendTPLists,
-         SourceLocation EllipsisLoc = {}, TemplateName Template = {});
+  FriendTemplateDecl(EmptyShell Empty) : Decl(Decl::FriendTemplate, Empty) {}
+
+public:
+  friend class ASTDeclReader;
 
   static FriendTemplateDecl *
   Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc,
-         TemplateName Template, SourceLocation FriendLoc,
-         ArrayRef<TemplateParameterList *> FriendTPLists,
-         SourceLocation EllipsisLoc = {});
+         MutableArrayRef<TemplateParameterList *> Params, FriendUnion Friend,
+         SourceLocation FriendLoc);
 
-  static FriendTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID,
-                                                unsigned NumFriendTPLists);
+  static FriendTemplateDecl *CreateDeserialized(ASTContext &C, GlobalDeclID 
ID);
 
-  SourceRange getSourceRange() const override LLVM_READONLY;
+  /// If this friend declaration names a templated type (or
+  /// a dependent member type of a templated type), return that
+  /// type;  otherwise return null.
+  TypeSourceInfo *getFriendType() const {
+    return Friend.dyn_cast<TypeSourceInfo*>();
+  }
 
-  TemplateName getFriendTemplateName() const { return Template; }
+  /// If this friend declaration names a templated function (or
+  /// a member function of a templated type), return that type;
+  /// otherwise return null.
+  NamedDecl *getFriendDecl() const {
+    return Friend.dyn_cast<NamedDecl*>();
+  }
 
-  FriendTemplateEntityKind getFriendKind() const {
-    if (getFriendType())
-      return FriendTemplateEntityKind::Type;
-    if (Template.isNull())
-      return FriendTemplateEntityKind::Decl;
-    return FriendTemplateEntityKind::Template;
+  /// Retrieves the location of the 'friend' keyword.
+  SourceLocation getFriendLoc() const {
+    return FriendLoc;
   }
 
-  NamedDecl *getFriendDecl() const override {
-    if (NamedDecl *ND = Friend.dyn_cast<NamedDecl *>())
-      return ND;
-    return Template.getAsTemplateDecl();
+  TemplateParameterList *getTemplateParameterList(unsigned i) const {
+    assert(i <= NumParams);
+    return Params[i];
   }
 
-  ArrayRef<TemplateParameterList *> getTemplateParameterLists() const {
-    return ArrayRef(getTrailingObjects(), NumTPLists);
+  unsigned getNumTemplateParameters() const {
+    return NumParams;
   }
 
   // Implement isa/cast/dyncast/etc.
diff --git a/clang/include/clang/AST/JSONNodeDumper.h 
b/clang/include/clang/AST/JSONNodeDumper.h
index 679ce4e4815ae..4e8d1649bbf8b 100644
--- a/clang/include/clang/AST/JSONNodeDumper.h
+++ b/clang/include/clang/AST/JSONNodeDumper.h
@@ -268,7 +268,6 @@ class JSONNodeDumper
   void VisitLinkageSpecDecl(const LinkageSpecDecl *LSD);
   void VisitAccessSpecDecl(const AccessSpecDecl *ASD);
   void VisitFriendDecl(const FriendDecl *FD);
-  void VisitFriendTemplateDecl(const FriendTemplateDecl *FD);
   void VisitExplicitInstantiationDecl(const ExplicitInstantiationDecl *D);
 
   void VisitObjCIvarDecl(const ObjCIvarDecl *D);
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h 
b/clang/include/clang/AST/RecursiveASTVisitor.h
index d435cda19fa49..12204dcfb5938 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1739,15 +1739,17 @@ DEF_TRAVERSE_DECL(FriendDecl, {
 })
 
 DEF_TRAVERSE_DECL(FriendTemplateDecl, {
-  const TemplateName Template = D->getFriendTemplateName();
   if (D->getFriendType())
     TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
-  else if (!Template.isNull())
-    TRY_TO(TraverseTemplateName(Template));
   else
     TRY_TO(TraverseDecl(D->getFriendDecl()));
-  for (TemplateParameterList *TPL : D->getTemplateParameterLists())
-    TRY_TO(TraverseTemplateParameterListHelper(TPL));
+  for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
+    TemplateParameterList *TPL = D->getTemplateParameterList(I);
+    for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = 
TPL->end();
+         ITPL != ETPL; ++ITPL) {
+      TRY_TO(TraverseDecl(*ITPL));
+    }
+  }
 })
 
 DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
diff --git a/clang/include/clang/AST/TextNodeDumper.h 
b/clang/include/clang/AST/TextNodeDumper.h
index 1eaafd49c2f06..41ddd88a8326c 100644
--- a/clang/include/clang/AST/TextNodeDumper.h
+++ b/clang/include/clang/AST/TextNodeDumper.h
@@ -399,7 +399,6 @@ class TextNodeDumper
   void VisitLinkageSpecDecl(const LinkageSpecDecl *D);
   void VisitAccessSpecDecl(const AccessSpecDecl *D);
   void VisitFriendDecl(const FriendDecl *D);
-  void VisitFriendTemplateDecl(const FriendTemplateDecl *D);
   void VisitExplicitInstantiationDecl(const ExplicitInstantiationDecl *D);
   void VisitObjCIvarDecl(const ObjCIvarDecl *D);
   void VisitObjCMethodDecl(const ObjCMethodDecl *D);
diff --git a/clang/include/clang/Basic/DeclNodes.td 
b/clang/include/clang/Basic/DeclNodes.td
index 114c6ae5282ef..8d1dc4936cc72 100644
--- a/clang/include/clang/Basic/DeclNodes.td
+++ b/clang/include/clang/Basic/DeclNodes.td
@@ -99,7 +99,7 @@ def FileScopeAsm : DeclNode<Decl>;
 def TopLevelStmt : DeclNode<Decl>, DeclContext;
 def AccessSpec : DeclNode<Decl>;
 def Friend : DeclNode<Decl>;
-def FriendTemplate : DeclNode<Friend>;
+def FriendTemplate : DeclNode<Decl>;
 def StaticAssert : DeclNode<Decl>;
 def ExplicitInstantiation : DeclNode<Decl>;
 def CXXExpansionStmt : DeclNode<Decl>, DeclContext;
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index a6cc17980e2c2..d44f69a815784 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -1206,6 +1206,7 @@ def Attributes : DiagGroup<"attributes", 
[UnknownAttributes,
 def UnknownSanitizers : DiagGroup<"unknown-sanitizers">;
 def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args",
                                         [CXX98CompatUnnamedTypeTemplateArgs]>;
+def UnsupportedFriend : DiagGroup<"unsupported-friend">;
 def UnusedArgument : DiagGroup<"unused-argument">;
 def UnusedCommandLineArgument : DiagGroup<"unused-command-line-argument">;
 def IgnoredOptimizationArgument : DiagGroup<"ignored-optimization-argument">;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 7c1e61120b0f2..b314c17ad27bd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1934,6 +1934,16 @@ def err_friend_not_first_in_declaration : Error<
   "'friend' must appear first in a non-function declaration">;
 def err_using_decl_friend : Error<
   "cannot befriend target of using declaration">;
+def warn_template_qualified_friend_unsupported
+    : Warning<
+          "dependent nested name specifier %0 for friend class declaration is "
+          "not supported; turning off access control for %1">,
+      InGroup<UnsupportedFriend>;
+def warn_template_qualified_friend_ignored
+    : Warning<"dependent nested name specifier %0 for friend template "
+              "declaration is "
+              "not supported; ignoring this friend declaration">,
+      InGroup<UnsupportedFriend>;
 def ext_friend_tag_redecl_outside_namespace : ExtWarn<
   "unqualified friend declaration referring to type outside of the nearest "
   "enclosing namespace is a Microsoft extension; add a nested name specifier">,
@@ -1943,16 +1953,6 @@ def err_friend_template_decl_multiple_specifiers: Error<
   "a friend declaration that befriends a template must contain exactly one 
type-specifier">;
 def friend_template_decl_malformed_pack_expansion : Error<
   "friend declaration expands pack %0 that is declared it its own template 
parameter list">;
-def err_pack_indexing_in_friend : Error<
-  "a pack indexing specifier cannot be used in a nested name specifier of a "
-  "friend declaration">;
-def err_dependent_friend_not_member_of_template_spec : Error<
-  "%0 does not name a class template">;
-def err_dependent_friend_not_member : Error<
-  "friend declaration does not name a member of a class template 
specialization">;
-def err_dependent_friend_undeduced_params : Error<
-  "%select{template...
[truncated]

``````````

</details>


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

Reply via email to