Author: rsmith Date: Fri Jan 27 20:56:07 2017 New Revision: 293367 URL: http://llvm.org/viewvc/llvm-project?rev=293367&view=rev Log: Switch the template specialization kind for a non-defining declaration of a non-template function instantiated from a friend declaration in a class template from TSK_ImplicitInstantiation to TSK_Undeclared.
It doesn't make sense for a non-template function to be flagged as being instantiated from a template; that property really belongs to the entity as a whole and not an individual declaration of it. There's some history here: * r137934 started marking these functions as instantiations in order to work around an issue where we might instantiate a class template while we're still parsing its member definitions, and would otherwise fail to instantiate the friend definition * r177003 fixed the same issue but for friend templates, but did so by making the friends claim to be definitions even before we'd parsed their actual bodies; this made the r137934 change redundant * r293558 worked around a problem caused by the marking of a non-template function as a template instantiation in r137934 This change reverts the code changes from r293358 and r137934 and retains all the tests. Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=293367&r1=293366&r2=293367&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri Jan 27 20:56:07 2017 @@ -1656,8 +1656,6 @@ Decl *TemplateDeclInstantiator::VisitFun FunctionTemplate->setLexicalDeclContext(LexicalDC); if (isFriend && D->isThisDeclarationADefinition()) { - // TODO: should we remember this connection regardless of whether - // the friend declaration provided a body? FunctionTemplate->setInstantiatedFromMemberTemplate( D->getDescribedFunctionTemplate()); } @@ -1668,13 +1666,10 @@ Decl *TemplateDeclInstantiator::VisitFun TemplateArgumentList::CreateCopy(SemaRef.Context, Innermost), /*InsertPos=*/nullptr); - } else if (isFriend) { - // Note, we need this connection even if the friend doesn't have a body. - // Its body may exist but not have been attached yet due to deferred - // parsing. - // FIXME: It might be cleaner to set this when attaching the body to the - // friend function declaration, however that would require finding all the - // instantiations and modifying them. + } else if (isFriend && D->isThisDeclarationADefinition()) { + // Do not connect the friend to the template unless it's actually a + // definition. We don't want non-template functions to be marked as being + // template instantiations. Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation); } @@ -3726,12 +3721,7 @@ void Sema::InstantiateFunctionDefinition PendingInstantiations.push_back( std::make_pair(Function, PointOfInstantiation)); } else if (TSK == TSK_ImplicitInstantiation) { - if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() && - // A non-template function that is only lexically in a dependent - // context, such as a friend function in a class template, should - // not produce a warning. - (PatternDecl->getDescribedFunctionTemplate() || - PatternDecl->getDeclContext()->isDependentContext())) { + if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) { Diag(PointOfInstantiation, diag::warn_func_template_missing) << Function; Diag(PatternDecl->getLocation(), diag::note_forward_template_decl); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits