[Lldb-commits] [lldb] Reapply [lldb][DWARF] Delay struct/class/union definition DIE searching when parsing declaration DIEs. (PR #98361)
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Thu Jul 11 23:36:35 PDT 2024
================
@@ -1603,41 +1633,76 @@ DWARFASTParserClang::GetCPlusPlusQualifiedName(const DWARFDIE &die) {
TypeSP
DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
- const DWARFDIE &decl_die,
+ const DWARFDIE &die,
ParsedDWARFTypeAttributes &attrs) {
CompilerType clang_type;
- const dw_tag_t tag = decl_die.Tag();
- SymbolFileDWARF *dwarf = decl_die.GetDWARF();
- LanguageType cu_language = SymbolFileDWARF::GetLanguage(*decl_die.GetCU());
+ const dw_tag_t tag = die.Tag();
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU());
Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
- // UniqueDWARFASTType is large, so don't create a local variables on the
- // stack, put it on the heap. This function is often called recursively and
- // clang isn't good at sharing the stack space for variables in different
- // blocks.
- auto unique_ast_entry_up = std::make_unique<UniqueDWARFASTType>();
-
ConstString unique_typename(attrs.name);
Declaration unique_decl(attrs.decl);
+ uint64_t byte_size = attrs.byte_size.value_or(0);
+ if (attrs.byte_size && *attrs.byte_size == 0 && attrs.name &&
+ !die.HasChildren() && cu_language == eLanguageTypeObjC) {
+ // Work around an issue with clang at the moment where forward
+ // declarations for objective C classes are emitted as:
+ // DW_TAG_structure_type [2]
+ // DW_AT_name( "ForwardObjcClass" )
+ // DW_AT_byte_size( 0x00 )
+ // DW_AT_decl_file( "..." )
+ // DW_AT_decl_line( 1 )
+ //
+ // Note that there is no DW_AT_declaration and there are no children,
+ // and the byte size is zero.
+ attrs.is_forward_declaration = true;
+ }
if (attrs.name) {
if (Language::LanguageIsCPlusPlus(cu_language)) {
// For C++, we rely solely upon the one definition rule that says
// only one thing can exist at a given decl context. We ignore the
// file and line that things are declared on.
- std::string qualified_name = GetCPlusPlusQualifiedName(decl_die);
+ std::string qualified_name = GetCPlusPlusQualifiedName(die);
if (!qualified_name.empty())
unique_typename = ConstString(qualified_name);
unique_decl.Clear();
}
- if (dwarf->GetUniqueDWARFASTTypeMap().Find(
- unique_typename, decl_die, unique_decl,
- attrs.byte_size.value_or(-1), *unique_ast_entry_up)) {
- if (TypeSP type_sp = unique_ast_entry_up->m_type_sp) {
+ if (UniqueDWARFASTType *unique_ast_entry_type =
+ dwarf->GetUniqueDWARFASTTypeMap().Find(
+ unique_typename, die, unique_decl, byte_size,
+ attrs.is_forward_declaration)) {
+ if (TypeSP type_sp = unique_ast_entry_type->m_type_sp) {
+ dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
LinkDeclContextToDIE(
- GetCachedClangDeclContextForDIE(unique_ast_entry_up->m_die),
- decl_die);
+ GetCachedClangDeclContextForDIE(unique_ast_entry_type->m_die), die);
+ // If the DIE being parsed in this function is a definition and the
+ // entry in the map is a declaration, then we need to update the entry
+ // to point to the definition DIE.
+ if (!attrs.is_forward_declaration &&
+ unique_ast_entry_type->m_is_forward_declaration) {
+ unique_ast_entry_type->m_die = die;
+ if (byte_size)
+ unique_ast_entry_type->m_byte_size = byte_size;
+ if (unique_decl.IsValid())
+ unique_ast_entry_type->m_declaration = unique_decl;
+ unique_ast_entry_type->m_is_forward_declaration = false;
+ // Need to update Type ID to refer to the definition DIE. because
+ // it's used in ParseCXXMethod to determine if we need to copy cxx
+ // method types from a declaration DIE to this definition DIE.
+ type_sp->SetID(die.GetID());
----------------
labath wrote:
And this could be a helper function to deduplicate the second part of `MappingDeclDIEToDefDIE`
https://github.com/llvm/llvm-project/pull/98361
More information about the lldb-commits
mailing list