aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-01-01 19:51:50 +0000
committerDouglas Gregor <dgregor@apple.com>2012-01-01 19:51:50 +0000
commit1d784b277cdfd4eba03680715d2a082b3f28d295 (patch)
tree5070a82eb117524e15f1f15ef324c52f4ea61687 /lib/Serialization
parent5e2a1ff9f28d2eab256d2553e76a9c9d54693875 (diff)
Introduce the core infrastructure needed to model redeclaration chains
for Objective-C protocols, including: - Using the first declaration as the canonical declaration - Using the definition as the primary DeclContext - Making sure that all declarations have a pointer to the definition data, and that we know which declaration is the definition - Serialization support for redeclaration chains and for adding definitions to already-serialized declarations. However, note that we're not taking advantage of much of this code yet, because we're still re-using ObjCProtocolDecls. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147410 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization')
-rw-r--r--lib/Serialization/ASTCommon.h3
-rw-r--r--lib/Serialization/ASTReader.cpp24
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp24
-rw-r--r--lib/Serialization/ASTWriter.cpp19
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp1
5 files changed, 61 insertions, 10 deletions
diff --git a/lib/Serialization/ASTCommon.h b/lib/Serialization/ASTCommon.h
index 2e3d70b853..2190844a83 100644
--- a/lib/Serialization/ASTCommon.h
+++ b/lib/Serialization/ASTCommon.h
@@ -27,7 +27,8 @@ enum DeclUpdateKind {
UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
UPD_CXX_ADDED_ANONYMOUS_NAMESPACE,
UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER,
- UPD_OBJC_SET_CLASS_DEFINITIONDATA
+ UPD_OBJC_SET_CLASS_DEFINITIONDATA,
+ UPD_OBJC_SET_PROTOCOL_DEFINITIONDATA
};
TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index dd48b2dc56..9c9e8b3ca9 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -6121,9 +6121,10 @@ void ASTReader::finishPendingActions() {
PendingChainedObjCCategories.clear();
}
- // If we deserialized any C++ or Objective-C class 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 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.
for (llvm::SmallPtrSet<Decl *, 4>::iterator D = PendingDefinitions.begin(),
DEnd = PendingDefinitions.end();
D != DEnd; ++D) {
@@ -6136,11 +6137,20 @@ void ASTReader::finishPendingActions() {
continue;
}
- ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(*D);
- for (ObjCInterfaceDecl::redecl_iterator R = ID->redecls_begin(),
- REnd = ID->redecls_end();
+ if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(*D)) {
+ for (ObjCInterfaceDecl::redecl_iterator R = ID->redecls_begin(),
+ REnd = ID->redecls_end();
+ R != REnd; ++R)
+ R->Data = ID->Data;
+
+ continue;
+ }
+
+ ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(*D);
+ for (ObjCProtocolDecl::redecl_iterator R = PD->redecls_begin(),
+ REnd = PD->redecls_end();
R != REnd; ++R)
- R->Data = ID->Data;
+ R->Data = PD->Data;
}
PendingDefinitions.clear();
}
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index f88a394e90..38b69413ac 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -760,6 +760,7 @@ void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) {
}
void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
+ VisitRedeclarable(PD);
VisitObjCContainerDecl(PD);
PD->InitiallyForwardDecl = Record[Idx++];
PD->isForwardProtoDecl = Record[Idx++];
@@ -782,8 +783,8 @@ void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
PD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
Reader.getContext());
- // FIXME: Note that we have deserialized a definition.
- // Reader.PendingDefinitions.insert(PD);
+ // Note that we have deserialized a definition.
+ Reader.PendingDefinitions.insert(PD);
} else if (Def && Def->Data) {
PD->Data = Def->Data;
}
@@ -1712,6 +1713,8 @@ void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *previous) {
TD->RedeclLink.setPointer(cast<TypedefNameDecl>(previous));
} else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
ID->RedeclLink.setPointer(cast<ObjCInterfaceDecl>(previous));
+ } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
+ PD->RedeclLink.setPointer(cast<ObjCProtocolDecl>(previous));
} else {
RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
TD->CommonOrPrev = cast<RedeclarableTemplateDecl>(previous);
@@ -1737,6 +1740,10 @@ void ASTDeclReader::attachLatestDecl(Decl *D, Decl *Latest) {
ID->RedeclLink
= Redeclarable<ObjCInterfaceDecl>::LatestDeclLink(
cast<ObjCInterfaceDecl>(Latest));
+ } else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
+ PD->RedeclLink
+ = Redeclarable<ObjCProtocolDecl>::LatestDeclLink(
+ cast<ObjCProtocolDecl>(Latest));
} else {
RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
TD->getCommonPtr()->Latest = cast<RedeclarableTemplateDecl>(Latest);
@@ -2201,6 +2208,8 @@ static Decl *getPreviousDecl(Decl *D) {
return TD->getPreviousDeclaration();
if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
return ID->getPreviousDeclaration();
+ if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
+ return PD->getPreviousDeclaration();
return cast<RedeclarableTemplateDecl>(D)->getPreviousDeclaration();
}
@@ -2217,6 +2226,8 @@ static Decl *getMostRecentDecl(Decl *D) {
return TD->getMostRecentDeclaration();
if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
return ID->getMostRecentDeclaration();
+ if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
+ return PD->getMostRecentDeclaration();
return cast<RedeclarableTemplateDecl>(D)->getMostRecentDeclaration();
}
@@ -2454,6 +2465,15 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
ID->Data = Def->Data;
break;
}
+
+ case UPD_OBJC_SET_PROTOCOL_DEFINITIONDATA: {
+ ObjCProtocolDecl *ID = cast<ObjCProtocolDecl>(D);
+ ObjCProtocolDecl *Def
+ = Reader.ReadDeclAs<ObjCProtocolDecl>(ModuleFile, Record, Idx);
+ if (Def->Data)
+ ID->Data = Def->Data;
+ break;
+ }
}
}
}
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index cfc83f7bc0..e59a3d39d1 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -3483,6 +3483,7 @@ void ASTWriter::ResolveDeclUpdatesBlocks() {
case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE:
case UPD_OBJC_SET_CLASS_DEFINITIONDATA:
+ case UPD_OBJC_SET_PROTOCOL_DEFINITIONDATA:
URec[Idx] = GetDeclRef(reinterpret_cast<Decl *>(URec[Idx]));
++Idx;
break;
@@ -4447,6 +4448,24 @@ void ASTWriter::CompletedObjCForwardRef(const ObjCContainerDecl *D) {
}
}
}
+
+ if (const ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
+ for (ObjCProtocolDecl::redecl_iterator I = PD->redecls_begin(),
+ E = PD->redecls_end();
+ I != E; ++I) {
+ if (*I == PD)
+ continue;
+
+ // We are interested when a PCH decl is modified.
+ if (I->isFromASTFile()) {
+ UpdateRecord &Record = DeclUpdates[*I];
+ Record.push_back(UPD_OBJC_SET_PROTOCOL_DEFINITIONDATA);
+ assert((*I)->hasDefinition());
+ assert((*I)->getDefinition() == D);
+ Record.push_back(reinterpret_cast<uint64_t>(D)); // the DefinitionDecl
+ }
+ }
+ }
}
void ASTWriter::AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index f1394850ed..f6fc4304e7 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -517,6 +517,7 @@ void ASTDeclWriter::VisitObjCIvarDecl(ObjCIvarDecl *D) {
}
void ASTDeclWriter::VisitObjCProtocolDecl(ObjCProtocolDecl *D) {
+ VisitRedeclarable(D);
VisitObjCContainerDecl(D);
Record.push_back(D->isInitiallyForwardDecl());
Record.push_back(D->isForwardProtoDecl);