<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">Thanks a lot!<br>
      On 23/08/16 22:50, Richard Smith via cfe-commits wrote:<br>
    </div>
    <blockquote
cite="mid:CAOfiQqkEer+=wWjWq7ndLCtsi_Q6u2J6YEV6=W=E7SsaibC9PQ@mail.gmail.com"
      type="cite">
      <div dir="ltr">Thanks. Fixed and reapplied as r279557.</div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">On Mon, Aug 22, 2016 at 7:08 PM,
          Chandler Carruth <span dir="ltr"><<a
              moz-do-not-send="true" href="mailto:chandlerc@gmail.com"
              target="_blank">chandlerc@gmail.com</a>></span> wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div dir="ltr">Reverted this per Richard's request
              in r279500.
              <div>
                <div class="h5"><br>
                  <br>
                  <div class="gmail_quote">
                    <div dir="ltr">On Mon, Aug 22, 2016 at 3:33 PM
                      Richard Smith via cfe-commits <<a
                        moz-do-not-send="true"
                        href="mailto:cfe-commits@lists.llvm.org"
                        target="_blank">cfe-commits@lists.llvm.org</a>>
                      wrote:<br>
                    </div>
                    <blockquote class="gmail_quote" style="margin:0 0 0
                      .8ex;border-left:1px #ccc solid;padding-left:1ex">Author:
                      rsmith<br>
                      Date: Mon Aug 22 17:25:03 2016<br>
                      New Revision: 279486<br>
                      <br>
                      URL: <a moz-do-not-send="true"
                        href="http://llvm.org/viewvc/llvm-project?rev=279486&view=rev"
                        rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=279486&view=rev</a><br>
                      Log:<br>
                      Fix regression introduced by r279164: only pass
                      definitions as the PatternDef<br>
                      to DiagnoseUninstantiableTemplate<wbr>, teach
                      hasVisibleDefinition to correctly<br>
                      determine whether a function definition is
                      visible, and mark both the function<br>
                      and the template as visible when merging function
                      template definitions to<br>
                      provide hasVisibleDefinition with the relevant
                      information.<br>
                      <br>
                      The change to always pass the right declaration as
                      the PatternDef to<br>
                      DiagnoseUninstantiableTemplate also caused those
                      checks to happen before other<br>
                      diagnostics in InstantiateFunctionDefinition,
                      giving worse diagnostics for the<br>
                      same situations, so I sunk the relevant
                      diagnostics into<br>
                      DiagnoseUninstantiableTemplate<wbr>. Those parts
                      of this patch are based on changes<br>
                      in <a moz-do-not-send="true"
                        href="http://reviews.llvm.org/D23492"
                        rel="noreferrer" target="_blank">reviews.llvm.org/D23492</a>
                      by Vassil Vassilev.<br>
                      <br>
                      Modified:<br>
                          cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp<br>
                          cfe/trunk/lib/Sema/<wbr>SemaTemplate.cpp<br>
                          cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiateDecl.<wbr>cpp<br>
                          cfe/trunk/lib/Sema/SemaType.<wbr>cpp<br>
                          cfe/trunk/test/Modules/Inputs/<wbr>merge-template-pattern-<wbr>visibility/a.h<br>
                          cfe/trunk/test/Modules/Inputs/<wbr>merge-template-pattern-<wbr>visibility/b.h<br>
                          cfe/trunk/test/Modules/merge-<wbr>template-pattern-visibility.<wbr>cpp<br>
                      <br>
                      Modified: cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp<br>
                      URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=279486&r1=279485&r2=279486&view=diff"
                        rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaDecl.cpp?rev=279486&r1=<wbr>279485&r2=279486&view=diff</a><br>
                      ==============================<wbr>==============================<wbr>==================<br>
                      --- cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp
                      (original)<br>
                      +++ cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp Mon Aug
                      22 17:25:03 2016<br>
                      @@ -11274,9 +11274,8 @@ Sema::<wbr>CheckForFunctionRedefinition(<wbr>Funct<br>
                           SkipBody->ShouldSkip = true;<br>
                           if (auto *TD = Definition-><wbr>getDescribedFunctionTemplate()<wbr>)<br>
                             makeMergedDefinitionVisible(<wbr>TD,
                      FD->getLocation());<br>
                      -    else<br>
                      -      makeMergedDefinitionVisible(<wbr>const_cast<FunctionDecl*>(<wbr>Definition),<br>
                      -                                 
                      FD->getLocation());<br>
                      +    makeMergedDefinitionVisible(<wbr>const_cast<FunctionDecl*>(<wbr>Definition),<br>
                      +                               
                      FD->getLocation());<br>
                           return;<br>
                         }<br>
                      <br>
                      <br>
                      Modified: cfe/trunk/lib/Sema/<wbr>SemaTemplate.cpp<br>
                      URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=279486&r1=279485&r2=279486&view=diff"
                        rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaTemplate.cpp?rev=279486&<wbr>r1=279485&r2=279486&view=diff</a><br>
                      ==============================<wbr>==============================<wbr>==================<br>
                      --- cfe/trunk/lib/Sema/<wbr>SemaTemplate.cpp
                      (original)<br>
                      +++ cfe/trunk/lib/Sema/<wbr>SemaTemplate.cpp Mon
                      Aug 22 17:25:03 2016<br>
                      @@ -487,8 +487,6 @@ bool Sema::<wbr>DiagnoseUninstantiableTemplat<br>
                         QualType InstantiationTy;<br>
                         if (TagDecl *TD = dyn_cast<TagDecl>(<wbr>Instantiation))<br>
                           InstantiationTy =
                      Context.getTypeDeclType(TD);<br>
                      -  else<br>
                      -    InstantiationTy = cast<FunctionDecl>(<wbr>Instantiation)->getType();<br>
                         if (!Complain || (PatternDef &&
                      PatternDef->isInvalidDecl())) {<br>
                           // Say nothing<br>
                         } else if (PatternDef) {<br>
                      @@ -500,15 +498,30 @@ bool Sema::<wbr>DiagnoseUninstantiableTemplat<br>
                           // we're lexically inside it.<br>
                           Instantiation-><wbr>setInvalidDecl();<br>
                         } else if (InstantiatedFromMember) {<br>
                      -    Diag(PointOfInstantiation,<br>
                      -         diag::err_implicit_<wbr>instantiate_member_undefined)<br>
                      -      << InstantiationTy;<br>
                      -    Diag(Pattern->getLocation(),
                      diag::note_member_declared_at)<wbr>;<br>
                      +    if (isa<FunctionDecl>(<wbr>Instantiation))
                      {<br>
                      +      Diag(PointOfInstantiation,<br>
                      +           diag::err_explicit_<wbr>instantiation_undefined_<wbr>member)<br>
                      +        << 1 <<
                      Instantiation->getDeclName() <<
                      Instantiation->getDeclContext(<wbr>);<br>
                      +    } else {<br>
                      +      Diag(PointOfInstantiation,<br>
                      +           diag::err_implicit_<wbr>instantiate_member_undefined)<br>
                      +        << InstantiationTy;<br>
                      +    }<br>
                      +    Diag(Pattern->getLocation(),
                      isa<FunctionDecl>(<wbr>Instantiation)<br>
                      +                                     ?
                      diag::note_explicit_<wbr>instantiation_here<br>
                      +                                     :
                      diag::note_member_declared_at)<wbr>;<br>
                         } else {<br>
                      -    Diag(PointOfInstantiation,
                      diag::err_template_<wbr>instantiate_undefined)<br>
                      -      << (TSK != TSK_ImplicitInstantiation)<br>
                      -      << InstantiationTy;<br>
                      -    Diag(Pattern->getLocation(),
                      diag::note_template_decl_here)<wbr>;<br>
                      +    if (isa<FunctionDecl>(<wbr>Instantiation))<br>
                      +      Diag(PointOfInstantiation,<br>
                      +           diag::err_explicit_<wbr>instantiation_undefined_func_<wbr>template)<br>
                      +        << Pattern;<br>
                      +    else<br>
                      +      Diag(PointOfInstantiation,
                      diag::err_template_<wbr>instantiate_undefined)<br>
                      +        << (TSK !=
                      TSK_ImplicitInstantiation)<br>
                      +        << InstantiationTy;<br>
                      +    Diag(Pattern->getLocation(),
                      isa<FunctionDecl>(<wbr>Instantiation)<br>
                      +                                     ?
                      diag::note_explicit_<wbr>instantiation_here<br>
                      +                                     :
                      diag::note_template_decl_here)<wbr>;<br>
                         }<br>
                      <br>
                         // In general, Instantiation isn't marked
                      invalid to get more than one<br>
                      <br>
                      Modified: cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiateDecl.<wbr>cpp<br>
                      URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=279486&r1=279485&r2=279486&view=diff"
                        rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiateDecl.<wbr>cpp?rev=279486&r1=279485&r2=<wbr>279486&view=diff</a><br>
                      ==============================<wbr>==============================<wbr>==================<br>
                      --- cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiateDecl.<wbr>cpp
                      (original)<br>
                      +++ cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiateDecl.<wbr>cpp
                      Mon Aug 22 17:25:03 2016<br>
                      @@ -3554,23 +3554,38 @@ void Sema::<wbr>InstantiateFunctionDefinition<br>
                         const FunctionDecl *PatternDecl = Function-><wbr>getTemplateInstantiationPatter<wbr>n();<br>
                         assert(PatternDecl && "instantiating a
                      non-template");<br>
                      <br>
                      -  Stmt *Pattern = PatternDecl->getBody(<wbr>PatternDecl);<br>
                      -  assert(PatternDecl && "template
                      definition is not a template");<br>
                      -  if (!Pattern) {<br>
                      -    // Try to find a defaulted definition<br>
                      -    PatternDecl->isDefined(<wbr>PatternDecl);<br>
                      -  }<br>
                      -  assert(PatternDecl && "template
                      definition is not a template");<br>
                      +  const FunctionDecl *PatternDef =
                      PatternDecl->getDefinition();<br>
                      +  Stmt *Pattern = PatternDef->getBody(<wbr>PatternDef);<br>
                      +  if (PatternDef)<br>
                      +    PatternDecl = PatternDef;<br>
                      <br>
                         // FIXME: We need to track the instantiation
                      stack in order to know which<br>
                         // definitions should be visible within this
                      instantiation.<br>
                         if (<wbr>DiagnoseUninstantiableTemplate<wbr>(PointOfInstantiation,
                      Function,<br>
                                                       Function-><wbr>getInstantiatedFromMemberFunct<wbr>ion(),<br>
                      -                                     PatternDecl,
                      PatternDecl, TSK,<br>
                      -                                     /*Complain*/<wbr>DefinitionRequired))<br>
                      -     return;<br>
                      -<br>
                      +                                     PatternDecl,
                      PatternDef, TSK,<br>
                      +                                     /*Complain*/<wbr>DefinitionRequired))
                      {<br>
                      +    if (DefinitionRequired)<br>
                      +      Function->setInvalidDecl();<br>
                      +    else if (TSK == TSK_<wbr>ExplicitInstantiationDefinitio<wbr>n)
                      {<br>
                      +      // Try again at the end of the translation
                      unit (at which point a<br>
                      +      // definition will be required).<br>
                      +      assert(!Recursive);<br>
                      +      PendingInstantiations.push_<wbr>back(<br>
                      +        std::make_pair(Function,
                      PointOfInstantiation));<br>
                      +    } else if (TSK == TSK_ImplicitInstantiation)
                      {<br>
                      +      if (AtEndOfTU && !getDiagnostics().<wbr>hasErrorOccurred())
                      {<br>
                      +        Diag(PointOfInstantiation,
                      diag::warn_func_template_<wbr>missing)<br>
                      +          << Function;<br>
                      +        Diag(PatternDecl->getLocation(<wbr>),
                      diag::note_forward_template_<wbr>decl);<br>
                      +        if (getLangOpts().CPlusPlus11)<br>
                      +          Diag(PointOfInstantiation,
                      diag::note_inst_declaration_<wbr>hint)<br>
                      +            << Function;<br>
                      +      }<br>
                      +    }<br>
                      <br>
                      +    return;<br>
                      +  }<br>
                      <br>
                         // Postpone late parsed template
                      instantiations.<br>
                         if (PatternDecl-><wbr>isLateTemplateParsed()
                      &&<br>
                      @@ -3604,40 +3619,9 @@ void Sema::<wbr>InstantiateFunctionDefinition<br>
                           Pattern = PatternDecl->getBody(<wbr>PatternDecl);<br>
                         }<br>
                      <br>
                      -  // FIXME: Check if we could sink these
                      diagnostics in<br>
                      -  // DiagnoseUninstantiableTemplate<wbr>.<br>
                      -  if (!Pattern &&
                      !PatternDecl->isDefaulted()) {<br>
                      -    if (DefinitionRequired) {<br>
                      -      if (Function->getPrimaryTemplate(<wbr>))<br>
                      -        Diag(PointOfInstantiation,<br>
                      -             diag::err_explicit_<wbr>instantiation_undefined_func_<wbr>template)<br>
                      -          <<
                      Function->getPrimaryTemplate()<wbr>;<br>
                      -      else<br>
                      -        Diag(PointOfInstantiation,<br>
                      -             diag::err_explicit_<wbr>instantiation_undefined_<wbr>member)<br>
                      -          << 1 <<
                      Function->getDeclName() <<
                      Function->getDeclContext();<br>
                      -<br>
                      -      if (PatternDecl)<br>
                      -        Diag(PatternDecl->getLocation(<wbr>),<br>
                      -             diag::note_explicit_<wbr>instantiation_here);<br>
                      -      Function->setInvalidDecl();<br>
                      -    } else if (TSK == TSK_<wbr>ExplicitInstantiationDefinitio<wbr>n)
                      {<br>
                      -      assert(!Recursive);<br>
                      -      PendingInstantiations.push_<wbr>back(<br>
                      -        std::make_pair(Function,
                      PointOfInstantiation));<br>
                      -    } else if (TSK == TSK_ImplicitInstantiation)
                      {<br>
                      -      if (AtEndOfTU && !getDiagnostics().<wbr>hasErrorOccurred())
                      {<br>
                      -        Diag(PointOfInstantiation,
                      diag::warn_func_template_<wbr>missing)<br>
                      -          << Function;<br>
                      -        Diag(PatternDecl->getLocation(<wbr>),
                      diag::note_forward_template_<wbr>decl);<br>
                      -        if (getLangOpts().CPlusPlus11)<br>
                      -          Diag(PointOfInstantiation,
                      diag::note_inst_declaration_<wbr>hint)<br>
                      -            << Function;<br>
                      -      }<br>
                      -    }<br>
                      -<br>
                      -    return;<br>
                      -  }<br>
                      +  // Note, we should never try to instantiate a
                      deleted function template.<br>
                      +  assert((Pattern ||
                      PatternDecl->isDefaulted()) &&<br>
                      +         "unexpected kind of function template
                      definition");<br>
                      <br>
                         // C++1y [temp.explicit]p10:<br>
                         //   Except for inline functions, declarations
                      with types deduced from their<br>
                      <br>
                      Modified: cfe/trunk/lib/Sema/SemaType.<wbr>cpp<br>
                      URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=279486&r1=279485&r2=279486&view=diff"
                        rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaType.cpp?rev=279486&r1=<wbr>279485&r2=279486&view=diff</a><br>
                      ==============================<wbr>==============================<wbr>==================<br>
                      --- cfe/trunk/lib/Sema/SemaType.<wbr>cpp
                      (original)<br>
                      +++ cfe/trunk/lib/Sema/SemaType.<wbr>cpp Mon Aug
                      22 17:25:03 2016<br>
                      @@ -6890,6 +6890,10 @@ bool
                      Sema::hasVisibleDefinition(<wbr>NamedDec<br>
                             return false;<br>
                           }<br>
                           D = ED->getDefinition();<br>
                      +  } else if (auto *FD =
                      dyn_cast<FunctionDecl>(D)) {<br>
                      +    if (auto *Pattern = FD-><wbr>getTemplateInstantiationPatter<wbr>n())<br>
                      +      FD = Pattern;<br>
                      +    D = FD->getDefinition();<br>
                         }<br>
                         assert(D && "missing definition for
                      pattern of instantiated definition");<br>
                      <br>
                      @@ -6897,7 +6901,7 @@ bool
                      Sema::hasVisibleDefinition(<wbr>NamedDec<br>
                         if (isVisible(D))<br>
                           return true;<br>
                      <br>
                      -  // The external source may have additional
                      definitions of this type that are<br>
                      +  // The external source may have additional
                      definitions of this entity that are<br>
                         // visible, so complete the redeclaration chain
                      now and ask again.<br>
                         if (auto *Source = Context.getExternalSource())
                      {<br>
                           Source->CompleteRedeclChain(<wbr>D);<br>
                      <br>
                      Modified: cfe/trunk/test/Modules/Inputs/<wbr>merge-template-pattern-<wbr>visibility/a.h<br>
                      URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/merge-template-pattern-visibility/a.h?rev=279486&r1=279485&r2=279486&view=diff"
                        rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>Modules/Inputs/merge-template-<wbr>pattern-visibility/a.h?rev=<wbr>279486&r1=279485&r2=279486&<wbr>view=diff</a><br>
                      ==============================<wbr>==============================<wbr>==================<br>
                      --- cfe/trunk/test/Modules/Inputs/<wbr>merge-template-pattern-<wbr>visibility/a.h
                      (original)<br>
                      +++ cfe/trunk/test/Modules/Inputs/<wbr>merge-template-pattern-<wbr>visibility/a.h
                      Mon Aug 22 17:25:03 2016<br>
                      @@ -3,3 +3,4 @@ template<typename T> struct
                      B;<br>
                      <br>
                       template<typename, typename> struct A {};<br>
                       template<typename T> struct B : A<T>
                      {};<br>
                      +template<typename T> inline auto C(T) {}<br>
                      <br>
                      Modified: cfe/trunk/test/Modules/Inputs/<wbr>merge-template-pattern-<wbr>visibility/b.h<br>
                      URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/merge-template-pattern-visibility/b.h?rev=279486&r1=279485&r2=279486&view=diff"
                        rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>Modules/Inputs/merge-template-<wbr>pattern-visibility/b.h?rev=<wbr>279486&r1=279485&r2=279486&<wbr>view=diff</a><br>
                      ==============================<wbr>==============================<wbr>==================<br>
                      --- cfe/trunk/test/Modules/Inputs/<wbr>merge-template-pattern-<wbr>visibility/b.h
                      (original)<br>
                      +++ cfe/trunk/test/Modules/Inputs/<wbr>merge-template-pattern-<wbr>visibility/b.h
                      Mon Aug 22 17:25:03 2016<br>
                      @@ -3,7 +3,9 @@ template<typename T> struct
                      B;<br>
                      <br>
                       template<typename, typename> struct A {};<br>
                       template<typename T> struct B : A<T>
                      {};<br>
                      +template<typename T> inline auto C(T) {}<br>
                      <br>
                       inline void f() {<br>
                         B<int> bi;<br>
                      +  C(0);<br>
                       }<br>
                      <br>
                      Modified: cfe/trunk/test/Modules/merge-<wbr>template-pattern-visibility.<wbr>cpp<br>
                      URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/merge-template-pattern-visibility.cpp?rev=279486&r1=279485&r2=279486&view=diff"
                        rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>Modules/merge-template-<wbr>pattern-visibility.cpp?rev=<wbr>279486&r1=279485&r2=279486&<wbr>view=diff</a><br>
                      ==============================<wbr>==============================<wbr>==================<br>
                      --- cfe/trunk/test/Modules/merge-<wbr>template-pattern-visibility.<wbr>cpp
                      (original)<br>
                      +++ cfe/trunk/test/Modules/merge-<wbr>template-pattern-visibility.<wbr>cpp
                      Mon Aug 22 17:25:03 2016<br>
                      @@ -1,4 +1,4 @@<br>
                       // RUN: rm -rf %t<br>
                      -// RUN: %clang_cc1 -fmodules
                      -fmodules-cache-path=%t
                      -fno-modules-error-recovery \<br>
                      +// RUN: %clang_cc1 -fmodules
                      -fno-modules-error-recovery -std=c++14 \<br>
                       // RUN:            -fmodule-name=X -emit-module
                      %S/Inputs/merge-template-<wbr>pattern-visibility/module.<wbr>modulemap
                      -x c++ \<br>
                      -// RUN:            -fmodules-local-submodule-<wbr>visibility<br>
                      +// RUN:            -fmodules-local-submodule-<wbr>visibility
                      -o %t/X.pcm<br>
                      <br>
                      <br>
                      ______________________________<wbr>_________________<br>
                      cfe-commits mailing list<br>
                      <a moz-do-not-send="true"
                        href="mailto:cfe-commits@lists.llvm.org"
                        target="_blank">cfe-commits@lists.llvm.org</a><br>
                      <a moz-do-not-send="true"
                        href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits"
                        rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
                    </blockquote>
                  </div>
                </div>
              </div>
            </div>
          </blockquote>
        </div>
        <br>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
cfe-commits mailing list
<a class="moz-txt-link-abbreviated" href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>
<a class="moz-txt-link-freetext" href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a>
</pre>
    </blockquote>
    <p><br>
    </p>
  </body>
</html>