aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2011-04-24 16:28:13 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2011-04-24 16:28:13 +0000
commit7c0837f29680f387fc4969b48a3643fe00b9b541 (patch)
tree14a162f7cbd5ddbff0760489c83b76f37b6d14ae
parent58a2cd8c0d52e710cbcc57a67eac7b51b0b831c4 (diff)
Fix adding an anonymous namespace in a chained PCH to a namespace from a previous PCH.
Fix anonymous namespaces in PCH. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130104 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Serialization/ASTCommon.h3
-rw-r--r--lib/Serialization/ASTReaderDecl.cpp10
-rw-r--r--lib/Serialization/ASTWriterDecl.cpp14
-rw-r--r--test/PCH/chain-late-anonymous-namespace.cpp41
4 files changed, 67 insertions, 1 deletions
diff --git a/lib/Serialization/ASTCommon.h b/lib/Serialization/ASTCommon.h
index d4166998d1..904f8ed6ae 100644
--- a/lib/Serialization/ASTCommon.h
+++ b/lib/Serialization/ASTCommon.h
@@ -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);
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 4d2da8decb..3d4e4cdd00 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -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;
+ }
}
}
}
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index b3b55f584a..db72be3f58 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -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
index 0000000000..53699477c9
--- /dev/null
+++ b/test/PCH/chain-late-anonymous-namespace.cpp
@@ -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