llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-modules Author: Krystian Stasiowski (sdkrystian) <details> <summary>Changes</summary> This reverts commit 2bb3d3a3f32ffaef3d9b6a27db7f1941f0cb1136. --- Patch is 105.20 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/115159.diff 21 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (-3) - (modified) clang/include/clang/AST/DeclTemplate.h (+36-59) - (modified) clang/include/clang/Sema/Sema.h (+19-6) - (modified) clang/lib/AST/Decl.cpp (+19-18) - (modified) clang/lib/AST/DeclCXX.cpp (+6-8) - (modified) clang/lib/AST/DeclTemplate.cpp (+16-14) - (modified) clang/lib/Sema/SemaConcept.cpp (+16-11) - (modified) clang/lib/Sema/SemaDecl.cpp (+17-14) - (modified) clang/lib/Sema/SemaDeclCXX.cpp (+2-2) - (modified) clang/lib/Sema/SemaInit.cpp (+1-1) - (modified) clang/lib/Sema/SemaTemplate.cpp (+89-83) - (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+30-3) - (modified) clang/lib/Sema/SemaTemplateDeductionGuide.cpp (+29-16) - (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+385-362) - (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+9-37) - (modified) clang/lib/Serialization/ASTReader.cpp (+1-2) - (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+8-8) - (modified) clang/lib/Serialization/ASTWriterDecl.cpp (+10-7) - (removed) clang/test/CXX/temp/temp.constr/temp.constr.decl/p4.cpp (-175) - (removed) clang/test/CXX/temp/temp.spec/temp.expl.spec/p7.cpp (-228) - (modified) clang/test/Modules/cxx-templates.cpp (+3-1) ``````````diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 88621809bad7e2..d60d88920c6d0f 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -569,9 +569,6 @@ Bug Fixes to C++ Support in certain friend declarations. (#GH93099) - Clang now instantiates the correct lambda call operator when a lambda's class type is merged across modules. (#GH110401) -- Clang now uses the correct set of template argument lists when comparing the constraints of - out-of-line definitions and member templates explicitly specialized for a given implicit instantiation of - a class template. (#GH102320) - Fix a crash when parsing a pseudo destructor involving an invalid type. (#GH111460) - Fixed an assertion failure when invoking recovery call expressions with explicit attributes and undeclared templates. (#GH107047), (#GH49093) diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index a572e3380f1655..e4bf54c3d77b7f 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -787,11 +787,15 @@ class RedeclarableTemplateDecl : public TemplateDecl, EntryType *Entry, void *InsertPos); struct CommonBase { - CommonBase() {} + CommonBase() : InstantiatedFromMember(nullptr, false) {} /// The template from which this was most /// directly instantiated (or null). - RedeclarableTemplateDecl *InstantiatedFromMember = nullptr; + /// + /// The boolean value indicates whether this template + /// was explicitly specialized. + llvm::PointerIntPair<RedeclarableTemplateDecl *, 1, bool> + InstantiatedFromMember; /// If non-null, points to an array of specializations (including /// partial specializations) known only by their external declaration IDs. @@ -802,19 +806,14 @@ class RedeclarableTemplateDecl : public TemplateDecl, }; /// Pointer to the common data shared by all declarations of this - /// template, and a flag indicating if the template is a member - /// specialization. - mutable llvm::PointerIntPair<CommonBase *, 1, bool> Common; - - CommonBase *getCommonPtrInternal() const { return Common.getPointer(); } + /// template. + mutable CommonBase *Common = nullptr; /// Retrieves the "common" pointer shared by all (re-)declarations of /// the same template. Calling this routine may implicitly allocate memory /// for the common pointer. CommonBase *getCommonPtr() const; - void setCommonPtr(CommonBase *C) const { Common.setPointer(C); } - virtual CommonBase *newCommon(ASTContext &C) const = 0; // Construct a template decl with name, parameters, and templated element. @@ -855,22 +854,15 @@ class RedeclarableTemplateDecl : public TemplateDecl, /// template<> template<typename T> /// struct X<int>::Inner { /* ... */ }; /// \endcode - bool isMemberSpecialization() const { return Common.getInt(); } - - /// Determines whether any redeclaration of this template was - /// a specialization of a member template. - bool hasMemberSpecialization() const { - for (const auto *D : redecls()) { - if (D->isMemberSpecialization()) - return true; - } - return false; + bool isMemberSpecialization() const { + return getCommonPtr()->InstantiatedFromMember.getInt(); } /// Note that this member template is a specialization. void setMemberSpecialization() { - assert(!isMemberSpecialization() && "already a member specialization"); - Common.setInt(true); + assert(getCommonPtr()->InstantiatedFromMember.getPointer() && + "Only member templates can be member template specializations"); + getCommonPtr()->InstantiatedFromMember.setInt(true); } /// Retrieve the member template from which this template was @@ -910,12 +902,12 @@ class RedeclarableTemplateDecl : public TemplateDecl, /// void X<T>::f(T, U); /// \endcode RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() const { - return getCommonPtr()->InstantiatedFromMember; + return getCommonPtr()->InstantiatedFromMember.getPointer(); } void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) { - assert(!getCommonPtr()->InstantiatedFromMember); - getCommonPtr()->InstantiatedFromMember = TD; + assert(!getCommonPtr()->InstantiatedFromMember.getPointer()); + getCommonPtr()->InstantiatedFromMember.setPointer(TD); } /// Retrieve the "injected" template arguments that correspond to the @@ -1997,8 +1989,6 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl, /// template arguments have been deduced. void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec, const TemplateArgumentList *TemplateArgs) { - assert(!isa<ClassTemplatePartialSpecializationDecl>(this) && - "A partial specialization cannot be instantiated from a template"); assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() && "Already set to a class template partial specialization!"); auto *PS = new (getASTContext()) SpecializedPartialSpecialization(); @@ -2010,8 +2000,6 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl, /// Note that this class template specialization is an instantiation /// of the given class template. void setInstantiationOf(ClassTemplateDecl *TemplDecl) { - assert(!isa<ClassTemplatePartialSpecializationDecl>(this) && - "A partial specialization cannot be instantiated from a template"); assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() && "Previously set to a class template partial specialization!"); SpecializedTemplate = TemplDecl; @@ -2205,22 +2193,18 @@ class ClassTemplatePartialSpecializationDecl /// struct X<int>::Inner<T*> { /* ... */ }; /// \endcode bool isMemberSpecialization() const { - return InstantiatedFromMember.getInt(); - } - - /// Determines whether any redeclaration of this this class template partial - /// specialization was a specialization of a member partial specialization. - bool hasMemberSpecialization() const { - for (const auto *D : redecls()) { - if (cast<ClassTemplatePartialSpecializationDecl>(D) - ->isMemberSpecialization()) - return true; - } - return false; + const auto *First = + cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl()); + return First->InstantiatedFromMember.getInt(); } /// Note that this member template is a specialization. - void setMemberSpecialization() { return InstantiatedFromMember.setInt(true); } + void setMemberSpecialization() { + auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl()); + assert(First->InstantiatedFromMember.getPointer() && + "Only member templates can be member template specializations"); + return First->InstantiatedFromMember.setInt(true); + } /// Retrieves the injected specialization type for this partial /// specialization. This is not the same as the type-decl-type for @@ -2290,6 +2274,8 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl { return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr()); } + void setCommonPtr(Common *C) { RedeclarableTemplateDecl::Common = C; } + public: friend class ASTDeclReader; @@ -2772,8 +2758,6 @@ class VarTemplateSpecializationDecl : public VarDecl, /// template arguments have been deduced. void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec, const TemplateArgumentList *TemplateArgs) { - assert(!isa<VarTemplatePartialSpecializationDecl>(this) && - "A partial specialization cannot be instantiated from a template"); assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() && "Already set to a variable template partial specialization!"); auto *PS = new (getASTContext()) SpecializedPartialSpecialization(); @@ -2785,8 +2769,6 @@ class VarTemplateSpecializationDecl : public VarDecl, /// Note that this variable template specialization is an instantiation /// of the given variable template. void setInstantiationOf(VarTemplateDecl *TemplDecl) { - assert(!isa<VarTemplatePartialSpecializationDecl>(this) && - "A partial specialization cannot be instantiated from a template"); assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() && "Previously set to a variable template partial specialization!"); SpecializedTemplate = TemplDecl; @@ -2977,23 +2959,18 @@ class VarTemplatePartialSpecializationDecl /// U* X<int>::Inner<T*> = (T*)(0) + 1; /// \endcode bool isMemberSpecialization() const { - return InstantiatedFromMember.getInt(); - } - - /// Determines whether any redeclaration of this this variable template - /// partial specialization was a specialization of a member partial - /// specialization. - bool hasMemberSpecialization() const { - for (const auto *D : redecls()) { - if (cast<VarTemplatePartialSpecializationDecl>(D) - ->isMemberSpecialization()) - return true; - } - return false; + const auto *First = + cast<VarTemplatePartialSpecializationDecl>(getFirstDecl()); + return First->InstantiatedFromMember.getInt(); } /// Note that this member template is a specialization. - void setMemberSpecialization() { return InstantiatedFromMember.setInt(true); } + void setMemberSpecialization() { + auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl()); + assert(First->InstantiatedFromMember.getPointer() && + "Only member templates can be member template specializations"); + return First->InstantiatedFromMember.setInt(true); + } SourceRange getSourceRange() const override LLVM_READONLY; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 93d98e1cbb9c81..aa2f5ff3ef7207 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -11328,9 +11328,9 @@ class Sema final : public SemaBase { CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, const ParsedAttributesView &Attr, TemplateParameterList *TemplateParams, AccessSpecifier AS, SourceLocation ModulePrivateLoc, - SourceLocation FriendLoc, - ArrayRef<TemplateParameterList *> OuterTemplateParamLists, - bool IsMemberSpecialization, SkipBodyInfo *SkipBody = nullptr); + SourceLocation FriendLoc, unsigned NumOuterTemplateParamLists, + TemplateParameterList **OuterTemplateParamLists, + SkipBodyInfo *SkipBody = nullptr); /// Translates template arguments as provided by the parser /// into template arguments used by semantic analysis. @@ -11369,8 +11369,7 @@ class Sema final : public SemaBase { DeclResult ActOnVarTemplateSpecialization( Scope *S, Declarator &D, TypeSourceInfo *DI, LookupResult &Previous, SourceLocation TemplateKWLoc, TemplateParameterList *TemplateParams, - StorageClass SC, bool IsPartialSpecialization, - bool IsMemberSpecialization); + StorageClass SC, bool IsPartialSpecialization); /// Get the specialization of the given variable template corresponding to /// the specified argument list, or a null-but-valid result if the arguments @@ -13012,14 +13011,28 @@ class Sema final : public SemaBase { /// dealing with a specialization. This is only relevant for function /// template specializations. /// + /// \param Pattern If non-NULL, indicates the pattern from which we will be + /// instantiating the definition of the given declaration, \p ND. This is + /// used to determine the proper set of template instantiation arguments for + /// friend function template specializations. + /// /// \param ForConstraintInstantiation when collecting arguments, /// ForConstraintInstantiation indicates we should continue looking when /// encountering a lambda generic call operator, and continue looking for /// arguments on an enclosing class template. + /// + /// \param SkipForSpecialization when specified, any template specializations + /// in a traversal would be ignored. + /// \param ForDefaultArgumentSubstitution indicates we should continue looking + /// when encountering a specialized member function template, rather than + /// returning immediately. MultiLevelTemplateArgumentList getTemplateInstantiationArgs( const NamedDecl *D, const DeclContext *DC = nullptr, bool Final = false, std::optional<ArrayRef<TemplateArgument>> Innermost = std::nullopt, - bool RelativeToPrimary = false, bool ForConstraintInstantiation = false); + bool RelativeToPrimary = false, const FunctionDecl *Pattern = nullptr, + bool ForConstraintInstantiation = false, + bool SkipForSpecialization = false, + bool ForDefaultArgumentSubstitution = false); /// RAII object to handle the state changes required to synthesize /// a function body. diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 86913763ef9ff5..8204e3509dd563 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2708,21 +2708,21 @@ VarDecl *VarDecl::getTemplateInstantiationPattern() const { if (isTemplateInstantiation(VDTemplSpec->getTemplateSpecializationKind())) { auto From = VDTemplSpec->getInstantiatedFrom(); if (auto *VTD = From.dyn_cast<VarTemplateDecl *>()) { - while (!VTD->hasMemberSpecialization()) { - if (auto *NewVTD = VTD->getInstantiatedFromMemberTemplate()) - VTD = NewVTD; - else + while (!VTD->isMemberSpecialization()) { + auto *NewVTD = VTD->getInstantiatedFromMemberTemplate(); + if (!NewVTD) break; + VTD = NewVTD; } return getDefinitionOrSelf(VTD->getTemplatedDecl()); } if (auto *VTPSD = From.dyn_cast<VarTemplatePartialSpecializationDecl *>()) { - while (!VTPSD->hasMemberSpecialization()) { - if (auto *NewVTPSD = VTPSD->getInstantiatedFromMember()) - VTPSD = NewVTPSD; - else + while (!VTPSD->isMemberSpecialization()) { + auto *NewVTPSD = VTPSD->getInstantiatedFromMember(); + if (!NewVTPSD) break; + VTPSD = NewVTPSD; } return getDefinitionOrSelf<VarDecl>(VTPSD); } @@ -2731,14 +2731,15 @@ VarDecl *VarDecl::getTemplateInstantiationPattern() const { // If this is the pattern of a variable template, find where it was // instantiated from. FIXME: Is this necessary? - if (VarTemplateDecl *VTD = VD->getDescribedVarTemplate()) { - while (!VTD->hasMemberSpecialization()) { - if (auto *NewVTD = VTD->getInstantiatedFromMemberTemplate()) - VTD = NewVTD; - else + if (VarTemplateDecl *VarTemplate = VD->getDescribedVarTemplate()) { + while (!VarTemplate->isMemberSpecialization()) { + auto *NewVT = VarTemplate->getInstantiatedFromMemberTemplate(); + if (!NewVT) break; + VarTemplate = NewVT; } - return getDefinitionOrSelf(VTD->getTemplatedDecl()); + + return getDefinitionOrSelf(VarTemplate->getTemplatedDecl()); } if (VD == this) @@ -4153,11 +4154,11 @@ FunctionDecl::getTemplateInstantiationPattern(bool ForDefinition) const { if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) { // If we hit a point where the user provided a specialization of this // template, we're done looking. - while (!ForDefinition || !Primary->hasMemberSpecialization()) { - if (auto *NewPrimary = Primary->getInstantiatedFromMemberTemplate()) - Primary = NewPrimary; - else + while (!ForDefinition || !Primary->isMemberSpecialization()) { + auto *NewPrimary = Primary->getInstantiatedFromMemberTemplate(); + if (!NewPrimary) break; + Primary = NewPrimary; } return getDefinitionOrSelf(Primary->getTemplatedDecl()); diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index db0ea62a2323eb..4394a0724b3c17 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -2030,21 +2030,19 @@ const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const { if (auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(this)) { auto From = TD->getInstantiatedFrom(); if (auto *CTD = From.dyn_cast<ClassTemplateDecl *>()) { - while (!CTD->hasMemberSpecialization()) { - if (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) - CTD = NewCTD; - else + while (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) { + if (NewCTD->isMemberSpecialization()) break; + CTD = NewCTD; } return GetDefinitionOrSelf(CTD->getTemplatedDecl()); } if (auto *CTPSD = From.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) { - while (!CTPSD->hasMemberSpecialization()) { - if (auto *NewCTPSD = CTPSD->getInstantiatedFromMemberTemplate()) - CTPSD = NewCTPSD; - else + while (auto *NewCTPSD = CTPSD->getInstantiatedFromMember()) { + if (NewCTPSD->isMemberSpecialization()) break; + CTPSD = NewCTPSD; } return GetDefinitionOrSelf(CTPSD); } diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 755ec72f00bf77..a221d619672b38 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -320,16 +320,16 @@ bool TemplateDecl::isTypeAlias() const { void RedeclarableTemplateDecl::anchor() {} RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const { - if (CommonBase *C = getCommonPtrInternal()) - return C; + if (Common) + return Common; // Walk the previous-declaration chain until we either find a declaration // with a common pointer or we run out of previous declarations. SmallVector<const RedeclarableTemplateDecl *, 2> PrevDecls; for (const RedeclarableTemplateDecl *Prev = getPreviousDecl(); Prev; Prev = Prev->getPreviousDecl()) { - if (CommonBase *C = Prev->getCommonPtrInternal()) { - setCommonPtr(C); + if (Prev->Common) { + Common = Prev->Common; break; } @@ -337,18 +337,18 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() c } // If we never found a common pointer, allocate one now. - if (!getCommonPtrInternal()) { + if (!Common) { // FIXME: If any of the declarations is from an AST file, we probably // need an update record to add the common data. - setCommonPtr(newCommon(getASTContext())); + Common = newCommon(getASTContext()); } // Update any previous declarations we saw with the common pointer. for (const RedeclarableTemplateDecl *Prev : PrevDecls) - Prev->setCommonPtr(getCommonPtrInternal()); + Prev->Common = Common; - return getCommonPtrInternal(); + return Common; } void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const { @@ -458,17 +458,19 @@ void FunctionTemplateDecl::addSpecialization( } void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) { + using Base = RedeclarableTemplateDecl; + // If we haven't created a common pointer yet, then it can just be created // with the usual method. - if (!getCommonPtrInternal()) + if (!Base::Common) return; - Common *ThisCommon = static_cast<Common *>(getCommonPtrInternal()); + Common *ThisCommon = static_cast<Common *>(Base::Common); Common *PrevCommon = nullptr; SmallVector<FunctionTemplateDecl *, 8> PreviousDecls; for (; Prev; Prev = Prev->getPreviousDecl()) { - if (CommonBase *C = Prev->getCommonPtrInternal()) { - PrevCommon = static_cast<Common *>(C); + if (Prev->Base::Common) { + PrevCommon = static_cast<Common *>(Prev->Base::Common); break; } PreviousDecls.push_back(Prev); @@ -478,7 +480,7 @@ void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) { // use this common pointer. if (!PrevCommon) { for (auto *D : PreviousDecls) - D->setCommonPtr(ThisCommon); + D->Base::Common = ThisCommon; return; } @@ -486,7 +488,7 @@ void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) { assert(ThisCommon->Specializations.size(... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/115159 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits