]> granicus.if.org Git - clang/commitdiff
Set the correct anonymous namespace (must be last reopening), and behave correctly...
authorSebastian Redl <sebastian.redl@getdesigned.at>
Sun, 24 Apr 2011 16:28:21 +0000 (16:28 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Sun, 24 Apr 2011 16:28:21 +0000 (16:28 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130105 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Decl.h
lib/Serialization/ASTReaderDecl.cpp
lib/Serialization/ASTWriterDecl.cpp
test/PCH/chain-late-anonymous-namespace.cpp

index 419e84e84694d4c3fcfd4ba0460f7b31c3d5c8a3..b778a60f60b195d09ee29b36de5a6af9f4cbf7bd 100644 (file)
@@ -447,7 +447,7 @@ public:
 
   void setAnonymousNamespace(NamespaceDecl *D) {
     assert(!D || D->isAnonymousNamespace());
-    assert(!D || D->getParent() == this);
+    assert(!D || D->getParent()->getRedeclContext() == this);
     getOriginalNamespace()->OrigOrAnonNamespace.setPointer(D);
   }
 
index 3d4e4cdd002c1f0132638bba59525783f929b2c2..52eff1957dc5bfc106fca804eea29484620b9a0a 100644 (file)
@@ -1741,10 +1741,15 @@ void ASTDeclReader::UpdateDecl(Decl *D, const RecordData &Record) {
 
     case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: {
       NamespaceDecl *Anon = cast<NamespaceDecl>(Reader.GetDecl(Record[Idx++]));
-      if (TranslationUnitDecl *TU = dyn_cast<TranslationUnitDecl>(D))
-        TU->setAnonymousNamespace(Anon);
-      else
-        cast<NamespaceDecl>(D)->OrigOrAnonNamespace.setPointer(Anon);
+      // 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);
+      }
       break;
     }
     }
index db72be3f584b8ba90a80f63a473fe43121a8c46b..df83f2f6940fe49ef51f17c138cdbb64ca0d8a43 100644 (file)
@@ -708,11 +708,13 @@ void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) {
     }
   }
 
-  if (Writer.hasChain() && D->isOriginalNamespace() &&
-      D->isAnonymousNamespace()) {
-    // This is an original anonymous namespace. If its parent is in a previous
-    // PCH (or is the TU), mark that parent for update.
-    Decl *Parent = cast<Decl>(D->getParent()->getPrimaryContext());
+  if (Writer.hasChain() && D->isAnonymousNamespace() && !D->getNextNamespace()){
+    // This is a most recent reopening of the anonymous namespace. If its parent
+    // is in a previous PCH (or is the TU), mark that parent for update, because
+    // the original namespace always points to the latest re-opening of its
+    // anonymous namespace.
+    Decl *Parent = cast<Decl>(
+        D->getParent()->getRedeclContext()->getPrimaryContext());
     if (Parent->getPCHLevel() > 0) {
       ASTWriter::UpdateRecord &Record = Writer.DeclUpdates[Parent];
       Record.push_back(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE);
index 53699477c9a3837f5c720072068ba36696cb1753..87205c631b3a8adbc02b36261493e6348e125d67 100644 (file)
@@ -6,6 +6,7 @@
 #define PASS1
 
 namespace ns {}
+namespace os {}
 
 #elif !defined(PASS2)
 #define PASS2
@@ -19,6 +20,16 @@ namespace ns {
 namespace {
   extern int y;
 }
+namespace {
+}
+
+namespace os {
+  extern "C" {
+    namespace {
+      extern int z;
+    }
+  }
+}
 
 #else
 
@@ -38,4 +49,13 @@ void test() {
   (void)y;
 }
 
+namespace os {
+  namespace {
+    int z;
+  }
+  void test() {
+    (void)z;
+  }
+}
+
 #endif