Skip to content

Commit 84ebf42

Browse files
committed
[FOLD] merge VarTemplateDecl::Common with previous decls
1 parent 11e6d82 commit 84ebf42

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

clang/include/clang/AST/DeclTemplate.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3119,6 +3119,9 @@ class VarTemplateDecl : public RedeclarableTemplateDecl {
31193119
return makeSpecIterator(getSpecializations(), true);
31203120
}
31213121

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

clang/lib/AST/DeclTemplate.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,6 +1293,39 @@ VarTemplateDecl::newCommon(ASTContext &C) const {
12931293
return CommonPtr;
12941294
}
12951295

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+
12961329
VarTemplateSpecializationDecl *
12971330
VarTemplateDecl::findSpecialization(ArrayRef<TemplateArgument> Args,
12981331
void *&InsertPos) {

clang/lib/Sema/SemaDecl.cpp

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

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

47024704
// Inherit access appropriately.
47034705
New->setAccess(Old->getAccess());

0 commit comments

Comments
 (0)