[Lldb-commits] [lldb] [WIP] [lldb][Progress] Report progress when completing types from DWARF (PR #91452)

Michael Buch via lldb-commits lldb-commits at lists.llvm.org
Wed May 8 02:59:06 PDT 2024


https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/91452

This is an attempt at displaying the work that's being done by LLDB when waiting on type-completion events, e.g., when running an expression. We add three new progress reports (across three commits):
1. When moving decls between ASTs.
2. When creating Clang ASTs from DWARF.
3. When doing a FindTypes lookup on a debug map.

Some remaining questions:
1. When do we want to destroy these `Progress` objects? Since the progress completed event is only sent on object destruction
2. How expensive is it to do this reporting unconditionally?
3. Are there more interesting places to report progress on?

>From 18303da3e0b318860df9f13d6309cbf94d795f5b Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 8 May 2024 10:47:07 +0100
Subject: [PATCH 1/3] [lldb][ClangASTImporter] Report progress when importing
 decls

---
 .../Clang/ClangASTImporter.cpp                | 35 +++++++++++++++++++
 .../ExpressionParser/Clang/ClangASTImporter.h |  4 +++
 2 files changed, 39 insertions(+)

diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
index 30b50df79da90..cf9f1a2d47922 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "lldb/Core/Module.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Utility/LLDBAssert.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
@@ -17,6 +18,7 @@
 #include "clang/AST/RecordLayout.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Sema.h"
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/Support/raw_ostream.h"
 
 #include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
@@ -1131,6 +1133,7 @@ ClangASTImporter::ASTImporterDelegate::ImportImpl(Decl *From) {
     LLDB_LOG(log, "[ClangASTImporter] Complete definition not found");
   }
 
+  UpdateImportProgress(From);
   return ASTImporter::ImportImpl(From);
 }
 
@@ -1411,3 +1414,35 @@ clang::Decl *
 ClangASTImporter::ASTImporterDelegate::GetOriginalDecl(clang::Decl *To) {
   return m_main.GetDeclOrigin(To).decl;
 }
+
+void ClangASTImporter::ASTImporterDelegate::UpdateImportProgress(
+    clang::Decl const *From) {
+  assert(From &&
+         "Trying to report import progress using an invalid clang::Decl.");
+
+  // If we can't determine the decl's name, we don't know what to
+  // update the progress bar with. So bail out.
+  auto const *ND = dyn_cast<NamedDecl>(From);
+  if (!ND)
+    return;
+
+  if (!m_import_progress_up) {
+    auto const *from_ast =
+        TypeSystemClang::GetASTContext(&From->getASTContext());
+    auto const *to_ast = TypeSystemClang::GetASTContext(&getToContext());
+
+    assert(from_ast && to_ast);
+
+    llvm::SmallVector<llvm::StringRef> from_name_parts;
+    llvm::SplitString(from_ast->getDisplayName(), from_name_parts, "/");
+    auto from_name = from_name_parts.back();
+
+    llvm::SmallVector<llvm::StringRef> to_name_parts;
+    llvm::SplitString(to_ast->getDisplayName(), to_name_parts, "/");
+    auto to_name = to_name_parts.back();
+    m_import_progress_up = std::make_unique<Progress>(
+        llvm::formatv("Importing '{0}' to '{1}'", from_name, to_name));
+  }
+
+  m_import_progress_up->Increment(1, ND->getNameAsString());
+}
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h
index bc962e544d2f1..f666d0c0fc52c 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.h
@@ -22,6 +22,7 @@
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileSystemOptions.h"
 
+#include "lldb/Core/Progress.h"
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Symbol/CompilerDeclContext.h"
 #include "lldb/Utility/LLDBAssert.h"
@@ -346,6 +347,8 @@ class ClangASTImporter {
     llvm::Expected<clang::Decl *> ImportImpl(clang::Decl *From) override;
 
   private:
+    void UpdateImportProgress(clang::Decl const *From);
+
     /// Decls we should ignore when mapping decls back to their original
     /// ASTContext. Used by the CxxModuleHandler to mark declarations that
     /// were created from the 'std' C++ module to prevent that the Importer
@@ -356,6 +359,7 @@ class ClangASTImporter {
     CxxModuleHandler *m_std_handler = nullptr;
     /// The currently attached listener.
     NewDeclListener *m_new_decl_listener = nullptr;
+    std::unique_ptr<lldb_private::Progress> m_import_progress_up = nullptr;
   };
 
   typedef std::shared_ptr<ASTImporterDelegate> ImporterDelegateSP;

>From 99d505d6ec7de91f48df06da1109f1206d410c38 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 8 May 2024 10:47:54 +0100
Subject: [PATCH 2/3] [lldb][DWARFASTParserClang] Report progress when parsing
 types from DWARF

---
 .../SymbolFile/DWARF/DWARFASTParserClang.cpp  | 19 +++++++++++++++++++
 .../SymbolFile/DWARF/DWARFASTParserClang.h    |  4 ++++
 2 files changed, 23 insertions(+)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index f8101aba5c627..605428619d805 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -479,6 +479,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
     return nullptr;
   }
 
+  UpdateParsingProgress(attrs.name.AsCString("(anonymous)"));
+
   if (type_is_new_ptr)
     *type_is_new_ptr = true;
 
@@ -3952,3 +3954,20 @@ void DWARFASTParserClang::ParseRustVariantPart(
 
   layout_info.field_offsets.insert({inner_field, 0});
 }
+
+void DWARFASTParserClang::UpdateParsingProgress(std::string message) {
+  if (!m_parsing_progress_up) {
+    SymbolFile *dwarf = m_ast.GetSymbolFile();
+    if (!dwarf)
+      return;
+
+    auto *obj = dwarf->GetObjectFile();
+    if (!obj)
+      return;
+
+    m_parsing_progress_up = std::make_unique<Progress>(
+        "Parsing DWARF in " + obj->GetFileSpec().GetFilename().GetString());
+  }
+
+  m_parsing_progress_up->Increment(1, std::move(message));
+}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 8d4af203bb287..aed7c07d3f607 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -24,6 +24,7 @@
 
 #include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+#include "lldb/Core/Progress.h"
 
 #include <optional>
 #include <vector>
@@ -135,6 +136,7 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
   DeclContextToDIEMap m_decl_ctx_to_die;
   DIEToModuleMap m_die_to_module;
   std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_up;
+  std::unique_ptr<lldb_private::Progress> m_parsing_progress_up;
   /// @}
 
   clang::DeclContext *
@@ -414,6 +416,8 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
                        lldb_private::CompilerType &class_clang_type,
                        const lldb::AccessType default_accesibility,
                        lldb_private::ClangASTImporter::LayoutInfo &layout_info);
+
+  void UpdateParsingProgress(std::string message);
 };
 
 /// Parsed form of all attributes that are relevant for type reconstruction.

>From 4fc71f1a7cdb43c9437d934e057ac47fdb464d46 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Wed, 8 May 2024 10:48:20 +0100
Subject: [PATCH 3/3] [lldb][SymbolFile] Report progress when calling FindTypes
 over object files in debug map

---
 .../Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp   | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index f066f13d51c5d..b20f2f6df210d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -14,6 +14,7 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Core/ModuleList.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Progress.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Utility/RangeMap.h"
@@ -1240,7 +1241,13 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
 void SymbolFileDWARFDebugMap::FindTypes(const TypeQuery &query,
                                         TypeResults &results) {
   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+  Progress progress(
+      llvm::formatv("Searching for type '{0}'",
+                    query.GetTypeBasename().AsCString("<<UNKNOWN>>")));
   ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
+    if (auto *obj = oso_dwarf->GetObjectFile())
+      progress.Increment(1, obj->GetFileSpec().GetPath());
+
     oso_dwarf->FindTypes(query, results);
     return results.Done(query) ? IterationAction::Stop
                                : IterationAction::Continue;



More information about the lldb-commits mailing list