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