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 11:40:16 PST 2017


Sorry about that, fixed in r319817.

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().getASTMutation
>> Listener())
>> +        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().getASTMutation
>> Listener())
>> +        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().getASTMutation
>> Listener())
>> +        L->InstantiationRequested(this);
>> +    }
>>    } else if (MemberSpecializationInfo *MSInfo
>>               = TemplateOrSpecialization.dyn_c
>> ast<MemberSpecializationInfo*>()) {
>>      MSInfo->setTemplateSpecializationKind(TSK);
>>      if (TSK != TSK_ExplicitSpecialization &&
>>          PointOfInstantiation.isValid() &&
>> -        MSInfo->getPointOfInstantiation().isInvalid())
>> +        MSInfo->getPointOfInstantiation().isInvalid()) {
>>        MSInfo->setPointOfInstantiation(PointOfInstantiation);
>> +      if (ASTMutationListener *L = getASTContext().getASTMutation
>> Listener())
>> +        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/SemaE
>> xpr.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->getTemplateSpecializatio
>> nKind();
>> +    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::a
>> nyDependentTemplateArguments(
>> @@ -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/SemaT
>> emplate.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/SemaT
>> emplateInstantiate.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/SemaT
>> emplateInstantiateDecl.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/SemaT
>> ype.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/Serializat
>> ion/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/Serializat
>> ion/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/Serializat
>> ion/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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171205/660a5590/attachment-0001.html>


More information about the cfe-commits mailing list