[cfe-dev] Redecl chain of friend class template is broken ?

Richard Smith via cfe-dev cfe-dev at lists.llvm.org
Tue Jul 23 08:16:44 PDT 2019


On Tue, 23 Jul 2019, 05:37 Gábor Márton via cfe-dev, <cfe-dev at lists.llvm.org>
wrote:

> Hi,
>
> During the improvement of clang::ASTImporter we discovered something
> strange with redecl chains.
>
> Consider the following code:
>    1         template <class T1, class T2>
>    2         struct Base {
>    3           template <class U1, class U2>
>    4           friend struct Class;
>    5         };
>    6         template <class T1, class T2>
>    7         struct Class { };
> 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).
> I wonder if this is an error in clang::Sema? If this is not an error then
> what is the explanation?
>

It's intentional. The friend in the template does not constitute a
declaration of ::Class until the template Base is instantiated. For
example, the template parameters of the friend are at different depths than
those of the class.

Thanks,
> Gabor
>
>
> TEST_P(ASTImporterOptionSpecificTestBase,
>        ImportExistingFriendClassTemplateDef) {
>   auto Code =
>       R"(
>         template <class T1, class T2>
>         struct Base {
>           template <class U1, class U2>
>           friend struct Class;
>         };
>         template <class T1, class T2>
>         struct Class { };
>         )";
>
>   TranslationUnitDecl *ToTU = getToTuDecl(Code, Lang_CXX);
>   TranslationUnitDecl *FromTU = getTuDecl(Code, Lang_CXX, "input.cc");
>
>   auto *ToClassProto = FirstDeclMatcher<ClassTemplateDecl>().match(
>       ToTU, classTemplateDecl(hasName("Class")));
>   auto *ToClassDef = LastDeclMatcher<ClassTemplateDecl>().match(
>       ToTU, classTemplateDecl(hasName("Class")));
>   ASSERT_FALSE(ToClassProto->isThisDeclarationADefinition());
>   ASSERT_TRUE(ToClassDef->isThisDeclarationADefinition());
>   // Previous friend decl is not linked to it!
>   ASSERT_FALSE(ToClassDef->getPreviousDecl());
>   ASSERT_EQ(ToClassDef->getMostRecentDecl(), ToClassDef);
>   ASSERT_EQ(ToClassProto->getMostRecentDecl(), ToClassProto);
> }
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20190723/b6f725d1/attachment.html>


More information about the cfe-dev mailing list