diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 169b74e01b45..1a6c5833fff9 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -239,7 +239,7 @@ class NamespaceDecl : public NamedDecl, public DeclContext { // there will be one NamespaceDecl for each declaration. // NextNamespace points to the next extended declaration. // OrigNamespace points to the original namespace declaration. - // OrigNamespace of the first namespace decl points to itself. + // OrigNamespace of the first namespace decl points to its anonymous namespace NamespaceDecl *NextNamespace; /// \brief A pointer to either the original namespace definition for @@ -277,7 +277,7 @@ public: return !getIdentifier(); } - /// \brief Return the next extended namespace declaration or null if this + /// \brief Return the next extended namespace declaration or null if there /// is none. NamespaceDecl *getNextNamespace() { return NextNamespace; } const NamespaceDecl *getNextNamespace() const { return NextNamespace; } diff --git a/clang/include/clang/Frontend/PCHWriter.h b/clang/include/clang/Frontend/PCHWriter.h index 811a5062167e..9f8b54c2fd5b 100644 --- a/clang/include/clang/Frontend/PCHWriter.h +++ b/clang/include/clang/Frontend/PCHWriter.h @@ -22,6 +22,7 @@ #include "clang/Frontend/PCHDeserializationListener.h" #include "clang/Sema/SemaConsumer.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Bitcode/BitstreamWriter.h" #include @@ -219,6 +220,13 @@ private: /// record. llvm::SmallVector ExternalDefinitions; + /// \brief Namespaces that have received extensions since their PCH form. + /// + /// Basically, when we're chaining and encountering a namespace, we check if + /// its primary namespace comes from the chain. If it does, we add the primary + /// to this set, so that we can write out lexical content updates for it. + llvm::SmallPtrSet UpdatedNamespaces; + /// \brief Statements that we've encountered while serializing a /// declaration or type. llvm::SmallVector StmtsToEmit; @@ -390,12 +398,17 @@ public: /// \brief Emit a UnresolvedSet structure. void AddUnresolvedSet(const UnresolvedSetImpl &Set, RecordData &Record); - /// brief Emit a C++ base specifier. + /// \brief Emit a C++ base specifier. void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base, RecordData &Record); /// \brief Add a string to the given record. void AddString(const std::string &Str, RecordData &Record); + /// \brief Mark a namespace as needing an update. + void AddUpdatedNamespace(const NamespaceDecl *NS) { + UpdatedNamespaces.insert(NS); + } + /// \brief Note that the identifier II occurs at the given offset /// within the identifier table. void SetIdentifierOffset(const IdentifierInfo *II, uint32_t Offset); diff --git a/clang/lib/Frontend/PCHWriterDecl.cpp b/clang/lib/Frontend/PCHWriterDecl.cpp index 9e9835adb424..a3d47bba585b 100644 --- a/clang/lib/Frontend/PCHWriterDecl.cpp +++ b/clang/lib/Frontend/PCHWriterDecl.cpp @@ -600,6 +600,11 @@ void PCHDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) { else Writer.AddDeclRef(D->getOriginalNamespace(), Record); Code = pch::DECL_NAMESPACE; + + if (Writer.hasChain() && !D->isOriginalNamespace() && + D->getOriginalNamespace()->getPCHLevel() > 0) { + Writer.AddUpdatedNamespace(D->getOriginalNamespace()); + } } void PCHDeclWriter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {