}
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.
+ for (llvm::SmallPtrSet<Decl *, 4>::iterator D = PendingDefinitions.begin(),
+ DEnd = PendingDefinitions.end();
+ D != DEnd; ++D) {
+ if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(*D)) {
+ for (CXXRecordDecl::redecl_iterator R = RD->redecls_begin(),
+ REnd = RD->redecls_end();
+ R != REnd; ++R)
+ cast<CXXRecordDecl>(*R)->DefinitionData = RD->DefinitionData;
+
+ continue;
+ }
+
+ ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(*D);
+ for (ObjCInterfaceDecl::redecl_iterator R = ID->redecls_begin(),
+ REnd = ID->redecls_end();
+ R != REnd; ++R)
+ R->Data = ID->Data;
+ }
+ PendingDefinitions.clear();
}
void ASTReader::FinishedDeserializing() {
// pending references were linked.
Reader.PendingForwardRefs.erase(ID);
#endif
+
+ // Note that we have deserialized a definition.
+ Reader.PendingDefinitions.insert(ID);
}
} else if (Def) {
if (Def->Data) {
Reader.PendingForwardRefs.erase(D);
#endif
}
+
+ // Note that we have deserialized a definition.
+ Reader.PendingDefinitions.insert(D);
} else if (DefinitionDecl) {
if (DefinitionDecl->DefinitionData) {
D->DefinitionData = DefinitionDecl->DefinitionData;
void ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
// Initialize CommonOrPrev before VisitTemplateDecl so that getCommonPtr()
// can be used while this is still initializing.
- enum RedeclKind { FirstDeclaration, PointsToPrevious };
+ enum RedeclKind { FirstDeclaration, FirstInFile, PointsToPrevious };
RedeclKind Kind = (RedeclKind)Record[Idx++];
// Determine the first declaration ID.
}
break;
}
-
+
+ case FirstInFile:
case PointsToPrevious: {
FirstDeclID = ReadDeclID(Record, Idx);
DeclID PrevDeclID = ReadDeclID(Record, Idx);
// loaded and attached later on.
D->CommonOrPrev = FirstDecl;
- // Make a note that we need to wire up this declaration to its
- // previous declaration, later.
- Reader.PendingPreviousDecls.push_back(std::make_pair(D, PrevDeclID));
+ 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;
}
}
template <typename T>
void ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
- enum RedeclKind { FirstDeclaration = 0, PointsToPrevious };
+ enum RedeclKind { FirstDeclaration = 0, FirstInFile, PointsToPrevious };
RedeclKind Kind = (RedeclKind)Record[Idx++];
DeclID FirstDeclID;
case FirstDeclaration:
FirstDeclID = ThisDeclID;
break;
-
+
+ case FirstInFile:
case PointsToPrevious: {
FirstDeclID = ReadDeclID(Record, Idx);
DeclID PrevDeclID = ReadDeclID(Record, Idx);
// loaded & attached later on.
D->RedeclLink = typename Redeclarable<T>::PreviousDeclLink(FirstDecl);
- // Make a note that we need to wire up this declaration to its
- // previous declaration, later.
- Reader.PendingPreviousDecls.push_back(std::make_pair(static_cast<T*>(D),
- PrevDeclID));
+ 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(static_cast<T*>(D),
+ PrevDeclID));
+ }
break;
}
}
void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
// Emit data to initialize CommonOrPrev before VisitTemplateDecl so that
// getCommonPtr() can be used while this is still initializing.
- enum { FirstDeclaration, PointsToPrevious };
+ enum { FirstDeclaration, FirstInFile, PointsToPrevious };
RedeclarableTemplateDecl *Prev = D->getPreviousDeclaration();
RedeclarableTemplateDecl *First = 0;
if (!Prev) {
Record.push_back(D->isMemberSpecialization());
} else {
First = D->getFirstDeclaration();
- Record.push_back(PointsToPrevious);
+ Record.push_back(Prev->isFromASTFile()? FirstInFile : PointsToPrevious);
Writer.AddDeclRef(First, Record);
Writer.AddDeclRef(Prev, Record);
}
template <typename T>
void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
- enum { FirstDeclaration = 0, PointsToPrevious };
+ enum { FirstDeclaration = 0, FirstInFile, PointsToPrevious };
T *Prev = D->getPreviousDeclaration();
T *First = D->getFirstDeclaration();
if (!Prev) {
Record.push_back(FirstDeclaration);
} else {
- Record.push_back(PointsToPrevious);
+ Record.push_back(Prev->isFromASTFile()? FirstInFile : PointsToPrevious);
Writer.AddDeclRef(First, Record);
Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
}