aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Serialization')
-rw-r--r--lib/Serialization/ASTReader.cpp26
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp77
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp31
3 files changed, 47 insertions, 87 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index fa21bf5fdb..2417845ff7 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -6152,10 +6152,10 @@ void ASTReader::finishPendingActions() {
PendingChainedObjCCategories.clear();
}
- // If we deserialized any C++ or Objective-C class definitions or any
- // Objective-C protocol definitions, make sure that all redeclarations point
- // to the definitions. Note that this can only happen now, after the
- // redeclaration chains have been fully wired.
+ // If we deserialized any C++ or Objective-C class definitions, any
+ // Objective-C protocol definitions, or any redeclarable templates, make sure
+ // that all redeclarations point to the definitions. Note that this can only
+ // happen now, after the redeclaration chains have been fully wired.
for (llvm::SmallPtrSet<Decl *, 4>::iterator D = PendingDefinitions.begin(),
DEnd = PendingDefinitions.end();
D != DEnd; ++D) {
@@ -6177,11 +6177,21 @@ void ASTReader::finishPendingActions() {
continue;
}
- ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(*D);
- for (ObjCProtocolDecl::redecl_iterator R = PD->redecls_begin(),
- REnd = PD->redecls_end();
+ if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(*D)) {
+ for (ObjCProtocolDecl::redecl_iterator R = PD->redecls_begin(),
+ REnd = PD->redecls_end();
+ R != REnd; ++R)
+ R->Data = PD->Data;
+
+ continue;
+ }
+
+ RedeclarableTemplateDecl *RTD
+ = cast<RedeclarableTemplateDecl>(*D)->getCanonicalDecl();
+ for (RedeclarableTemplateDecl::redecl_iterator R = RTD->redecls_begin(),
+ REnd = RTD->redecls_end();
R != REnd; ++R)
- R->Data = PD->Data;
+ R->Common = RTD->Common;
}
PendingDefinitions.clear();
}
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 75c079fb65..21a0fb06a9 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -1234,72 +1234,40 @@ void ASTDeclReader::VisitTemplateDecl(TemplateDecl *D) {
ASTDeclReader::RedeclarableResult
ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
- // Initialize CommonOrPrev before VisitTemplateDecl so that getCommonPtr()
- // can be used while this is still initializing.
- enum RedeclKind { FirstDeclaration, FirstInFile, PointsToPrevious };
- RedeclKind Kind = (RedeclKind)Record[Idx++];
-
- // Determine the first declaration ID.
- DeclID FirstDeclID = 0;
- switch (Kind) {
- case FirstDeclaration: {
- FirstDeclID = ThisDeclID;
+ RedeclarableResult Redecl = VisitRedeclarable(D);
- // Since this is the first declaration of the template, fill in the
- // information for the 'common' pointer.
- if (D->CommonOrPrev.isNull()) {
- RedeclarableTemplateDecl::CommonBase *Common
- = D->newCommon(Reader.getContext());
- Common->Latest = D;
- D->CommonOrPrev = Common;
- }
+ // Make sure we've allocated the Common pointer first. We do this before
+ // VisitTemplateDecl so that getCommonPtr() can be used during initialization.
+ RedeclarableTemplateDecl *CanonD = D->getCanonicalDecl();
+ if (!CanonD->Common) {
+ CanonD->Common = CanonD->newCommon(Reader.getContext());
+ Reader.PendingDefinitions.insert(CanonD);
+ }
+ D->Common = CanonD->Common;
+ // If this is the first declaration of the template, fill in the information
+ // for the 'common' pointer.
+ if (ThisDeclID == Redecl.getFirstID()) {
if (RedeclarableTemplateDecl *RTD
= ReadDeclAs<RedeclarableTemplateDecl>(Record, Idx)) {
assert(RTD->getKind() == D->getKind() &&
"InstantiatedFromMemberTemplate kind mismatch");
- D->setInstantiatedFromMemberTemplateImpl(RTD);
+ D->setInstantiatedFromMemberTemplate(RTD);
if (Record[Idx++])
D->setMemberSpecialization();
}
- break;
}
-
- case FirstInFile:
- case PointsToPrevious: {
- FirstDeclID = ReadDeclID(Record, Idx);
- DeclID PrevDeclID = ReadDeclID(Record, Idx);
-
- RedeclarableTemplateDecl *FirstDecl
- = cast_or_null<RedeclarableTemplateDecl>(Reader.GetDecl(FirstDeclID));
-
- // We delay loading of the redeclaration chain to avoid deeply nested calls.
- // We temporarily set the first (canonical) declaration as the previous one
- // which is the one that matters and mark the real previous DeclID to be
- // loaded and attached later on.
- D->CommonOrPrev = FirstDecl;
-
- if (Kind == PointsToPrevious) {
- // Make a note that we need to wire up this declaration to its
- // previous declaration, later. We don't need to do this for the first
- // declaration in any given module file, because those will be wired
- // together later.
- Reader.PendingPreviousDecls.push_back(std::make_pair(D, PrevDeclID));
- }
- break;
- }
- }
-
+
VisitTemplateDecl(D);
D->IdentifierNamespace = Record[Idx++];
- return RedeclarableResult(Reader, FirstDeclID);
+ return Redecl;
}
void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
- VisitRedeclarableTemplateDecl(D);
+ RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
- if (D->getPreviousDeclaration() == 0) {
+ if (ThisDeclID == Redecl.getFirstID()) {
// This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of
// the specializations.
SmallVector<serialization::DeclID, 2> SpecIDs;
@@ -1321,6 +1289,7 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
typedef serialization::DeclID DeclID;
ClassTemplateDecl::Common *CommonPtr = D->getCommonPtr();
+ // FIXME: Append specializations!
CommonPtr->LazySpecializations
= new (Reader.getContext()) DeclID [SpecIDs.size()];
memcpy(CommonPtr->LazySpecializations, SpecIDs.data(),
@@ -1415,9 +1384,9 @@ void ASTDeclReader::VisitClassScopeFunctionSpecializationDecl(
}
void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
- VisitRedeclarableTemplateDecl(D);
+ RedeclarableResult Redecl = VisitRedeclarableTemplateDecl(D);
- if (D->getPreviousDeclaration() == 0) {
+ if (ThisDeclID == Redecl.getFirstID()) {
// This FunctionTemplateDecl owns a CommonPtr; read it.
// Read the function specialization declarations.
@@ -1808,7 +1777,7 @@ void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *previous) {
ND->RedeclLink.setPointer(cast<NamespaceDecl>(previous));
} else {
RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
- TD->CommonOrPrev = cast<RedeclarableTemplateDecl>(previous);
+ TD->RedeclLink.setPointer(cast<RedeclarableTemplateDecl>(previous));
}
}
@@ -1841,7 +1810,9 @@ void ASTDeclReader::attachLatestDecl(Decl *D, Decl *Latest) {
cast<NamespaceDecl>(Latest));
} else {
RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
- TD->getCommonPtr()->Latest = cast<RedeclarableTemplateDecl>(Latest);
+ TD->RedeclLink
+ = Redeclarable<RedeclarableTemplateDecl>::LatestDeclLink(
+ cast<RedeclarableTemplateDecl>(Latest));
}
}
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index b0ba7b47c9..32432c0a4f 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -1031,38 +1031,17 @@ void ASTDeclWriter::VisitTemplateDecl(TemplateDecl *D) {
}
void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
+ VisitRedeclarable(D);
+
// Emit data to initialize CommonOrPrev before VisitTemplateDecl so that
// getCommonPtr() can be used while this is still initializing.
- enum { FirstDeclaration, FirstInFile, PointsToPrevious };
- RedeclarableTemplateDecl *Prev = D->getPreviousDeclaration();
- RedeclarableTemplateDecl *First = 0;
- if (!Prev) {
- Record.push_back(FirstDeclaration);
-
+ if (D->isFirstDeclaration()) {
// This declaration owns the 'common' pointer, so serialize that data now.
Writer.AddDeclRef(D->getInstantiatedFromMemberTemplate(), Record);
if (D->getInstantiatedFromMemberTemplate())
Record.push_back(D->isMemberSpecialization());
- } else {
- First = D->getFirstDeclaration();
- Record.push_back(Prev->isFromASTFile()? FirstInFile : PointsToPrevious);
- Writer.AddDeclRef(First, Record);
- Writer.AddDeclRef(Prev, Record);
}
- if (D->getMostRecentDeclaration() != D && (!Prev || Prev->isFromASTFile())) {
- if (!First)
- First = D->getFirstDeclaration();
-
- // Capture the set of redeclarations in this file.
- LocalRedeclarationsInfo LocalInfo = {
- Writer.GetDeclRef(First),
- Writer.GetDeclRef(D),
- Writer.GetDeclRef(D->getMostRecentDeclaration())
- };
- Writer.LocalRedeclarations.push_back(LocalInfo);
- }
-
VisitTemplateDecl(D);
Record.push_back(D->getIdentifierNamespace());
}
@@ -1070,7 +1049,7 @@ void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
void ASTDeclWriter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
VisitRedeclarableTemplateDecl(D);
- if (D->getPreviousDeclaration() == 0) {
+ if (D->isFirstDeclaration()) {
typedef llvm::FoldingSet<ClassTemplateSpecializationDecl> CTSDSetTy;
CTSDSetTy &CTSDSet = D->getSpecializations();
Record.push_back(CTSDSet.size());
@@ -1158,7 +1137,7 @@ void ASTDeclWriter::VisitClassScopeFunctionSpecializationDecl(
void ASTDeclWriter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
VisitRedeclarableTemplateDecl(D);
- if (D->getPreviousDeclaration() == 0) {
+ if (D->isFirstDeclaration()) {
// This FunctionTemplateDecl owns the CommonPtr; write it.
// Write the function specialization declarations.