[Lldb-commits] [lldb] Reapply [lldb][DWARF] Delay struct/class/union definition DIE searching when parsing declaration DIEs. (PR #92328)

Zequan Wu via lldb-commits lldb-commits at lists.llvm.org
Thu May 16 13:00:22 PDT 2024


================
@@ -321,6 +326,10 @@ class SymbolFileDWARFDebugMap : public SymbolFileCommon {
   std::vector<uint32_t> m_func_indexes; // Sorted by address
   std::vector<uint32_t> m_glob_indexes;
   std::map<std::pair<ConstString, llvm::sys::TimePoint<>>, OSOInfoSP> m_oso_map;
+  // A map from CompilerType to the struct/class/union/enum DIE (might be a
+  // declaration or a definition) that is used to construct it.
+  llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef>
+      m_forward_decl_compiler_type_to_die;
----------------
ZequanWu wrote:

TL;DR: This is because this change let `UniqueDWARFASTTypeMap` to cache created Type from declaration DIE. Before this, it was only used for caching Type created from definition DIE. And `UniqueDWARFASTTypeMap` is shared among all `SymbolFileDWARF`s belongs to one `SymbolFileDWARFDebugMap`, so should `m_forward_decl_compiler_type_to_die` which interacts with it.

Here's an example with debug map used:
The declaration DIE for `bar` is in foo.o and the definition DIE is in main.o. `ParseStructureLikeDIE` was firstly asked to parse the declaration DIE.

Before, it will always find the definition DIE in main.o and insert the CompilerType to definition DIE to `m_forward_decl_compiler_type_to_die` which belongs to SymbolFileDWARF(main.o). When `TypeSystemClang::CompleteTagDecl` wants to complete `bar`, it asks `SymbolFileDWARFDebugMap::CompleteType` to complete, which iterates all its SymbolFileDWARF(main.o, foo.o) and check if the any of them has the compiler type in their maps: https://github.com/llvm/llvm-project/blob/9144553207052a868efc5a8ce61a0afbb0eaf236/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp#L808-L812. If exists, then it assumes that symbol file should have the definition DIE and able to complete it. Since `bar`'s compiler type exists in symbol file(main.o)'s map which also has the definition DIE as value, the type completion will success. 

If I don't add the fix, we have [bar's compiler type -> bar's declaration DIE] in foo.o's map. When searching for definition DIE, we found that in main.o. Because we have already created its Type from declaration, the `UniqueDWARFASTTypeMap` will find the entry. Then it updates the entry to points to the definition DIE. It updates main.o's `m_forward_decl_compiler_type_to_die` to pointing to the definition DIE, which is **wrong**, since there's no such entry in main.o's map. It should update foo.o's map. The result is that `SymbolFileDWARFDebugMap::CompleteType` find bar's compiler type exists in foo.o and ask foo.o's symbol file to complete it, but it only has declaration DIE.

The fix is to share one `m_forward_decl_compiler_type_to_die` among one `SymbolFileDWARFDebugMap`. With this, when creating compiler type to declaration DIE in the map or updating an entry to point to a definition DIE, we are operating in the same map.

https://github.com/llvm/llvm-project/pull/92328


More information about the lldb-commits mailing list