Sorry about that, fixed in r319817. On 5 December 2017 at 10:38, Galina Kistanova via cfe-commits < cfe-commits@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@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@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits > >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits