Skip to content

[lldb][cherry-pick] Various fixes to definition DIE parsing #9788

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 4 additions & 22 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,8 +565,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
while (!m_to_complete.empty()) {
TypeToComplete to_complete = m_to_complete.back();
m_to_complete.pop_back();
CompleteRecordType(to_complete.die, to_complete.type.get(),
to_complete.clang_type);
CompleteRecordType(to_complete.die, to_complete.clang_type);
}
}

Expand Down Expand Up @@ -1810,20 +1809,6 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
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) {
GetUniqueTypeNameAndDeclaration(die, cu_language, unique_typename,
Expand Down Expand Up @@ -1873,8 +1858,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,

if ((attrs.class_language == eLanguageTypeObjC ||
attrs.class_language == eLanguageTypeObjC_plus_plus) &&
!attrs.is_complete_objc_class &&
die.Supports_DW_AT_APPLE_objc_complete_type()) {
!attrs.is_complete_objc_class) {
// We have a valid eSymbolTypeObjCClass class symbol whose name
// matches the current objective C class that we are trying to find
// and this DIE isn't the complete definition (we checked
Expand Down Expand Up @@ -2241,7 +2225,6 @@ bool DWARFASTParserClang::ParseTemplateParameterInfos(
}

bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die,
lldb_private::Type *type,
CompilerType &clang_type) {
if (TypeSystemClang::UseRedeclCompletion())
if (!m_currently_parsed_record_dies.insert(die.GetDIE()).second)
Expand Down Expand Up @@ -2424,7 +2407,7 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_class_type:
CompleteRecordType(die, type, clang_type);
CompleteRecordType(die, clang_type);
break;
case DW_TAG_enumeration_type:
CompleteEnumType(die, type, clang_type);
Expand Down Expand Up @@ -3909,8 +3892,7 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
static_cast<DWARFASTParserClang *>(
SymbolFileDWARF::GetDWARFParser(*dst_class_die.GetCU()));
auto link = [&](DWARFDIE src, DWARFDIE dst) {
SymbolFileDWARF::DIEToTypePtr &die_to_type =
dst_class_die.GetDWARF()->GetDIEToType();
auto &die_to_type = dst_class_die.GetDWARF()->GetDIEToType();
clang::DeclContext *dst_decl_ctx =
dst_dwarf_ast_parser->m_die_to_decl_ctx[dst.GetDIE()];
if (dst_decl_ctx)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,6 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
const lldb_private::CompilerType &class_clang_type);

bool CompleteRecordType(const lldb_private::plugin::dwarf::DWARFDIE &die,
lldb_private::Type *type,
lldb_private::CompilerType &clang_type);
bool CompleteEnumType(const lldb_private::plugin::dwarf::DWARFDIE &die,
lldb_private::Type *type,
Expand Down
4 changes: 0 additions & 4 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,6 @@ bool DWARFBaseDIE::HasChildren() const {
return m_die && m_die->HasChildren();
}

bool DWARFBaseDIE::Supports_DW_AT_APPLE_objc_complete_type() const {
return IsValid() && GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu);
}

DWARFAttributes DWARFBaseDIE::GetAttributes(Recurse recurse) const {
if (IsValid())
return m_die->GetAttributes(m_cu, recurse);
Expand Down
16 changes: 0 additions & 16 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -734,16 +734,6 @@ bool DWARFUnit::LinkToSkeletonUnit(DWARFUnit &skeleton_unit) {
return false; // Already linked to a different unit.
}

bool DWARFUnit::Supports_DW_AT_APPLE_objc_complete_type() {
return GetProducer() != eProducerLLVMGCC;
}

bool DWARFUnit::DW_AT_decl_file_attributes_are_invalid() {
// llvm-gcc makes completely invalid decl file attributes and won't ever be
// fixed, so we need to know to ignore these.
return GetProducer() == eProducerLLVMGCC;
}

bool DWARFUnit::Supports_unnamed_objc_bitfields() {
if (GetProducer() == eProducerClang)
return GetProducerVersion() >= llvm::VersionTuple(425, 0, 13);
Expand All @@ -766,10 +756,6 @@ void DWARFUnit::ParseProducerInfo() {
llvm::StringRef(R"(swiftlang-([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?))"));
static const RegularExpression g_clang_version_regex(
llvm::StringRef(R"(clang-([0-9]+\.[0-9]+\.[0-9]+(\.[0-9]+)?))"));
static const RegularExpression g_llvm_gcc_regex(
llvm::StringRef(R"(4\.[012]\.[01] )"
R"(\(Based on Apple Inc\. build [0-9]+\) )"
R"(\(LLVM build [\.0-9]+\)$)"));

llvm::SmallVector<llvm::StringRef, 3> matches;
if (g_swiftlang_version_regex.Execute(producer, &matches)) {
Expand All @@ -781,8 +767,6 @@ void DWARFUnit::ParseProducerInfo() {
m_producer = eProducerClang;
} else if (producer.contains("GNU")) {
m_producer = eProducerGCC;
} else if (g_llvm_gcc_regex.Execute(producer)) {
m_producer = eProducerLLVMGCC;
}
}

Expand Down
5 changes: 0 additions & 5 deletions lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ enum DWARFProducer {
eProducerInvalid = 0,
eProducerClang,
eProducerGCC,
eProducerLLVMGCC,
eProducerSwift,
eProducerOther
};
Expand Down Expand Up @@ -172,10 +171,6 @@ class DWARFUnit : public UserID {

bool LinkToSkeletonUnit(DWARFUnit &skeleton_unit);

bool Supports_DW_AT_APPLE_objc_complete_type();

bool DW_AT_decl_file_attributes_are_invalid();

bool Supports_unnamed_objc_bitfields();

SymbolFileDWARF &GetSymbolFileDWARF() const { return m_dwarf; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,11 +271,6 @@ void DebugNamesDWARFIndex::GetCompleteObjCClass(
// Report invalid
continue;
}
DWARFUnit *cu = die.GetCU();
if (!cu->Supports_DW_AT_APPLE_objc_complete_type()) {
incomplete_types.push_back(die);
continue;
}

if (die.GetAttributeValueAsUnsigned(DW_AT_APPLE_objc_complete_type, 0)) {
// If we find the complete version we're done.
Expand Down
46 changes: 11 additions & 35 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,8 +472,7 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp,
: SymbolFileCommon(std::move(objfile_sp)), m_debug_map_module_wp(),
m_debug_map_symfile(nullptr),
m_context(m_objfile_sp->GetModule()->GetSectionList(), dwo_section_list),
m_fetched_external_modules(false),
m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
m_fetched_external_modules(false) {}

SymbolFileDWARF::~SymbolFileDWARF() = default;

Expand All @@ -482,6 +481,13 @@ static ConstString GetDWARFMachOSegmentName() {
return g_dwarf_section_name;
}

llvm::DenseMap<const DWARFDebugInfoEntry *, Type *> &
SymbolFileDWARF::GetDIEToType() {
if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())
return debug_map_symfile->GetDIEToType();
return m_die_to_type;
}

llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef> &
SymbolFileDWARF::GetForwardDeclCompilerTypeToDIE() {
if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())
Expand Down Expand Up @@ -1675,6 +1681,8 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
if (!dwarf_ast)
return false;
Type *type = GetDIEToType().lookup(decl_die.GetDIE());
assert(type);

if (decl_die != def_die) {
GetDIEToType()[def_die.GetDIE()] = type;
DWARFASTParserClang *ast_parser =
Expand Down Expand Up @@ -3072,37 +3080,6 @@ Symbol *SymbolFileDWARF::GetObjCClassSymbol(ConstString objc_class_name) {
return objc_class_symbol;
}

// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If
// they don't then we can end up looking through all class types for a complete
// type and never find the full definition. We need to know if this attribute
// is supported, so we determine this here and cache th result. We also need to
// worry about the debug map
// DWARF file
// if we are doing darwin DWARF in .o file debugging.
bool SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu) {
if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) {
m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
else {
DWARFDebugInfo &debug_info = DebugInfo();
const uint32_t num_compile_units = GetNumCompileUnits();
for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) {
DWARFUnit *dwarf_cu = debug_info.GetUnitAtIndex(cu_idx);
if (dwarf_cu != cu &&
dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type()) {
m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
break;
}
}
}
if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo &&
GetDebugMapSymfile())
return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type(this);
}
return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
}

// This function can be used when a DIE is found that is a forward declaration
// DIE and we want to try and find a type that has the complete definition.
TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
Expand All @@ -3120,8 +3097,7 @@ TypeSP SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE(
if (type_die == die || !IsStructOrClassTag(type_die.Tag()))
return true;

if (must_be_implementation &&
type_die.Supports_DW_AT_APPLE_objc_complete_type()) {
if (must_be_implementation) {
const bool try_resolving_type = type_die.GetAttributeValueAsUnsigned(
DW_AT_APPLE_objc_complete_type, 0);
if (!try_resolving_type)
Expand Down
9 changes: 2 additions & 7 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,6 @@ class SymbolFileDWARF : public SymbolFileCommon {
virtual void GetObjCMethods(ConstString class_name,
llvm::function_ref<bool(DWARFDIE die)> callback);

bool Supports_DW_AT_APPLE_objc_complete_type(DWARFUnit *cu);

DebugMacrosSP ParseDebugMacros(lldb::offset_t *offset);

static DWARFDIE GetParentSymbolContextDIE(const DWARFDIE &die);
Expand Down Expand Up @@ -358,9 +356,7 @@ class SymbolFileDWARF : public SymbolFileCommon {
m_file_index = file_index;
}

typedef llvm::DenseMap<const DWARFDebugInfoEntry *, Type *> DIEToTypePtr;

virtual DIEToTypePtr &GetDIEToType() { return m_die_to_type; }
virtual llvm::DenseMap<const DWARFDebugInfoEntry *, Type *> &GetDIEToType();

virtual llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef> &
GetForwardDeclCompilerTypeToDIE();
Expand Down Expand Up @@ -556,7 +552,6 @@ class SymbolFileDWARF : public SymbolFileCommon {
ExternalTypeModuleMap m_external_type_modules;
std::unique_ptr<DWARFIndex> m_index;
bool m_fetched_external_modules : 1;
LazyBool m_supports_DW_AT_APPLE_objc_complete_type;

typedef std::set<DIERef> DIERefSet;
typedef llvm::StringMap<DIERefSet> NameToOffsetMap;
Expand All @@ -565,7 +560,7 @@ class SymbolFileDWARF : public SymbolFileCommon {
UniqueDWARFASTTypeMap m_unique_ast_type_map;
// A map from DIE to lldb_private::Type. For record type, the key might be
// either declaration DIE or definition DIE.
DIEToTypePtr m_die_to_type;
llvm::DenseMap<const DWARFDebugInfoEntry *, Type *> m_die_to_type;
DIEToVariableSP m_die_to_variable_sp;
// A map from CompilerType to the struct/class/union/enum DIE (might be a
// declaration or a definition) that is used to construct it.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,8 @@ SymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFileSP objfile_sp) {
}

SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFileSP objfile_sp)
: SymbolFileCommon(std::move(objfile_sp)), m_flags(), m_compile_unit_infos(),
m_func_indexes(), m_glob_indexes(),
m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {}
: SymbolFileCommon(std::move(objfile_sp)), m_flags(),
m_compile_unit_infos(), m_func_indexes(), m_glob_indexes() {}

SymbolFileDWARFDebugMap::~SymbolFileDWARFDebugMap() = default;

Expand Down Expand Up @@ -1178,22 +1177,6 @@ DWARFDIE SymbolFileDWARFDebugMap::FindDefinitionDIE(const DWARFDIE &die) {
return result;
}

bool SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type(
SymbolFileDWARF *skip_dwarf_oso) {
if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) {
m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
if (skip_dwarf_oso != oso_dwarf &&
oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(nullptr)) {
m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
return IterationAction::Stop;
}
return IterationAction::Continue;
});
}
return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
}

TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
const DWARFDIE &die, ConstString type_name,
bool must_be_implementation) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,6 @@ class SymbolFileDWARFDebugMap : public SymbolFileCommon {

DWARFDIE FindDefinitionDIE(const DWARFDIE &die);

bool Supports_DW_AT_APPLE_objc_complete_type(SymbolFileDWARF *skip_dwarf_oso);

lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
const DWARFDIE &die, ConstString type_name, bool must_be_implementation);

Expand All @@ -307,6 +305,10 @@ class SymbolFileDWARFDebugMap : public SymbolFileCommon {
return m_unique_ast_type_map;
}

llvm::DenseMap<const DWARFDebugInfoEntry *, Type *> &GetDIEToType() {
return m_die_to_type;
}

// OSOEntry
class OSOEntry {
public:
Expand Down Expand Up @@ -345,7 +347,8 @@ class SymbolFileDWARFDebugMap : public SymbolFileCommon {
llvm::DenseMap<lldb::opaque_compiler_type_t, DIERef>
m_forward_decl_compiler_type_to_die;
UniqueDWARFASTTypeMap m_unique_ast_type_map;
LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
llvm::DenseMap<const DWARFDebugInfoEntry *, Type *> m_die_to_type;

DebugMap m_debug_map;

// When an object file from the debug map gets parsed in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ bool SymbolFileDWARFDwo::ParseVendorDWARFOpcode(
return GetBaseSymbolFile().ParseVendorDWARFOpcode(op, opcodes, offset, stack);
}

SymbolFileDWARF::DIEToTypePtr &SymbolFileDWARFDwo::GetDIEToType() {
llvm::DenseMap<const DWARFDebugInfoEntry *, Type *> &
SymbolFileDWARFDwo::GetDIEToType() {
return GetBaseSymbolFile().GetDIEToType();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class SymbolFileDWARFDwo : public SymbolFileDWARF {
SymbolFileDWARF *GetDIERefSymbolFile(const DIERef &die_ref) override;

protected:
DIEToTypePtr &GetDIEToType() override;
llvm::DenseMap<const DWARFDebugInfoEntry *, Type *> &GetDIEToType() override;

DIEToVariableSP &GetDIEToVariable() override;

Expand Down
Loading