diff options
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 84 |
1 files changed, 73 insertions, 11 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 31353e45ba..fad3c065e8 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1747,10 +1747,13 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation); } + if (isFriend) + Function->setObjectOfFriendDecl(); + if (InitFunctionInstantiation(Function, D)) Function->setInvalidDecl(); - bool isExplicitSpecialization = false; + bool IsExplicitSpecialization = false; LookupResult Previous( SemaRef, Function->getDeclName(), SourceLocation(), @@ -1763,9 +1766,6 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, = D->getDependentSpecializationInfo()) { assert(isFriend && "non-friend has dependent specialization info?"); - // This needs to be set now for future sanity. - Function->setObjectOfFriendDecl(); - // Instantiate the explicit template arguments. TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(), Info->getRAngleLoc()); @@ -1788,8 +1788,25 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, Previous)) Function->setInvalidDecl(); - isExplicitSpecialization = true; + IsExplicitSpecialization = true; + } else if (const ASTTemplateArgumentListInfo *Info = + D->getTemplateSpecializationArgsAsWritten()) { + // The name of this function was written as a template-id. + SemaRef.LookupQualifiedName(Previous, DC); + // Instantiate the explicit template arguments. + TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(), + Info->getRAngleLoc()); + if (SemaRef.Subst(Info->getTemplateArgs(), Info->getNumTemplateArgs(), + ExplicitArgs, TemplateArgs)) + return nullptr; + + if (SemaRef.CheckFunctionTemplateSpecialization(Function, + &ExplicitArgs, + Previous)) + Function->setInvalidDecl(); + + IsExplicitSpecialization = true; } else if (TemplateParams || !FunctionTemplate) { // Look only into the namespace where the friend would be declared to // find a previous declaration. This is the innermost enclosing namespace, @@ -1804,11 +1821,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, Previous.clear(); } - if (isFriend) - Function->setObjectOfFriendDecl(); - SemaRef.CheckFunctionDeclaration(/*Scope*/ nullptr, Function, Previous, - isExplicitSpecialization); + IsExplicitSpecialization); NamedDecl *PrincipalDecl = (TemplateParams ? cast<NamedDecl>(FunctionTemplate) @@ -2055,7 +2069,54 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, LookupResult Previous(SemaRef, NameInfo, Sema::LookupOrdinaryName, Sema::ForExternalRedeclaration); - if (!FunctionTemplate || TemplateParams || isFriend) { + bool IsExplicitSpecialization = false; + + // If the name of this function was written as a template-id, instantiate + // the explicit template arguments. + if (DependentFunctionTemplateSpecializationInfo *Info + = D->getDependentSpecializationInfo()) { + assert(isFriend && "non-friend has dependent specialization info?"); + + // Instantiate the explicit template arguments. + TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(), + Info->getRAngleLoc()); + if (SemaRef.Subst(Info->getTemplateArgs(), Info->getNumTemplateArgs(), + ExplicitArgs, TemplateArgs)) + return nullptr; + + // Map the candidate templates to their instantiations. + for (unsigned I = 0, E = Info->getNumTemplates(); I != E; ++I) { + Decl *Temp = SemaRef.FindInstantiatedDecl(D->getLocation(), + Info->getTemplate(I), + TemplateArgs); + if (!Temp) return nullptr; + + Previous.addDecl(cast<FunctionTemplateDecl>(Temp)); + } + + if (SemaRef.CheckFunctionTemplateSpecialization(Method, + &ExplicitArgs, + Previous)) + Method->setInvalidDecl(); + + IsExplicitSpecialization = true; + } else if (const ASTTemplateArgumentListInfo *Info = + D->getTemplateSpecializationArgsAsWritten()) { + SemaRef.LookupQualifiedName(Previous, DC); + + TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(), + Info->getRAngleLoc()); + if (SemaRef.Subst(Info->getTemplateArgs(), Info->getNumTemplateArgs(), + ExplicitArgs, TemplateArgs)) + return nullptr; + + if (SemaRef.CheckFunctionTemplateSpecialization(Method, + &ExplicitArgs, + Previous)) + Method->setInvalidDecl(); + + IsExplicitSpecialization = true; + } else if (!FunctionTemplate || TemplateParams || isFriend) { SemaRef.LookupQualifiedName(Previous, Record); // In C++, the previous declaration we find might be a tag type @@ -2067,7 +2128,8 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, } if (!IsClassScopeSpecialization) - SemaRef.CheckFunctionDeclaration(nullptr, Method, Previous, false); + SemaRef.CheckFunctionDeclaration(nullptr, Method, Previous, + IsExplicitSpecialization); if (D->isPure()) SemaRef.CheckPureMethod(Method, SourceRange()); |