<div dir="ltr">Should be fixed in r319835. I'd forgotten that Darwin / MachO uses a different mechanism from COMDATs here.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On 5 December 2017 at 13:27, Ahmed Bougacha via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On Tue, Dec 5, 2017 at 11:40 AM, Richard Smith via cfe-commits<br>
<<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br>
> Sorry about that, fixed in r319817.<br>
<br>
</span>Hey Richard,<br>
<br>
Looks like that's not enough on darwin:<br>
  <a href="http://green.lab.llvm.org/green/job/clang-stage1-cmake-RA-incremental/44764/consoleFull#-126347322349ba4694-19c4-4d7e-bec5-911270d8a58c" rel="noreferrer" target="_blank">http://green.lab.llvm.org/<wbr>green/job/clang-stage1-cmake-<wbr>RA-incremental/44764/<wbr>consoleFull#-<wbr>126347322349ba4694-19c4-4d7e-<wbr>bec5-911270d8a58c</a><br>
<br>
Can you have a look?  Thanks!<br>
-Ahmed<br>
<div class="HOEnZb"><div class="h5"><br>
> On 5 December 2017 at 10:38, Galina Kistanova via cfe-commits<br>
> <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br>
>><br>
>> Hello Richard,<br>
>><br>
>> This commit broke tests on one of our bots:<br>
>><br>
>><br>
>> <a href="http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/6568" rel="noreferrer" target="_blank">http://lab.llvm.org:8011/<wbr>builders/llvm-clang-x86_64-<wbr>expensive-checks-win/builds/<wbr>6568</a><br>
>><br>
>> Failing Tests (3):<br>
>> . . .<br>
>>     Clang :: Modules/var-templates.cpp<br>
>> . . .<br>
>><br>
>> Please have a look?<br>
>><br>
>> Thanks<br>
>><br>
>> Galina<br>
>><br>
>> On Mon, Dec 4, 2017 at 5:31 PM, Richard Smith via cfe-commits<br>
>> <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br>
>>><br>
>>> Author: rsmith<br>
>>> Date: Mon Dec  4 17:31:47 2017<br>
>>> New Revision: 319727<br>
>>><br>
>>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=319727&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=319727&view=rev</a><br>
>>> Log:<br>
>>> Generalize "static data member instantiated" notification to cover<br>
>>> variable templates too.<br>
>>><br>
>>> While here, split the "point of instantiation changed" notification out<br>
>>> from<br>
>>> it; these two really are orthogonal changes.<br>
>>><br>
>>> Added:<br>
>>>     cfe/trunk/test/Modules/var-<wbr>templates.cpp<br>
>>> Modified:<br>
>>>     cfe/trunk/include/clang/AST/<wbr>ASTMutationListener.h<br>
>>>     cfe/trunk/include/clang/Sema/<wbr>Sema.h<br>
>>>     cfe/trunk/include/clang/<wbr>Serialization/ASTWriter.h<br>
>>>     cfe/trunk/lib/AST/Decl.cpp<br>
>>>     cfe/trunk/lib/Frontend/<wbr>MultiplexConsumer.cpp<br>
>>>     cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp<br>
>>>     cfe/trunk/lib/Sema/<wbr>SemaTemplate.cpp<br>
>>>     cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiate.cpp<br>
>>>     cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiateDecl.<wbr>cpp<br>
>>>     cfe/trunk/lib/Sema/SemaType.<wbr>cpp<br>
>>>     cfe/trunk/lib/Serialization/<wbr>ASTCommon.h<br>
>>>     cfe/trunk/lib/Serialization/<wbr>ASTReaderDecl.cpp<br>
>>>     cfe/trunk/lib/Serialization/<wbr>ASTWriter.cpp<br>
>>><br>
>>> Modified: cfe/trunk/include/clang/AST/<wbr>ASTMutationListener.h<br>
>>> URL:<br>
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTMutationListener.h?rev=319727&r1=319726&r2=319727&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/AST/ASTMutationListener.<wbr>h?rev=319727&r1=319726&r2=<wbr>319727&view=diff</a><br>
>>><br>
>>> ==============================<wbr>==============================<wbr>==================<br>
>>> --- cfe/trunk/include/clang/AST/<wbr>ASTMutationListener.h (original)<br>
>>> +++ cfe/trunk/include/clang/AST/<wbr>ASTMutationListener.h Mon Dec  4 17:31:47<br>
>>> 2017<br>
>>> @@ -36,6 +36,7 @@ namespace clang {<br>
>>>    class QualType;<br>
>>>    class RecordDecl;<br>
>>>    class TagDecl;<br>
>>> +  class ValueDecl;<br>
>>>    class VarDecl;<br>
>>>    class VarTemplateDecl;<br>
>>>    class VarTemplateSpecializationDecl;<br>
>>> @@ -87,8 +88,13 @@ public:<br>
>>>    /// \brief An implicit member got a definition.<br>
>>>    virtual void CompletedImplicitDefinition(<wbr>const FunctionDecl *D) {}<br>
>>><br>
>>> -  /// \brief A static data member was implicitly instantiated.<br>
>>> -  virtual void StaticDataMemberInstantiated(<wbr>const VarDecl *D) {}<br>
>>> +  /// \brief The instantiation of a templated function or variable was<br>
>>> +  /// requested. In particular, the point of instantiation and template<br>
>>> +  /// specialization kind of \p D may have changed.<br>
>>> +  virtual void InstantiationRequested(const ValueDecl *D) {}<br>
>>> +<br>
>>> +  /// \brief A templated variable's definition was implicitly<br>
>>> instantiated.<br>
>>> +  virtual void VariableDefinitionInstantiated<wbr>(const VarDecl *D) {}<br>
>>><br>
>>>    /// \brief A function template's definition was instantiated.<br>
>>>    virtual void FunctionDefinitionInstantiated<wbr>(const FunctionDecl *D) {}<br>
>>><br>
>>> Modified: cfe/trunk/include/clang/Sema/<wbr>Sema.h<br>
>>> URL:<br>
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=319727&r1=319726&r2=319727&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Sema/Sema.h?rev=319727&<wbr>r1=319726&r2=319727&view=diff</a><br>
>>><br>
>>> ==============================<wbr>==============================<wbr>==================<br>
>>> --- cfe/trunk/include/clang/Sema/<wbr>Sema.h (original)<br>
>>> +++ cfe/trunk/include/clang/Sema/<wbr>Sema.h Mon Dec  4 17:31:47 2017<br>
>>> @@ -7790,11 +7790,6 @@ public:<br>
>>>                                       VarDecl *Var, bool Recursive =<br>
>>> false,<br>
>>>                                       bool DefinitionRequired = false,<br>
>>>                                       bool AtEndOfTU = false);<br>
>>> -  void InstantiateStaticDataMemberDef<wbr>inition(<br>
>>> -                                     SourceLocation<br>
>>> PointOfInstantiation,<br>
>>> -                                     VarDecl *Var,<br>
>>> -                                     bool Recursive = false,<br>
>>> -                                     bool DefinitionRequired = false);<br>
>>><br>
>>>    void InstantiateMemInitializers(<wbr>CXXConstructorDecl *New,<br>
>>>                                    const CXXConstructorDecl *Tmpl,<br>
>>><br>
>>> Modified: cfe/trunk/include/clang/<wbr>Serialization/ASTWriter.h<br>
>>> URL:<br>
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=319727&r1=319726&r2=319727&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Serialization/ASTWriter.<wbr>h?rev=319727&r1=319726&r2=<wbr>319727&view=diff</a><br>
>>><br>
>>> ==============================<wbr>==============================<wbr>==================<br>
>>> --- cfe/trunk/include/clang/<wbr>Serialization/ASTWriter.h (original)<br>
>>> +++ cfe/trunk/include/clang/<wbr>Serialization/ASTWriter.h Mon Dec  4 17:31:47<br>
>>> 2017<br>
>>> @@ -727,10 +727,11 @@ private:<br>
>>>                                const FunctionDecl *Delete,<br>
>>>                                Expr *ThisArg) override;<br>
>>>    void CompletedImplicitDefinition(<wbr>const FunctionDecl *D) override;<br>
>>> -  void StaticDataMemberInstantiated(<wbr>const VarDecl *D) override;<br>
>>> +  void InstantiationRequested(const ValueDecl *D) override;<br>
>>> +  void VariableDefinitionInstantiated<wbr>(const VarDecl *D) override;<br>
>>> +  void FunctionDefinitionInstantiated<wbr>(const FunctionDecl *D) override;<br>
>>>    void DefaultArgumentInstantiated(<wbr>const ParmVarDecl *D) override;<br>
>>>    void DefaultMemberInitializerInstan<wbr>tiated(const FieldDecl *D)<br>
>>> override;<br>
>>> -  void FunctionDefinitionInstantiated<wbr>(const FunctionDecl *D) override;<br>
>>>    void AddedObjCCategoryToInterface(<wbr>const ObjCCategoryDecl *CatD,<br>
>>>                                      const ObjCInterfaceDecl *IFD)<br>
>>> override;<br>
>>>    void DeclarationMarkedUsed(const Decl *D) override;<br>
>>><br>
>>> Modified: cfe/trunk/lib/AST/Decl.cpp<br>
>>> URL:<br>
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=319727&r1=319726&r2=319727&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>Decl.cpp?rev=319727&r1=319726&<wbr>r2=319727&view=diff</a><br>
>>><br>
>>> ==============================<wbr>==============================<wbr>==================<br>
>>> --- cfe/trunk/lib/AST/Decl.cpp (original)<br>
>>> +++ cfe/trunk/lib/AST/Decl.cpp Mon Dec  4 17:31:47 2017<br>
>>> @@ -2418,15 +2418,21 @@ void VarDecl::<wbr>setTemplateSpecializationK<br>
>>>            dyn_cast<<wbr>VarTemplateSpecializationDecl><wbr>(this)) {<br>
>>>      Spec->setSpecializationKind(<wbr>TSK);<br>
>>>      if (TSK != TSK_ExplicitSpecialization &&<br>
>>> PointOfInstantiation.isValid() &&<br>
>>> -        Spec->getPointOfInstantiation(<wbr>).isInvalid())<br>
>>> +        Spec->getPointOfInstantiation(<wbr>).isInvalid()) {<br>
>>>        Spec->setPointOfInstantiation(<wbr>PointOfInstantiation);<br>
>>> +      if (ASTMutationListener *L =<br>
>>> getASTContext().<wbr>getASTMutationListener())<br>
>>> +        L->InstantiationRequested(<wbr>this);<br>
>>> +    }<br>
>>>    }<br>
>>><br>
>>>    if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) {<br>
>>>      MSI-><wbr>setTemplateSpecializationKind(<wbr>TSK);<br>
>>>      if (TSK != TSK_ExplicitSpecialization &&<br>
>>> PointOfInstantiation.isValid() &&<br>
>>> -        MSI->getPointOfInstantiation()<wbr>.isInvalid())<br>
>>> +        MSI->getPointOfInstantiation()<wbr>.isInvalid()) {<br>
>>>        MSI->setPointOfInstantiation(<wbr>PointOfInstantiation);<br>
>>> +      if (ASTMutationListener *L =<br>
>>> getASTContext().<wbr>getASTMutationListener())<br>
>>> +        L->InstantiationRequested(<wbr>this);<br>
>>> +    }<br>
>>>    }<br>
>>>  }<br>
>>><br>
>>> @@ -3442,15 +3448,21 @@ FunctionDecl::<wbr>setTemplateSpecializationK<br>
>>>      FTSInfo-><wbr>setTemplateSpecializationKind(<wbr>TSK);<br>
>>>      if (TSK != TSK_ExplicitSpecialization &&<br>
>>>          PointOfInstantiation.isValid() &&<br>
>>> -        FTSInfo-><wbr>getPointOfInstantiation().<wbr>isInvalid())<br>
>>> +        FTSInfo-><wbr>getPointOfInstantiation().<wbr>isInvalid()) {<br>
>>>        FTSInfo-><wbr>setPointOfInstantiation(<wbr>PointOfInstantiation);<br>
>>> +      if (ASTMutationListener *L =<br>
>>> getASTContext().<wbr>getASTMutationListener())<br>
>>> +        L->InstantiationRequested(<wbr>this);<br>
>>> +    }<br>
>>>    } else if (MemberSpecializationInfo *MSInfo<br>
>>>               =<br>
>>> TemplateOrSpecialization.dyn_<wbr>cast<MemberSpecializationInfo*<wbr>>()) {<br>
>>>      MSInfo-><wbr>setTemplateSpecializationKind(<wbr>TSK);<br>
>>>      if (TSK != TSK_ExplicitSpecialization &&<br>
>>>          PointOfInstantiation.isValid() &&<br>
>>> -        MSInfo-><wbr>getPointOfInstantiation().<wbr>isInvalid())<br>
>>> +        MSInfo-><wbr>getPointOfInstantiation().<wbr>isInvalid()) {<br>
>>>        MSInfo-><wbr>setPointOfInstantiation(<wbr>PointOfInstantiation);<br>
>>> +      if (ASTMutationListener *L =<br>
>>> getASTContext().<wbr>getASTMutationListener())<br>
>>> +        L->InstantiationRequested(<wbr>this);<br>
>>> +    }<br>
>>>    } else<br>
>>>      llvm_unreachable("Function cannot have a template specialization<br>
>>> kind");<br>
>>>  }<br>
>>><br>
>>> Modified: cfe/trunk/lib/Frontend/<wbr>MultiplexConsumer.cpp<br>
>>> URL:<br>
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/MultiplexConsumer.cpp?rev=319727&r1=319726&r2=319727&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/<wbr>Frontend/MultiplexConsumer.<wbr>cpp?rev=319727&r1=319726&r2=<wbr>319727&view=diff</a><br>
>>><br>
>>> ==============================<wbr>==============================<wbr>==================<br>
>>> --- cfe/trunk/lib/Frontend/<wbr>MultiplexConsumer.cpp (original)<br>
>>> +++ cfe/trunk/lib/Frontend/<wbr>MultiplexConsumer.cpp Mon Dec  4 17:31:47 2017<br>
>>> @@ -119,12 +119,13 @@ public:<br>
>>>                                const FunctionDecl *Delete,<br>
>>>                                Expr *ThisArg) override;<br>
>>>    void CompletedImplicitDefinition(<wbr>const FunctionDecl *D) override;<br>
>>> -  void StaticDataMemberInstantiated(<wbr>const VarDecl *D) override;<br>
>>> +  void InstantiationRequested(const ValueDecl *D) override;<br>
>>> +  void VariableDefinitionInstantiated<wbr>(const VarDecl *D) override;<br>
>>> +  void FunctionDefinitionInstantiated<wbr>(const FunctionDecl *D) override;<br>
>>>    void DefaultArgumentInstantiated(<wbr>const ParmVarDecl *D) override;<br>
>>>    void DefaultMemberInitializerInstan<wbr>tiated(const FieldDecl *D)<br>
>>> override;<br>
>>>    void AddedObjCCategoryToInterface(<wbr>const ObjCCategoryDecl *CatD,<br>
>>>                                      const ObjCInterfaceDecl *IFD)<br>
>>> override;<br>
>>> -  void FunctionDefinitionInstantiated<wbr>(const FunctionDecl *D) override;<br>
>>>    void DeclarationMarkedUsed(const Decl *D) override;<br>
>>>    void DeclarationMarkedOpenMPThreadP<wbr>rivate(const Decl *D) override;<br>
>>>    void DeclarationMarkedOpenMPDeclare<wbr>Target(const Decl *D,<br>
>>> @@ -193,10 +194,19 @@ void MultiplexASTMutationListener::<wbr>Compl<br>
>>>    for (size_t i = 0, e = Listeners.size(); i != e; ++i)<br>
>>>      Listeners[i]-><wbr>CompletedImplicitDefinition(D)<wbr>;<br>
>>>  }<br>
>>> -void MultiplexASTMutationListener::<wbr>StaticDataMemberInstantiated(<br>
>>> -                                                             const<br>
>>> VarDecl *D) {<br>
>>> +void MultiplexASTMutationListener::<wbr>InstantiationRequested(const<br>
>>> ValueDecl *D) {<br>
>>> +  for (size_t i = 0, e = Listeners.size(); i != e; ++i)<br>
>>> +    Listeners[i]-><wbr>InstantiationRequested(D);<br>
>>> +}<br>
>>> +void MultiplexASTMutationListener::<wbr>VariableDefinitionInstantiated<wbr>(<br>
>>> +    const VarDecl *D) {<br>
>>>    for (size_t i = 0, e = Listeners.size(); i != e; ++i)<br>
>>> -    Listeners[i]-><wbr>StaticDataMemberInstantiated(<wbr>D);<br>
>>> +    Listeners[i]-><wbr>VariableDefinitionInstantiated<wbr>(D);<br>
>>> +}<br>
>>> +void MultiplexASTMutationListener::<wbr>FunctionDefinitionInstantiated<wbr>(<br>
>>> +    const FunctionDecl *D) {<br>
>>> +  for (auto &Listener : Listeners)<br>
>>> +    Listener-><wbr>FunctionDefinitionInstantiated<wbr>(D);<br>
>>>  }<br>
>>>  void MultiplexASTMutationListener::<wbr>DefaultArgumentInstantiated(<br>
>>>                                                           const<br>
>>> ParmVarDecl *D) {<br>
>>> @@ -214,11 +224,6 @@ void MultiplexASTMutationListener::<wbr>Added<br>
>>>    for (size_t i = 0, e = Listeners.size(); i != e; ++i)<br>
>>>      Listeners[i]-><wbr>AddedObjCCategoryToInterface(<wbr>CatD, IFD);<br>
>>>  }<br>
>>> -void MultiplexASTMutationListener::<wbr>FunctionDefinitionInstantiated<wbr>(<br>
>>> -    const FunctionDecl *D) {<br>
>>> -  for (auto &Listener : Listeners)<br>
>>> -    Listener-><wbr>FunctionDefinitionInstantiated<wbr>(D);<br>
>>> -}<br>
>>>  void MultiplexASTMutationListener::<wbr>DeclarationMarkedUsed(const Decl *D)<br>
>>> {<br>
>>>    for (size_t i = 0, e = Listeners.size(); i != e; ++i)<br>
>>>      Listeners[i]-><wbr>DeclarationMarkedUsed(D);<br>
>>><br>
>>> Modified: cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp<br>
>>> URL:<br>
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=319727&r1=319726&r2=319727&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaExpr.cpp?rev=319727&r1=<wbr>319726&r2=319727&view=diff</a><br>
>>><br>
>>> ==============================<wbr>==============================<wbr>==================<br>
>>> --- cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp (original)<br>
>>> +++ cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp Mon Dec  4 17:31:47 2017<br>
>>> @@ -13960,29 +13960,21 @@ void Sema::MarkFunctionReferenced(<wbr>Source<br>
>>>    // Implicit instantiation of function templates and member functions<br>
>>> of<br>
>>>    // class templates.<br>
>>>    if (Func-><wbr>isImplicitlyInstantiable()) {<br>
>>> -    bool AlreadyInstantiated = false;<br>
>>> -    SourceLocation PointOfInstantiation = Loc;<br>
>>> -    if (<wbr>FunctionTemplateSpecialization<wbr>Info *SpecInfo<br>
>>> -                              = Func-><wbr>getTemplateSpecializationInfo(<wbr>)) {<br>
>>> -      if (SpecInfo-><wbr>getPointOfInstantiation().<wbr>isInvalid())<br>
>>> -        SpecInfo-><wbr>setPointOfInstantiation(Loc);<br>
>>> -      else if (SpecInfo-><wbr>getTemplateSpecializationKind(<wbr>)<br>
>>> -                 == TSK_ImplicitInstantiation) {<br>
>>> -        AlreadyInstantiated = true;<br>
>>> -        PointOfInstantiation = SpecInfo-><wbr>getPointOfInstantiation();<br>
>>> -      }<br>
>>> -    } else if (MemberSpecializationInfo *MSInfo<br>
>>> -                                = Func-><wbr>getMemberSpecializationInfo()) {<br>
>>> -      if (MSInfo-><wbr>getPointOfInstantiation().<wbr>isInvalid())<br>
>>> -        MSInfo-><wbr>setPointOfInstantiation(Loc);<br>
>>> -      else if (MSInfo-><wbr>getTemplateSpecializationKind(<wbr>)<br>
>>> -                 == TSK_ImplicitInstantiation) {<br>
>>> -        AlreadyInstantiated = true;<br>
>>> -        PointOfInstantiation = MSInfo-><wbr>getPointOfInstantiation();<br>
>>> -      }<br>
>>> +    TemplateSpecializationKind TSK =<br>
>>> Func-><wbr>getTemplateSpecializationKind(<wbr>);<br>
>>> +    SourceLocation PointOfInstantiation =<br>
>>> Func->getPointOfInstantiation(<wbr>);<br>
>>> +    bool FirstInstantiation = PointOfInstantiation.<wbr>isInvalid();<br>
>>> +    if (FirstInstantiation) {<br>
>>> +      PointOfInstantiation = Loc;<br>
>>> +      Func-><wbr>setTemplateSpecializationKind(<wbr>TSK, PointOfInstantiation);<br>
>>> +    } else if (TSK != TSK_ImplicitInstantiation) {<br>
>>> +      // Use the point of use as the point of instantiation, instead of<br>
>>> the<br>
>>> +      // point of explicit instantiation (which we track as the actual<br>
>>> point of<br>
>>> +      // instantiation). This gives better backtraces in diagnostics.<br>
>>> +      PointOfInstantiation = Loc;<br>
>>>      }<br>
>>><br>
>>> -    if (!AlreadyInstantiated || Func->isConstexpr()) {<br>
>>> +    if (FirstInstantiation || TSK != TSK_ImplicitInstantiation ||<br>
>>> +        Func->isConstexpr()) {<br>
>>>        if (isa<CXXRecordDecl>(Func-><wbr>getDeclContext()) &&<br>
>>>            cast<CXXRecordDecl>(Func-><wbr>getDeclContext())-><wbr>isLocalClass() &&<br>
>>>            CodeSynthesisContexts.size())<br>
>>> @@ -14859,22 +14851,14 @@ static void DoMarkVarDeclReferenced(Sema<br>
>>>          TSK == TSK_ImplicitInstantiation ||<br>
>>>          (TSK == TSK_<wbr>ExplicitInstantiationDeclarati<wbr>on &&<br>
>>> UsableInConstantExpr);<br>
>>><br>
>>> -    if (TryInstantiating && !isa<<wbr>VarTemplateSpecializationDecl><wbr>(Var)) {<br>
>>> -      if (Var->getPointOfInstantiation(<wbr>).isInvalid()) {<br>
>>> -        // This is a modification of an existing AST node. Notify<br>
>>> listeners.<br>
>>> -        if (ASTMutationListener *L = SemaRef.<wbr>getASTMutationListener())<br>
>>> -          L-><wbr>StaticDataMemberInstantiated(<wbr>Var);<br>
>>> -      } else if (!UsableInConstantExpr)<br>
>>> -        // Don't bother trying to instantiate it again, unless we might<br>
>>> need<br>
>>> -        // its initializer before we get to the end of the TU.<br>
>>> -        TryInstantiating = false;<br>
>>> -    }<br>
>>> -<br>
>>> -    if (Var->getPointOfInstantiation(<wbr>).isInvalid())<br>
>>> -      Var-><wbr>setTemplateSpecializationKind(<wbr>TSK, Loc);<br>
>>> -<br>
>>>      if (TryInstantiating) {<br>
>>>        SourceLocation PointOfInstantiation =<br>
>>> Var->getPointOfInstantiation()<wbr>;<br>
>>> +      bool FirstInstantiation = PointOfInstantiation.<wbr>isInvalid();<br>
>>> +      if (FirstInstantiation) {<br>
>>> +        PointOfInstantiation = Loc;<br>
>>> +        Var-><wbr>setTemplateSpecializationKind(<wbr>TSK, PointOfInstantiation);<br>
>>> +      }<br>
>>> +<br>
>>>        bool InstantiationDependent = false;<br>
>>>        bool IsNonDependent =<br>
>>>            VarSpec ?<br>
>>> !TemplateSpecializationType::<wbr>anyDependentTemplateArguments(<br>
>>> @@ -14884,10 +14868,16 @@ static void DoMarkVarDeclReferenced(Sema<br>
>>>        // Do not instantiate specializations that are still<br>
>>> type-dependent.<br>
>>>        if (IsNonDependent) {<br>
>>>          if (UsableInConstantExpr) {<br>
>>> -          // Do not defer instantiations of variables which could be<br>
>>> used in a<br>
>>> +          // Do not defer instantiations of variables that could be used<br>
>>> in a<br>
>>>            // constant expression.<br>
>>>            SemaRef.<wbr>InstantiateVariableDefinition(<wbr>PointOfInstantiation,<br>
>>> Var);<br>
>>> -        } else {<br>
>>> +        } else if (FirstInstantiation ||<br>
>>> +                   isa<<wbr>VarTemplateSpecializationDecl><wbr>(Var)) {<br>
>>> +          // FIXME: For a specialization of a variable template, we<br>
>>> don't<br>
>>> +          // distinguish between "declaration and type implicitly<br>
>>> instantiated"<br>
>>> +          // and "implicit instantiation of definition requested", so we<br>
>>> have<br>
>>> +          // no direct way to avoid enqueueing the pending instantiation<br>
>>> +          // multiple times.<br>
>>>            SemaRef.PendingInstantiations<br>
>>>                .push_back(std::make_pair(Var, PointOfInstantiation));<br>
>>>          }<br>
>>><br>
>>> Modified: cfe/trunk/lib/Sema/<wbr>SemaTemplate.cpp<br>
>>> URL:<br>
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=319727&r1=319726&r2=319727&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaTemplate.cpp?rev=319727&<wbr>r1=319726&r2=319727&view=diff</a><br>
>>><br>
>>> ==============================<wbr>==============================<wbr>==================<br>
>>> --- cfe/trunk/lib/Sema/<wbr>SemaTemplate.cpp (original)<br>
>>> +++ cfe/trunk/lib/Sema/<wbr>SemaTemplate.cpp Mon Dec  4 17:31:47 2017<br>
>>> @@ -9071,7 +9071,6 @@ DeclResult Sema::ActOnExplicitInstantiat<br>
>>><br>
>>>      if (!HasNoEffect) {<br>
>>>        // Instantiate static data member or variable template.<br>
>>> -<br>
>>>        Prev-><wbr>setTemplateSpecializationKind(<wbr>TSK, D.getIdentifierLoc());<br>
>>>        if (PrevTemplate) {<br>
>>>          // Merge attributes.<br>
>>><br>
>>> Modified: cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiate.cpp<br>
>>> URL:<br>
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=319727&r1=319726&r2=319727&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiate.cpp?<wbr>rev=319727&r1=319726&r2=<wbr>319727&view=diff</a><br>
>>><br>
>>> ==============================<wbr>==============================<wbr>==================<br>
>>> --- cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiate.cpp (original)<br>
>>> +++ cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiate.cpp Mon Dec  4 17:31:47<br>
>>> 2017<br>
>>> @@ -2613,7 +2613,7 @@ Sema::InstantiateClassMembers(<wbr>SourceLoca<br>
>>>              continue;<br>
>>><br>
>>>            Var-><wbr>setTemplateSpecializationKind(<wbr>TSK, PointOfInstantiation);<br>
>>> -          InstantiateStaticDataMemberDef<wbr>inition(PointOfInstantiation,<br>
>>> Var);<br>
>>> +          InstantiateVariableDefinition(<wbr>PointOfInstantiation, Var);<br>
>>>          } else {<br>
>>>            Var-><wbr>setTemplateSpecializationKind(<wbr>TSK, PointOfInstantiation);<br>
>>>          }<br>
>>><br>
>>> Modified: cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiateDecl.<wbr>cpp<br>
>>> URL:<br>
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=319727&r1=319726&r2=319727&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiateDecl.<wbr>cpp?rev=319727&r1=319726&r2=<wbr>319727&view=diff</a><br>
>>><br>
>>> ==============================<wbr>==============================<wbr>==================<br>
>>> --- cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiateDecl.<wbr>cpp (original)<br>
>>> +++ cfe/trunk/lib/Sema/<wbr>SemaTemplateInstantiateDecl.<wbr>cpp Mon Dec  4<br>
>>> 17:31:47 2017<br>
>>> @@ -4142,6 +4142,9 @@ void Sema::<wbr>BuildVariableInstantiation(<br>
>>>  void Sema::<wbr>InstantiateVariableInitializer<wbr>(<br>
>>>      VarDecl *Var, VarDecl *OldVar,<br>
>>>      const MultiLevelTemplateArgumentList &TemplateArgs) {<br>
>>> +  if (ASTMutationListener *L = getASTContext().<wbr>getASTMutationListener())<br>
>>> +    L-><wbr>VariableDefinitionInstantiated<wbr>(Var);<br>
>>> +<br>
>>>    // We propagate the 'inline' flag with the initializer, because it<br>
>>>    // would otherwise imply that the variable is a definition for a<br>
>>>    // non-static data member.<br>
>>> @@ -4204,36 +4207,22 @@ void Sema::<wbr>InstantiateVariableInitialize<br>
>>>  ///<br>
>>>  /// \param PointOfInstantiation the point at which the instantiation was<br>
>>>  /// required. Note that this is not precisely a "point of instantiation"<br>
>>> -/// for the function, but it's close.<br>
>>> +/// for the variable, but it's close.<br>
>>>  ///<br>
>>> -/// \param Var the already-instantiated declaration of a static member<br>
>>> -/// variable of a class template specialization.<br>
>>> +/// \param Var the already-instantiated declaration of a templated<br>
>>> variable.<br>
>>>  ///<br>
>>>  /// \param Recursive if true, recursively instantiates any functions<br>
>>> that<br>
>>>  /// are required by this instantiation.<br>
>>>  ///<br>
>>>  /// \param DefinitionRequired if true, then we are performing an<br>
>>> explicit<br>
>>> -/// instantiation where an out-of-line definition of the member variable<br>
>>> -/// is required. Complain if there is no such definition.<br>
>>> -void Sema::<wbr>InstantiateStaticDataMemberDef<wbr>inition(<br>
>>> -                                          SourceLocation<br>
>>> PointOfInstantiation,<br>
>>> -                                                 VarDecl *Var,<br>
>>> -                                                 bool Recursive,<br>
>>> -                                                 bool<br>
>>> DefinitionRequired) {<br>
>>> -  InstantiateVariableDefinition(<wbr>PointOfInstantiation, Var, Recursive,<br>
>>> -                                DefinitionRequired);<br>
>>> -}<br>
>>> -<br>
>>> +/// instantiation where a definition of the variable is required.<br>
>>> Complain<br>
>>> +/// if there is no such definition.<br>
>>>  void Sema::<wbr>InstantiateVariableDefinition(<wbr>SourceLocation<br>
>>> PointOfInstantiation,<br>
>>>                                           VarDecl *Var, bool Recursive,<br>
>>>                                        bool DefinitionRequired, bool<br>
>>> AtEndOfTU) {<br>
>>>    if (Var->isInvalidDecl())<br>
>>>      return;<br>
>>><br>
>>> -  // FIXME: We're missing ASTMutationListener notifications for all of<br>
>>> the work<br>
>>> -  // done here. (Some of our callers notify the listeners for the static<br>
>>> data<br>
>>> -  // member case, but not in general.)<br>
>>> -<br>
>>>    VarTemplateSpecializationDecl *VarSpec =<br>
>>>        dyn_cast<<wbr>VarTemplateSpecializationDecl><wbr>(Var);<br>
>>>    VarDecl *PatternDecl = nullptr, *Def = nullptr;<br>
>>> @@ -4284,6 +4273,11 @@ void Sema::<wbr>InstantiateVariableDefinition<br>
>>>      // If this is a static data member template, there might be an<br>
>>>      // uninstantiated initializer on the declaration. If so, instantiate<br>
>>>      // it now.<br>
>>> +    //<br>
>>> +    // FIXME: This largely duplicates what we would do below. The<br>
>>> difference<br>
>>> +    // is that along this path we may instantiate an initializer from an<br>
>>> +    // in-class declaration of the template and instantiate the<br>
>>> definition<br>
>>> +    // from a separate out-of-class definition.<br>
>>>      if (PatternDecl-><wbr>isStaticDataMember() &&<br>
>>>          (PatternDecl = PatternDecl->getFirstDecl())-><wbr>hasInit() &&<br>
>>>          !Var->hasInit()) {<br>
>>><br>
>>> Modified: cfe/trunk/lib/Sema/SemaType.<wbr>cpp<br>
>>> URL:<br>
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=319727&r1=319726&r2=319727&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaType.cpp?rev=319727&r1=<wbr>319726&r2=319727&view=diff</a><br>
>>><br>
>>> ==============================<wbr>==============================<wbr>==================<br>
>>> --- cfe/trunk/lib/Sema/SemaType.<wbr>cpp (original)<br>
>>> +++ cfe/trunk/lib/Sema/SemaType.<wbr>cpp Mon Dec  4 17:31:47 2017<br>
>>> @@ -7268,32 +7268,28 @@ static void processTypeAttrs(TypeProcess<br>
>>>  void Sema::completeExprArrayBound(<wbr>Expr *E) {<br>
>>>    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E-><wbr>IgnoreParens())) {<br>
>>>      if (VarDecl *Var = dyn_cast<VarDecl>(DRE-><wbr>getDecl())) {<br>
>>> -      if (isTemplateInstantiation(Var-><wbr>getTemplateSpecializationKind(<wbr>)))<br>
>>> {<br>
>>> +      if (isTemplateInstantiation(Var-><wbr>getTemplateSpecializationKind(<wbr>))<br>
>>> &&<br>
>>> +          !Var->getDefinition()) {<br>
>>>          SourceLocation PointOfInstantiation = E->getExprLoc();<br>
>>> +        InstantiateVariableDefinition(<wbr>PointOfInstantiation, Var);<br>
>>> +        auto *Def = Var->getDefinition();<br>
>>><br>
>>> -        if (MemberSpecializationInfo *MSInfo =<br>
>>> -                Var-><wbr>getMemberSpecializationInfo()) {<br>
>>> -          // If we don't already have a point of instantiation, this is<br>
>>> it.<br>
>>> -          if (MSInfo-><wbr>getPointOfInstantiation().<wbr>isInvalid()) {<br>
>>> -            MSInfo-><wbr>setPointOfInstantiation(<wbr>PointOfInstantiation);<br>
>>> -<br>
>>> -            // This is a modification of an existing AST node. Notify<br>
>>> -            // listeners.<br>
>>> -            if (ASTMutationListener *L = getASTMutationListener())<br>
>>> -              L-><wbr>StaticDataMemberInstantiated(<wbr>Var);<br>
>>> -          }<br>
>>> -        } else {<br>
>>> -          VarTemplateSpecializationDecl *VarSpec =<br>
>>> -              cast<<wbr>VarTemplateSpecializationDecl><wbr>(Var);<br>
>>> -          if (VarSpec-><wbr>getPointOfInstantiation().<wbr>isInvalid())<br>
>>> -            VarSpec-><wbr>setPointOfInstantiation(<wbr>PointOfInstantiation);<br>
>>> +        // If we don't already have a point of instantiation, and we<br>
>>> managed to<br>
>>> +        // instantiate a definition, this is the point of instantiation.<br>
>>> +        // Otherwise, we don't request an end-of-TU instantiation, so<br>
>>> this is<br>
>>> +        // not a point of instantiation.<br>
>>> +        // FIXME: Is this really the right behavior?<br>
>>> +        if (Var->getPointOfInstantiation(<wbr>).isInvalid() && Def) {<br>
>>> +          assert(Var-><wbr>getTemplateSpecializationKind(<wbr>) ==<br>
>>> +                     TSK_ImplicitInstantiation &&<br>
>>> +                 "explicit instantiation with no point of<br>
>>> instantiation");<br>
>>> +          Var-><wbr>setTemplateSpecializationKind(<br>
>>> +              Var-><wbr>getTemplateSpecializationKind(<wbr>),<br>
>>> PointOfInstantiation);<br>
>>>          }<br>
>>><br>
>>> -        InstantiateVariableDefinition(<wbr>PointOfInstantiation, Var);<br>
>>> -<br>
>>>          // Update the type to the newly instantiated definition's type<br>
>>> both<br>
>>>          // here and within the expression.<br>
>>> -        if (VarDecl *Def = Var->getDefinition()) {<br>
>>> +        if (Def) {<br>
>>>            DRE->setDecl(Def);<br>
>>>            QualType T = Def->getType();<br>
>>>            DRE->setType(T);<br>
>>><br>
>>> Modified: cfe/trunk/lib/Serialization/<wbr>ASTCommon.h<br>
>>> URL:<br>
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.h?rev=319727&r1=319726&r2=319727&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/<wbr>Serialization/ASTCommon.h?rev=<wbr>319727&r1=319726&r2=319727&<wbr>view=diff</a><br>
>>><br>
>>> ==============================<wbr>==============================<wbr>==================<br>
>>> --- cfe/trunk/lib/Serialization/<wbr>ASTCommon.h (original)<br>
>>> +++ cfe/trunk/lib/Serialization/<wbr>ASTCommon.h Mon Dec  4 17:31:47 2017<br>
>>> @@ -27,7 +27,8 @@ enum DeclUpdateKind {<br>
>>>    UPD_CXX_ADDED_TEMPLATE_<wbr>SPECIALIZATION,<br>
>>>    UPD_CXX_ADDED_ANONYMOUS_<wbr>NAMESPACE,<br>
>>>    UPD_CXX_ADDED_FUNCTION_<wbr>DEFINITION,<br>
>>> -  UPD_CXX_INSTANTIATED_STATIC_<wbr>DATA_MEMBER,<br>
>>> +  UPD_CXX_ADDED_VAR_DEFINITION,<br>
>>> +  UPD_CXX_POINT_OF_<wbr>INSTANTIATION,<br>
>>>    UPD_CXX_INSTANTIATED_CLASS_<wbr>DEFINITION,<br>
>>>    UPD_CXX_INSTANTIATED_DEFAULT_<wbr>ARGUMENT,<br>
>>>    UPD_CXX_INSTANTIATED_DEFAULT_<wbr>MEMBER_INITIALIZER,<br>
>>><br>
>>> Modified: cfe/trunk/lib/Serialization/<wbr>ASTReaderDecl.cpp<br>
>>> URL:<br>
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=319727&r1=319726&r2=319727&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/<wbr>Serialization/ASTReaderDecl.<wbr>cpp?rev=319727&r1=319726&r2=<wbr>319727&view=diff</a><br>
>>><br>
>>> ==============================<wbr>==============================<wbr>==================<br>
>>> --- cfe/trunk/lib/Serialization/<wbr>ASTReaderDecl.cpp (original)<br>
>>> +++ cfe/trunk/lib/Serialization/<wbr>ASTReaderDecl.cpp Mon Dec  4 17:31:47<br>
>>> 2017<br>
>>> @@ -3984,10 +3984,8 @@ void ASTDeclReader::UpdateDecl(Decl *D,<br>
>>>        break;<br>
>>>      }<br>
>>><br>
>>> -    case UPD_CXX_INSTANTIATED_STATIC_<wbr>DATA_MEMBER: {<br>
>>> +    case UPD_CXX_ADDED_VAR_DEFINITION: {<br>
>>>        VarDecl *VD = cast<VarDecl>(D);<br>
>>> -      VD-><wbr>getMemberSpecializationInfo()-<wbr>>setPointOfInstantiation(<br>
>>> -          ReadSourceLocation());<br>
>>>        VD->NonParmVarDeclBits.<wbr>IsInline = Record.readInt();<br>
>>>        VD->NonParmVarDeclBits.<wbr>IsInlineSpecified = Record.readInt();<br>
>>>        uint64_t Val = Record.readInt();<br>
>>> @@ -4001,6 +3999,25 @@ void ASTDeclReader::UpdateDecl(Decl *D,<br>
>>>        }<br>
>>>        break;<br>
>>>      }<br>
>>> +<br>
>>> +    case UPD_CXX_POINT_OF_<wbr>INSTANTIATION: {<br>
>>> +      SourceLocation POI = Record.readSourceLocation();<br>
>>> +      if (VarTemplateSpecializationDecl *VTSD =<br>
>>> +              dyn_cast<<wbr>VarTemplateSpecializationDecl><wbr>(D)) {<br>
>>> +        VTSD->setPointOfInstantiation(<wbr>POI);<br>
>>> +      } else if (auto *VD = dyn_cast<VarDecl>(D)) {<br>
>>> +        VD-><wbr>getMemberSpecializationInfo()-<wbr>>setPointOfInstantiation(POI);<br>
>>> +      } else {<br>
>>> +        auto *FD = cast<FunctionDecl>(D);<br>
>>> +        if (auto *FTSInfo = FD->TemplateOrSpecialization<br>
>>> +                    .dyn_cast<<wbr>FunctionTemplateSpecialization<wbr>Info *>())<br>
>>> +          FTSInfo-><wbr>setPointOfInstantiation(POI);<br>
>>> +        else<br>
>>> +          FD->TemplateOrSpecialization.<wbr>get<MemberSpecializationInfo *>()<br>
>>> +              ->setPointOfInstantiation(POI)<wbr>;<br>
>>> +      }<br>
>>> +      break;<br>
>>> +    }<br>
>>><br>
>>>      case UPD_CXX_INSTANTIATED_DEFAULT_<wbr>ARGUMENT: {<br>
>>>        auto Param = cast<ParmVarDecl>(D);<br>
>>><br>
>>> Modified: cfe/trunk/lib/Serialization/<wbr>ASTWriter.cpp<br>
>>> URL:<br>
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=319727&r1=319726&r2=319727&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/<wbr>Serialization/ASTWriter.cpp?<wbr>rev=319727&r1=319726&r2=<wbr>319727&view=diff</a><br>
>>><br>
>>> ==============================<wbr>==============================<wbr>==================<br>
>>> --- cfe/trunk/lib/Serialization/<wbr>ASTWriter.cpp (original)<br>
>>> +++ cfe/trunk/lib/Serialization/<wbr>ASTWriter.cpp Mon Dec  4 17:31:47 2017<br>
>>> @@ -5135,9 +5135,13 @@ void ASTWriter::<wbr>WriteDeclUpdatesBlocks(R<br>
>>>        case UPD_CXX_ADDED_FUNCTION_<wbr>DEFINITION:<br>
>>>          break;<br>
>>><br>
>>> -      case UPD_CXX_INSTANTIATED_STATIC_<wbr>DATA_MEMBER: {<br>
>>> -        const VarDecl *VD = cast<VarDecl>(D);<br>
>>> +      case UPD_CXX_POINT_OF_<wbr>INSTANTIATION:<br>
>>> +        // FIXME: Do we need to also save the template specialization<br>
>>> kind here?<br>
>>>          Record.AddSourceLocation(<wbr>Update.getLoc());<br>
>>> +        break;<br>
>>> +<br>
>>> +      case UPD_CXX_ADDED_VAR_DEFINITION: {<br>
>>> +        const VarDecl *VD = cast<VarDecl>(D);<br>
>>>          Record.push_back(VD->isInline(<wbr>));<br>
>>>          Record.push_back(VD-><wbr>isInlineSpecified());<br>
>>>          if (VD->getInit()) {<br>
>>> @@ -6256,6 +6260,15 @@ void ASTWriter::<wbr>CompletedImplicitDefinit<br>
>>><br>
>>> DeclUpdates[D].push_back(<wbr>DeclUpdate(UPD_CXX_ADDED_<wbr>FUNCTION_DEFINITION));<br>
>>>  }<br>
>>><br>
>>> +void ASTWriter::<wbr>VariableDefinitionInstantiated<wbr>(const VarDecl *D) {<br>
>>> +  if (Chain && Chain-><wbr>isProcessingUpdateRecords()) return;<br>
>>> +  assert(!WritingAST && "Already writing the AST!");<br>
>>> +  if (!D->isFromASTFile())<br>
>>> +    return;<br>
>>> +<br>
>>> +  DeclUpdates[D].push_back(<wbr>DeclUpdate(UPD_CXX_ADDED_VAR_<wbr>DEFINITION));<br>
>>> +}<br>
>>> +<br>
>>>  void ASTWriter::<wbr>FunctionDefinitionInstantiated<wbr>(const FunctionDecl *D) {<br>
>>>    if (Chain && Chain-><wbr>isProcessingUpdateRecords()) return;<br>
>>>    assert(!WritingAST && "Already writing the AST!");<br>
>>> @@ -6265,7 +6278,7 @@ void ASTWriter::<wbr>FunctionDefinitionInstan<br>
>>><br>
>>> DeclUpdates[D].push_back(<wbr>DeclUpdate(UPD_CXX_ADDED_<wbr>FUNCTION_DEFINITION));<br>
>>>  }<br>
>>><br>
>>> -void ASTWriter::<wbr>StaticDataMemberInstantiated(<wbr>const VarDecl *D) {<br>
>>> +void ASTWriter::<wbr>InstantiationRequested(const ValueDecl *D) {<br>
>>>    if (Chain && Chain-><wbr>isProcessingUpdateRecords()) return;<br>
>>>    assert(!WritingAST && "Already writing the AST!");<br>
>>>    if (!D->isFromASTFile())<br>
>>> @@ -6273,9 +6286,12 @@ void ASTWriter::<wbr>StaticDataMemberInstanti<br>
>>><br>
>>>    // Since the actual instantiation is delayed, this really means that<br>
>>> we need<br>
>>>    // to update the instantiation location.<br>
>>> -  DeclUpdates[D].push_back(<br>
>>> -      DeclUpdate(UPD_CXX_<wbr>INSTANTIATED_STATIC_DATA_<wbr>MEMBER,<br>
>>> -       D-><wbr>getMemberSpecializationInfo()-<wbr>>getPointOfInstantiation()));<br>
>>> +  SourceLocation POI;<br>
>>> +  if (auto *VD = dyn_cast<VarDecl>(D))<br>
>>> +    POI = VD->getPointOfInstantiation();<br>
>>> +  else<br>
>>> +    POI = cast<FunctionDecl>(D)-><wbr>getPointOfInstantiation();<br>
>>> +  DeclUpdates[D].push_back(<wbr>DeclUpdate(UPD_CXX_POINT_OF_<wbr>INSTANTIATION,<br>
>>> POI));<br>
>>>  }<br>
>>><br>
>>>  void ASTWriter::<wbr>DefaultArgumentInstantiated(<wbr>const ParmVarDecl *D) {<br>
>>><br>
>>> Added: cfe/trunk/test/Modules/var-<wbr>templates.cpp<br>
>>> URL:<br>
>>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/var-templates.cpp?rev=319727&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>Modules/var-templates.cpp?rev=<wbr>319727&view=auto</a><br>
>>><br>
>>> ==============================<wbr>==============================<wbr>==================<br>
>>> --- cfe/trunk/test/Modules/var-<wbr>templates.cpp (added)<br>
>>> +++ cfe/trunk/test/Modules/var-<wbr>templates.cpp Mon Dec  4 17:31:47 2017<br>
>>> @@ -0,0 +1,24 @@<br>
>>> +// RUN: %clang_cc1 -fmodules -std=c++14 -emit-llvm %s -o - | FileCheck<br>
>>> %s<br>
>>> +<br>
>>> +#pragma clang module build A<br>
>>> +module A {}<br>
>>> +#pragma clang module contents<br>
>>> +#pragma clang module begin A<br>
>>> +template<int> int n = 42;<br>
>>> +decltype(n<0>) f();<br>
>>> +#pragma clang module end<br>
>>> +#pragma clang module endbuild<br>
>>> +<br>
>>> +#pragma clang module build B<br>
>>> +module B {}<br>
>>> +#pragma clang module contents<br>
>>> +#pragma clang module begin B<br>
>>> +#pragma clang module import A<br>
>>> +inline int f() { return n<0>; }<br>
>>> +#pragma clang module end<br>
>>> +#pragma clang module endbuild<br>
>>> +<br>
>>> +#pragma clang module import B<br>
>>> +<br>
>>> +// CHECK: @_Z1nILi0EE = linkonce_odr global i32 42, comdat<br>
>>> +int g() { return f(); }<br>
>>><br>
>>><br>
>>> ______________________________<wbr>_________________<br>
>>> cfe-commits mailing list<br>
>>> <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
>>> <a 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>
>><br>
>><br>
>><br>
>> ______________________________<wbr>_________________<br>
>> cfe-commits mailing list<br>
>> <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
>> <a 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>
>><br>
><br>
><br>
> ______________________________<wbr>_________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
> <a 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>
><br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a 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>
</div></div></blockquote></div><br></div>