summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ASTReaderDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Serialization/ASTReaderDecl.cpp')
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp46
1 files changed, 28 insertions, 18 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 24ac976c108..6e73388da16 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -967,17 +967,22 @@ void ASTDeclReader::VisitLabelDecl(LabelDecl *D) {
void ASTDeclReader::VisitNamespaceDecl(NamespaceDecl *D) {
+ RedeclarableResult Redecl = VisitRedeclarable(D);
VisitNamedDecl(D);
- D->IsInline = Record[Idx++];
+ D->setInline(Record[Idx++]);
D->LocStart = ReadSourceLocation(Record, Idx);
D->RBraceLoc = ReadSourceLocation(Record, Idx);
- D->NextNamespace = Record[Idx++];
-
- bool IsOriginal = Record[Idx++];
- // FIXME: Modules will likely have trouble with pointing directly at
- // the original namespace.
- D->OrigOrAnonNamespace.setInt(IsOriginal);
- D->OrigOrAnonNamespace.setPointer(ReadDeclAs<NamespaceDecl>(Record, Idx));
+
+ if (Redecl.getFirstID() == ThisDeclID) {
+ // FIXME: If there's already an anonymous namespace, do we merge it with
+ // this one? Or do we, when loading modules, just forget about anonymous
+ // namespace entirely?
+ D->setAnonymousNamespace(ReadDeclAs<NamespaceDecl>(Record, Idx));
+ } else {
+ // Link this namespace back to the first declaration, which has already
+ // been deserialized.
+ D->AnonOrFirstNamespaceAndInline.setPointer(D->getFirstDeclaration());
+ }
}
void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
@@ -1772,6 +1777,8 @@ void ASTDeclReader::attachPreviousDecl(Decl *D, Decl *previous) {
ID->RedeclLink.setPointer(cast<ObjCInterfaceDecl>(previous));
} else if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D)) {
PD->RedeclLink.setPointer(cast<ObjCProtocolDecl>(previous));
+ } else if (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D)) {
+ ND->RedeclLink.setPointer(cast<NamespaceDecl>(previous));
} else {
RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
TD->CommonOrPrev = cast<RedeclarableTemplateDecl>(previous);
@@ -1801,6 +1808,10 @@ void ASTDeclReader::attachLatestDecl(Decl *D, Decl *Latest) {
PD->RedeclLink
= Redeclarable<ObjCProtocolDecl>::LatestDeclLink(
cast<ObjCProtocolDecl>(Latest));
+ } else if (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D)) {
+ ND->RedeclLink
+ = Redeclarable<NamespaceDecl>::LatestDeclLink(
+ cast<NamespaceDecl>(Latest));
} else {
RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
TD->getCommonPtr()->Latest = cast<RedeclarableTemplateDecl>(Latest);
@@ -2216,6 +2227,8 @@ static Decl *getPreviousDecl(Decl *D) {
return ID->getPreviousDeclaration();
if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
return PD->getPreviousDeclaration();
+ if (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D))
+ return ND->getPreviousDeclaration();
return cast<RedeclarableTemplateDecl>(D)->getPreviousDeclaration();
}
@@ -2234,7 +2247,9 @@ static Decl *getMostRecentDecl(Decl *D) {
return ID->getMostRecentDeclaration();
if (ObjCProtocolDecl *PD = dyn_cast<ObjCProtocolDecl>(D))
return PD->getMostRecentDeclaration();
-
+ if (NamespaceDecl *ND = dyn_cast<NamespaceDecl>(D))
+ return ND->getMostRecentDeclaration();
+
return cast<RedeclarableTemplateDecl>(D)->getMostRecentDeclaration();
}
@@ -2446,15 +2461,10 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: {
NamespaceDecl *Anon
= Reader.ReadDeclAs<NamespaceDecl>(ModuleFile, Record, Idx);
- // Guard against these being loaded out of original order. Don't use
- // getNextNamespace(), since it tries to access the context and can't in
- // the middle of deserialization.
- if (!Anon->NextNamespace) {
- if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(D))
- TU->setAnonymousNamespace(Anon);
- else
- cast<NamespaceDecl>(D)->OrigOrAnonNamespace.setPointer(Anon);
- }
+ if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(D))
+ TU->setAnonymousNamespace(Anon);
+ else
+ cast<NamespaceDecl>(D)->setAnonymousNamespace(Anon);
break;
}
OpenPOWER on IntegriCloud