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

Gábor Márton via cfe-dev cfe-dev at lists.llvm.org
Tue Jul 23 08:24:04 PDT 2019


Ok, thanks for the clarification.

On Tue, Jul 23, 2019 at 5:17 PM Richard Smith <richard at metafoo.co.uk> wrote:

> 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/68db0e6e/attachment.html>


More information about the cfe-dev mailing list