diff options
Diffstat (limited to 'lib/Serialization/ASTWriterDecl.cpp')
-rw-r--r-- | lib/Serialization/ASTWriterDecl.cpp | 89 |
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 |