Skip to content

Commit 4afa978

Browse files
Revert "[Clang][Sema] Always use latest redeclaration of primary template" (llvm#114304)
Clang importer doesn't seem to work well with this change, see discussion in the original PR. Reverts llvm#114258
1 parent f7c36d2 commit 4afa978

File tree

9 files changed

+66
-165
lines changed

9 files changed

+66
-165
lines changed

clang/include/clang/AST/DeclTemplate.h

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -857,6 +857,16 @@ class RedeclarableTemplateDecl : public TemplateDecl,
857857
/// \endcode
858858
bool isMemberSpecialization() const { return Common.getInt(); }
859859

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;
868+
}
869+
860870
/// Note that this member template is a specialization.
861871
void setMemberSpecialization() {
862872
assert(!isMemberSpecialization() && "already a member specialization");
@@ -1955,7 +1965,13 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
19551965
/// specialization which was specialized by this.
19561966
llvm::PointerUnion<ClassTemplateDecl *,
19571967
ClassTemplatePartialSpecializationDecl *>
1958-
getSpecializedTemplateOrPartial() const;
1968+
getSpecializedTemplateOrPartial() const {
1969+
if (const auto *PartialSpec =
1970+
SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1971+
return PartialSpec->PartialSpecialization;
1972+
1973+
return SpecializedTemplate.get<ClassTemplateDecl*>();
1974+
}
19591975

19601976
/// Retrieve the set of template arguments that should be used
19611977
/// to instantiate members of the class template or class template partial
@@ -2192,6 +2208,17 @@ class ClassTemplatePartialSpecializationDecl
21922208
return InstantiatedFromMember.getInt();
21932209
}
21942210

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;
2220+
}
2221+
21952222
/// Note that this member template is a specialization.
21962223
void setMemberSpecialization() { return InstantiatedFromMember.setInt(true); }
21972224

@@ -2713,7 +2740,13 @@ class VarTemplateSpecializationDecl : public VarDecl,
27132740
/// Retrieve the variable template or variable template partial
27142741
/// specialization which was specialized by this.
27152742
llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
2716-
getSpecializedTemplateOrPartial() const;
2743+
getSpecializedTemplateOrPartial() const {
2744+
if (const auto *PartialSpec =
2745+
SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
2746+
return PartialSpec->PartialSpecialization;
2747+
2748+
return SpecializedTemplate.get<VarTemplateDecl *>();
2749+
}
27172750

27182751
/// Retrieve the set of template arguments that should be used
27192752
/// to instantiate the initializer of the variable template or variable
@@ -2947,6 +2980,18 @@ class VarTemplatePartialSpecializationDecl
29472980
return InstantiatedFromMember.getInt();
29482981
}
29492982

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;
2993+
}
2994+
29502995
/// Note that this member template is a specialization.
29512996
void setMemberSpecialization() { return InstantiatedFromMember.setInt(true); }
29522997

@@ -3119,9 +3164,6 @@ class VarTemplateDecl : public RedeclarableTemplateDecl {
31193164
return makeSpecIterator(getSpecializations(), true);
31203165
}
31213166

3122-
/// Merge \p Prev with our RedeclarableTemplateDecl::Common.
3123-
void mergePrevDecl(VarTemplateDecl *Prev);
3124-
31253167
// Implement isa/cast/dyncast support
31263168
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
31273169
static bool classofKind(Kind K) { return K == VarTemplate; }

clang/lib/AST/Decl.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2708,7 +2708,7 @@ 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->isMemberSpecialization()) {
2711+
while (!VTD->hasMemberSpecialization()) {
27122712
if (auto *NewVTD = VTD->getInstantiatedFromMemberTemplate())
27132713
VTD = NewVTD;
27142714
else
@@ -2718,7 +2718,7 @@ VarDecl *VarDecl::getTemplateInstantiationPattern() const {
27182718
}
27192719
if (auto *VTPSD =
27202720
From.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
2721-
while (!VTPSD->isMemberSpecialization()) {
2721+
while (!VTPSD->hasMemberSpecialization()) {
27222722
if (auto *NewVTPSD = VTPSD->getInstantiatedFromMember())
27232723
VTPSD = NewVTPSD;
27242724
else
@@ -2732,7 +2732,7 @@ VarDecl *VarDecl::getTemplateInstantiationPattern() const {
27322732
// If this is the pattern of a variable template, find where it was
27332733
// instantiated from. FIXME: Is this necessary?
27342734
if (VarTemplateDecl *VTD = VD->getDescribedVarTemplate()) {
2735-
while (!VTD->isMemberSpecialization()) {
2735+
while (!VTD->hasMemberSpecialization()) {
27362736
if (auto *NewVTD = VTD->getInstantiatedFromMemberTemplate())
27372737
VTD = NewVTD;
27382738
else
@@ -4153,7 +4153,7 @@ FunctionDecl::getTemplateInstantiationPattern(bool ForDefinition) const {
41534153
if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) {
41544154
// If we hit a point where the user provided a specialization of this
41554155
// template, we're done looking.
4156-
while (!ForDefinition || !Primary->isMemberSpecialization()) {
4156+
while (!ForDefinition || !Primary->hasMemberSpecialization()) {
41574157
if (auto *NewPrimary = Primary->getInstantiatedFromMemberTemplate())
41584158
Primary = NewPrimary;
41594159
else
@@ -4170,7 +4170,7 @@ FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const {
41704170
if (FunctionTemplateSpecializationInfo *Info
41714171
= TemplateOrSpecialization
41724172
.dyn_cast<FunctionTemplateSpecializationInfo*>()) {
4173-
return Info->getTemplate()->getMostRecentDecl();
4173+
return Info->getTemplate();
41744174
}
41754175
return nullptr;
41764176
}

clang/lib/AST/DeclCXX.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2030,7 +2030,7 @@ 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->isMemberSpecialization()) {
2033+
while (!CTD->hasMemberSpecialization()) {
20342034
if (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate())
20352035
CTD = NewCTD;
20362036
else
@@ -2040,7 +2040,7 @@ const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const {
20402040
}
20412041
if (auto *CTPSD =
20422042
From.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) {
2043-
while (!CTPSD->isMemberSpecialization()) {
2043+
while (!CTPSD->hasMemberSpecialization()) {
20442044
if (auto *NewCTPSD = CTPSD->getInstantiatedFromMemberTemplate())
20452045
CTPSD = NewCTPSD;
20462046
else

clang/lib/AST/DeclTemplate.cpp

Lines changed: 2 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -993,17 +993,7 @@ ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
993993
if (const auto *PartialSpec =
994994
SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
995995
return PartialSpec->PartialSpecialization->getSpecializedTemplate();
996-
return SpecializedTemplate.get<ClassTemplateDecl *>()->getMostRecentDecl();
997-
}
998-
999-
llvm::PointerUnion<ClassTemplateDecl *,
1000-
ClassTemplatePartialSpecializationDecl *>
1001-
ClassTemplateSpecializationDecl::getSpecializedTemplateOrPartial() const {
1002-
if (const auto *PartialSpec =
1003-
SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1004-
return PartialSpec->PartialSpecialization->getMostRecentDecl();
1005-
1006-
return SpecializedTemplate.get<ClassTemplateDecl *>()->getMostRecentDecl();
996+
return SpecializedTemplate.get<ClassTemplateDecl*>();
1007997
}
1008998

1009999
SourceRange
@@ -1293,39 +1283,6 @@ VarTemplateDecl::newCommon(ASTContext &C) const {
12931283
return CommonPtr;
12941284
}
12951285

1296-
void VarTemplateDecl::mergePrevDecl(VarTemplateDecl *Prev) {
1297-
// If we haven't created a common pointer yet, then it can just be created
1298-
// with the usual method.
1299-
if (!getCommonPtrInternal())
1300-
return;
1301-
1302-
Common *ThisCommon = static_cast<Common *>(getCommonPtrInternal());
1303-
Common *PrevCommon = nullptr;
1304-
SmallVector<VarTemplateDecl *, 8> PreviousDecls;
1305-
for (; Prev; Prev = Prev->getPreviousDecl()) {
1306-
if (CommonBase *C = Prev->getCommonPtrInternal()) {
1307-
PrevCommon = static_cast<Common *>(C);
1308-
break;
1309-
}
1310-
PreviousDecls.push_back(Prev);
1311-
}
1312-
1313-
// If the previous redecl chain hasn't created a common pointer yet, then just
1314-
// use this common pointer.
1315-
if (!PrevCommon) {
1316-
for (auto *D : PreviousDecls)
1317-
D->setCommonPtr(ThisCommon);
1318-
return;
1319-
}
1320-
1321-
// Ensure we don't leak any important state.
1322-
assert(ThisCommon->Specializations.empty() &&
1323-
ThisCommon->PartialSpecializations.empty() &&
1324-
"Can't merge incompatible declarations!");
1325-
1326-
setCommonPtr(PrevCommon);
1327-
}
1328-
13291286
VarTemplateSpecializationDecl *
13301287
VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
13311288
void *&InsertPos) {
@@ -1448,16 +1405,7 @@ VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
14481405
if (const auto *PartialSpec =
14491406
SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
14501407
return PartialSpec->PartialSpecialization->getSpecializedTemplate();
1451-
return SpecializedTemplate.get<VarTemplateDecl *>()->getMostRecentDecl();
1452-
}
1453-
1454-
llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
1455-
VarTemplateSpecializationDecl::getSpecializedTemplateOrPartial() const {
1456-
if (const auto *PartialSpec =
1457-
SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
1458-
return PartialSpec->PartialSpecialization->getMostRecentDecl();
1459-
1460-
return SpecializedTemplate.get<VarTemplateDecl *>()->getMostRecentDecl();
1408+
return SpecializedTemplate.get<VarTemplateDecl *>();
14611409
}
14621410

14631411
SourceRange VarTemplateSpecializationDecl::getSourceRange() const {

clang/lib/Sema/SemaDecl.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4696,10 +4696,8 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
46964696

46974697
// Keep a chain of previous declarations.
46984698
New->setPreviousDecl(Old);
4699-
if (NewTemplate) {
4700-
NewTemplate->mergePrevDecl(OldTemplate);
4699+
if (NewTemplate)
47014700
NewTemplate->setPreviousDecl(OldTemplate);
4702-
}
47034701

47044702
// Inherit access appropriately.
47054703
New->setAccess(Old->getAccess());

clang/lib/Sema/SemaInit.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9954,7 +9954,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
99549954
auto SynthesizeAggrGuide = [&](InitListExpr *ListInit) {
99559955
auto *Pattern = Template;
99569956
while (Pattern->getInstantiatedFromMemberTemplate()) {
9957-
if (Pattern->isMemberSpecialization())
9957+
if (Pattern->hasMemberSpecialization())
99589958
break;
99599959
Pattern = Pattern->getInstantiatedFromMemberTemplate();
99609960
}

clang/lib/Sema/SemaTemplateInstantiate.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ struct TemplateInstantiationArgumentCollecter
343343
// If this function was instantiated from a specialized member that is
344344
// a function template, we're done.
345345
assert(FD->getPrimaryTemplate() && "No function template?");
346-
if (FD->getPrimaryTemplate()->isMemberSpecialization())
346+
if (FD->getPrimaryTemplate()->hasMemberSpecialization())
347347
return Done();
348348

349349
// If this function is a generic lambda specialization, we are done.
@@ -442,11 +442,11 @@ struct TemplateInstantiationArgumentCollecter
442442
Specialized = CTSD->getSpecializedTemplateOrPartial();
443443
if (auto *CTPSD =
444444
Specialized.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) {
445-
if (CTPSD->isMemberSpecialization())
445+
if (CTPSD->hasMemberSpecialization())
446446
return Done();
447447
} else {
448448
auto *CTD = Specialized.get<ClassTemplateDecl *>();
449-
if (CTD->isMemberSpecialization())
449+
if (CTD->hasMemberSpecialization())
450450
return Done();
451451
}
452452
return UseNextDecl(CTSD);
@@ -478,11 +478,11 @@ struct TemplateInstantiationArgumentCollecter
478478
Specialized = VTSD->getSpecializedTemplateOrPartial();
479479
if (auto *VTPSD =
480480
Specialized.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
481-
if (VTPSD->isMemberSpecialization())
481+
if (VTPSD->hasMemberSpecialization())
482482
return Done();
483483
} else {
484484
auto *VTD = Specialized.get<VarTemplateDecl *>();
485-
if (VTD->isMemberSpecialization())
485+
if (VTD->hasMemberSpecialization())
486486
return Done();
487487
}
488488
return UseNextDecl(VTSD);
@@ -4141,7 +4141,7 @@ getPatternForClassTemplateSpecialization(
41414141
CXXRecordDecl *Pattern = nullptr;
41424142
Specialized = ClassTemplateSpec->getSpecializedTemplateOrPartial();
41434143
if (auto *CTD = Specialized.dyn_cast<ClassTemplateDecl *>()) {
4144-
while (!CTD->isMemberSpecialization()) {
4144+
while (!CTD->hasMemberSpecialization()) {
41454145
if (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate())
41464146
CTD = NewCTD;
41474147
else
@@ -4151,7 +4151,7 @@ getPatternForClassTemplateSpecialization(
41514151
} else if (auto *CTPSD =
41524152
Specialized
41534153
.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) {
4154-
while (!CTPSD->isMemberSpecialization()) {
4154+
while (!CTPSD->hasMemberSpecialization()) {
41554155
if (auto *NewCTPSD = CTPSD->getInstantiatedFromMemberTemplate())
41564156
CTPSD = NewCTPSD;
41574157
else

clang/test/AST/ast-dump-decl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ namespace testCanonicalTemplate {
530530
// CHECK-NEXT: | `-ClassTemplateDecl 0x{{.+}} parent 0x{{.+}} <col:5, col:40> col:40 friend_undeclared TestClassTemplate{{$}}
531531
// CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} <col:14, col:23> col:23 typename depth 1 index 0 T2{{$}}
532532
// CHECK-NEXT: | `-CXXRecordDecl 0x{{.+}} parent 0x{{.+}} <col:34, col:40> col:40 class TestClassTemplate{{$}}
533-
// CHECK-NEXT: `-ClassTemplateSpecializationDecl 0x{{.+}} <col:5, col:40> line:[[@LINE-19]]:31 class TestClassTemplate definition implicit_instantiation{{$}}
533+
// CHECK-NEXT: `-ClassTemplateSpecializationDecl 0x{{.+}} <line:[[@LINE-19]]:3, line:[[@LINE-17]]:3> line:[[@LINE-19]]:31 class TestClassTemplate definition implicit_instantiation{{$}}
534534
// CHECK-NEXT: |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init{{$}}
535535
// CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr defaulted_is_constexpr{{$}}
536536
// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param implicit_has_const_param{{$}}

0 commit comments

Comments
 (0)