diff options
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 14 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterDecl.cpp | 55 | ||||
-rw-r--r-- | test/Modules/Inputs/redecl-merge-bottom.h | 3 | ||||
-rw-r--r-- | test/Modules/Inputs/redecl-merge-left.h | 4 | ||||
-rw-r--r-- | test/Modules/Inputs/redecl-merge-right.h | 2 | ||||
-rw-r--r-- | test/Modules/Inputs/redecl-merge-top.h | 2 | ||||
-rw-r--r-- | test/Modules/redecl-merge.m | 5 |
7 files changed, 45 insertions, 40 deletions
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index d538d6ebb6..3e08d99ae6 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -1410,9 +1410,18 @@ ASTDeclReader::VisitDeclContext(DeclContext *DC) { template <typename T> void ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { - enum RedeclKind { FirstInFile, PointsToPrevious }; + enum RedeclKind { OnlyDeclaration = 0, FirstInFile, PointsToPrevious }; RedeclKind Kind = (RedeclKind)Record[Idx++]; + // If this is the only known declaration of this entity, this module file + // has no additional redeclaration information. However, other module + // files might have redeclarations. + if (Kind == OnlyDeclaration) { + if (Reader.PendingDeclChainsKnown.insert(ThisDeclID)) + Reader.PendingDeclChains.push_back(ThisDeclID); + return; + } + // Read the first declaration ID, and note that we need to reconstruct // the redeclaration chain once we hit the top level. DeclID FirstDeclID = ReadDeclID(Record, Idx); @@ -1422,6 +1431,9 @@ void ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) { T *FirstDecl = cast_or_null<T>(Reader.GetDecl(FirstDeclID)); switch (Kind) { + case OnlyDeclaration: + llvm_unreachable("only declaration handled above"); + case FirstInFile: if (FirstDecl != D) D->RedeclLink = typename Redeclarable<T>::PreviousDeclLink(FirstDecl); diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 4e9a315d22..bb4359a54b 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -126,30 +126,6 @@ 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); @@ -212,7 +188,7 @@ void ASTDeclWriter::VisitTypedefDecl(TypedefDecl *D) { if (!D->hasAttrs() && !D->isImplicit() && !D->isUsed(false) && - isFirstDeclInFile(D) && + D->RedeclLink.getPointer() == D && !D->isInvalidDecl() && !D->isReferenced() && !D->isTopLevelDeclInObjCContainer() && @@ -262,7 +238,7 @@ void ASTDeclWriter::VisitEnumDecl(EnumDecl *D) { !D->isImplicit() && !D->isUsed(false) && !D->hasExtInfo() && - isFirstDeclInFile(D) && + D->RedeclLink.getPointer() == D && !D->isInvalidDecl() && !D->isReferenced() && !D->isTopLevelDeclInObjCContainer() && @@ -286,7 +262,7 @@ void ASTDeclWriter::VisitRecordDecl(RecordDecl *D) { !D->isImplicit() && !D->isUsed(false) && !D->hasExtInfo() && - isFirstDeclInFile(D) && + D->RedeclLink.getPointer() == D && !D->isInvalidDecl() && !D->isReferenced() && !D->isTopLevelDeclInObjCContainer() && @@ -732,7 +708,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) { !D->isModulePrivate() && D->getDeclName().getNameKind() == DeclarationName::Identifier && !D->hasExtInfo() && - isFirstDeclInFile(D) && + D->RedeclLink.getPointer() == D && !D->hasCXXDirectInitializer() && D->getInit() == 0 && !isa<ParmVarDecl>(D) && @@ -1298,7 +1274,13 @@ void ASTDeclWriter::VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset, template <typename T> void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) { - enum { FirstInFile, PointsToPrevious }; + enum { OnlyDeclaration = 0, FirstInFile, PointsToPrevious }; + if (D->RedeclLink.getPointer() == D) { + // This is the only declaration. + Record.push_back(OnlyDeclaration); + return; + } + T *First = D->getFirstDeclaration(); if (!D->getPreviousDeclaration() || D->getPreviousDeclaration()->isFromASTFile()) { @@ -1399,8 +1381,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { Abv = new BitCodeAbbrev(); Abv->Add(BitCodeAbbrevOp(serialization::DECL_ENUM)); // Redeclarable - Abv->Add(BitCodeAbbrevOp(0)); // First in file - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // First ID + Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext @@ -1447,8 +1428,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { Abv = new BitCodeAbbrev(); Abv->Add(BitCodeAbbrevOp(serialization::DECL_RECORD)); // Redeclarable - Abv->Add(BitCodeAbbrevOp(0)); // First in file - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // First ID + Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext @@ -1489,8 +1469,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { Abv = new BitCodeAbbrev(); Abv->Add(BitCodeAbbrevOp(serialization::DECL_PARM_VAR)); // Redeclarable - Abv->Add(BitCodeAbbrevOp(0)); // First in file - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // First ID + Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext @@ -1540,8 +1519,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { 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 + Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext @@ -1569,8 +1547,7 @@ void ASTWriter::WriteDeclsBlockAbbrevs() { Abv = new BitCodeAbbrev(); Abv->Add(BitCodeAbbrevOp(serialization::DECL_VAR)); // Redeclarable - Abv->Add(BitCodeAbbrevOp(0)); // First in file - Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // First ID + Abv->Add(BitCodeAbbrevOp(0)); // No redeclaration // Decl Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // DeclContext Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LexicalDeclContext diff --git a/test/Modules/Inputs/redecl-merge-bottom.h b/test/Modules/Inputs/redecl-merge-bottom.h index e45e0dea04..198bde3e5f 100644 --- a/test/Modules/Inputs/redecl-merge-bottom.h +++ b/test/Modules/Inputs/redecl-merge-bottom.h @@ -1,4 +1,7 @@ __import_module__ redecl_merge_left; __import_module__ redecl_merge_right; +@class B; + @class A; + diff --git a/test/Modules/Inputs/redecl-merge-left.h b/test/Modules/Inputs/redecl-merge-left.h index 0858922348..048b3e6c2d 100644 --- a/test/Modules/Inputs/redecl-merge-left.h +++ b/test/Modules/Inputs/redecl-merge-left.h @@ -4,4 +4,8 @@ __import_module__ redecl_merge_top; @class A; +@interface B +@end + @class A; + diff --git a/test/Modules/Inputs/redecl-merge-right.h b/test/Modules/Inputs/redecl-merge-right.h index 266146c995..d8fd45f2b9 100644 --- a/test/Modules/Inputs/redecl-merge-right.h +++ b/test/Modules/Inputs/redecl-merge-right.h @@ -7,3 +7,5 @@ __import_module__ redecl_merge_top; - (Super*)init; @end +@class B; + diff --git a/test/Modules/Inputs/redecl-merge-top.h b/test/Modules/Inputs/redecl-merge-top.h index 886436cdda..68dae5058e 100644 --- a/test/Modules/Inputs/redecl-merge-top.h +++ b/test/Modules/Inputs/redecl-merge-top.h @@ -3,3 +3,5 @@ @class A; @class A; + +@class B; diff --git a/test/Modules/redecl-merge.m b/test/Modules/redecl-merge.m index d62d504868..fe25044166 100644 --- a/test/Modules/redecl-merge.m +++ b/test/Modules/redecl-merge.m @@ -14,8 +14,13 @@ void f(A *a) { @class A; +@class B; + __import_module__ redecl_merge_bottom; +@implementation B +@end + void g(A *a) { [a init]; } |