danix800 updated this revision to Diff 545912. danix800 added a comment. Cleanup as @balazske suggested.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D155661/new/ https://reviews.llvm.org/D155661 Files: 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) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits