r319727 - Generalize "static data member instantiated" notification to cover variable templates too.

Ahmed Bougacha via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 5 13:27:05 PST 2017


On Tue, Dec 5, 2017 at 11:40 AM, Richard Smith via cfe-commits
<cfe-commits at lists.llvm.org> wrote:
> Sorry about that, fixed in r319817.

Hey Richard,

Looks like that's not enough on darwin:
  http://green.lab.llvm.org/green/job/clang-stage1-cmake-RA-incremental/44764/consoleFull#-126347322349ba4694-19c4-4d7e-bec5-911270d8a58c

Can you have a look?  Thanks!
-Ahmed

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


More information about the cfe-commits mailing list