diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-10-28 07:38:51 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2010-10-28 07:38:51 +0000 |
commit | 100050bf643bcfe2d06bdcef491e387171249260 (patch) | |
tree | 293e9e960189a66f50d2a687b2ad48818f82b2d1 | |
parent | 0f04f69acd0a86ff78961933c13fe5aeda94e1b6 (diff) |
Use the ASTMutationListener to track when a named decl gets added to a DeclContext,
meaning we need to rewrite its name lookup table in a chained PCH.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117536 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/ASTMutationListener.h | 3 | ||||
-rw-r--r-- | include/clang/Serialization/ASTWriter.h | 13 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 7 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 39 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterDecl.cpp | 2 |
5 files changed, 40 insertions, 24 deletions
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h index dd0c2019d5..e0b02b83e6 100644 --- a/include/clang/AST/ASTMutationListener.h +++ b/include/clang/AST/ASTMutationListener.h @@ -30,6 +30,9 @@ public: /// \brief A new TagDecl definition was completed. virtual void CompletedTagDefinition(const TagDecl *D) { } + /// \brief A new declaration with name has been added to a DeclContext. + virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D) {} + /// \brief An implicit member was added after the definition was completed. virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {} diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index 83feed90d9..99f3ece3dd 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -215,13 +215,13 @@ private: /// record. llvm::SmallVector<uint64_t, 16> ExternalDefinitions; - /// \brief Namespaces that have received extensions since their serialized + /// \brief DeclContexts that have received extensions since their serialized /// form. /// - /// Basically, when we're chaining and encountering a namespace, we check if + /// For namespaces, 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<const NamespaceDecl *, 16> UpdatedNamespaces; + llvm::SmallPtrSet<const DeclContext *, 16> UpdatedDeclContexts; typedef llvm::SmallPtrSet<const Decl *, 16> DeclsToRewriteTy; /// \brief Decls that will be replaced in the current dependent AST file. @@ -443,9 +443,9 @@ public: /// \brief Add a string to the given record. void AddString(llvm::StringRef Str, RecordDataImpl &Record); - /// \brief Mark a namespace as needing an update. - void AddUpdatedNamespace(const NamespaceDecl *NS) { - UpdatedNamespaces.insert(NS); + /// \brief Mark a declaration context as needing an update. + void AddUpdatedDeclContext(const DeclContext *DC) { + UpdatedDeclContexts.insert(DC); } void RewriteDecl(const Decl *D) { @@ -502,6 +502,7 @@ public: // ASTMutationListener implementation. virtual void CompletedTagDefinition(const TagDecl *D); + virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D); virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D); virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, const ClassTemplateSpecializationDecl *D); diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 5606d54478..5ba6623b20 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -24,6 +24,7 @@ #include "clang/AST/Type.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" +#include "clang/AST/ASTMutationListener.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> @@ -952,6 +953,12 @@ void DeclContext::makeDeclVisibleInContext(NamedDecl *D, bool Recoverable) { // parent context, too. This operation is recursive. if (isTransparentContext() || isInlineNamespace()) getParent()->makeDeclVisibleInContext(D, Recoverable); + + Decl *DCAsDecl = cast<Decl>(this); + // Notify that a decl was made visible unless it's a Tag being defined. + if (!(isa<TagDecl>(DCAsDecl) && cast<TagDecl>(DCAsDecl)->isBeingDefined())) + if (ASTMutationListener *L = DCAsDecl->getASTMutationListener()) + L->AddedVisibleDecl(this, D); } void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) { diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 283d086f0c..114f9205d4 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -2139,9 +2139,6 @@ uint64_t ASTWriter::WriteDeclContextVisibleBlock(ASTContext &Context, /// DeclContext in a dependent AST file. As such, they only exist for the TU /// (in C++) and for namespaces. void ASTWriter::WriteDeclContextVisibleUpdate(const DeclContext *DC) { - assert((DC->isTranslationUnit() || DC->isNamespace()) && - "Only TU and namespaces should have visible decl updates."); - // Make the context build its lookup table, but don't make it load external // decls. DC->lookup(DeclarationName()); @@ -2496,16 +2493,14 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record, reinterpret_cast<const char*>(NewGlobalDecls.data()), NewGlobalDecls.size() * sizeof(KindDeclIDPair)); - // And in C++, a visible updates block for the TU. - if (Context.getLangOptions().CPlusPlus) { - Abv = new llvm::BitCodeAbbrev(); - Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE)); - Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6)); - Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 32)); - Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); - UpdateVisibleAbbrev = Stream.EmitAbbrev(Abv); - WriteDeclContextVisibleUpdate(TU); - } + // And a visible updates block for the DeclContexts. + Abv = new llvm::BitCodeAbbrev(); + Abv->Add(llvm::BitCodeAbbrevOp(UPDATE_VISIBLE)); + Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6)); + Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed, 32)); + Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); + UpdateVisibleAbbrev = Stream.EmitAbbrev(Abv); + WriteDeclContextVisibleUpdate(TU); // Build a record containing all of the new tentative definitions in this // file, in TentativeDefinitions order. @@ -2674,10 +2669,10 @@ void ASTWriter::WriteASTChain(Sema &SemaRef, MemorizeStatCalls *StatCalls, if (!SemaDeclRefs.empty()) Stream.EmitRecord(SEMA_DECL_REFS, SemaDeclRefs); - // Write the updates to C++ namespaces. - for (llvm::SmallPtrSet<const NamespaceDecl *, 16>::iterator - I = UpdatedNamespaces.begin(), - E = UpdatedNamespaces.end(); + // Write the updates to DeclContexts. + for (llvm::SmallPtrSet<const DeclContext *, 16>::iterator + I = UpdatedDeclContexts.begin(), + E = UpdatedDeclContexts.end(); I != E; ++I) WriteDeclContextVisibleUpdate(*I); @@ -3306,6 +3301,16 @@ void ASTWriter::CompletedTagDefinition(const TagDecl *D) { } } } +void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) { + // TU and namespaces are handled elsewhere. + if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC)) + return; + + if (!(D->getPCHLevel() == 0 && cast<Decl>(DC)->getPCHLevel() > 0)) + return; // Not a source decl added to a DeclContext from PCH. + + AddUpdatedDeclContext(DC); +} void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) { assert(D->isImplicit()); diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 5b403cf715..3c6dd9bbc2 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -638,7 +638,7 @@ void ASTDeclWriter::VisitNamespaceDecl(NamespaceDecl *D) { if (Writer.hasChain() && !D->isOriginalNamespace() && D->getOriginalNamespace()->getPCHLevel() > 0) { NamespaceDecl *NS = D->getOriginalNamespace(); - Writer.AddUpdatedNamespace(NS); + Writer.AddUpdatedDeclContext(NS); // Make sure all visible decls are written. They will be recorded later. NS->lookup(DeclarationName()); |