Skip to content

Commit 88925f8

Browse files
committed
Revert "Reapply "[Clang][Sema] Refactor collection of multi-level template argument lists (llvm#106585)" (llvm#111173)"
This reverts commit 4da8ac3.
1 parent 91dd4ec commit 88925f8

20 files changed

+702
-1005
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -477,9 +477,6 @@ Bug Fixes to C++ Support
477477
in certain friend declarations. (#GH93099)
478478
- Clang now instantiates the correct lambda call operator when a lambda's class type is
479479
merged across modules. (#GH110401)
480-
- Clang now uses the correct set of template argument lists when comparing the constraints of
481-
out-of-line definitions and member templates explicitly specialized for a given implicit instantiation of
482-
a class template. (#GH102320)
483480
- Fix a crash when parsing a pseudo destructor involving an invalid type. (#GH111460)
484481

485482
Bug Fixes to AST Handling

clang/include/clang/AST/DeclTemplate.h

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -781,11 +781,15 @@ class RedeclarableTemplateDecl : public TemplateDecl,
781781
EntryType *Entry, void *InsertPos);
782782

783783
struct CommonBase {
784-
CommonBase() {}
784+
CommonBase() : InstantiatedFromMember(nullptr, false) {}
785785

786786
/// The template from which this was most
787787
/// directly instantiated (or null).
788-
RedeclarableTemplateDecl *InstantiatedFromMember = nullptr;
788+
///
789+
/// The boolean value indicates whether this template
790+
/// was explicitly specialized.
791+
llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
792+
InstantiatedFromMember;
789793

790794
/// If non-null, points to an array of specializations (including
791795
/// partial specializations) known only by their external declaration IDs.
@@ -805,19 +809,14 @@ class RedeclarableTemplateDecl : public TemplateDecl,
805809
};
806810

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

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

819-
void setCommonPtr(CommonBase *C) const { Common.setPointer(C); }
820-
821820
virtual CommonBase *newCommon(ASTContext &C) const = 0;
822821

823822
// Construct a template decl with name, parameters, and templated element.
@@ -858,12 +857,15 @@ class RedeclarableTemplateDecl : public TemplateDecl,
858857
/// template<> template<typename T>
859858
/// struct X<int>::Inner { /* ... */ };
860859
/// \endcode
861-
bool isMemberSpecialization() const { return Common.getInt(); }
860+
bool isMemberSpecialization() const {
861+
return getCommonPtr()->InstantiatedFromMember.getInt();
862+
}
862863

863864
/// Note that this member template is a specialization.
864865
void setMemberSpecialization() {
865-
assert(!isMemberSpecialization() && "already a member specialization");
866-
Common.setInt(true);
866+
assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
867+
"Only member templates can be member template specializations");
868+
getCommonPtr()->InstantiatedFromMember.setInt(true);
867869
}
868870

869871
/// Retrieve the member template from which this template was
@@ -903,12 +905,12 @@ class RedeclarableTemplateDecl : public TemplateDecl,
903905
/// void X<T>::f(T, U);
904906
/// \endcode
905907
RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() const {
906-
return getCommonPtr()->InstantiatedFromMember;
908+
return getCommonPtr()->InstantiatedFromMember.getPointer();
907909
}
908910

909911
void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) {
910-
assert(!getCommonPtr()->InstantiatedFromMember);
911-
getCommonPtr()->InstantiatedFromMember = TD;
912+
assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
913+
getCommonPtr()->InstantiatedFromMember.setPointer(TD);
912914
}
913915

914916
/// Retrieve the "injected" template arguments that correspond to the
@@ -1987,8 +1989,6 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
19871989
/// template arguments have been deduced.
19881990
void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
19891991
const TemplateArgumentList *TemplateArgs) {
1990-
assert(!isa<ClassTemplatePartialSpecializationDecl>(this) &&
1991-
"A partial specialization cannot be instantiated from a template");
19921992
assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
19931993
"Already set to a class template partial specialization!");
19941994
auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
@@ -2000,8 +2000,6 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
20002000
/// Note that this class template specialization is an instantiation
20012001
/// of the given class template.
20022002
void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
2003-
assert(!isa<ClassTemplatePartialSpecializationDecl>(this) &&
2004-
"A partial specialization cannot be instantiated from a template");
20052003
assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
20062004
"Previously set to a class template partial specialization!");
20072005
SpecializedTemplate = TemplDecl;
@@ -2189,11 +2187,18 @@ class ClassTemplatePartialSpecializationDecl
21892187
/// struct X<int>::Inner<T*> { /* ... */ };
21902188
/// \endcode
21912189
bool isMemberSpecialization() const {
2192-
return InstantiatedFromMember.getInt();
2190+
const auto *First =
2191+
cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2192+
return First->InstantiatedFromMember.getInt();
21932193
}
21942194

21952195
/// Note that this member template is a specialization.
2196-
void setMemberSpecialization() { return InstantiatedFromMember.setInt(true); }
2196+
void setMemberSpecialization() {
2197+
auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
2198+
assert(First->InstantiatedFromMember.getPointer() &&
2199+
"Only member templates can be member template specializations");
2200+
return First->InstantiatedFromMember.setInt(true);
2201+
}
21972202

21982203
/// Retrieves the injected specialization type for this partial
21992204
/// specialization. This is not the same as the type-decl-type for
@@ -2263,6 +2268,10 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
22632268
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
22642269
}
22652270

2271+
void setCommonPtr(Common *C) {
2272+
RedeclarableTemplateDecl::Common = C;
2273+
}
2274+
22662275
public:
22672276

22682277
friend class ASTDeclReader;
@@ -2745,8 +2754,6 @@ class VarTemplateSpecializationDecl : public VarDecl,
27452754
/// template arguments have been deduced.
27462755
void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec,
27472756
const TemplateArgumentList *TemplateArgs) {
2748-
assert(!isa<VarTemplatePartialSpecializationDecl>(this) &&
2749-
"A partial specialization cannot be instantiated from a template");
27502757
assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
27512758
"Already set to a variable template partial specialization!");
27522759
auto *PS = new (getASTContext()) SpecializedPartialSpecialization();
@@ -2758,8 +2765,6 @@ class VarTemplateSpecializationDecl : public VarDecl,
27582765
/// Note that this variable template specialization is an instantiation
27592766
/// of the given variable template.
27602767
void setInstantiationOf(VarTemplateDecl *TemplDecl) {
2761-
assert(!isa<VarTemplatePartialSpecializationDecl>(this) &&
2762-
"A partial specialization cannot be instantiated from a template");
27632768
assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
27642769
"Previously set to a variable template partial specialization!");
27652770
SpecializedTemplate = TemplDecl;
@@ -2944,11 +2949,18 @@ class VarTemplatePartialSpecializationDecl
29442949
/// U* X<int>::Inner<T*> = (T*)(0) + 1;
29452950
/// \endcode
29462951
bool isMemberSpecialization() const {
2947-
return InstantiatedFromMember.getInt();
2952+
const auto *First =
2953+
cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2954+
return First->InstantiatedFromMember.getInt();
29482955
}
29492956

29502957
/// Note that this member template is a specialization.
2951-
void setMemberSpecialization() { return InstantiatedFromMember.setInt(true); }
2958+
void setMemberSpecialization() {
2959+
auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
2960+
assert(First->InstantiatedFromMember.getPointer() &&
2961+
"Only member templates can be member template specializations");
2962+
return First->InstantiatedFromMember.setInt(true);
2963+
}
29522964

29532965
SourceRange getSourceRange() const override LLVM_READONLY;
29542966

clang/include/clang/Sema/Sema.h

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11325,9 +11325,9 @@ class Sema final : public SemaBase {
1132511325
CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc,
1132611326
const ParsedAttributesView &Attr, TemplateParameterList *TemplateParams,
1132711327
AccessSpecifier AS, SourceLocation ModulePrivateLoc,
11328-
SourceLocation FriendLoc,
11329-
ArrayRef<TemplateParameterList *> OuterTemplateParamLists,
11330-
bool IsMemberSpecialization, SkipBodyInfo *SkipBody = nullptr);
11328+
SourceLocation FriendLoc, unsigned NumOuterTemplateParamLists,
11329+
TemplateParameterList **OuterTemplateParamLists,
11330+
SkipBodyInfo *SkipBody = nullptr);
1133111331

1133211332
/// Translates template arguments as provided by the parser
1133311333
/// into template arguments used by semantic analysis.
@@ -11366,8 +11366,7 @@ class Sema final : public SemaBase {
1136611366
DeclResult ActOnVarTemplateSpecialization(
1136711367
Scope *S, Declarator &D, TypeSourceInfo *DI, LookupResult &Previous,
1136811368
SourceLocation TemplateKWLoc, TemplateParameterList *TemplateParams,
11369-
StorageClass SC, bool IsPartialSpecialization,
11370-
bool IsMemberSpecialization);
11369+
StorageClass SC, bool IsPartialSpecialization);
1137111370

1137211371
/// Get the specialization of the given variable template corresponding to
1137311372
/// the specified argument list, or a null-but-valid result if the arguments
@@ -13008,14 +13007,28 @@ class Sema final : public SemaBase {
1300813007
/// dealing with a specialization. This is only relevant for function
1300913008
/// template specializations.
1301013009
///
13010+
/// \param Pattern If non-NULL, indicates the pattern from which we will be
13011+
/// instantiating the definition of the given declaration, \p ND. This is
13012+
/// used to determine the proper set of template instantiation arguments for
13013+
/// friend function template specializations.
13014+
///
1301113015
/// \param ForConstraintInstantiation when collecting arguments,
1301213016
/// ForConstraintInstantiation indicates we should continue looking when
1301313017
/// encountering a lambda generic call operator, and continue looking for
1301413018
/// arguments on an enclosing class template.
13019+
///
13020+
/// \param SkipForSpecialization when specified, any template specializations
13021+
/// in a traversal would be ignored.
13022+
/// \param ForDefaultArgumentSubstitution indicates we should continue looking
13023+
/// when encountering a specialized member function template, rather than
13024+
/// returning immediately.
1301513025
MultiLevelTemplateArgumentList getTemplateInstantiationArgs(
1301613026
const NamedDecl *D, const DeclContext *DC = nullptr, bool Final = false,
1301713027
std::optional<ArrayRef<TemplateArgument>> Innermost = std::nullopt,
13018-
bool RelativeToPrimary = false, bool ForConstraintInstantiation = false);
13028+
bool RelativeToPrimary = false, const FunctionDecl *Pattern = nullptr,
13029+
bool ForConstraintInstantiation = false,
13030+
bool SkipForSpecialization = false,
13031+
bool ForDefaultArgumentSubstitution = false);
1301913032

1302013033
/// RAII object to handle the state changes required to synthesize
1302113034
/// a function body.

clang/lib/AST/Decl.cpp

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2696,27 +2696,21 @@ VarDecl *VarDecl::getTemplateInstantiationPattern() const {
26962696
if (isTemplateInstantiation(VDTemplSpec->getTemplateSpecializationKind())) {
26972697
auto From = VDTemplSpec->getInstantiatedFrom();
26982698
if (auto *VTD = From.dyn_cast<VarTemplateDecl *>()) {
2699-
while (true) {
2700-
VTD = VTD->getMostRecentDecl();
2701-
if (VTD->isMemberSpecialization())
2702-
break;
2703-
if (auto *NewVTD = VTD->getInstantiatedFromMemberTemplate())
2704-
VTD = NewVTD;
2705-
else
2699+
while (!VTD->isMemberSpecialization()) {
2700+
auto *NewVTD = VTD->getInstantiatedFromMemberTemplate();
2701+
if (!NewVTD)
27062702
break;
2703+
VTD = NewVTD;
27072704
}
27082705
return getDefinitionOrSelf(VTD->getTemplatedDecl());
27092706
}
27102707
if (auto *VTPSD =
27112708
From.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
2712-
while (true) {
2713-
VTPSD = VTPSD->getMostRecentDecl();
2714-
if (VTPSD->isMemberSpecialization())
2715-
break;
2716-
if (auto *NewVTPSD = VTPSD->getInstantiatedFromMember())
2717-
VTPSD = NewVTPSD;
2718-
else
2709+
while (!VTPSD->isMemberSpecialization()) {
2710+
auto *NewVTPSD = VTPSD->getInstantiatedFromMember();
2711+
if (!NewVTPSD)
27192712
break;
2713+
VTPSD = NewVTPSD;
27202714
}
27212715
return getDefinitionOrSelf<VarDecl>(VTPSD);
27222716
}
@@ -2725,17 +2719,15 @@ VarDecl *VarDecl::getTemplateInstantiationPattern() const {
27252719

27262720
// If this is the pattern of a variable template, find where it was
27272721
// instantiated from. FIXME: Is this necessary?
2728-
if (VarTemplateDecl *VTD = VD->getDescribedVarTemplate()) {
2729-
while (true) {
2730-
VTD = VTD->getMostRecentDecl();
2731-
if (VTD->isMemberSpecialization())
2732-
break;
2733-
if (auto *NewVTD = VTD->getInstantiatedFromMemberTemplate())
2734-
VTD = NewVTD;
2735-
else
2722+
if (VarTemplateDecl *VarTemplate = VD->getDescribedVarTemplate()) {
2723+
while (!VarTemplate->isMemberSpecialization()) {
2724+
auto *NewVT = VarTemplate->getInstantiatedFromMemberTemplate();
2725+
if (!NewVT)
27362726
break;
2727+
VarTemplate = NewVT;
27372728
}
2738-
return getDefinitionOrSelf(VTD->getTemplatedDecl());
2729+
2730+
return getDefinitionOrSelf(VarTemplate->getTemplatedDecl());
27392731
}
27402732

27412733
if (VD == this)
@@ -4150,14 +4142,11 @@ FunctionDecl::getTemplateInstantiationPattern(bool ForDefinition) const {
41504142
if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) {
41514143
// If we hit a point where the user provided a specialization of this
41524144
// template, we're done looking.
4153-
while (true) {
4154-
Primary = Primary->getMostRecentDecl();
4155-
if (ForDefinition && Primary->isMemberSpecialization())
4156-
break;
4157-
if (auto *NewPrimary = Primary->getInstantiatedFromMemberTemplate())
4158-
Primary = NewPrimary;
4159-
else
4145+
while (!ForDefinition || !Primary->isMemberSpecialization()) {
4146+
auto *NewPrimary = Primary->getInstantiatedFromMemberTemplate();
4147+
if (!NewPrimary)
41604148
break;
4149+
Primary = NewPrimary;
41614150
}
41624151

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

clang/lib/AST/DeclCXX.cpp

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2023,27 +2023,19 @@ const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const {
20232023
if (auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(this)) {
20242024
auto From = TD->getInstantiatedFrom();
20252025
if (auto *CTD = From.dyn_cast<ClassTemplateDecl *>()) {
2026-
while (true) {
2027-
CTD = CTD->getMostRecentDecl();
2028-
if (CTD->isMemberSpecialization())
2029-
break;
2030-
if (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate())
2031-
CTD = NewCTD;
2032-
else
2026+
while (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) {
2027+
if (NewCTD->isMemberSpecialization())
20332028
break;
2029+
CTD = NewCTD;
20342030
}
20352031
return GetDefinitionOrSelf(CTD->getTemplatedDecl());
20362032
}
20372033
if (auto *CTPSD =
20382034
From.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) {
2039-
while (true) {
2040-
CTPSD = CTPSD->getMostRecentDecl();
2041-
if (CTPSD->isMemberSpecialization())
2042-
break;
2043-
if (auto *NewCTPSD = CTPSD->getInstantiatedFromMemberTemplate())
2044-
CTPSD = NewCTPSD;
2045-
else
2035+
while (auto *NewCTPSD = CTPSD->getInstantiatedFromMember()) {
2036+
if (NewCTPSD->isMemberSpecialization())
20462037
break;
2038+
CTPSD = NewCTPSD;
20472039
}
20482040
return GetDefinitionOrSelf(CTPSD);
20492041
}

0 commit comments

Comments
 (0)