Skip to content

Commit 44ab380

Browse files
authored
Revert "Reapply "[Clang][Sema] Refactor collection of multi-level template argument lists (#106585, #111173)" (#111852)" (#115159)
This reverts commit 2bb3d3a.
1 parent fbd89bc commit 44ab380

21 files changed

+696
-1058
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -569,9 +569,6 @@ Bug Fixes to C++ Support
569569
in certain friend declarations. (#GH93099)
570570
- Clang now instantiates the correct lambda call operator when a lambda's class type is
571571
merged across modules. (#GH110401)
572-
- Clang now uses the correct set of template argument lists when comparing the constraints of
573-
out-of-line definitions and member templates explicitly specialized for a given implicit instantiation of
574-
a class template. (#GH102320)
575572
- Fix a crash when parsing a pseudo destructor involving an invalid type. (#GH111460)
576573
- Fixed an assertion failure when invoking recovery call expressions with explicit attributes
577574
and undeclared templates. (#GH107047), (#GH49093)

clang/include/clang/AST/DeclTemplate.h

Lines changed: 36 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -787,11 +787,15 @@ class RedeclarableTemplateDecl : public TemplateDecl,
787787
EntryType *Entry, void *InsertPos);
788788

789789
struct CommonBase {
790-
CommonBase() {}
790+
CommonBase() : InstantiatedFromMember(nullptr, false) {}
791791

792792
/// The template from which this was most
793793
/// directly instantiated (or null).
794-
RedeclarableTemplateDecl *InstantiatedFromMember = nullptr;
794+
///
795+
/// The boolean value indicates whether this template
796+
/// was explicitly specialized.
797+
llvm::PointerIntPair<RedeclarableTemplateDecl *, 1, bool>
798+
InstantiatedFromMember;
795799

796800
/// If non-null, points to an array of specializations (including
797801
/// partial specializations) known only by their external declaration IDs.
@@ -802,19 +806,14 @@ class RedeclarableTemplateDecl : public TemplateDecl,
802806
};
803807

804808
/// Pointer to the common data shared by all declarations of this
805-
/// template, and a flag indicating if the template is a member
806-
/// specialization.
807-
mutable llvm::PointerIntPair<CommonBase *, 1, bool> Common;
808-
809-
CommonBase *getCommonPtrInternal() const { return Common.getPointer(); }
809+
/// template.
810+
mutable CommonBase *Common = nullptr;
810811

811812
/// Retrieves the "common" pointer shared by all (re-)declarations of
812813
/// the same template. Calling this routine may implicitly allocate memory
813814
/// for the common pointer.
814815
CommonBase *getCommonPtr() const;
815816

816-
void setCommonPtr(CommonBase *C) const { Common.setPointer(C); }
817-
818817
virtual CommonBase *newCommon(ASTContext &C) const = 0;
819818

820819
// Construct a template decl with name, parameters, and templated element.
@@ -855,22 +854,15 @@ class RedeclarableTemplateDecl : public TemplateDecl,
855854
/// template<> template<typename T>
856855
/// struct X<int>::Inner { /* ... */ };
857856
/// \endcode
858-
bool isMemberSpecialization() const { return Common.getInt(); }
859-
860-
/// Determines whether any redeclaration of this template was
861-
/// a specialization of a member template.
862-
bool hasMemberSpecialization() const {
863-
for (const auto *D : redecls()) {
864-
if (D->isMemberSpecialization())
865-
return true;
866-
}
867-
return false;
857+
bool isMemberSpecialization() const {
858+
return getCommonPtr()->InstantiatedFromMember.getInt();
868859
}
869860

870861
/// Note that this member template is a specialization.
871862
void setMemberSpecialization() {
872-
assert(!isMemberSpecialization() && "already a member specialization");
873-
Common.setInt(true);
863+
assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
864+
"Only member templates can be member template specializations");
865+
getCommonPtr()->InstantiatedFromMember.setInt(true);
874866
}
875867

876868
/// Retrieve the member template from which this template was
@@ -910,12 +902,12 @@ class RedeclarableTemplateDecl : public TemplateDecl,
910902
/// void X<T>::f(T, U);
911903
/// \endcode
912904
RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() const {
913-
return getCommonPtr()->InstantiatedFromMember;
905+
return getCommonPtr()->InstantiatedFromMember.getPointer();
914906
}
915907

916908
void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) {
917-
assert(!getCommonPtr()->InstantiatedFromMember);
918-
getCommonPtr()->InstantiatedFromMember = TD;
909+
assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
910+
getCommonPtr()->InstantiatedFromMember.setPointer(TD);
919911
}
920912

921913
/// Retrieve the "injected" template arguments that correspond to the
@@ -1997,8 +1989,6 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
19971989
/// template arguments have been deduced.
19981990
void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
19991991
const TemplateArgumentList *TemplateArgs) {
2000-
assert(!isa<ClassTemplatePartialSpecializationDecl>(this) &&
2001-
"A partial specialization cannot be instantiated from a template");
20021992
assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
20031993
"Already set to a class template partial specialization!");
20041994
auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
@@ -2010,8 +2000,6 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
20102000
/// Note that this class template specialization is an instantiation
20112001
/// of the given class template.
20122002
void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
2013-
assert(!isa<ClassTemplatePartialSpecializationDecl>(this) &&
2014-
"A partial specialization cannot be instantiated from a template");
20152003
assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
20162004
"Previously set to a class template partial specialization!");
20172005
SpecializedTemplate = TemplDecl;
@@ -2205,22 +2193,18 @@ class ClassTemplatePartialSpecializationDecl
22052193
/// struct X<int>::Inner<T*> { /* ... */ };
22062194
/// \endcode
22072195
bool isMemberSpecialization() const {
2208-
return InstantiatedFromMember.getInt();
2209-
}
2210-
2211-
/// Determines whether any redeclaration of this this class template partial
2212-
/// specialization was a specialization of a member partial specialization.
2213-
bool hasMemberSpecialization() const {
2214-
for (const auto *D : redecls()) {
2215-
if (cast<ClassTemplatePartialSpecializationDecl>(D)
2216-
->isMemberSpecialization())
2217-
return true;
2218-
}
2219-
return false;
2196+
const auto *First =
2197+
cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2198+
return First->InstantiatedFromMember.getInt();
22202199
}
22212200

22222201
/// Note that this member template is a specialization.
2223-
void setMemberSpecialization() { return InstantiatedFromMember.setInt(true); }
2202+
void setMemberSpecialization() {
2203+
auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2204+
assert(First->InstantiatedFromMember.getPointer() &&
2205+
"Only member templates can be member template specializations");
2206+
return First->InstantiatedFromMember.setInt(true);
2207+
}
22242208

22252209
/// Retrieves the injected specialization type for this partial
22262210
/// specialization. This is not the same as the type-decl-type for
@@ -2290,6 +2274,8 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
22902274
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
22912275
}
22922276

2277+
void setCommonPtr(Common *C) { RedeclarableTemplateDecl::Common = C; }
2278+
22932279
public:
22942280

22952281
friend class ASTDeclReader;
@@ -2772,8 +2758,6 @@ class VarTemplateSpecializationDecl : public VarDecl,
27722758
/// template arguments have been deduced.
27732759
void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec,
27742760
const TemplateArgumentList *TemplateArgs) {
2775-
assert(!isa<VarTemplatePartialSpecializationDecl>(this) &&
2776-
"A partial specialization cannot be instantiated from a template");
27772761
assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
27782762
"Already set to a variable template partial specialization!");
27792763
auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
@@ -2785,8 +2769,6 @@ class VarTemplateSpecializationDecl : public VarDecl,
27852769
/// Note that this variable template specialization is an instantiation
27862770
/// of the given variable template.
27872771
void setInstantiationOf(VarTemplateDecl *TemplDecl) {
2788-
assert(!isa<VarTemplatePartialSpecializationDecl>(this) &&
2789-
"A partial specialization cannot be instantiated from a template");
27902772
assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
27912773
"Previously set to a variable template partial specialization!");
27922774
SpecializedTemplate = TemplDecl;
@@ -2977,23 +2959,18 @@ class VarTemplatePartialSpecializationDecl
29772959
/// U* X<int>::Inner<T*> = (T*)(0) + 1;
29782960
/// \endcode
29792961
bool isMemberSpecialization() const {
2980-
return InstantiatedFromMember.getInt();
2981-
}
2982-
2983-
/// Determines whether any redeclaration of this this variable template
2984-
/// partial specialization was a specialization of a member partial
2985-
/// specialization.
2986-
bool hasMemberSpecialization() const {
2987-
for (const auto *D : redecls()) {
2988-
if (cast<VarTemplatePartialSpecializationDecl>(D)
2989-
->isMemberSpecialization())
2990-
return true;
2991-
}
2992-
return false;
2962+
const auto *First =
2963+
cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2964+
return First->InstantiatedFromMember.getInt();
29932965
}
29942966

29952967
/// Note that this member template is a specialization.
2996-
void setMemberSpecialization() { return InstantiatedFromMember.setInt(true); }
2968+
void setMemberSpecialization() {
2969+
auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2970+
assert(First->InstantiatedFromMember.getPointer() &&
2971+
"Only member templates can be member template specializations");
2972+
return First->InstantiatedFromMember.setInt(true);
2973+
}
29972974

29982975
SourceRange getSourceRange() const override LLVM_READONLY;
29992976

clang/include/clang/Sema/Sema.h

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11328,9 +11328,9 @@ class Sema final : public SemaBase {
1132811328
CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc,
1132911329
const ParsedAttributesView &Attr, TemplateParameterList *TemplateParams,
1133011330
AccessSpecifier AS, SourceLocation ModulePrivateLoc,
11331-
SourceLocation FriendLoc,
11332-
ArrayRef<TemplateParameterList *> OuterTemplateParamLists,
11333-
bool IsMemberSpecialization, SkipBodyInfo *SkipBody = nullptr);
11331+
SourceLocation FriendLoc, unsigned NumOuterTemplateParamLists,
11332+
TemplateParameterList **OuterTemplateParamLists,
11333+
SkipBodyInfo *SkipBody = nullptr);
1133411334

1133511335
/// Translates template arguments as provided by the parser
1133611336
/// into template arguments used by semantic analysis.
@@ -11369,8 +11369,7 @@ class Sema final : public SemaBase {
1136911369
DeclResult ActOnVarTemplateSpecialization(
1137011370
Scope *S, Declarator &D, TypeSourceInfo *DI, LookupResult &Previous,
1137111371
SourceLocation TemplateKWLoc, TemplateParameterList *TemplateParams,
11372-
StorageClass SC, bool IsPartialSpecialization,
11373-
bool IsMemberSpecialization);
11372+
StorageClass SC, bool IsPartialSpecialization);
1137411373

1137511374
/// Get the specialization of the given variable template corresponding to
1137611375
/// the specified argument list, or a null-but-valid result if the arguments
@@ -13012,14 +13011,28 @@ class Sema final : public SemaBase {
1301213011
/// dealing with a specialization. This is only relevant for function
1301313012
/// template specializations.
1301413013
///
13014+
/// \param Pattern If non-NULL, indicates the pattern from which we will be
13015+
/// instantiating the definition of the given declaration, \p ND. This is
13016+
/// used to determine the proper set of template instantiation arguments for
13017+
/// friend function template specializations.
13018+
///
1301513019
/// \param ForConstraintInstantiation when collecting arguments,
1301613020
/// ForConstraintInstantiation indicates we should continue looking when
1301713021
/// encountering a lambda generic call operator, and continue looking for
1301813022
/// arguments on an enclosing class template.
13023+
///
13024+
/// \param SkipForSpecialization when specified, any template specializations
13025+
/// in a traversal would be ignored.
13026+
/// \param ForDefaultArgumentSubstitution indicates we should continue looking
13027+
/// when encountering a specialized member function template, rather than
13028+
/// returning immediately.
1301913029
MultiLevelTemplateArgumentList getTemplateInstantiationArgs(
1302013030
const NamedDecl *D, const DeclContext *DC = nullptr, bool Final = false,
1302113031
std::optional<ArrayRef<TemplateArgument>> Innermost = std::nullopt,
13022-
bool RelativeToPrimary = false, bool ForConstraintInstantiation = false);
13032+
bool RelativeToPrimary = false, const FunctionDecl *Pattern = nullptr,
13033+
bool ForConstraintInstantiation = false,
13034+
bool SkipForSpecialization = false,
13035+
bool ForDefaultArgumentSubstitution = false);
1302313036

1302413037
/// RAII object to handle the state changes required to synthesize
1302513038
/// a function body.

clang/lib/AST/Decl.cpp

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2708,21 +2708,21 @@ VarDecl *VarDecl::getTemplateInstantiationPattern() const {
27082708
if (isTemplateInstantiation(VDTemplSpec->getTemplateSpecializationKind())) {
27092709
auto From = VDTemplSpec->getInstantiatedFrom();
27102710
if (auto *VTD = From.dyn_cast<VarTemplateDecl *>()) {
2711-
while (!VTD->hasMemberSpecialization()) {
2712-
if (auto *NewVTD = VTD->getInstantiatedFromMemberTemplate())
2713-
VTD = NewVTD;
2714-
else
2711+
while (!VTD->isMemberSpecialization()) {
2712+
auto *NewVTD = VTD->getInstantiatedFromMemberTemplate();
2713+
if (!NewVTD)
27152714
break;
2715+
VTD = NewVTD;
27162716
}
27172717
return getDefinitionOrSelf(VTD->getTemplatedDecl());
27182718
}
27192719
if (auto *VTPSD =
27202720
From.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
2721-
while (!VTPSD->hasMemberSpecialization()) {
2722-
if (auto *NewVTPSD = VTPSD->getInstantiatedFromMember())
2723-
VTPSD = NewVTPSD;
2724-
else
2721+
while (!VTPSD->isMemberSpecialization()) {
2722+
auto *NewVTPSD = VTPSD->getInstantiatedFromMember();
2723+
if (!NewVTPSD)
27252724
break;
2725+
VTPSD = NewVTPSD;
27262726
}
27272727
return getDefinitionOrSelf<VarDecl>(VTPSD);
27282728
}
@@ -2731,14 +2731,15 @@ VarDecl *VarDecl::getTemplateInstantiationPattern() const {
27312731

27322732
// If this is the pattern of a variable template, find where it was
27332733
// instantiated from. FIXME: Is this necessary?
2734-
if (VarTemplateDecl *VTD = VD->getDescribedVarTemplate()) {
2735-
while (!VTD->hasMemberSpecialization()) {
2736-
if (auto *NewVTD = VTD->getInstantiatedFromMemberTemplate())
2737-
VTD = NewVTD;
2738-
else
2734+
if (VarTemplateDecl *VarTemplate = VD->getDescribedVarTemplate()) {
2735+
while (!VarTemplate->isMemberSpecialization()) {
2736+
auto *NewVT = VarTemplate->getInstantiatedFromMemberTemplate();
2737+
if (!NewVT)
27392738
break;
2739+
VarTemplate = NewVT;
27402740
}
2741-
return getDefinitionOrSelf(VTD->getTemplatedDecl());
2741+
2742+
return getDefinitionOrSelf(VarTemplate->getTemplatedDecl());
27422743
}
27432744

27442745
if (VD == this)
@@ -4153,11 +4154,11 @@ FunctionDecl::getTemplateInstantiationPattern(bool ForDefinition) const {
41534154
if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) {
41544155
// If we hit a point where the user provided a specialization of this
41554156
// template, we're done looking.
4156-
while (!ForDefinition || !Primary->hasMemberSpecialization()) {
4157-
if (auto *NewPrimary = Primary->getInstantiatedFromMemberTemplate())
4158-
Primary = NewPrimary;
4159-
else
4157+
while (!ForDefinition || !Primary->isMemberSpecialization()) {
4158+
auto *NewPrimary = Primary->getInstantiatedFromMemberTemplate();
4159+
if (!NewPrimary)
41604160
break;
4161+
Primary = NewPrimary;
41614162
}
41624163

41634164
return getDefinitionOrSelf(Primary->getTemplatedDecl());

clang/lib/AST/DeclCXX.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2030,21 +2030,19 @@ const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const {
20302030
if (auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(this)) {
20312031
auto From = TD->getInstantiatedFrom();
20322032
if (auto *CTD = From.dyn_cast<ClassTemplateDecl *>()) {
2033-
while (!CTD->hasMemberSpecialization()) {
2034-
if (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate())
2035-
CTD = NewCTD;
2036-
else
2033+
while (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) {
2034+
if (NewCTD->isMemberSpecialization())
20372035
break;
2036+
CTD = NewCTD;
20382037
}
20392038
return GetDefinitionOrSelf(CTD->getTemplatedDecl());
20402039
}
20412040
if (auto *CTPSD =
20422041
From.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) {
2043-
while (!CTPSD->hasMemberSpecialization()) {
2044-
if (auto *NewCTPSD = CTPSD->getInstantiatedFromMemberTemplate())
2045-
CTPSD = NewCTPSD;
2046-
else
2042+
while (auto *NewCTPSD = CTPSD->getInstantiatedFromMember()) {
2043+
if (NewCTPSD->isMemberSpecialization())
20472044
break;
2045+
CTPSD = NewCTPSD;
20482046
}
20492047
return GetDefinitionOrSelf(CTPSD);
20502048
}

0 commit comments

Comments
 (0)