]> granicus.if.org Git - clang/commitdiff
Use the ASTMutationListener to track when a named decl gets added to a DeclContext,
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 28 Oct 2010 07:38:51 +0000 (07:38 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Thu, 28 Oct 2010 07:38:51 +0000 (07:38 +0000)
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

include/clang/AST/ASTMutationListener.h
include/clang/Serialization/ASTWriter.h
lib/AST/DeclBase.cpp
lib/Serialization/ASTWriter.cpp
lib/Serialization/ASTWriterDecl.cpp

index dd0c2019d5d2870244639a892f7db361a323a645..e0b02b83e658909625492b8f3d1498c0fe9f86b1 100644 (file)
@@ -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) {}
 
index 83feed90d96f528f9cd9d6075717220bd4f6dda6..99f3ece3ddd92d34f62d7cd83ec7f735ffab9f16 100644 (file)
@@ -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);
index 5606d54478fe0c75d839dea4f0fe7f04e86eefd6..5ba6623b20bb189afd93aad33088e038858beb53 100644 (file)
@@ -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) {
index 283d086f0c7c4cd9478870f98fb89fcf4a66fe22..114f9205d4bb61ca5dc16822f16586ca16d7241f 100644 (file)
@@ -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());
index 5b403cf715343204e115ca95122929214296dad6..3c6dd9bbc2095d51ea2557724fa9d760dd332fa1 100644 (file)
@@ -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());