[clang] [WIP] Fix the crash when dump the deserialized decl (PR #133395)

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 28 02:27:41 PDT 2025


https://github.com/hokein updated https://github.com/llvm/llvm-project/pull/133395

>From 517f66dd11729a833ea64350622d2a10d83c2c3b Mon Sep 17 00:00:00 2001
From: Haojian Wu <hokein.wu at gmail.com>
Date: Fri, 28 Mar 2025 09:32:50 +0100
Subject: [PATCH] Fix the crash when dumping the deserialized decls

---
 clang/docs/ReleaseNotes.rst                   |  1 +
 .../ASTDeserializationListener.h              |  4 ++
 clang/lib/Frontend/FrontendAction.cpp         | 44 ++++++++++++++++---
 clang/lib/Serialization/ASTReader.cpp         |  2 +
 4 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 04ec2cfef679c..9ae29d7e58626 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -316,6 +316,7 @@ Bug Fixes in This Version
 - Fixed a modules crash where exception specifications were not propagated properly (#GH121245, relanded in #GH129982)
 - Fixed a problematic case with recursive deserialization within ``FinishedDeserializing()`` where
   ``PassInterestingDeclsToConsumer()`` was called before the declarations were safe to be passed. (#GH129982)
+- Fixed a module crash with `-dump-deserialized-decls`
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/Serialization/ASTDeserializationListener.h b/clang/include/clang/Serialization/ASTDeserializationListener.h
index ea96faa07c191..ccbaae93f9048 100644
--- a/clang/include/clang/Serialization/ASTDeserializationListener.h
+++ b/clang/include/clang/Serialization/ASTDeserializationListener.h
@@ -27,6 +27,8 @@ class MacroInfo;
 class Module;
 class SourceLocation;
 
+// IMPORTANT: when you add a new interface to this class, please update the
+// DelegatingDeserializationListener in FrontendAction.cpp
 class ASTDeserializationListener {
 public:
   virtual ~ASTDeserializationListener();
@@ -57,6 +59,8 @@ class ASTDeserializationListener {
   /// A module import was read from the AST file.
   virtual void ModuleImportRead(serialization::SubmoduleID ID,
                                 SourceLocation ImportLoc) {}
+  /// The deserialization of the AST file was finished.
+  virtual void FinishedDeserializing() {}
 };
 }
 
diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp
index 9f789f093f55d..416ee50593e74 100644
--- a/clang/lib/Frontend/FrontendAction.cpp
+++ b/clang/lib/Frontend/FrontendAction.cpp
@@ -76,6 +76,10 @@ class DelegatingDeserializationListener : public ASTDeserializationListener {
     if (Previous)
       Previous->IdentifierRead(ID, II);
   }
+  void MacroRead(serialization::MacroID ID, MacroInfo *MI) override {
+    if (Previous)
+      Previous->MacroRead(ID, MI);
+  }
   void TypeRead(serialization::TypeIdx Idx, QualType T) override {
     if (Previous)
       Previous->TypeRead(Idx, T);
@@ -93,6 +97,19 @@ class DelegatingDeserializationListener : public ASTDeserializationListener {
     if (Previous)
       Previous->MacroDefinitionRead(PPID, MD);
   }
+  void ModuleRead(serialization::SubmoduleID ID, Module *Mod) override {
+    if (Previous)
+      Previous->ModuleRead(ID, Mod);
+  }
+  void ModuleImportRead(serialization::SubmoduleID ID,
+                        SourceLocation ImportLoc) override {
+    if (Previous)
+      Previous->ModuleImportRead(ID, ImportLoc);
+  }
+  void FinishedDeserializing() override {
+    if (Previous)
+      Previous->FinishedDeserializing();
+  }
 };
 
 /// Dumps deserialized declarations.
@@ -103,15 +120,30 @@ class DeserializedDeclsDumper : public DelegatingDeserializationListener {
       : DelegatingDeserializationListener(Previous, DeletePrevious) {}
 
   void DeclRead(GlobalDeclID ID, const Decl *D) override {
-    llvm::outs() << "PCH DECL: " << D->getDeclKindName();
-    if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
-      llvm::outs() << " - ";
-      ND->printQualifiedName(llvm::outs());
+    PendingDecls.push_back(D);
+    DelegatingDeserializationListener::DeclRead(ID, D);
+  }
+  void FinishedDeserializing() override {
+    auto Decls = std::move(PendingDecls);
+    for (const auto *D : Decls) {
+      llvm::outs() << "PCH DECL: " << D->getDeclKindName();
+      if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
+        llvm::outs() << " - ";
+        ND->printQualifiedName(llvm::outs());
+      }
+      llvm::outs() << "\n";
     }
-    llvm::outs() << "\n";
 
-    DelegatingDeserializationListener::DeclRead(ID, D);
+    if (!PendingDecls.empty()) {
+      llvm::errs() << "Deserialized more decls while printing, total of "
+                   << PendingDecls.size() << "\n";
+      PendingDecls.clear();
+    }
+    DelegatingDeserializationListener::FinishedDeserializing();
   }
+
+private:
+  std::vector<const Decl *> PendingDecls;
 };
 
 /// Checks deserialized declarations and emits error if a name
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 0cd2cedb48dd9..9e3712226491a 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -10877,6 +10877,8 @@ void ASTReader::FinishedDeserializing() {
     // decls to the consumer.
     if (Consumer)
       PassInterestingDeclsToConsumer();
+    if (DeserializationListener)
+      DeserializationListener->FinishedDeserializing();
   }
 }
 



More information about the cfe-commits mailing list