[PATCH] D157170: [clang][AST]Don't increase depth in friend tempalte class declaration

Qizhi Hu via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 4 20:43:08 PDT 2023


jcsxky created this revision.
jcsxky added reviewers: a.sidorin, shafik, balazske, steakhal, aaron.ballman, Michael137.
jcsxky added projects: clang, clang-c.
Herald added a project: All.
jcsxky requested review of this revision.
Herald added a subscriber: cfe-commits.

Don't increase template parameter's depth when it's a friend declaration in template class. The reason is that this member(template class) should match the previous class definition and when import from external ast file, type of them should be equivalence.
See import issue <https://reviews.llvm.org/D156693>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D157170

Files:
  clang/lib/Parse/ParseTemplate.cpp
  clang/unittests/AST/ASTImporterTest.cpp


Index: clang/unittests/AST/ASTImporterTest.cpp
===================================================================
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -4212,6 +4212,56 @@
   EXPECT_TRUE(Imported->getPreviousDecl());
 }
 
+TEST_P(ImportFriendClasses, SkipFriendTemplateDeclaration) {
+  Decl *ToTU = getToTuDecl(
+      R"(
+          template <class T, T U>
+          class A;
+
+          template <class T, T U>
+          class A {
+          public:
+            template <class P, P Q>
+            friend class A;
+
+            A(T x):x(x) {}
+
+          private:
+            T x;
+          };
+      )",
+      Lang_CXX11);
+
+  auto *Fwd = FirstDeclMatcher<ClassTemplateDecl>().match(
+      ToTU, classTemplateDecl(hasName("A")));
+  Decl *FromTU = getTuDecl(
+      R"(
+          template <class T, T U>
+          class A;
+
+          template <class T, T U>
+          class A {
+          public:
+            template <class P, P Q>
+            friend class A;
+
+            A(T x):x(x) {}
+
+          private:
+            T x;
+          };
+
+          A<int, 3> a1(0);
+      )",
+      Lang_CXX11, "input1.cc");
+  auto *FromA = FirstDeclMatcher<ClassTemplateDecl>().match(
+      FromTU, classTemplateDecl(hasName("A")));
+  auto *ToA = Import(FromA, Lang_CXX11);
+  EXPECT_TRUE(ToA);
+  EXPECT_EQ(Fwd->getTemplatedDecl()->getTypeForDecl(),
+            ToA->getTemplatedDecl()->getTypeForDecl());
+}
+
 TEST_P(ImportFriendClasses,
        ImportOfClassTemplateDefinitionShouldConnectToFwdFriend) {
   Decl *ToTU = getToTuDecl(
Index: clang/lib/Parse/ParseTemplate.cpp
===================================================================
--- clang/lib/Parse/ParseTemplate.cpp
+++ clang/lib/Parse/ParseTemplate.cpp
@@ -127,8 +127,30 @@
     // Parse the '<' template-parameter-list '>'
     SourceLocation LAngleLoc, RAngleLoc;
     SmallVector<NamedDecl*, 4> TemplateParams;
+
+    bool SeeFriendKeyWord = false;
+    {
+      SmallVector<NamedDecl *, 4> TemplateParams;
+      SourceLocation LAngleLoc, RAngleLoc;
+      RevertingTentativeParsingAction TPA(*this);
+      MultiParseScope TemplateParamScopesTmp(*this);
+      if (ParseTemplateParameters(TemplateParamScopesTmp,
+                                  CurTemplateDepthTracker.getDepth(),
+                                  TemplateParams, LAngleLoc, RAngleLoc)) {
+        // returns true don't need process
+        // returns false, blowe 'ParseTemplateParameters' will do it after
+        // revert
+      }
+      // skip outmost declaration
+      if (Tok.is(tok::kw_friend) && CurTemplateDepthTracker.getDepth() > 0) {
+        SeeFriendKeyWord = true;
+      }
+    }
+
     if (ParseTemplateParameters(TemplateParamScopes,
-                                CurTemplateDepthTracker.getDepth(),
+                                SeeFriendKeyWord
+                                    ? CurTemplateDepthTracker.getDepth() - 1
+                                    : CurTemplateDepthTracker.getDepth(),
                                 TemplateParams, LAngleLoc, RAngleLoc)) {
       // Skip until the semi-colon or a '}'.
       SkipUntil(tok::r_brace, StopAtSemi | StopBeforeMatch);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D157170.547442.patch
Type: text/x-patch
Size: 3232 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230805/a69e026b/attachment.bin>


More information about the cfe-commits mailing list