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