Should be fixed in r319835. I'd forgotten that Darwin / MachO uses a different mechanism from COMDATs here.
On 5 December 2017 at 13:27, Ahmed Bougacha via cfe-commits < cfe-commits@lists.llvm.org> wrote: > On Tue, Dec 5, 2017 at 11:40 AM, Richard Smith via cfe-commits > <cfe-commits@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@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().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@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 > > > _______________________________________________ > 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