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);
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);
};
}
-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);
if (!D->hasAttrs() &&
!D->isImplicit() &&
!D->isUsed(false) &&
- isFirstDeclInFile(D) &&
+ D->RedeclLink.getPointer() == D &&
!D->isInvalidDecl() &&
!D->isReferenced() &&
!D->isTopLevelDeclInObjCContainer() &&
!D->isImplicit() &&
!D->isUsed(false) &&
!D->hasExtInfo() &&
- isFirstDeclInFile(D) &&
+ D->RedeclLink.getPointer() == D &&
!D->isInvalidDecl() &&
!D->isReferenced() &&
!D->isTopLevelDeclInObjCContainer() &&
!D->isImplicit() &&
!D->isUsed(false) &&
!D->hasExtInfo() &&
- isFirstDeclInFile(D) &&
+ D->RedeclLink.getPointer() == D &&
!D->isInvalidDecl() &&
!D->isReferenced() &&
!D->isTopLevelDeclInObjCContainer() &&
!D->isModulePrivate() &&
D->getDeclName().getNameKind() == DeclarationName::Identifier &&
!D->hasExtInfo() &&
- isFirstDeclInFile(D) &&
+ D->RedeclLink.getPointer() == D &&
!D->hasCXXDirectInitializer() &&
D->getInit() == 0 &&
!isa<ParmVarDecl>(D) &&
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()) {
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
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
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
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
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