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