summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Serialization')
-rw-r--r--clang/lib/Serialization/ASTReader.cpp19
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp23
2 files changed, 41 insertions, 1 deletions
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index eb151ef16f6..f6d705af88c 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -5940,6 +5940,15 @@ Decl *ASTReader::GetExternalDecl(uint32_t ID) {
}
void ASTReader::CompleteRedeclChain(const Decl *D) {
+ if (NumCurrentElementsDeserializing) {
+ // We arrange to not care about the complete redeclaration chain while we're
+ // deserializing. Just remember that the AST has marked this one as complete
+ // but that it's not actually complete yet, so we know we still need to
+ // complete it later.
+ PendingIncompleteDeclChains.push_back(const_cast<Decl*>(D));
+ return;
+ }
+
const DeclContext *DC = D->getDeclContext()->getRedeclContext();
// Recursively ensure that the decl context itself is complete
@@ -7983,7 +7992,8 @@ std::string ASTReader::getOwningModuleNameForDiagnostic(const Decl *D) {
}
void ASTReader::finishPendingActions() {
- while (!PendingIdentifierInfos.empty() || !PendingDeclChains.empty() ||
+ while (!PendingIdentifierInfos.empty() ||
+ !PendingIncompleteDeclChains.empty() || !PendingDeclChains.empty() ||
!PendingMacroIDs.empty() || !PendingDeclContextInfos.empty() ||
!PendingUpdateRecords.empty() || !PendingOdrMergeChecks.empty()) {
// If any identifiers with corresponding top-level declarations have
@@ -8001,6 +8011,13 @@ void ASTReader::finishPendingActions() {
SetGloballyVisibleDecls(II, DeclIDs, &TopLevelDecls[II]);
}
+ // For each decl chain that we wanted to complete while deserializing, mark
+ // it as "still needs to be completed".
+ for (unsigned I = 0; I != PendingIncompleteDeclChains.size(); ++I) {
+ markIncompleteDeclChain(PendingIncompleteDeclChains[I]);
+ }
+ PendingIncompleteDeclChains.clear();
+
// Load pending declaration chains.
for (unsigned I = 0; I != PendingDeclChains.size(); ++I) {
loadPendingDeclChain(PendingDeclChains[I]);
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 719d56edf2c..bb87632962e 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -208,6 +208,10 @@ namespace clang {
static void attachLatestDeclImpl(...);
static void attachLatestDecl(Decl *D, Decl *latest);
+ template <typename DeclT>
+ static void markIncompleteDeclChainImpl(Redeclarable<DeclT> *D);
+ static void markIncompleteDeclChainImpl(...);
+
/// \brief Determine whether this declaration has a pending body.
bool hasPendingBody() const { return HasPendingBody; }
@@ -2510,6 +2514,25 @@ void ASTDeclReader::attachLatestDecl(Decl *D, Decl *Latest) {
}
}
+template<typename DeclT>
+void ASTDeclReader::markIncompleteDeclChainImpl(Redeclarable<DeclT> *D) {
+ D->RedeclLink.markIncomplete();
+}
+void ASTDeclReader::markIncompleteDeclChainImpl(...) {
+ llvm_unreachable("markIncompleteDeclChain on non-redeclarable declaration");
+}
+
+void ASTReader::markIncompleteDeclChain(Decl *D) {
+ switch (D->getKind()) {
+#define ABSTRACT_DECL(TYPE)
+#define DECL(TYPE, BASE) \
+ case Decl::TYPE: \
+ ASTDeclReader::markIncompleteDeclChainImpl(cast<TYPE##Decl>(D)); \
+ break;
+#include "clang/AST/DeclNodes.inc"
+ }
+}
+
ASTReader::MergedDeclsMap::iterator
ASTReader::combineStoredMergedDecls(Decl *Canon, GlobalDeclID CanonID) {
// If we don't have any stored merged declarations, just look in the
OpenPOWER on IntegriCloud