================ @@ -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()); ---------------- ZequanWu wrote:
Done. https://github.com/llvm/llvm-project/pull/98361 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits