]> granicus.if.org Git - clang/commitdiff
Fix adding an anonymous namespace in a chained PCH to a namespace from a previous...
authorSebastian Redl <sebastian.redl@getdesigned.at>
Sun, 24 Apr 2011 16:28:13 +0000 (16:28 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Sun, 24 Apr 2011 16:28:13 +0000 (16:28 +0000)
Fix anonymous namespaces in PCH.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130104 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Serialization/ASTCommon.h
lib/Serialization/ASTReaderDecl.cpp
lib/Serialization/ASTWriterDecl.cpp
test/PCH/chain-late-anonymous-namespace.cpp [new file with mode: 0644]

index d4166998d1cf4a1179166b4bb1f12d39e0b3791a..904f8ed6ae49827ee5b609862bee0fcea98f8cb4 100644 (file)
@@ -23,7 +23,8 @@ namespace serialization {
 enum DeclUpdateKind {
   UPD_CXX_SET_DEFINITIONDATA,
   UPD_CXX_ADDED_IMPLICIT_MEMBER,
-  UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION
+  UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
+  UPD_CXX_ADDED_ANONYMOUS_NAMESPACE
 };
 
 TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);
index 4d2da8decb1f2770a5964023e38fb3e14b567986..3d4e4cdd002c1f0132638bba59525783f929b2c2 100644 (file)
@@ -1737,6 +1737,16 @@ void ASTDeclReader::UpdateDecl(Decl *D, const RecordData &Record) {
     case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION:
       // It will be added to the template's specializations set when loaded.
       Reader.GetDecl(Record[Idx++]);
+      break;
+
+    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);
+      break;
+    }
     }
   }
 }
index b3b55f584aecf5dc224130a292342bcc05f1db46..db72be3f584b8ba90a80f63a473fe43121a8c46b 100644 (file)
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Serialization/ASTWriter.h"
+#include "ASTCommon.h"
 #include "clang/AST/DeclVisitor.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclTemplate.h"
@@ -21,6 +22,7 @@
 #include "llvm/Bitcode/BitstreamWriter.h"
 #include "llvm/Support/ErrorHandling.h"
 using namespace clang;
+using namespace serialization;
 
 //===----------------------------------------------------------------------===//
 // Declaration serialization
@@ -705,6 +707,18 @@ 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 (Parent->getPCHLevel() > 0) {
+      ASTWriter::UpdateRecord &Record = Writer.DeclUpdates[Parent];
+      Record.push_back(UPD_CXX_ADDED_ANONYMOUS_NAMESPACE);
+      Writer.AddDeclRef(D, Record);
+    }
+  }
 }
 
 void ASTDeclWriter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
diff --git a/test/PCH/chain-late-anonymous-namespace.cpp b/test/PCH/chain-late-anonymous-namespace.cpp
new file mode 100644 (file)
index 0000000..5369947
--- /dev/null
@@ -0,0 +1,41 @@
+// no PCH
+// RUN: %clang_cc1 -include %s -include %s -fsyntax-only %s
+// with PCH
+// RUN: %clang_cc1 -chain-include %s -chain-include %s -fsyntax-only %s
+#if !defined(PASS1)
+#define PASS1
+
+namespace ns {}
+
+#elif !defined(PASS2)
+#define PASS2
+
+namespace ns {
+  namespace {
+    extern int x;
+  }
+}
+
+namespace {
+  extern int y;
+}
+
+#else
+
+namespace ns {
+  namespace {
+    int x;
+  }
+  void test() {
+    (void)x;
+  }
+}
+
+namespace {
+  int y;
+}
+void test() {
+  (void)y;
+}
+
+#endif