Store latest redeclaration for each redeclarable template declaration

This patch adds a Latest field to RedeclarableTemplateDecl's CommonBase
class which is used to store the latest redeclaration.

llvm-svn: 109755
This commit is contained in:
Peter Collingbourne 2010-07-29 16:12:01 +00:00
parent 91b25b7419
commit 2bf3d24ca1
4 changed files with 25 additions and 4 deletions

View File

@ -492,10 +492,7 @@ class RedeclarableTemplateDecl : public TemplateDecl {
RedeclarableTemplateDecl *getCanonicalDeclImpl(); RedeclarableTemplateDecl *getCanonicalDeclImpl();
void setPreviousDeclarationImpl(RedeclarableTemplateDecl *Prev) { void setPreviousDeclarationImpl(RedeclarableTemplateDecl *Prev);
if (Prev)
CommonOrPrev = Prev;
}
RedeclarableTemplateDecl *getInstantiatedFromMemberTemplateImpl() { RedeclarableTemplateDecl *getInstantiatedFromMemberTemplateImpl() {
return getCommonPtr()->InstantiatedFromMember.getPointer(); return getCommonPtr()->InstantiatedFromMember.getPointer();
@ -517,6 +514,9 @@ protected:
/// was explicitly specialized. /// was explicitly specialized.
llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool> llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
InstantiatedFromMember; InstantiatedFromMember;
/// \brief The latest declaration of this template.
RedeclarableTemplateDecl *Latest;
}; };
/// \brief A pointer to the previous declaration (if this is a redeclaration) /// \brief A pointer to the previous declaration (if this is a redeclaration)
@ -602,6 +602,7 @@ public:
} }
friend class PCHDeclReader; friend class PCHDeclReader;
friend class PCHDeclWriter;
}; };
template <class decl_type> template <class decl_type>

View File

@ -94,6 +94,7 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() {
if (First->CommonOrPrev.isNull()) { if (First->CommonOrPrev.isNull()) {
CommonBase *CommonPtr = First->newCommon(); CommonBase *CommonPtr = First->newCommon();
First->CommonOrPrev = CommonPtr; First->CommonOrPrev = CommonPtr;
CommonPtr->Latest = First;
} }
return First->CommonOrPrev.get<CommonBase*>(); return First->CommonOrPrev.get<CommonBase*>();
} }
@ -106,6 +107,18 @@ RedeclarableTemplateDecl *RedeclarableTemplateDecl::getCanonicalDeclImpl() {
return Tmpl; return Tmpl;
} }
void RedeclarableTemplateDecl::setPreviousDeclarationImpl(
RedeclarableTemplateDecl *Prev) {
if (Prev) {
CommonBase *Common = Prev->getCommonPtr();
Prev = Common->Latest;
Common->Latest = this;
CommonOrPrev = Prev;
} else {
assert(CommonOrPrev.is<CommonBase*>() && "Cannot reset TemplateDecl Prev");
}
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// FunctionTemplateDecl Implementation // FunctionTemplateDecl Implementation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -915,6 +915,11 @@ void PCHDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
if (Record[Idx++]) if (Record[Idx++])
D->setMemberSpecialization(); D->setMemberSpecialization();
} }
RedeclarableTemplateDecl *LatestDecl =
cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(Record[Idx++]));
assert(LatestDecl->getKind() == D->getKind() && "Latest kind mismatch");
D->getCommonPtr()->Latest = LatestDecl;
} }
} }

View File

@ -852,6 +852,8 @@ void PCHDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
Writer.AddDeclRef(D->getInstantiatedFromMemberTemplate(), Record); Writer.AddDeclRef(D->getInstantiatedFromMemberTemplate(), Record);
if (D->getInstantiatedFromMemberTemplate()) if (D->getInstantiatedFromMemberTemplate())
Record.push_back(D->isMemberSpecialization()); Record.push_back(D->isMemberSpecialization());
Writer.AddDeclRef(D->getCommonPtr()->Latest, Record);
} }
} }