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

Galina Kistanova via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 5 10:38:47 PST 2017


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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171205/0753cad5/attachment-0001.html>


More information about the cfe-commits mailing list