|
12 | 12 | #include "TreeTransform.h" |
13 | 13 | #include "clang/AST/ASTConsumer.h" |
14 | 14 | #include "clang/AST/ASTContext.h" |
| 15 | +#include "clang/AST/ASTLambda.h" |
15 | 16 | #include "clang/AST/ASTMutationListener.h" |
16 | 17 | #include "clang/AST/DeclTemplate.h" |
17 | 18 | #include "clang/AST/DeclVisitor.h" |
@@ -1994,8 +1995,10 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { |
1994 | 1995 | // Link the instantiation back to the pattern *unless* this is a |
1995 | 1996 | // non-definition friend declaration. |
1996 | 1997 | if (!InstTemplate->getInstantiatedFromMemberTemplate() && |
1997 | | - !(isFriend && !D->getTemplatedDecl()->isThisDeclarationADefinition())) |
| 1998 | + !(isFriend && !D->getTemplatedDecl()->isThisDeclarationADefinition())) { |
| 1999 | + InstTemplate->setInstantiatedFromDefinition(); |
1998 | 2000 | InstTemplate->setInstantiatedFromMemberTemplate(D); |
| 2001 | + } |
1999 | 2002 |
|
2000 | 2003 | // Make declarations visible in the appropriate context. |
2001 | 2004 | if (!isFriend) { |
@@ -2299,6 +2302,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl( |
2299 | 2302 | FunctionTemplate->setLexicalDeclContext(LexicalDC); |
2300 | 2303 |
|
2301 | 2304 | if (isFriend && D->isThisDeclarationADefinition()) { |
| 2305 | + FunctionTemplate->setInstantiatedFromDefinition(); |
2302 | 2306 | FunctionTemplate->setInstantiatedFromMemberTemplate( |
2303 | 2307 | D->getDescribedFunctionTemplate()); |
2304 | 2308 | } |
@@ -5185,9 +5189,27 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, |
5185 | 5189 | RebuildTypeSourceInfoForDefaultSpecialMembers(); |
5186 | 5190 | SetDeclDefaulted(Function, PatternDecl->getLocation()); |
5187 | 5191 | } else { |
| 5192 | + NamedDecl *ND = Function; |
| 5193 | + std::optional<ArrayRef<TemplateArgument>> Innermost; |
| 5194 | + if (auto *Primary = Function->getPrimaryTemplate(); |
| 5195 | + Primary && |
| 5196 | + !isGenericLambdaCallOperatorOrStaticInvokerSpecialization(Function)) { |
| 5197 | + auto It = llvm::find_if(Primary->redecls(), |
| 5198 | + [](const RedeclarableTemplateDecl *RTD) { |
| 5199 | + auto *FTD = cast<FunctionTemplateDecl>(RTD); |
| 5200 | + return FTD->isInstantiatedFromDefinition() || |
| 5201 | + FTD->isThisDeclarationADefinition(); |
| 5202 | + }); |
| 5203 | + assert(It != Primary->redecls().end() && |
| 5204 | + "Should't get here without a definition"); |
| 5205 | + ND = *It; |
| 5206 | + if (Function->getTemplateSpecializationKind() != |
| 5207 | + TSK_ExplicitSpecialization) |
| 5208 | + Innermost.emplace(Function->getTemplateSpecializationArgs()->asArray()); |
| 5209 | + } |
5188 | 5210 | MultiLevelTemplateArgumentList TemplateArgs = getTemplateInstantiationArgs( |
5189 | | - Function, Function->getLexicalDeclContext(), /*Final=*/false, |
5190 | | - /*Innermost=*/std::nullopt, false, PatternDecl); |
| 5211 | + Function, ND->getLexicalDeclContext(), /*Final=*/false, Innermost, |
| 5212 | + false, PatternDecl); |
5191 | 5213 |
|
5192 | 5214 | // Substitute into the qualifier; we can get a substitution failure here |
5193 | 5215 | // through evil use of alias templates. |
|
0 commit comments