<div dir="ltr"><div>Hi,</div><div><br></div><div>During the improvement of clang::ASTImporter we discovered something strange with redecl chains. </div><div><br></div><div>Consider the following code:</div>   1         template <class T1, class T2><br>   2         struct Base {<br>   3           template <class U1, class U2><br>   4           friend struct Class;<br>   5         };<br>   6         template <class T1, class T2><br>   7         struct Class { }; <div>Here we'd expect that the prototype of `Class` at line 4 is linked to the same redecl chain as the definition at line 7 (see the test case below to be more precise, the test passes on llvm/master).</div><div>I wonder if this is an error in clang::Sema? If this is not an error then what is the explanation?</div><div><br></div><div>Thanks,</div><div>Gabor</div><div><br></div><div><br></div>TEST_P(ASTImporterOptionSpecificTestBase,<br>       ImportExistingFriendClassTemplateDef) {<br>  auto Code =<br>      R"(<br>        template <class T1, class T2><br>        struct Base {<br>          template <class U1, class U2><br>          friend struct Class;<br>        };<br>        template <class T1, class T2><br>        struct Class { };<br>        )";<br><br>  TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX);<br>  TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX, "input.cc");<br><br>  auto *ToClassProto = FirstDeclMatcher<ClassTemplateDecl>().match(<br>      ToTU, classTemplateDecl(hasName("Class")));<br>  auto *ToClassDef = LastDeclMatcher<ClassTemplateDecl>().match(<br>      ToTU, classTemplateDecl(hasName("Class")));<br>  ASSERT_FALSE(ToClassProto->isThisDeclarationADefinition());<br>  ASSERT_TRUE(ToClassDef->isThisDeclarationADefinition());<br>  // Previous friend decl is not linked to it!<br>  ASSERT_FALSE(ToClassDef->getPreviousDecl());<br>  ASSERT_EQ(ToClassDef->getMostRecentDecl(), ToClassDef);<br>  ASSERT_EQ(ToClassProto->getMostRecentDecl(), ToClassProto);<br>}<br></div>