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