aboutsummaryrefslogtreecommitdiff
path: root/lib/Serialization/ASTWriterDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Serialization/ASTWriterDecl.cpp')
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp89
1 files changed, 58 insertions, 31 deletions
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 9b74aaeae4..6c6428d55a 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -125,6 +125,30 @@ namespace clang {
};
}
+static bool isFirstDeclInFile(Decl *D) {
+ // FIXME: There must be a better way to abstract Redeclarable<T> into a
+ // more-general "redeclarable type".
+ if (TagDecl *Tag = dyn_cast<TagDecl>(D))
+ return !Tag->getPreviousDeclaration() ||
+ Tag->getPreviousDeclaration()->isFromASTFile();
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ return !FD->getPreviousDeclaration() ||
+ FD->getPreviousDeclaration()->isFromASTFile();
+ if (VarDecl *VD = dyn_cast<VarDecl>(D))
+ return !VD->getPreviousDeclaration() ||
+ VD->getPreviousDeclaration()->isFromASTFile();
+ if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D))
+ return !TD->getPreviousDeclaration() ||
+ TD->getPreviousDeclaration()->isFromASTFile();
+ if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
+ return !ID->getPreviousDeclaration() ||
+ ID->getPreviousDeclaration()->isFromASTFile();
+
+ RedeclarableTemplateDecl *RTD = cast<RedeclarableTemplateDecl>(D);
+ return !RTD->getPreviousDeclaration() ||
+ RTD->getPreviousDeclaration()->isFromASTFile();
+}
+
void ASTDeclWriter::Visit(Decl *D) {
DeclVisitor<ASTDeclWriter>::Visit(D);
@@ -177,13 +201,14 @@ void ASTDeclWriter::VisitTypeDecl(TypeDecl *D) {
}
void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
+ VisitRedeclarable(D);
VisitTypeDecl(D);
Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
if (!D->hasAttrs() &&
!D->isImplicit() &&
!D->isUsed(false) &&
- D->RedeclLink.getNext() == D &&
+ isFirstDeclInFile(D) &&
!D->isInvalidDecl() &&
!D->isReferenced() &&
!D->isTopLevelDeclInObjCContainer() &&
@@ -196,6 +221,7 @@ void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) {
}
void ASTDeclWriter::VisitTypeAliasDecl(TypeAliasDecl *D) {
+ VisitRedeclarable(D);
VisitTypeDecl(D);
Writer.AddTypeSourceInfo(D->getTypeSourceInfo(), Record);
Code = serialization::DECL_TYPEALIAS;
@@ -234,7 +260,7 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) {
!D->isImplicit() &&
!D->isUsed(false) &&
!D->hasExtInfo() &&
- D->RedeclLink.getNext() == D &&
+ isFirstDeclInFile(D) &&
!D->isInvalidDecl() &&
!D->isReferenced() &&
!D->isTopLevelDeclInObjCContainer() &&
@@ -258,7 +284,7 @@ void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) {
!D->isImplicit() &&
!D->isUsed(false) &&
!D->hasExtInfo() &&
- D->RedeclLink.getNext() == D &&
+ isFirstDeclInFile(D) &&
!D->isInvalidDecl() &&
!D->isReferenced() &&
!D->isTopLevelDeclInObjCContainer() &&
@@ -701,7 +727,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
!D->isModulePrivate() &&
D->getDeclName().getNameKind() == DeclarationName::Identifier &&
!D->hasExtInfo() &&
- D->RedeclLink.getNext() == D &&
+ isFirstDeclInFile(D) &&
!D->hasCXXDirectInitializer() &&
D->getInit() == 0 &&
!isa<ParmVarDecl>(D) &&
@@ -1267,30 +1293,24 @@ void ASTDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
template <typename T>
void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
- enum { NoRedeclaration = 0, PointsToPrevious, PointsToLatest };
- if (D->RedeclLink.getNext() == D) {
- Record.push_back(NoRedeclaration);
- } else {
- if (D->RedeclLink.NextIsPrevious()) {
- Record.push_back(PointsToPrevious);
- Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
- Writer.AddDeclRef(D->getFirstDeclaration(), Record);
- } else {
- Record.push_back(PointsToLatest);
- Writer.AddDeclRef(D->RedeclLink.getPointer(), Record);
- }
- }
-
+ enum { FirstInFile, PointsToPrevious };
T *First = D->getFirstDeclaration();
- T *ThisDecl = static_cast<T*>(D);
- // If this is a most recent redeclaration that is pointed to by a first decl
- // in a chained PCH, keep track of the association with the map so we can
- // update the first decl during AST reading.
- if (ThisDecl != First && First->getMostRecentDeclaration() == ThisDecl &&
- First->isFromASTFile() && !ThisDecl->isFromASTFile()) {
- assert(Writer.FirstLatestDecls.find(First) == Writer.FirstLatestDecls.end()
- && "The latest is already set");
- Writer.FirstLatestDecls[First] = ThisDecl;
+ if (!D->getPreviousDeclaration() ||
+ D->getPreviousDeclaration()->isFromASTFile()) {
+ Record.push_back(FirstInFile);
+ Writer.AddDeclRef(First, Record);
+
+ // Capture the set of redeclarations in this file.
+ LocalRedeclarationsInfo LocalInfo = {
+ Writer.GetDeclRef(First),
+ Writer.GetDeclRef(static_cast<T*>(D)),
+ Writer.GetDeclRef(D->getMostRecentDeclaration())
+ };
+ Writer.LocalRedeclarations.push_back(LocalInfo);
+ } else {
+ Record.push_back(PointsToPrevious);
+ Writer.AddDeclRef(First, Record);
+ Writer.AddDeclRef(D->getPreviousDeclaration(), Record);
}
}
@@ -1374,7 +1394,8 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_ENUM));
// Redeclarable
- Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
+ Abv->Add(BitCodeAbbrevOp(0)); // First in file
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // First ID
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
@@ -1421,7 +1442,8 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_RECORD));
// Redeclarable
- Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
+ Abv->Add(BitCodeAbbrevOp(0)); // First in file
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // First ID
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
@@ -1462,7 +1484,8 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_PARM_VAR));
// Redeclarable
- Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
+ Abv->Add(BitCodeAbbrevOp(0)); // First in file
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // First ID
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
@@ -1511,6 +1534,9 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
// Abbreviation for DECL_TYPEDEF
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_TYPEDEF));
+ // Redeclarable
+ Abv->Add(BitCodeAbbrevOp(0)); // First in file
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // First ID
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext
@@ -1538,7 +1564,8 @@ void ASTWriter::WriteDeclsBlockAbbrevs() {
Abv = new BitCodeAbbrev();
Abv->Add(BitCodeAbbrevOp(serialization::DECL_VAR));
// Redeclarable
- Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration
+ Abv->Add(BitCodeAbbrevOp(0)); // First in file
+ Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // First ID
// Decl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext