@@ -1976,16 +1976,14 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
19761976 if (!InstParams)
19771977 return nullptr ;
19781978
1979- // Use canonical templated decl because only canonical decl has body
1980- // if declarations were merged during loading from modules.
1981- FunctionDecl *TemplatedDecl = D->getTemplatedDecl ()->getCanonicalDecl ();
19821979 FunctionDecl *Instantiated = nullptr ;
1983- if (CXXMethodDecl *DMethod = dyn_cast<CXXMethodDecl>(TemplatedDecl ))
1984- Instantiated =
1985- cast_or_null<FunctionDecl>( VisitCXXMethodDecl (DMethod, InstParams));
1980+ if (CXXMethodDecl *DMethod = dyn_cast<CXXMethodDecl>(D-> getTemplatedDecl () ))
1981+ Instantiated = cast_or_null<FunctionDecl>( VisitCXXMethodDecl (DMethod,
1982+ InstParams));
19861983 else
1987- Instantiated = cast_or_null<FunctionDecl>(
1988- VisitFunctionDecl (TemplatedDecl, InstParams));
1984+ Instantiated = cast_or_null<FunctionDecl>(VisitFunctionDecl (
1985+ D->getTemplatedDecl (),
1986+ InstParams));
19891987
19901988 if (!Instantiated)
19911989 return nullptr ;
@@ -2003,7 +2001,7 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
20032001 // Link the instantiation back to the pattern *unless* this is a
20042002 // non-definition friend declaration.
20052003 if (!InstTemplate->getInstantiatedFromMemberTemplate () &&
2006- !(isFriend && !TemplatedDecl ->isThisDeclarationADefinition ()))
2004+ !(isFriend && !D-> getTemplatedDecl () ->isThisDeclarationADefinition ()))
20072005 InstTemplate->setInstantiatedFromMemberTemplate (D);
20082006
20092007 // Make declarations visible in the appropriate context.
@@ -2148,6 +2146,21 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(
21482146 // Check whether there is already a function template specialization for
21492147 // this declaration.
21502148 FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate ();
2149+ bool isFriend;
2150+ if (FunctionTemplate)
2151+ isFriend = (FunctionTemplate->getFriendObjectKind () != Decl::FOK_None);
2152+ else
2153+ isFriend = (D->getFriendObjectKind () != Decl::FOK_None);
2154+ // Friend function defined withing class template may stop being function
2155+ // definition during AST merges from different modules, in this case decl
2156+ // with function body should be used for instantiation.
2157+ if (isFriend) {
2158+ const FunctionDecl* Defn = nullptr ;
2159+ if (D->hasBody (Defn)) {
2160+ D = const_cast <FunctionDecl*>(Defn);
2161+ FunctionTemplate = Defn->getDescribedFunctionTemplate ();
2162+ }
2163+ }
21512164 if (FunctionTemplate && !TemplateParams) {
21522165 ArrayRef<TemplateArgument> Innermost = TemplateArgs.getInnermost ();
21532166
@@ -2160,12 +2173,6 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(
21602173 return SpecFunc;
21612174 }
21622175
2163- bool isFriend;
2164- if (FunctionTemplate)
2165- isFriend = (FunctionTemplate->getFriendObjectKind () != Decl::FOK_None);
2166- else
2167- isFriend = (D->getFriendObjectKind () != Decl::FOK_None);
2168-
21692176 bool MergeWithParentScope = (TemplateParams != nullptr ) ||
21702177 Owner->isFunctionOrMethod () ||
21712178 !(isa<Decl>(Owner) &&
0 commit comments