HerrCai0907 updated this revision to Diff 516151. HerrCai0907 added a comment.
update Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D149009/new/ https://reviews.llvm.org/D149009 Files: clang/lib/Sema/SemaTemplateDeduction.cpp clang/test/SemaTemplate/template-friend-definition-in-template.cpp Index: clang/test/SemaTemplate/template-friend-definition-in-template.cpp =================================================================== --- /dev/null +++ clang/test/SemaTemplate/template-friend-definition-in-template.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// expected-no-diagnostics + +template <class F1> int foo(F1 X1); + +template <int A1> struct A { + template <class F2> friend int foo(F2 X2) { + return A1; + } +}; + +template struct A<1>; +int main() { + foo(1.0); +} Index: clang/lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- clang/lib/Sema/SemaTemplateDeduction.cpp +++ clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3591,11 +3591,19 @@ DeclContext *Owner = FunctionTemplate->getDeclContext(); if (FunctionTemplate->getFriendObjectKind()) Owner = FunctionTemplate->getLexicalDeclContext(); + FunctionDecl *FD = FunctionTemplate->getTemplatedDecl(); + const FunctionDecl *FDFriend; + if (FD->getFriendObjectKind() == Decl::FriendObjectKind::FOK_None && + FD->isDefined(FDFriend, true) && + FDFriend->getFriendObjectKind() != Decl::FriendObjectKind::FOK_None) { + FD = const_cast<FunctionDecl *>(FDFriend); + Owner = FD->getDescribedFunctionTemplate()->getLexicalDeclContext(); + } MultiLevelTemplateArgumentList SubstArgs( FunctionTemplate, CanonicalDeducedArgumentList->asArray(), /*Final=*/false); Specialization = cast_or_null<FunctionDecl>( - SubstDecl(FunctionTemplate->getTemplatedDecl(), Owner, SubstArgs)); + SubstDecl(FD, Owner, SubstArgs)); if (!Specialization || Specialization->isInvalidDecl()) return TDK_SubstitutionFailure;
Index: clang/test/SemaTemplate/template-friend-definition-in-template.cpp =================================================================== --- /dev/null +++ clang/test/SemaTemplate/template-friend-definition-in-template.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// expected-no-diagnostics + +template <class F1> int foo(F1 X1); + +template <int A1> struct A { + template <class F2> friend int foo(F2 X2) { + return A1; + } +}; + +template struct A<1>; +int main() { + foo(1.0); +} Index: clang/lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- clang/lib/Sema/SemaTemplateDeduction.cpp +++ clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3591,11 +3591,19 @@ DeclContext *Owner = FunctionTemplate->getDeclContext(); if (FunctionTemplate->getFriendObjectKind()) Owner = FunctionTemplate->getLexicalDeclContext(); + FunctionDecl *FD = FunctionTemplate->getTemplatedDecl(); + const FunctionDecl *FDFriend; + if (FD->getFriendObjectKind() == Decl::FriendObjectKind::FOK_None && + FD->isDefined(FDFriend, true) && + FDFriend->getFriendObjectKind() != Decl::FriendObjectKind::FOK_None) { + FD = const_cast<FunctionDecl *>(FDFriend); + Owner = FD->getDescribedFunctionTemplate()->getLexicalDeclContext(); + } MultiLevelTemplateArgumentList SubstArgs( FunctionTemplate, CanonicalDeducedArgumentList->asArray(), /*Final=*/false); Specialization = cast_or_null<FunctionDecl>( - SubstDecl(FunctionTemplate->getTemplatedDecl(), Owner, SubstArgs)); + SubstDecl(FD, Owner, SubstArgs)); if (!Specialization || Specialization->isInvalidDecl()) return TDK_SubstitutionFailure;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits