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

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue Dec 5 13:31:20 PST 2017


Should be fixed in r319835. I'd forgotten that Darwin / MachO uses a
different mechanism from COMDATs here.

On 5 December 2017 at 13:27, Ahmed Bougacha via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> 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
> >
> _______________________________________________
> 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/7b437cfe/attachment-0001.html>


More information about the cfe-commits mailing list