r293367 - Switch the template specialization kind for a non-defining declaration of a

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Fri Jan 27 18:56:08 PST 2017


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);




More information about the cfe-commits mailing list