danix800 updated this revision to Diff 545913.
danix800 added a comment.
Update ReleaseNotes.rst
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D155661/new/
https://reviews.llvm.org/D155661
Files:
clang/docs/ReleaseNotes.rst
clang/lib/AST/ASTImporter.cpp
clang/unittests/AST/ASTImporterTest.cpp
Index: clang/unittests/AST/ASTImporterTest.cpp
===================================================================
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -3968,8 +3968,31 @@
EXPECT_EQ(ToDef->getPreviousDecl(), ToProto);
}
-
-struct ImportFriendClasses : ASTImporterOptionSpecificTestBase {};
+struct ImportFriendClasses : ASTImporterOptionSpecificTestBase {
+ void testRecursiveFriendClassTemplate(Decl *FromTu) {
+ auto *FromD = FirstDeclMatcher<ClassTemplateDecl>().match(
+ FromTu, classTemplateDecl());
+ auto *ToD = Import(FromD, Lang_CXX03);
+
+ auto Pattern = classTemplateDecl(
+ has(cxxRecordDecl(has(friendDecl(has(classTemplateDecl()))))));
+ ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromD, Pattern));
+ EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToD, Pattern));
+
+ auto *FromFriend =
+ FirstDeclMatcher<FriendDecl>().match(FromD, friendDecl());
+ auto *FromClass =
+ FirstDeclMatcher<ClassTemplateDecl>().match(FromD, classTemplateDecl());
+ EXPECT_NE(FromFriend->getFriendDecl(), FromClass);
+ EXPECT_TRUE(FromFriend->getFriendDecl()->getPreviousDecl() == nullptr);
+
+ auto *Class =
+ FirstDeclMatcher<ClassTemplateDecl>().match(ToD, classTemplateDecl());
+ auto *Friend = FirstDeclMatcher<FriendDecl>().match(ToD, friendDecl());
+ EXPECT_NE(Friend->getFriendDecl(), Class);
+ EXPECT_TRUE(Friend->getFriendDecl()->getPreviousDecl() == nullptr);
+ }
+};
TEST_P(ImportFriendClasses, ImportOfFriendRecordDoesNotMergeDefinition) {
Decl *FromTU = getTuDecl(
@@ -4074,20 +4097,19 @@
)",
Lang_CXX03, "input.cc");
- auto *FromD =
- FirstDeclMatcher<ClassTemplateDecl>().match(FromTu, classTemplateDecl());
- auto *ToD = Import(FromD, Lang_CXX03);
-
- auto Pattern = classTemplateDecl(
- has(cxxRecordDecl(has(friendDecl(has(classTemplateDecl()))))));
- ASSERT_TRUE(MatchVerifier<Decl>{}.match(FromD, Pattern));
- EXPECT_TRUE(MatchVerifier<Decl>{}.match(ToD, Pattern));
+ testRecursiveFriendClassTemplate(FromTu);
+}
- auto *Class =
- FirstDeclMatcher<ClassTemplateDecl>().match(ToD, classTemplateDecl());
- auto *Friend = FirstDeclMatcher<FriendDecl>().match(ToD, friendDecl());
- EXPECT_NE(Friend->getFriendDecl(), Class);
- EXPECT_EQ(Friend->getFriendDecl()->getPreviousDecl(), Class);
+TEST_P(ImportFriendClasses,
+ ImportOfRecursiveFriendClassTemplateWithNonTypeParm) {
+ Decl *FromTu = getTuDecl(
+ R"(
+ template<class A1, A1 A> class declToImport {
+ template<class B1, B1> friend class declToImport;
+ };
+ )",
+ Lang_CXX03, "input.cc");
+ testRecursiveFriendClassTemplate(FromTu);
}
TEST_P(ImportFriendClasses, ProperPrevDeclForClassTemplateDecls) {
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -2857,9 +2857,13 @@
} else if (Importer.getToContext().getLangOpts().CPlusPlus)
IDNS |= Decl::IDNS_Ordinary | Decl::IDNS_TagFriend;
+ bool IsDependentContext = DC != LexicalDC ? LexicalDC->isDependentContext()
+ : DC->isDependentContext();
+ bool DependentFriend = IsFriendTemplate && IsDependentContext;
+
// We may already have a record of the same name; try to find and match it.
RecordDecl *PrevDecl = nullptr;
- if (!DC->isFunctionOrMethod() && !D->isLambda()) {
+ if (!DependentFriend && !DC->isFunctionOrMethod() && !D->isLambda()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
auto FoundDecls =
Importer.findDeclsInToCtx(DC, SearchName);
@@ -5796,10 +5800,15 @@
if (ToD)
return ToD;
+ bool IsFriendTemplate = D->getFriendObjectKind() != Decl::FOK_None;
+ bool IsDependentContext = DC != LexicalDC ? LexicalDC->isDependentContext()
+ : DC->isDependentContext();
+ bool DependentFriend = IsFriendTemplate && IsDependentContext;
+
ClassTemplateDecl *FoundByLookup = nullptr;
// We may already have a template of the same name; try to find and match it.
- if (!DC->isFunctionOrMethod()) {
+ if (!DependentFriend && !DC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -131,6 +131,8 @@
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
+- Fixed an import failure of recursive friend class template.
+ `Issue 64169 <https://github.com/llvm/llvm-project/issues/64169>`_
Miscellaneous Bug Fixes
^^^^^^^^^^^^^^^^^^^^^^^
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits