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