[Lldb-commits] [lldb] [lldb][DWARF] Delay struct/class/union definition DIE searching when parsing declaration DIEs. (PR #90663)
Zequan Wu via lldb-commits
lldb-commits at lists.llvm.org
Tue May 7 08:21:39 PDT 2024
https://github.com/ZequanWu updated https://github.com/llvm/llvm-project/pull/90663
>From 4e800003099b593e66f12dc21be5fbac5279e03e Mon Sep 17 00:00:00 2001
From: Zequan Wu <zequanwu at google.com>
Date: Tue, 30 Apr 2024 16:23:11 -0400
Subject: [PATCH 1/7] [lldb][DWARF] Delay struct/class/union definition DIE
searching when parsing declaration DIEs.
---
.../SymbolFile/DWARF/DWARFASTParserClang.cpp | 270 +++++++-----------
.../SymbolFile/DWARF/SymbolFileDWARF.cpp | 105 ++++++-
.../SymbolFile/DWARF/SymbolFileDWARF.h | 14 +
.../SymbolFile/DWARF/SymbolFileDWARFDwo.cpp | 5 +
.../SymbolFile/DWARF/SymbolFileDWARFDwo.h | 2 +
.../SymbolFile/DWARF/UniqueDWARFASTType.cpp | 95 +++---
.../SymbolFile/DWARF/UniqueDWARFASTType.h | 21 +-
7 files changed, 296 insertions(+), 216 deletions(-)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index bea11e0e3840a..7ad661c9a9d49 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -252,7 +252,8 @@ static void ForcefullyCompleteType(CompilerType type) {
static void PrepareContextToReceiveMembers(TypeSystemClang &ast,
ClangASTImporter &ast_importer,
clang::DeclContext *decl_ctx,
- DWARFDIE die,
+ const DWARFDIE &decl_ctx_die,
+ const DWARFDIE &die,
const char *type_name_cstr) {
auto *tag_decl_ctx = clang::dyn_cast<clang::TagDecl>(decl_ctx);
if (!tag_decl_ctx)
@@ -279,6 +280,13 @@ static void PrepareContextToReceiveMembers(TypeSystemClang &ast,
type_name_cstr ? type_name_cstr : "", die.GetOffset());
}
+ // By searching for the definition DIE of the decl_ctx type, we will either:
+ // 1. Found the the definition DIE and start its definition with
+ // TypeSystemClang::StartTagDeclarationDefinition.
+ // 2. Unable to find it, then need to forcefully complete it.
+ die.GetDWARF()->FindDefinitionDIE(decl_ctx_die);
+ if (tag_decl_ctx->isCompleteDefinition() || tag_decl_ctx->isBeingDefined())
+ return;
// We don't have a type definition and/or the import failed. We must
// forcefully complete the type to avoid crashes.
ForcefullyCompleteType(type);
@@ -620,10 +628,11 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
if (tag == DW_TAG_typedef) {
// DeclContext will be populated when the clang type is materialized in
// Type::ResolveCompilerType.
- PrepareContextToReceiveMembers(
- m_ast, GetClangASTImporter(),
- GetClangDeclContextContainingDIE(die, nullptr), die,
- attrs.name.GetCString());
+ DWARFDIE decl_ctx_die;
+ clang::DeclContext *decl_ctx =
+ GetClangDeclContextContainingDIE(die, &decl_ctx_die);
+ PrepareContextToReceiveMembers(m_ast, GetClangASTImporter(), decl_ctx,
+ decl_ctx_die, die, attrs.name.GetCString());
if (attrs.type.IsValid()) {
// Try to parse a typedef from the (DWARF embedded in the) Clang
@@ -1100,32 +1109,6 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
// struct and see if this is actually a C++ method
Type *class_type = dwarf->ResolveType(decl_ctx_die);
if (class_type) {
- if (class_type->GetID() != decl_ctx_die.GetID() ||
- IsClangModuleFwdDecl(decl_ctx_die)) {
-
- // We uniqued the parent class of this function to another
- // class so we now need to associate all dies under
- // "decl_ctx_die" to DIEs in the DIE for "class_type"...
- DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID());
-
- if (class_type_die) {
- std::vector<DWARFDIE> failures;
-
- CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die,
- class_type, failures);
-
- // FIXME do something with these failures that's
- // smarter than just dropping them on the ground.
- // Unfortunately classes don't like having stuff added
- // to them after their definitions are complete...
-
- Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
- if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
- return type_ptr->shared_from_this();
- }
- }
- }
-
if (attrs.specification.IsValid()) {
// We have a specification which we are going to base our
// function prototype off of, so we need this type to be
@@ -1260,6 +1243,39 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
}
}
}
+ // By here, we should have already completed the c++ class_type
+ // because if either specification or abstract_origin is present, we
+ // call GetClangDeclContextForDIE to resolve the DW_TAG_subprogram
+ // refered by this one until we reached the DW_TAG_subprogram without
+ // specification or abstract_origin (the else branch above). Then the
+ // above GetFullCompilerType() will complete the class_type if it's
+ // not completed yet. After that, we will have the mapping from DIEs
+ // in class_type_die to DeclContexts in m_die_to_decl_ctx.
+ if (class_type->GetID() != decl_ctx_die.GetID() ||
+ IsClangModuleFwdDecl(decl_ctx_die)) {
+
+ // We uniqued the parent class of this function to another
+ // class so we now need to associate all dies under
+ // "decl_ctx_die" to DIEs in the DIE for "class_type"...
+ DWARFDIE class_type_die = dwarf->GetDIE(class_type->GetID());
+
+ if (class_type_die) {
+ std::vector<DWARFDIE> failures;
+
+ CopyUniqueClassMethodTypes(decl_ctx_die, class_type_die,
+ class_type, failures);
+
+ // FIXME do something with these failures that's
+ // smarter than just dropping them on the ground.
+ // Unfortunately classes don't like having stuff added
+ // to them after their definitions are complete...
+
+ Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
+ if (type_ptr && type_ptr != DIE_IS_BEING_PARSED) {
+ return type_ptr->shared_from_this();
+ }
+ }
+ }
}
}
}
@@ -1651,6 +1667,7 @@ 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.name) {
if (Language::LanguageIsCPlusPlus(cu_language)) {
@@ -1664,13 +1681,34 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
}
if (dwarf->GetUniqueDWARFASTTypeMap().Find(
- unique_typename, die, unique_decl, attrs.byte_size.value_or(-1),
- *unique_ast_entry_up)) {
+ unique_typename, die, unique_decl, byte_size,
+ attrs.is_forward_declaration, *unique_ast_entry_up)) {
type_sp = unique_ast_entry_up->m_type_sp;
if (type_sp) {
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
LinkDeclContextToDIE(
GetCachedClangDeclContextForDIE(unique_ast_entry_up->m_die), die);
+ if (!attrs.is_forward_declaration) {
+ dwarf->GetDeclarationDIEToDefinitionDIE().try_emplace(
+ unique_ast_entry_up->m_die.GetDIE(), *die.GetDIERef());
+ // If the parameter DIE is definition and the entry in the map is
+ // declaration, then we need to update the entry to point to the
+ // definition DIE.
+ if (unique_ast_entry_up->m_is_forward_declaration) {
+ unique_ast_entry_up->m_die = die;
+ unique_ast_entry_up->m_byte_size = byte_size;
+ unique_ast_entry_up->m_declaration = unique_decl;
+ unique_ast_entry_up->m_is_forward_declaration = false;
+ // Need to update Type ID to refer to the definition DIE. because
+ // it's used in ParseSubroutine to determine if we need to copy cxx
+ // method types from a declaration DIE to this definition DIE.
+ type_sp->SetID(die.GetID());
+ if (attrs.class_language != eLanguageTypeObjC &&
+ attrs.class_language != eLanguageTypeObjC_plus_plus)
+ TypeSystemClang::StartTagDeclarationDefinition(
+ type_sp->GetForwardCompilerType());
+ }
+ }
return type_sp;
}
}
@@ -1707,112 +1745,22 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
attrs.is_forward_declaration = true;
}
- if (attrs.class_language == eLanguageTypeObjC ||
- attrs.class_language == eLanguageTypeObjC_plus_plus) {
- if (!attrs.is_complete_objc_class &&
- die.Supports_DW_AT_APPLE_objc_complete_type()) {
- // 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
- // is_complete_objc_class above and know it is false), so the real
- // definition is in here somewhere
- type_sp =
- dwarf->FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true);
-
- if (!type_sp) {
- SymbolFileDWARFDebugMap *debug_map_symfile =
- dwarf->GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We weren't able to find a full declaration in this DWARF,
- // see if we have a declaration anywhere else...
- type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
- die, attrs.name, true);
- }
- }
-
- if (type_sp) {
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF({0:p}) - {1:x16}: {2} type "
- "\"{3}\" is an "
- "incomplete objc type, complete type is {4:x8}",
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), attrs.name.GetCString(),
- type_sp->GetID());
- }
-
- // We found a real definition for this type elsewhere so lets use
- // it and cache the fact that we found a complete type for this
- // die
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- return type_sp;
- }
- }
- }
-
if (attrs.is_forward_declaration) {
- // We have a forward declaration to a type and we need to try and
- // find a full declaration. We look in the current type index just in
- // case we have a forward declaration followed by an actual
- // declarations in the DWARF. If this fails, we need to look
- // elsewhere...
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF({0:p}) - {1:x16}: {2} type \"{3}\" is a "
- "forward declaration, trying to find complete type",
- static_cast<void *>(this), die.GetOffset(), DW_TAG_value_to_name(tag),
- attrs.name.GetCString());
- }
-
// See if the type comes from a Clang module and if so, track down
// that type.
type_sp = ParseTypeFromClangModule(sc, die, log);
if (type_sp)
return type_sp;
-
- // type_sp = FindDefinitionTypeForDIE (dwarf_cu, die,
- // type_name_const_str);
- type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die);
-
- if (!type_sp) {
- SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We weren't able to find a full declaration in this DWARF, see
- // if we have a declaration anywhere else...
- type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(die);
- }
- }
-
- if (type_sp) {
- if (log) {
- dwarf->GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF({0:p}) - {1:x16}: {2} type \"{3}\" is a "
- "forward declaration, complete type is {4:x8}",
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), attrs.name.GetCString(),
- type_sp->GetID());
- }
-
- // We found a real definition for this type elsewhere so lets use
- // it and cache the fact that we found a complete type for this die
- dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
- clang::DeclContext *defn_decl_ctx =
- GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
- if (defn_decl_ctx)
- LinkDeclContextToDIE(defn_decl_ctx, die);
- return type_sp;
- }
}
+
assert(tag_decl_kind != -1);
UNUSED_IF_ASSERT_DISABLED(tag_decl_kind);
- bool clang_type_was_created = false;
- clang::DeclContext *decl_ctx = GetClangDeclContextContainingDIE(die, nullptr);
+ DWARFDIE decl_ctx_die;
+ clang::DeclContext *decl_ctx =
+ GetClangDeclContextContainingDIE(die, &decl_ctx_die);
- PrepareContextToReceiveMembers(m_ast, GetClangASTImporter(), decl_ctx, die,
- attrs.name.GetCString());
+ PrepareContextToReceiveMembers(m_ast, GetClangASTImporter(), decl_ctx,
+ decl_ctx_die, die, attrs.name.GetCString());
if (attrs.accessibility == eAccessNone && decl_ctx) {
// Check the decl context that contains this class/struct/union. If
@@ -1850,20 +1798,20 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
tag_decl_kind, template_param_infos);
clang_type =
m_ast.CreateClassTemplateSpecializationType(class_specialization_decl);
- clang_type_was_created = true;
m_ast.SetMetadata(class_template_decl, metadata);
m_ast.SetMetadata(class_specialization_decl, metadata);
}
- if (!clang_type_was_created) {
- clang_type_was_created = true;
+ if (!clang_type) {
clang_type = m_ast.CreateRecordType(
decl_ctx, GetOwningClangModule(die), attrs.accessibility,
attrs.name.GetCString(), tag_decl_kind, attrs.class_language, &metadata,
attrs.exports_symbols);
}
-
+ if (!attrs.is_forward_declaration)
+ dwarf->GetDeclarationDIEToDefinitionDIE().try_emplace(die.GetDIE(),
+ *die.GetDIERef());
// Store a forward declaration to this class type in case any
// parameters in any class methods need it for the clang types for
// function prototypes.
@@ -1880,7 +1828,8 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
unique_ast_entry_up->m_type_sp = type_sp;
unique_ast_entry_up->m_die = die;
unique_ast_entry_up->m_declaration = unique_decl;
- unique_ast_entry_up->m_byte_size = attrs.byte_size.value_or(0);
+ unique_ast_entry_up->m_byte_size = byte_size;
+ unique_ast_entry_up->m_is_forward_declaration = attrs.is_forward_declaration;
dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,
*unique_ast_entry_up);
@@ -1921,38 +1870,33 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
GetClangASTImporter().SetRecordLayout(record_decl, layout);
}
}
- } else if (clang_type_was_created) {
- // Start the definition if the class is not objective C since the
- // underlying decls respond to isCompleteDefinition(). Objective
- // C decls don't respond to isCompleteDefinition() so we can't
- // start the declaration definition right away. For C++
- // class/union/structs we want to start the definition in case the
- // class is needed as the declaration context for a contained class
- // or type without the need to complete that type..
-
- if (attrs.class_language != eLanguageTypeObjC &&
- attrs.class_language != eLanguageTypeObjC_plus_plus)
- TypeSystemClang::StartTagDeclarationDefinition(clang_type);
-
- // Leave this as a forward declaration until we need to know the
- // details of the type. lldb_private::Type will automatically call
- // the SymbolFile virtual function
- // "SymbolFileDWARF::CompleteType(Type *)" When the definition
- // needs to be defined.
- assert(!dwarf->GetForwardDeclCompilerTypeToDIE().count(
- ClangUtil::RemoveFastQualifiers(clang_type)
- .GetOpaqueQualType()) &&
- "Type already in the forward declaration map!");
- // Can't assume m_ast.GetSymbolFile() is actually a
- // SymbolFileDWARF, it can be a SymbolFileDWARFDebugMap for Apple
- // binaries.
- dwarf->GetForwardDeclCompilerTypeToDIE().try_emplace(
- ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType(),
- *die.GetDIERef());
- m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
}
+ // Start the definition if the class is not objective C since the
+ // underlying decls respond to isCompleteDefinition(). Objective
+ // C decls don't respond to isCompleteDefinition() so we can't
+ // start the declaration definition right away. For C++
+ // class/union/structs we want to start the definition in case the
+ // class is needed as the declaration context for a contained class
+ // or type without the need to complete that type..
+
+ if (attrs.class_language != eLanguageTypeObjC &&
+ attrs.class_language != eLanguageTypeObjC_plus_plus)
+ TypeSystemClang::StartTagDeclarationDefinition(clang_type);
}
+ // Leave this as a forward declaration until we need to know the
+ // details of the type. lldb_private::Type will automatically call
+ // the SymbolFile virtual function
+ // "SymbolFileDWARF::CompleteType(Type *)" When the definition
+ // needs to be defined.
+ assert(!dwarf->GetForwardDeclCompilerTypeToDIE().count(
+ ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()) &&
+ "Type already in the forward declaration map!");
+ dwarf->GetForwardDeclCompilerTypeToDIE().try_emplace(
+ ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType(),
+ *die.GetDIERef());
+ m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true);
+
// If we made a clang type, set the trivial abi if applicable: We only
// do this for pass by value - which implies the Trivial ABI. There
// isn't a way to assert that something that would normally be pass by
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 49f13d2c89e38..5a317db7e7402 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1631,13 +1631,19 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
return true;
}
- DWARFDIE dwarf_die = GetDIE(die_it->getSecond());
+ DWARFDIE dwarf_die = FindDefinitionDIE(GetDIE(die_it->getSecond()));
if (dwarf_die) {
// Once we start resolving this type, remove it from the forward
// declaration map in case anyone child members or other types require this
// type to get resolved. The type will get resolved when all of the calls
// to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition are done.
- GetForwardDeclCompilerTypeToDIE().erase(die_it);
+ // Need to get a new iterator because FindDefinitionDIE might add new
+ // entries into the map and invalidate previous iterator.
+ auto die_it = GetForwardDeclCompilerTypeToDIE().find(
+ compiler_type_no_qualifiers.GetOpaqueQualType());
+ if (die_it != GetForwardDeclCompilerTypeToDIE().end()) {
+ GetForwardDeclCompilerTypeToDIE().erase(die_it);
+ }
Type *type = GetDIEToType().lookup(dwarf_die.GetDIE());
@@ -1654,6 +1660,101 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
return false;
}
+DWARFDIE SymbolFileDWARF::FindDefinitionDIE(const DWARFDIE &die) {
+ auto def_die_it = GetDeclarationDIEToDefinitionDIE().find(die.GetDIE());
+ if (def_die_it != GetDeclarationDIEToDefinitionDIE().end())
+ return GetDIE(def_die_it->getSecond());
+
+ ParsedDWARFTypeAttributes attrs(die);
+ const dw_tag_t tag = die.Tag();
+ TypeSP type_sp;
+ Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
+ if (log) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF({0:p}) - {1:x16}: {2} type \"{3}\" is a "
+ "forward declaration DIE, trying to find definition DIE",
+ static_cast<void *>(this), die.GetOffset(), DW_TAG_value_to_name(tag),
+ attrs.name.GetCString());
+ }
+ // We haven't parse definition die for this type, starting to search for it.
+ // After we found the definition die, the GetDeclarationDIEToDefinitionDIE()
+ // map will have the new mapping from this declaration die to definition die.
+ if (attrs.class_language == eLanguageTypeObjC ||
+ attrs.class_language == eLanguageTypeObjC_plus_plus) {
+ if (!attrs.is_complete_objc_class &&
+ die.Supports_DW_AT_APPLE_objc_complete_type()) {
+ // 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
+ // is_complete_objc_class above and know it is false), so the real
+ // definition is in here somewhere
+ type_sp =
+ FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true);
+
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile =
+ GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in this DWARF,
+ // see if we have a declaration anywhere else...
+ type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
+ die, attrs.name, true);
+ }
+ }
+
+ if (type_sp && log) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF({0:p}) - {1:x16}: {2} type "
+ "\"{3}\" is an "
+ "incomplete objc type, complete type is {4:x8}",
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), attrs.name.GetCString(),
+ type_sp->GetID());
+ }
+ }
+ }
+ bool is_forward_declaration =
+ attrs.is_forward_declaration ||
+ (attrs.byte_size && *attrs.byte_size == 0 && attrs.name &&
+ !die.HasChildren() &&
+ SymbolFileDWARF::GetLanguage(*die.GetCU()) == eLanguageTypeObjC);
+ if (is_forward_declaration) {
+ type_sp = FindDefinitionTypeForDWARFDeclContext(die);
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in this DWARF, see
+ // if we have a declaration anywhere else...
+ type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(die);
+ }
+ if (type_sp && log) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF({0:p}) - {1:x16}: {2} type \"{3}\" is a "
+ "forward declaration, complete type is {4:x8}",
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), attrs.name.GetCString(),
+ type_sp->GetID());
+ }
+ }
+ }
+ def_die_it = GetDeclarationDIEToDefinitionDIE().find(die.GetDIE());
+ if (def_die_it != GetDeclarationDIEToDefinitionDIE().end())
+ return GetDIE(def_die_it->getSecond());
+
+ if (log) {
+ GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF({0:p}) - {1:x16}: {2} type \"{3}\" is a "
+ "forward declaration, unable to find definition DIE for it",
+ static_cast<void *>(this), die.GetOffset(), DW_TAG_value_to_name(tag),
+ attrs.name.GetCString());
+ }
+ return DWARFDIE();
+}
+
Type *SymbolFileDWARF::ResolveType(const DWARFDIE &die,
bool assert_not_being_parsed,
bool resolve_function_context) {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 7282c08c6857c..86d5a3d4f6c46 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -182,6 +182,8 @@ class SymbolFileDWARF : public SymbolFileCommon {
void FindFunctions(const RegularExpression ®ex, bool include_inlines,
SymbolContextList &sc_list) override;
+ DWARFDIE FindDefinitionDIE(const DWARFDIE &die);
+
void
GetMangledNamesForFunction(const std::string &scope_qualified_name,
std::vector<ConstString> &mangled_names) override;
@@ -342,6 +344,11 @@ class SymbolFileDWARF : public SymbolFileCommon {
return m_forward_decl_compiler_type_to_die;
}
+ typedef llvm::DenseMap<const DWARFDebugInfoEntry *, DIERef> DIEToDIE;
+ virtual DIEToDIE &GetDeclarationDIEToDefinitionDIE() {
+ return m_die_to_def_die;
+ }
+
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP>
DIEToVariableSP;
@@ -533,9 +540,16 @@ class SymbolFileDWARF : public SymbolFileCommon {
NameToOffsetMap m_function_scope_qualified_name_map;
std::unique_ptr<DWARFDebugRanges> m_ranges;
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;
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.
CompilerTypeToDIE m_forward_decl_compiler_type_to_die;
+ // A map from a struct/class/union/enum DIE (might be a declaration or a
+ // definition) to its definition DIE.
+ DIEToDIE m_die_to_def_die;
llvm::DenseMap<dw_offset_t, std::unique_ptr<SupportFileList>>
m_type_unit_support_files;
std::vector<uint32_t> m_lldb_cu_to_dwarf_unit;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index 85e1afd0d8976..cb5ec4ae026b3 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -110,6 +110,11 @@ SymbolFileDWARF::DIEToVariableSP &SymbolFileDWARFDwo::GetDIEToVariable() {
return GetBaseSymbolFile().GetDIEToVariable();
}
+SymbolFileDWARF::DIEToDIE &
+SymbolFileDWARFDwo::GetDeclarationDIEToDefinitionDIE() {
+ return GetBaseSymbolFile().GetDeclarationDIEToDefinitionDIE();
+}
+
SymbolFileDWARF::CompilerTypeToDIE &
SymbolFileDWARFDwo::GetForwardDeclCompilerTypeToDIE() {
return GetBaseSymbolFile().GetForwardDeclCompilerTypeToDIE();
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index 1500540424b52..3e8cfb885aaee 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -74,6 +74,8 @@ class SymbolFileDWARFDwo : public SymbolFileDWARF {
CompilerTypeToDIE &GetForwardDeclCompilerTypeToDIE() override;
+ DIEToDIE &GetDeclarationDIEToDefinitionDIE() override;
+
UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap() override;
lldb::TypeSP
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
index 223518f0ae824..cc23bb86f6805 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
@@ -16,60 +16,65 @@ using namespace lldb_private::plugin::dwarf;
bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die,
const lldb_private::Declaration &decl,
const int32_t byte_size,
+ bool is_forward_declaration,
UniqueDWARFASTType &entry) const {
for (const UniqueDWARFASTType &udt : m_collection) {
// Make sure the tags match
if (udt.m_die.Tag() == die.Tag()) {
- // Validate byte sizes of both types only if both are valid.
- if (udt.m_byte_size < 0 || byte_size < 0 ||
- udt.m_byte_size == byte_size) {
- // Make sure the file and line match
- if (udt.m_declaration == decl) {
- // The type has the same name, and was defined on the same file and
- // line. Now verify all of the parent DIEs match.
- DWARFDIE parent_arg_die = die.GetParent();
- DWARFDIE parent_pos_die = udt.m_die.GetParent();
- bool match = true;
- bool done = false;
- while (!done && match && parent_arg_die && parent_pos_die) {
- const dw_tag_t parent_arg_tag = parent_arg_die.Tag();
- const dw_tag_t parent_pos_tag = parent_pos_die.Tag();
- if (parent_arg_tag == parent_pos_tag) {
- switch (parent_arg_tag) {
- case DW_TAG_class_type:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_namespace: {
- const char *parent_arg_die_name = parent_arg_die.GetName();
- if (parent_arg_die_name ==
- nullptr) // Anonymous (i.e. no-name) struct
- {
+ // If they are not both definition DIEs or both declaration DIEs, then
+ // don't check for byte size and declaration location, because declaration
+ // DIEs usually don't have those info.
+ bool matching_size_declaration =
+ udt.m_is_forward_declaration != is_forward_declaration
+ ? true
+ : (udt.m_byte_size < 0 || byte_size < 0 ||
+ udt.m_byte_size == byte_size) &&
+ udt.m_declaration == decl;
+ if (matching_size_declaration) {
+ // The type has the same name, and was defined on the same file and
+ // line. Now verify all of the parent DIEs match.
+ DWARFDIE parent_arg_die = die.GetParent();
+ DWARFDIE parent_pos_die = udt.m_die.GetParent();
+ bool match = true;
+ bool done = false;
+ while (!done && match && parent_arg_die && parent_pos_die) {
+ const dw_tag_t parent_arg_tag = parent_arg_die.Tag();
+ const dw_tag_t parent_pos_tag = parent_pos_die.Tag();
+ if (parent_arg_tag == parent_pos_tag) {
+ switch (parent_arg_tag) {
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_namespace: {
+ const char *parent_arg_die_name = parent_arg_die.GetName();
+ if (parent_arg_die_name ==
+ nullptr) // Anonymous (i.e. no-name) struct
+ {
+ match = false;
+ } else {
+ const char *parent_pos_die_name = parent_pos_die.GetName();
+ if (parent_pos_die_name == nullptr ||
+ ((parent_arg_die_name != parent_pos_die_name) &&
+ strcmp(parent_arg_die_name, parent_pos_die_name)))
match = false;
- } else {
- const char *parent_pos_die_name = parent_pos_die.GetName();
- if (parent_pos_die_name == nullptr ||
- ((parent_arg_die_name != parent_pos_die_name) &&
- strcmp(parent_arg_die_name, parent_pos_die_name)))
- match = false;
- }
- } break;
-
- case DW_TAG_compile_unit:
- case DW_TAG_partial_unit:
- done = true;
- break;
- default:
- break;
}
+ } break;
+
+ case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
+ done = true;
+ break;
+ default:
+ break;
}
- parent_arg_die = parent_arg_die.GetParent();
- parent_pos_die = parent_pos_die.GetParent();
}
+ parent_arg_die = parent_arg_die.GetParent();
+ parent_pos_die = parent_pos_die.GetParent();
+ }
- if (match) {
- entry = udt;
- return true;
- }
+ if (match) {
+ entry = udt;
+ return true;
}
}
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
index bf3cbae55e5c7..94619953d07ac 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
@@ -24,13 +24,16 @@ class UniqueDWARFASTType {
UniqueDWARFASTType() : m_type_sp(), m_die(), m_declaration() {}
UniqueDWARFASTType(lldb::TypeSP &type_sp, const DWARFDIE &die,
- const Declaration &decl, int32_t byte_size)
+ const Declaration &decl, int32_t byte_size,
+ bool is_forward_declaration)
: m_type_sp(type_sp), m_die(die), m_declaration(decl),
- m_byte_size(byte_size) {}
+ m_byte_size(byte_size),
+ m_is_forward_declaration(is_forward_declaration) {}
UniqueDWARFASTType(const UniqueDWARFASTType &rhs)
: m_type_sp(rhs.m_type_sp), m_die(rhs.m_die),
- m_declaration(rhs.m_declaration), m_byte_size(rhs.m_byte_size) {}
+ m_declaration(rhs.m_declaration), m_byte_size(rhs.m_byte_size),
+ m_is_forward_declaration(rhs.m_is_forward_declaration) {}
~UniqueDWARFASTType() = default;
@@ -40,6 +43,7 @@ class UniqueDWARFASTType {
m_die = rhs.m_die;
m_declaration = rhs.m_declaration;
m_byte_size = rhs.m_byte_size;
+ m_is_forward_declaration = rhs.m_is_forward_declaration;
}
return *this;
}
@@ -48,6 +52,8 @@ class UniqueDWARFASTType {
DWARFDIE m_die;
Declaration m_declaration;
int32_t m_byte_size = -1;
+ // True if the m_die is a forward declaration DIE.
+ bool m_is_forward_declaration = true;
};
class UniqueDWARFASTTypeList {
@@ -63,7 +69,8 @@ class UniqueDWARFASTTypeList {
}
bool Find(const DWARFDIE &die, const Declaration &decl,
- const int32_t byte_size, UniqueDWARFASTType &entry) const;
+ const int32_t byte_size, bool is_forward_declaration,
+ UniqueDWARFASTType &entry) const;
protected:
typedef std::vector<UniqueDWARFASTType> collection;
@@ -81,11 +88,13 @@ class UniqueDWARFASTTypeMap {
}
bool Find(ConstString name, const DWARFDIE &die, const Declaration &decl,
- const int32_t byte_size, UniqueDWARFASTType &entry) const {
+ const int32_t byte_size, bool is_forward_declaration,
+ UniqueDWARFASTType &entry) const {
const char *unique_name_cstr = name.GetCString();
collection::const_iterator pos = m_collection.find(unique_name_cstr);
if (pos != m_collection.end()) {
- return pos->second.Find(die, decl, byte_size, entry);
+ return pos->second.Find(die, decl, byte_size, is_forward_declaration,
+ entry);
}
return false;
}
>From 751a58d24ec9e32234d2bfa672f51d255bfd78fa Mon Sep 17 00:00:00 2001
From: Zequan Wu <zequanwu at google.com>
Date: Wed, 1 May 2024 10:25:28 -0400
Subject: [PATCH 2/7] fix format
---
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 5a317db7e7402..c7069550ccf70 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1689,12 +1689,10 @@ DWARFDIE SymbolFileDWARF::FindDefinitionDIE(const DWARFDIE &die) {
// and this DIE isn't the complete definition (we checked
// is_complete_objc_class above and know it is false), so the real
// definition is in here somewhere
- type_sp =
- FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true);
+ type_sp = FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true);
if (!type_sp) {
- SymbolFileDWARFDebugMap *debug_map_symfile =
- GetDebugMapSymfile();
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
if (debug_map_symfile) {
// We weren't able to find a full declaration in this DWARF,
// see if we have a declaration anywhere else...
>From c0a539ec9b3b468e5568cd6f569f51663fdafcac Mon Sep 17 00:00:00 2001
From: Zequan Wu <zequanwu at google.com>
Date: Thu, 2 May 2024 14:08:11 -0400
Subject: [PATCH 3/7] address comments
---
.../Plugins/SymbolFile/DWARF/DWARFASTParser.h | 6 +
.../SymbolFile/DWARF/DWARFASTParserClang.cpp | 166 ++++++++++++++----
.../SymbolFile/DWARF/DWARFASTParserClang.h | 10 ++
.../SymbolFile/DWARF/SymbolFileDWARF.cpp | 146 ++++-----------
.../SymbolFile/DWARF/SymbolFileDWARF.h | 10 --
.../SymbolFile/DWARF/SymbolFileDWARFDwo.cpp | 5 -
.../SymbolFile/DWARF/SymbolFileDWARFDwo.h | 2 -
7 files changed, 179 insertions(+), 166 deletions(-)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index 66db396279e06..14b9cba05d321 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -60,6 +60,12 @@ class DWARFASTParser {
virtual ConstString GetDIEClassTemplateParams(const DWARFDIE &die) = 0;
+ // Return true if we found the definition DIE for it. is_forward_declaration
+ // is set to true if the parameter die is a declaration.
+ virtual bool
+ FindDefinitionDIE(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ bool &is_forward_declaration) = 0;
+
static std::optional<SymbolFile::ArrayInfo>
ParseChildArrayInfo(const DWARFDIE &parent_die,
const ExecutionContext *exe_ctx = nullptr);
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 7ad661c9a9d49..8a8c303e1a8b2 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -154,6 +154,27 @@ static bool TagIsRecordType(dw_tag_t tag) {
}
}
+static bool
+IsForwardDeclaration(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ const ParsedDWARFTypeAttributes &attrs,
+ LanguageType cu_language) {
+ 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.
+ return true;
+ }
+ return attrs.is_forward_declaration;
+}
+
TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
const DWARFDIE &die,
Log *log) {
@@ -249,12 +270,10 @@ static void ForcefullyCompleteType(CompilerType type) {
/// This function serves a similar purpose as RequireCompleteType above, but it
/// avoids completing the type if it is not immediately necessary. It only
/// ensures we _can_ complete the type later.
-static void PrepareContextToReceiveMembers(TypeSystemClang &ast,
- ClangASTImporter &ast_importer,
- clang::DeclContext *decl_ctx,
- const DWARFDIE &decl_ctx_die,
- const DWARFDIE &die,
- const char *type_name_cstr) {
+void DWARFASTParserClang::PrepareContextToReceiveMembers(
+ TypeSystemClang &ast, clang::DeclContext *decl_ctx,
+ const DWARFDIE &decl_ctx_die, const DWARFDIE &die,
+ const char *type_name_cstr) {
auto *tag_decl_ctx = clang::dyn_cast<clang::TagDecl>(decl_ctx);
if (!tag_decl_ctx)
return; // Non-tag context are always ready.
@@ -270,6 +289,7 @@ static void PrepareContextToReceiveMembers(TypeSystemClang &ast,
// If this type was not imported from an external AST, there's nothing to do.
CompilerType type = ast.GetTypeForDecl(tag_decl_ctx);
+ ClangASTImporter &ast_importer = GetClangASTImporter();
if (type && ast_importer.CanImport(type)) {
auto qual_type = ClangUtil::GetQualType(type);
if (ast_importer.RequireCompleteType(qual_type))
@@ -284,7 +304,8 @@ static void PrepareContextToReceiveMembers(TypeSystemClang &ast,
// 1. Found the the definition DIE and start its definition with
// TypeSystemClang::StartTagDeclarationDefinition.
// 2. Unable to find it, then need to forcefully complete it.
- die.GetDWARF()->FindDefinitionDIE(decl_ctx_die);
+ bool is_forward_declaration = false;
+ FindDefinitionDIE(decl_ctx_die, is_forward_declaration);
if (tag_decl_ctx->isCompleteDefinition() || tag_decl_ctx->isBeingDefined())
return;
// We don't have a type definition and/or the import failed. We must
@@ -631,8 +652,8 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
DWARFDIE decl_ctx_die;
clang::DeclContext *decl_ctx =
GetClangDeclContextContainingDIE(die, &decl_ctx_die);
- PrepareContextToReceiveMembers(m_ast, GetClangASTImporter(), decl_ctx,
- decl_ctx_die, die, attrs.name.GetCString());
+ PrepareContextToReceiveMembers(m_ast, decl_ctx, decl_ctx_die, die,
+ attrs.name.GetCString());
if (attrs.type.IsValid()) {
// Try to parse a typedef from the (DWARF embedded in the) Clang
@@ -1648,6 +1669,96 @@ DWARFASTParserClang::GetCPlusPlusQualifiedName(const DWARFDIE &die) {
return qualified_name;
}
+bool DWARFASTParserClang::FindDefinitionDIE(const DWARFDIE &die,
+ bool &is_forward_declaration) {
+ ParsedDWARFTypeAttributes attrs(die);
+ is_forward_declaration = IsForwardDeclaration(
+ die, attrs, SymbolFileDWARF::GetLanguage(*die.GetCU()));
+ if (!is_forward_declaration)
+ return true;
+
+ const dw_tag_t tag = die.Tag();
+ TypeSP type_sp;
+ SymbolFileDWARF *dwarf = die.GetDWARF();
+ Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF({0:p}) - {1:x16}: {2} type \"{3}\" is a "
+ "forward declaration DIE, trying to find definition DIE",
+ static_cast<void *>(this), die.GetOffset(), DW_TAG_value_to_name(tag),
+ attrs.name.GetCString());
+ }
+ // We haven't parse definition die for this type, starting to search for it.
+ // After we found the definition die, the GetDeclarationDIEToDefinitionDIE()
+ // map will have the new mapping from this declaration die to definition die.
+ if (attrs.class_language == eLanguageTypeObjC ||
+ attrs.class_language == eLanguageTypeObjC_plus_plus) {
+ if (!attrs.is_complete_objc_class &&
+ die.Supports_DW_AT_APPLE_objc_complete_type()) {
+ // 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
+ // is_complete_objc_class above and know it is false), so the real
+ // definition is in here somewhere
+ type_sp =
+ dwarf->FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true);
+
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile =
+ dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in this DWARF,
+ // see if we have a declaration anywhere else...
+ type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
+ die, attrs.name, true);
+ }
+ }
+
+ if (type_sp && log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF({0:p}) - {1:x16}: {2} type "
+ "\"{3}\" is an "
+ "incomplete objc type, complete type is {4:x8}",
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), attrs.name.GetCString(),
+ type_sp->GetID());
+ }
+ }
+ }
+
+ type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die);
+ if (!type_sp) {
+ SymbolFileDWARFDebugMap *debug_map_symfile = dwarf->GetDebugMapSymfile();
+ if (debug_map_symfile) {
+ // We weren't able to find a full declaration in this DWARF, see
+ // if we have a declaration anywhere else...
+ type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(die);
+ }
+ if (type_sp && log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF({0:p}) - {1:x16}: {2} type \"{3}\" is a "
+ "forward declaration, complete type is {4:x8}",
+ static_cast<void *>(this), die.GetOffset(), DW_TAG_value_to_name(tag),
+ attrs.name.GetCString(), type_sp->GetID());
+ }
+ }
+ if (type_sp)
+ return true;
+
+ if (log) {
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF({0:p}) - {1:x16}: {2} type \"{3}\" is a "
+ "forward declaration, unable to find definition DIE for it",
+ static_cast<void *>(this), die.GetOffset(), DW_TAG_value_to_name(tag),
+ attrs.name.GetCString());
+ }
+ return false;
+}
+
TypeSP
DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
const DWARFDIE &die,
@@ -1668,6 +1779,7 @@ 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);
+ attrs.is_forward_declaration = IsForwardDeclaration(die, attrs, cu_language);
if (attrs.name) {
if (Language::LanguageIsCPlusPlus(cu_language)) {
@@ -1689,8 +1801,6 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
LinkDeclContextToDIE(
GetCachedClangDeclContextForDIE(unique_ast_entry_up->m_die), die);
if (!attrs.is_forward_declaration) {
- dwarf->GetDeclarationDIEToDefinitionDIE().try_emplace(
- unique_ast_entry_up->m_die.GetDIE(), *die.GetDIERef());
// If the parameter DIE is definition and the entry in the map is
// declaration, then we need to update the entry to point to the
// definition DIE.
@@ -1703,10 +1813,18 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
// it's used in ParseSubroutine to determine if we need to copy cxx
// method types from a declaration DIE to this definition DIE.
type_sp->SetID(die.GetID());
+ clang_type = type_sp->GetForwardCompilerType();
if (attrs.class_language != eLanguageTypeObjC &&
attrs.class_language != eLanguageTypeObjC_plus_plus)
- TypeSystemClang::StartTagDeclarationDefinition(
- type_sp->GetForwardCompilerType());
+ TypeSystemClang::StartTagDeclarationDefinition(clang_type);
+
+ CompilerType compiler_type_no_qualifiers =
+ ClangUtil::RemoveFastQualifiers(clang_type);
+ auto result = dwarf->GetForwardDeclCompilerTypeToDIE().try_emplace(
+ compiler_type_no_qualifiers.GetOpaqueQualType(),
+ *die.GetDIERef());
+ if (!result.second)
+ result.first->second = *die.GetDIERef();
}
}
return type_sp;
@@ -1730,21 +1848,6 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
default_accessibility = eAccessPrivate;
}
- 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.is_forward_declaration) {
// See if the type comes from a Clang module and if so, track down
// that type.
@@ -1759,8 +1862,8 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
clang::DeclContext *decl_ctx =
GetClangDeclContextContainingDIE(die, &decl_ctx_die);
- PrepareContextToReceiveMembers(m_ast, GetClangASTImporter(), decl_ctx,
- decl_ctx_die, die, attrs.name.GetCString());
+ PrepareContextToReceiveMembers(m_ast, decl_ctx, decl_ctx_die, die,
+ attrs.name.GetCString());
if (attrs.accessibility == eAccessNone && decl_ctx) {
// Check the decl context that contains this class/struct/union. If
@@ -1809,9 +1912,6 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
attrs.name.GetCString(), tag_decl_kind, attrs.class_language, &metadata,
attrs.exports_symbols);
}
- if (!attrs.is_forward_declaration)
- dwarf->GetDeclarationDIEToDefinitionDIE().try_emplace(die.GetDIE(),
- *die.GetDIERef());
// Store a forward declaration to this class type in case any
// parameters in any class methods need it for the clang types for
// function prototypes.
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 8d4af203bb287..b884d6869add8 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -108,6 +108,9 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
lldb_private::ConstString GetDIEClassTemplateParams(
const lldb_private::plugin::dwarf::DWARFDIE &die) override;
+ bool FindDefinitionDIE(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ bool &is_forward_declaration) override;
+
protected:
/// Protected typedefs and members.
/// @{
@@ -246,6 +249,13 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
lldb::ModuleSP
GetModuleForType(const lldb_private::plugin::dwarf::DWARFDIE &die);
+ void PrepareContextToReceiveMembers(
+ lldb_private::TypeSystemClang &ast,
+ clang::DeclContext *decl_ctx,
+ const lldb_private::plugin::dwarf::DWARFDIE &decl_ctx_die,
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ const char *type_name_cstr);
+
static bool classof(const DWARFASTParser *Parser) {
return Parser->GetKind() == Kind::DWARFASTParserClang;
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index c7069550ccf70..d2f66b00c1794 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1631,126 +1631,40 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
return true;
}
- DWARFDIE dwarf_die = FindDefinitionDIE(GetDIE(die_it->getSecond()));
- if (dwarf_die) {
- // Once we start resolving this type, remove it from the forward
- // declaration map in case anyone child members or other types require this
- // type to get resolved. The type will get resolved when all of the calls
- // to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition are done.
- // Need to get a new iterator because FindDefinitionDIE might add new
- // entries into the map and invalidate previous iterator.
- auto die_it = GetForwardDeclCompilerTypeToDIE().find(
- compiler_type_no_qualifiers.GetOpaqueQualType());
- if (die_it != GetForwardDeclCompilerTypeToDIE().end()) {
- GetForwardDeclCompilerTypeToDIE().erase(die_it);
- }
-
- Type *type = GetDIEToType().lookup(dwarf_die.GetDIE());
+ // Once we start resolving this type, remove it from the forward
+ // declaration map in case anyone child members or other types require this
+ // type to get resolved.
+ DWARFDIE dwarf_die = GetDIE(die_it->second);
+ GetForwardDeclCompilerTypeToDIE().erase(die_it);
+ // The DWARFASTParser might determine if this is a declaration or not with
+ // information other than DW_AT_declaration depending on the language.
+ bool is_forward_declaration = false;
+ bool found_def_die = false;
+ if (DWARFASTParser *dwarf_ast = GetDWARFParser(*dwarf_die.GetCU()))
+ found_def_die =
+ dwarf_ast->FindDefinitionDIE(dwarf_die, is_forward_declaration);
+ if (!found_def_die)
+ return false;
- Log *log = GetLog(DWARFLog::DebugInfo | DWARFLog::TypeCompletion);
- if (log)
- GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
- log, "{0:x8}: {1} '{2}' resolving forward declaration...",
- dwarf_die.GetID(), dwarf_die.GetTagAsCString(),
- type->GetName().AsCString());
- assert(compiler_type);
- if (DWARFASTParser *dwarf_ast = GetDWARFParser(*dwarf_die.GetCU()))
- return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type, compiler_type);
+ die_it = GetForwardDeclCompilerTypeToDIE().find(
+ compiler_type_no_qualifiers.GetOpaqueQualType());
+ if (die_it != GetForwardDeclCompilerTypeToDIE().end()) {
+ dwarf_die = GetDIE(die_it->getSecond());
+ GetForwardDeclCompilerTypeToDIE().erase(die_it);
}
- return false;
-}
-DWARFDIE SymbolFileDWARF::FindDefinitionDIE(const DWARFDIE &die) {
- auto def_die_it = GetDeclarationDIEToDefinitionDIE().find(die.GetDIE());
- if (def_die_it != GetDeclarationDIEToDefinitionDIE().end())
- return GetDIE(def_die_it->getSecond());
+ Type *type = GetDIEToType().lookup(dwarf_die.GetDIE());
- ParsedDWARFTypeAttributes attrs(die);
- const dw_tag_t tag = die.Tag();
- TypeSP type_sp;
- Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
- if (log) {
- GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF({0:p}) - {1:x16}: {2} type \"{3}\" is a "
- "forward declaration DIE, trying to find definition DIE",
- static_cast<void *>(this), die.GetOffset(), DW_TAG_value_to_name(tag),
- attrs.name.GetCString());
- }
- // We haven't parse definition die for this type, starting to search for it.
- // After we found the definition die, the GetDeclarationDIEToDefinitionDIE()
- // map will have the new mapping from this declaration die to definition die.
- if (attrs.class_language == eLanguageTypeObjC ||
- attrs.class_language == eLanguageTypeObjC_plus_plus) {
- if (!attrs.is_complete_objc_class &&
- die.Supports_DW_AT_APPLE_objc_complete_type()) {
- // 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
- // is_complete_objc_class above and know it is false), so the real
- // definition is in here somewhere
- type_sp = FindCompleteObjCDefinitionTypeForDIE(die, attrs.name, true);
-
- if (!type_sp) {
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We weren't able to find a full declaration in this DWARF,
- // see if we have a declaration anywhere else...
- type_sp = debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE(
- die, attrs.name, true);
- }
- }
-
- if (type_sp && log) {
- GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF({0:p}) - {1:x16}: {2} type "
- "\"{3}\" is an "
- "incomplete objc type, complete type is {4:x8}",
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), attrs.name.GetCString(),
- type_sp->GetID());
- }
- }
- }
- bool is_forward_declaration =
- attrs.is_forward_declaration ||
- (attrs.byte_size && *attrs.byte_size == 0 && attrs.name &&
- !die.HasChildren() &&
- SymbolFileDWARF::GetLanguage(*die.GetCU()) == eLanguageTypeObjC);
- if (is_forward_declaration) {
- type_sp = FindDefinitionTypeForDWARFDeclContext(die);
- if (!type_sp) {
- SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
- if (debug_map_symfile) {
- // We weren't able to find a full declaration in this DWARF, see
- // if we have a declaration anywhere else...
- type_sp = debug_map_symfile->FindDefinitionTypeForDWARFDeclContext(die);
- }
- if (type_sp && log) {
- GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF({0:p}) - {1:x16}: {2} type \"{3}\" is a "
- "forward declaration, complete type is {4:x8}",
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), attrs.name.GetCString(),
- type_sp->GetID());
- }
- }
- }
- def_die_it = GetDeclarationDIEToDefinitionDIE().find(die.GetDIE());
- if (def_die_it != GetDeclarationDIEToDefinitionDIE().end())
- return GetDIE(def_die_it->getSecond());
-
- if (log) {
- GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF({0:p}) - {1:x16}: {2} type \"{3}\" is a "
- "forward declaration, unable to find definition DIE for it",
- static_cast<void *>(this), die.GetOffset(), DW_TAG_value_to_name(tag),
- attrs.name.GetCString());
- }
- return DWARFDIE();
+ Log *log = GetLog(DWARFLog::DebugInfo | DWARFLog::TypeCompletion);
+ if (log)
+ GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
+ log, "{0:x8}: {1} '{2}' resolving forward declaration...",
+ dwarf_die.GetID(), dwarf_die.GetTagAsCString(),
+ type->GetName().AsCString());
+ assert(compiler_type);
+ if (DWARFASTParser *dwarf_ast = GetDWARFParser(*dwarf_die.GetCU()))
+ return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type, compiler_type);
+ return true;
}
Type *SymbolFileDWARF::ResolveType(const DWARFDIE &die,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 86d5a3d4f6c46..94aa810680c52 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -182,8 +182,6 @@ class SymbolFileDWARF : public SymbolFileCommon {
void FindFunctions(const RegularExpression ®ex, bool include_inlines,
SymbolContextList &sc_list) override;
- DWARFDIE FindDefinitionDIE(const DWARFDIE &die);
-
void
GetMangledNamesForFunction(const std::string &scope_qualified_name,
std::vector<ConstString> &mangled_names) override;
@@ -344,11 +342,6 @@ class SymbolFileDWARF : public SymbolFileCommon {
return m_forward_decl_compiler_type_to_die;
}
- typedef llvm::DenseMap<const DWARFDebugInfoEntry *, DIERef> DIEToDIE;
- virtual DIEToDIE &GetDeclarationDIEToDefinitionDIE() {
- return m_die_to_def_die;
- }
-
typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP>
DIEToVariableSP;
@@ -547,9 +540,6 @@ class SymbolFileDWARF : public SymbolFileCommon {
// A map from CompilerType to the struct/class/union/enum DIE (might be a
// declaration or a definition) that is used to construct it.
CompilerTypeToDIE m_forward_decl_compiler_type_to_die;
- // A map from a struct/class/union/enum DIE (might be a declaration or a
- // definition) to its definition DIE.
- DIEToDIE m_die_to_def_die;
llvm::DenseMap<dw_offset_t, std::unique_ptr<SupportFileList>>
m_type_unit_support_files;
std::vector<uint32_t> m_lldb_cu_to_dwarf_unit;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index cb5ec4ae026b3..85e1afd0d8976 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -110,11 +110,6 @@ SymbolFileDWARF::DIEToVariableSP &SymbolFileDWARFDwo::GetDIEToVariable() {
return GetBaseSymbolFile().GetDIEToVariable();
}
-SymbolFileDWARF::DIEToDIE &
-SymbolFileDWARFDwo::GetDeclarationDIEToDefinitionDIE() {
- return GetBaseSymbolFile().GetDeclarationDIEToDefinitionDIE();
-}
-
SymbolFileDWARF::CompilerTypeToDIE &
SymbolFileDWARFDwo::GetForwardDeclCompilerTypeToDIE() {
return GetBaseSymbolFile().GetForwardDeclCompilerTypeToDIE();
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index 3e8cfb885aaee..1500540424b52 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -74,8 +74,6 @@ class SymbolFileDWARFDwo : public SymbolFileDWARF {
CompilerTypeToDIE &GetForwardDeclCompilerTypeToDIE() override;
- DIEToDIE &GetDeclarationDIEToDefinitionDIE() override;
-
UniqueDWARFASTTypeMap &GetUniqueDWARFASTTypeMap() override;
lldb::TypeSP
>From 515c85d30fbacb523d51b024010056a61956e93b Mon Sep 17 00:00:00 2001
From: Zequan Wu <zequanwu at google.com>
Date: Fri, 3 May 2024 10:39:07 -0400
Subject: [PATCH 4/7] Address comments
---
.../Plugins/SymbolFile/DWARF/DWARFASTParser.h | 6 +-
.../SymbolFile/DWARF/DWARFASTParserClang.cpp | 68 +++---
.../SymbolFile/DWARF/DWARFASTParserClang.h | 203 ++++++++----------
.../SymbolFile/DWARF/SymbolFileDWARF.cpp | 12 +-
.../SymbolFile/DWARF/UniqueDWARFASTType.cpp | 82 +++----
5 files changed, 163 insertions(+), 208 deletions(-)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index 14b9cba05d321..e144cf0f9bd94 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -60,11 +60,7 @@ class DWARFASTParser {
virtual ConstString GetDIEClassTemplateParams(const DWARFDIE &die) = 0;
- // Return true if we found the definition DIE for it. is_forward_declaration
- // is set to true if the parameter die is a declaration.
- virtual bool
- FindDefinitionDIE(const lldb_private::plugin::dwarf::DWARFDIE &die,
- bool &is_forward_declaration) = 0;
+ virtual lldb_private::Type *FindDefinitionTypeForDIE(const DWARFDIE &die) = 0;
static std::optional<SymbolFile::ArrayInfo>
ParseChildArrayInfo(const DWARFDIE &parent_die,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 8a8c303e1a8b2..0db2e7984d13e 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -271,9 +271,8 @@ static void ForcefullyCompleteType(CompilerType type) {
/// avoids completing the type if it is not immediately necessary. It only
/// ensures we _can_ complete the type later.
void DWARFASTParserClang::PrepareContextToReceiveMembers(
- TypeSystemClang &ast, clang::DeclContext *decl_ctx,
- const DWARFDIE &decl_ctx_die, const DWARFDIE &die,
- const char *type_name_cstr) {
+ clang::DeclContext *decl_ctx, const DWARFDIE &decl_ctx_die,
+ const DWARFDIE &die, const char *type_name_cstr) {
auto *tag_decl_ctx = clang::dyn_cast<clang::TagDecl>(decl_ctx);
if (!tag_decl_ctx)
return; // Non-tag context are always ready.
@@ -288,7 +287,7 @@ void DWARFASTParserClang::PrepareContextToReceiveMembers(
// gmodules case), we can complete the type by doing a full import.
// If this type was not imported from an external AST, there's nothing to do.
- CompilerType type = ast.GetTypeForDecl(tag_decl_ctx);
+ CompilerType type = m_ast.GetTypeForDecl(tag_decl_ctx);
ClangASTImporter &ast_importer = GetClangASTImporter();
if (type && ast_importer.CanImport(type)) {
auto qual_type = ClangUtil::GetQualType(type);
@@ -304,8 +303,7 @@ void DWARFASTParserClang::PrepareContextToReceiveMembers(
// 1. Found the the definition DIE and start its definition with
// TypeSystemClang::StartTagDeclarationDefinition.
// 2. Unable to find it, then need to forcefully complete it.
- bool is_forward_declaration = false;
- FindDefinitionDIE(decl_ctx_die, is_forward_declaration);
+ FindDefinitionTypeForDIE(decl_ctx_die);
if (tag_decl_ctx->isCompleteDefinition() || tag_decl_ctx->isBeingDefined())
return;
// We don't have a type definition and/or the import failed. We must
@@ -652,7 +650,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
DWARFDIE decl_ctx_die;
clang::DeclContext *decl_ctx =
GetClangDeclContextContainingDIE(die, &decl_ctx_die);
- PrepareContextToReceiveMembers(m_ast, decl_ctx, decl_ctx_die, die,
+ PrepareContextToReceiveMembers(decl_ctx, decl_ctx_die, die,
attrs.name.GetCString());
if (attrs.type.IsValid()) {
@@ -1669,17 +1667,17 @@ DWARFASTParserClang::GetCPlusPlusQualifiedName(const DWARFDIE &die) {
return qualified_name;
}
-bool DWARFASTParserClang::FindDefinitionDIE(const DWARFDIE &die,
- bool &is_forward_declaration) {
+lldb_private::Type *
+DWARFASTParserClang::FindDefinitionTypeForDIE(const DWARFDIE &die) {
+ SymbolFileDWARF *dwarf = die.GetDWARF();
ParsedDWARFTypeAttributes attrs(die);
- is_forward_declaration = IsForwardDeclaration(
+ bool is_forward_declaration = IsForwardDeclaration(
die, attrs, SymbolFileDWARF::GetLanguage(*die.GetCU()));
if (!is_forward_declaration)
- return true;
+ return dwarf->GetDIEToType()[die.GetDIE()];
const dw_tag_t tag = die.Tag();
TypeSP type_sp;
- SymbolFileDWARF *dwarf = die.GetDWARF();
Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
if (log) {
dwarf->GetObjectFile()->GetModule()->LogMessage(
@@ -1745,10 +1743,8 @@ bool DWARFASTParserClang::FindDefinitionDIE(const DWARFDIE &die,
attrs.name.GetCString(), type_sp->GetID());
}
}
- if (type_sp)
- return true;
- if (log) {
+ if (!type_sp && log) {
dwarf->GetObjectFile()->GetModule()->LogMessage(
log,
"SymbolFileDWARF({0:p}) - {1:x16}: {2} type \"{3}\" is a "
@@ -1756,7 +1752,7 @@ bool DWARFASTParserClang::FindDefinitionDIE(const DWARFDIE &die,
static_cast<void *>(this), die.GetOffset(), DW_TAG_value_to_name(tag),
attrs.name.GetCString());
}
- return false;
+ return type_sp.get();
}
TypeSP
@@ -1801,9 +1797,9 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
LinkDeclContextToDIE(
GetCachedClangDeclContextForDIE(unique_ast_entry_up->m_die), die);
if (!attrs.is_forward_declaration) {
- // If the parameter DIE is definition and the entry in the map is
- // declaration, then we need to update the entry to point to the
- // definition 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 (unique_ast_entry_up->m_is_forward_declaration) {
unique_ast_entry_up->m_die = die;
unique_ast_entry_up->m_byte_size = byte_size;
@@ -1862,7 +1858,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
clang::DeclContext *decl_ctx =
GetClangDeclContextContainingDIE(die, &decl_ctx_die);
- PrepareContextToReceiveMembers(m_ast, decl_ctx, decl_ctx_die, die,
+ PrepareContextToReceiveMembers(decl_ctx, decl_ctx_die, die,
attrs.name.GetCString());
if (attrs.accessibility == eAccessNone && decl_ctx) {
@@ -1970,25 +1966,25 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
GetClangASTImporter().SetRecordLayout(record_decl, layout);
}
}
- }
- // Start the definition if the class is not objective C since the
- // underlying decls respond to isCompleteDefinition(). Objective
- // C decls don't respond to isCompleteDefinition() so we can't
- // start the declaration definition right away. For C++
- // class/union/structs we want to start the definition in case the
- // class is needed as the declaration context for a contained class
- // or type without the need to complete that type..
+ } else {
+ // Start the definition if the class is not objective C since the
+ // underlying decls respond to isCompleteDefinition(). Objective
+ // C decls don't respond to isCompleteDefinition() so we can't
+ // start the declaration definition right away. For C++
+ // class/union/structs we want to start the definition in case the
+ // class is needed as the declaration context for a contained class
+ // or type without the need to complete that type..
- if (attrs.class_language != eLanguageTypeObjC &&
- attrs.class_language != eLanguageTypeObjC_plus_plus)
- TypeSystemClang::StartTagDeclarationDefinition(clang_type);
+ if (attrs.class_language != eLanguageTypeObjC &&
+ attrs.class_language != eLanguageTypeObjC_plus_plus)
+ TypeSystemClang::StartTagDeclarationDefinition(clang_type);
+ }
}
- // Leave this as a forward declaration until we need to know the
- // details of the type. lldb_private::Type will automatically call
- // the SymbolFile virtual function
- // "SymbolFileDWARF::CompleteType(Type *)" When the definition
- // needs to be defined.
+ // If this is a declaration DIE, leave this as a forward declaration until we
+ // need to know the details of the type. lldb_private::Type will automatically
+ // call the SymbolFile virtual function "SymbolFileDWARF::CompleteType(Type
+ // *)" When the definition needs to be defined.
assert(!dwarf->GetForwardDeclCompilerTypeToDIE().count(
ClangUtil::RemoveFastQualifiers(clang_type).GetOpaqueQualType()) &&
"Type already in the forward declaration map!");
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index b884d6869add8..853b8ccc30369 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -42,40 +42,40 @@ struct ParsedDWARFTypeAttributes;
class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
public:
+ typedef lldb_private::plugin::dwarf::DWARFDIE DWARFDIE;
+
DWARFASTParserClang(lldb_private::TypeSystemClang &ast);
~DWARFASTParserClang() override;
// DWARFASTParser interface.
- lldb::TypeSP
- ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
- const lldb_private::plugin::dwarf::DWARFDIE &die,
- bool *type_is_new_ptr) override;
+ lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
+ const DWARFDIE &die,
+ bool *type_is_new_ptr) override;
- lldb_private::ConstString ConstructDemangledNameFromDWARF(
- const lldb_private::plugin::dwarf::DWARFDIE &die) override;
+ lldb_private::ConstString
+ ConstructDemangledNameFromDWARF(const DWARFDIE &die) override;
lldb_private::Function *
ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit,
- const lldb_private::plugin::dwarf::DWARFDIE &die,
+ const DWARFDIE &die,
const lldb_private::AddressRange &func_range) override;
bool
- CompleteTypeFromDWARF(const lldb_private::plugin::dwarf::DWARFDIE &die,
- lldb_private::Type *type,
+ CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,
lldb_private::CompilerType &compiler_type) override;
- lldb_private::CompilerDecl GetDeclForUIDFromDWARF(
- const lldb_private::plugin::dwarf::DWARFDIE &die) override;
+ lldb_private::CompilerDecl
+ GetDeclForUIDFromDWARF(const DWARFDIE &die) override;
void EnsureAllDIEsInDeclContextHaveBeenParsed(
lldb_private::CompilerDeclContext decl_context) override;
- lldb_private::CompilerDeclContext GetDeclContextForUIDFromDWARF(
- const lldb_private::plugin::dwarf::DWARFDIE &die) override;
+ lldb_private::CompilerDeclContext
+ GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override;
- lldb_private::CompilerDeclContext GetDeclContextContainingUIDFromDWARF(
- const lldb_private::plugin::dwarf::DWARFDIE &die) override;
+ lldb_private::CompilerDeclContext
+ GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override;
lldb_private::ClangASTImporter &GetClangASTImporter();
@@ -105,11 +105,13 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
/// \return A string, including surrounding '<>', of the template parameters.
/// If the DIE's name already has '<>', returns an empty ConstString because
/// it's assumed that the caller is using the DIE name anyway.
- lldb_private::ConstString GetDIEClassTemplateParams(
- const lldb_private::plugin::dwarf::DWARFDIE &die) override;
+ lldb_private::ConstString
+ GetDIEClassTemplateParams(const DWARFDIE &die) override;
- bool FindDefinitionDIE(const lldb_private::plugin::dwarf::DWARFDIE &die,
- bool &is_forward_declaration) override;
+ // Searching for definition DIE for the given DIE and return the type
+ // associated with the definition DIE, or nullptr if definition DIE is not
+ // found.
+ lldb_private::Type *FindDefinitionTypeForDIE(const DWARFDIE &die) override;
protected:
/// Protected typedefs and members.
@@ -121,8 +123,7 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
const lldb_private::plugin::dwarf::DWARFDebugInfoEntry *,
clang::DeclContext *>
DIEToDeclContextMap;
- typedef std::multimap<const clang::DeclContext *,
- const lldb_private::plugin::dwarf::DWARFDIE>
+ typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
DeclContextToDIEMap;
typedef llvm::DenseMap<
const lldb_private::plugin::dwarf::DWARFDebugInfoEntry *,
@@ -140,14 +141,11 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_up;
/// @}
- clang::DeclContext *
- GetDeclContextForBlock(const lldb_private::plugin::dwarf::DWARFDIE &die);
+ clang::DeclContext *GetDeclContextForBlock(const DWARFDIE &die);
- clang::BlockDecl *
- ResolveBlockDIE(const lldb_private::plugin::dwarf::DWARFDIE &die);
+ clang::BlockDecl *ResolveBlockDIE(const DWARFDIE &die);
- clang::NamespaceDecl *
- ResolveNamespaceDIE(const lldb_private::plugin::dwarf::DWARFDIE &die);
+ clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die);
/// Returns the namespace decl that a DW_TAG_imported_declaration imports.
///
@@ -158,103 +156,86 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
/// 'die' imports. If the imported entity is not a namespace
/// or another import declaration, returns nullptr. If an error
/// occurs, returns nullptr.
- clang::NamespaceDecl *ResolveImportedDeclarationDIE(
- const lldb_private::plugin::dwarf::DWARFDIE &die);
+ clang::NamespaceDecl *ResolveImportedDeclarationDIE(const DWARFDIE &die);
- bool ParseTemplateDIE(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ bool ParseTemplateDIE(const DWARFDIE &die,
lldb_private::TypeSystemClang::TemplateParameterInfos
&template_param_infos);
bool ParseTemplateParameterInfos(
- const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
+ const DWARFDIE &parent_die,
lldb_private::TypeSystemClang::TemplateParameterInfos
&template_param_infos);
- std::string
- GetCPlusPlusQualifiedName(const lldb_private::plugin::dwarf::DWARFDIE &die);
+ std::string GetCPlusPlusQualifiedName(const DWARFDIE &die);
bool ParseChildMembers(
- const lldb_private::plugin::dwarf::DWARFDIE &die,
- lldb_private::CompilerType &class_compiler_type,
+ const DWARFDIE &die, lldb_private::CompilerType &class_compiler_type,
std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
- std::vector<lldb_private::plugin::dwarf::DWARFDIE> &member_function_dies,
- std::vector<lldb_private::plugin::dwarf::DWARFDIE> &contained_type_dies,
+ std::vector<DWARFDIE> &member_function_dies,
+ std::vector<DWARFDIE> &contained_type_dies,
DelayedPropertyList &delayed_properties,
const lldb::AccessType default_accessibility,
lldb_private::ClangASTImporter::LayoutInfo &layout_info);
size_t
ParseChildParameters(clang::DeclContext *containing_decl_ctx,
- const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
- bool skip_artificial, bool &is_static, bool &is_variadic,
+ const DWARFDIE &parent_die, bool skip_artificial,
+ bool &is_static, bool &is_variadic,
bool &has_template_params,
std::vector<lldb_private::CompilerType> &function_args,
std::vector<clang::ParmVarDecl *> &function_param_decls,
unsigned &type_quals);
- size_t ParseChildEnumerators(
- lldb_private::CompilerType &compiler_type, bool is_signed,
- uint32_t enumerator_byte_size,
- const lldb_private::plugin::dwarf::DWARFDIE &parent_die);
+ size_t ParseChildEnumerators(lldb_private::CompilerType &compiler_type,
+ bool is_signed, uint32_t enumerator_byte_size,
+ const DWARFDIE &parent_die);
/// Parse a structure, class, or union type DIE.
- lldb::TypeSP
- ParseStructureLikeDIE(const lldb_private::SymbolContext &sc,
- const lldb_private::plugin::dwarf::DWARFDIE &die,
- ParsedDWARFTypeAttributes &attrs);
+ lldb::TypeSP ParseStructureLikeDIE(const lldb_private::SymbolContext &sc,
+ const DWARFDIE &die,
+ ParsedDWARFTypeAttributes &attrs);
- clang::Decl *
- GetClangDeclForDIE(const lldb_private::plugin::dwarf::DWARFDIE &die);
+ clang::Decl *GetClangDeclForDIE(const DWARFDIE &die);
- clang::DeclContext *
- GetClangDeclContextForDIE(const lldb_private::plugin::dwarf::DWARFDIE &die);
+ clang::DeclContext *GetClangDeclContextForDIE(const DWARFDIE &die);
- clang::DeclContext *GetClangDeclContextContainingDIE(
- const lldb_private::plugin::dwarf::DWARFDIE &die,
- lldb_private::plugin::dwarf::DWARFDIE *decl_ctx_die);
- lldb_private::OptionalClangModuleID
- GetOwningClangModule(const lldb_private::plugin::dwarf::DWARFDIE &die);
+ clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die,
+ DWARFDIE *decl_ctx_die);
+ lldb_private::OptionalClangModuleID GetOwningClangModule(const DWARFDIE &die);
- bool CopyUniqueClassMethodTypes(
- const lldb_private::plugin::dwarf::DWARFDIE &src_class_die,
- const lldb_private::plugin::dwarf::DWARFDIE &dst_class_die,
- lldb_private::Type *class_type,
- std::vector<lldb_private::plugin::dwarf::DWARFDIE> &failures);
+ bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die,
+ const DWARFDIE &dst_class_die,
+ lldb_private::Type *class_type,
+ std::vector<DWARFDIE> &failures);
- clang::DeclContext *GetCachedClangDeclContextForDIE(
- const lldb_private::plugin::dwarf::DWARFDIE &die);
+ clang::DeclContext *GetCachedClangDeclContextForDIE(const DWARFDIE &die);
- void LinkDeclContextToDIE(clang::DeclContext *decl_ctx,
- const lldb_private::plugin::dwarf::DWARFDIE &die);
+ void LinkDeclContextToDIE(clang::DeclContext *decl_ctx, const DWARFDIE &die);
- void LinkDeclToDIE(clang::Decl *decl,
- const lldb_private::plugin::dwarf::DWARFDIE &die);
+ void LinkDeclToDIE(clang::Decl *decl, const DWARFDIE &die);
/// If \p type_sp is valid, calculate and set its symbol context scope, and
/// update the type list for its backing symbol file.
///
/// Returns \p type_sp.
- lldb::TypeSP UpdateSymbolContextScopeForType(
- const lldb_private::SymbolContext &sc,
- const lldb_private::plugin::dwarf::DWARFDIE &die, lldb::TypeSP type_sp);
+ lldb::TypeSP
+ UpdateSymbolContextScopeForType(const lldb_private::SymbolContext &sc,
+ const DWARFDIE &die, lldb::TypeSP type_sp);
/// Follow Clang Module Skeleton CU references to find a type definition.
- lldb::TypeSP
- ParseTypeFromClangModule(const lldb_private::SymbolContext &sc,
- const lldb_private::plugin::dwarf::DWARFDIE &die,
- lldb_private::Log *log);
+ lldb::TypeSP ParseTypeFromClangModule(const lldb_private::SymbolContext &sc,
+ const DWARFDIE &die,
+ lldb_private::Log *log);
// Return true if this type is a declaration to a type in an external
// module.
- lldb::ModuleSP
- GetModuleForType(const lldb_private::plugin::dwarf::DWARFDIE &die);
+ lldb::ModuleSP GetModuleForType(const DWARFDIE &die);
- void PrepareContextToReceiveMembers(
- lldb_private::TypeSystemClang &ast,
- clang::DeclContext *decl_ctx,
- const lldb_private::plugin::dwarf::DWARFDIE &decl_ctx_die,
- const lldb_private::plugin::dwarf::DWARFDIE &die,
- const char *type_name_cstr);
+ void PrepareContextToReceiveMembers(clang::DeclContext *decl_ctx,
+ const DWARFDIE &decl_ctx_die,
+ const DWARFDIE &die,
+ const char *type_name_cstr);
static bool classof(const DWARFASTParser *Parser) {
return Parser->GetKind() == Kind::DWARFASTParserClang;
@@ -284,10 +265,8 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
/// Parsed form of all attributes that are relevant for parsing type members.
struct MemberAttributes {
- explicit MemberAttributes(
- const lldb_private::plugin::dwarf::DWARFDIE &die,
- const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
- lldb::ModuleSP module_sp);
+ explicit MemberAttributes(const DWARFDIE &die, const DWARFDIE &parent_die,
+ lldb::ModuleSP module_sp);
const char *name = nullptr;
/// Indicates how many bits into the word (according to the host endianness)
/// the low-order bit of the field starts. Can be negative.
@@ -334,15 +313,12 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
/// created property.
/// \param delayed_properties The list of delayed properties that the result
/// will be appended to.
- void
- ParseObjCProperty(const lldb_private::plugin::dwarf::DWARFDIE &die,
- const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
- const lldb_private::CompilerType &class_clang_type,
- DelayedPropertyList &delayed_properties);
+ void ParseObjCProperty(const DWARFDIE &die, const DWARFDIE &parent_die,
+ const lldb_private::CompilerType &class_clang_type,
+ DelayedPropertyList &delayed_properties);
void
- ParseSingleMember(const lldb_private::plugin::dwarf::DWARFDIE &die,
- const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
+ ParseSingleMember(const DWARFDIE &die, const DWARFDIE &parent_die,
const lldb_private::CompilerType &class_clang_type,
lldb::AccessType default_accessibility,
lldb_private::ClangASTImporter::LayoutInfo &layout_info,
@@ -360,31 +336,25 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
/// \param[in] class_clang_type The parent RecordType of the static
/// member this function will create.
void CreateStaticMemberVariable(
- const lldb_private::plugin::dwarf::DWARFDIE &die,
- const MemberAttributes &attrs,
+ const DWARFDIE &die, const MemberAttributes &attrs,
const lldb_private::CompilerType &class_clang_type);
- bool CompleteRecordType(const lldb_private::plugin::dwarf::DWARFDIE &die,
- lldb_private::Type *type,
+ bool CompleteRecordType(const DWARFDIE &die, lldb_private::Type *type,
lldb_private::CompilerType &clang_type);
- bool CompleteEnumType(const lldb_private::plugin::dwarf::DWARFDIE &die,
- lldb_private::Type *type,
+ bool CompleteEnumType(const DWARFDIE &die, lldb_private::Type *type,
lldb_private::CompilerType &clang_type);
- lldb::TypeSP
- ParseTypeModifier(const lldb_private::SymbolContext &sc,
- const lldb_private::plugin::dwarf::DWARFDIE &die,
- ParsedDWARFTypeAttributes &attrs);
+ lldb::TypeSP ParseTypeModifier(const lldb_private::SymbolContext &sc,
+ const DWARFDIE &die,
+ ParsedDWARFTypeAttributes &attrs);
lldb::TypeSP ParseEnum(const lldb_private::SymbolContext &sc,
- const lldb_private::plugin::dwarf::DWARFDIE &die,
- ParsedDWARFTypeAttributes &attrs);
- lldb::TypeSP ParseSubroutine(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ const DWARFDIE &die, ParsedDWARFTypeAttributes &attrs);
+ lldb::TypeSP ParseSubroutine(const DWARFDIE &die,
const ParsedDWARFTypeAttributes &attrs);
- lldb::TypeSP ParseArrayType(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ lldb::TypeSP ParseArrayType(const DWARFDIE &die,
const ParsedDWARFTypeAttributes &attrs);
- lldb::TypeSP
- ParsePointerToMemberType(const lldb_private::plugin::dwarf::DWARFDIE &die,
- const ParsedDWARFTypeAttributes &attrs);
+ lldb::TypeSP ParsePointerToMemberType(const DWARFDIE &die,
+ const ParsedDWARFTypeAttributes &attrs);
/// Parses a DW_TAG_inheritance DIE into a base/super class.
///
@@ -401,8 +371,7 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
/// \param layout_info The layout information that will be updated for C++
/// base classes with the base offset.
void ParseInheritance(
- const lldb_private::plugin::dwarf::DWARFDIE &die,
- const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
+ const DWARFDIE &die, const DWARFDIE &parent_die,
const lldb_private::CompilerType class_clang_type,
const lldb::AccessType default_accessibility,
const lldb::ModuleSP &module_sp,
@@ -419,8 +388,7 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
/// \param layout_info The layout information that will be updated for
// base classes with the base offset
void
- ParseRustVariantPart(lldb_private::plugin::dwarf::DWARFDIE &die,
- const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
+ ParseRustVariantPart(DWARFDIE &die, const DWARFDIE &parent_die,
lldb_private::CompilerType &class_clang_type,
const lldb::AccessType default_accesibility,
lldb_private::ClangASTImporter::LayoutInfo &layout_info);
@@ -430,8 +398,9 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
/// Some attributes are relevant for all kinds of types (declaration), while
/// others are only meaningful to a specific type (is_virtual)
struct ParsedDWARFTypeAttributes {
- explicit ParsedDWARFTypeAttributes(
- const lldb_private::plugin::dwarf::DWARFDIE &die);
+ typedef lldb_private::plugin::dwarf::DWARFDIE DWARFDIE;
+
+ explicit ParsedDWARFTypeAttributes(const DWARFDIE &die);
lldb::AccessType accessibility = lldb::eAccessNone;
bool is_artificial = false;
@@ -448,7 +417,7 @@ struct ParsedDWARFTypeAttributes {
const char *mangled_name = nullptr;
lldb_private::ConstString name;
lldb_private::Declaration decl;
- lldb_private::plugin::dwarf::DWARFDIE object_pointer;
+ DWARFDIE object_pointer;
lldb_private::plugin::dwarf::DWARFFormValue abstract_origin;
lldb_private::plugin::dwarf::DWARFFormValue containing_type;
lldb_private::plugin::dwarf::DWARFFormValue signature;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index d2f66b00c1794..10b9ae7d5ab4e 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1636,14 +1636,10 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
// type to get resolved.
DWARFDIE dwarf_die = GetDIE(die_it->second);
GetForwardDeclCompilerTypeToDIE().erase(die_it);
- // The DWARFASTParser might determine if this is a declaration or not with
- // information other than DW_AT_declaration depending on the language.
- bool is_forward_declaration = false;
- bool found_def_die = false;
+ Type *type = nullptr;
if (DWARFASTParser *dwarf_ast = GetDWARFParser(*dwarf_die.GetCU()))
- found_def_die =
- dwarf_ast->FindDefinitionDIE(dwarf_die, is_forward_declaration);
- if (!found_def_die)
+ type = dwarf_ast->FindDefinitionTypeForDIE(dwarf_die);
+ if (!type)
return false;
die_it = GetForwardDeclCompilerTypeToDIE().find(
@@ -1653,8 +1649,6 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
GetForwardDeclCompilerTypeToDIE().erase(die_it);
}
- Type *type = GetDIEToType().lookup(dwarf_die.GetDIE());
-
Log *log = GetLog(DWARFLog::DebugInfo | DWARFLog::TypeCompletion);
if (log)
GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
index cc23bb86f6805..8b7b413fcf66e 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
@@ -30,52 +30,52 @@ bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die,
: (udt.m_byte_size < 0 || byte_size < 0 ||
udt.m_byte_size == byte_size) &&
udt.m_declaration == decl;
- if (matching_size_declaration) {
- // The type has the same name, and was defined on the same file and
- // line. Now verify all of the parent DIEs match.
- DWARFDIE parent_arg_die = die.GetParent();
- DWARFDIE parent_pos_die = udt.m_die.GetParent();
- bool match = true;
- bool done = false;
- while (!done && match && parent_arg_die && parent_pos_die) {
- const dw_tag_t parent_arg_tag = parent_arg_die.Tag();
- const dw_tag_t parent_pos_tag = parent_pos_die.Tag();
- if (parent_arg_tag == parent_pos_tag) {
- switch (parent_arg_tag) {
- case DW_TAG_class_type:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_namespace: {
- const char *parent_arg_die_name = parent_arg_die.GetName();
- if (parent_arg_die_name ==
- nullptr) // Anonymous (i.e. no-name) struct
- {
+ if (!matching_size_declaration)
+ continue;
+ // The type has the same name, and was defined on the same file and
+ // line. Now verify all of the parent DIEs match.
+ DWARFDIE parent_arg_die = die.GetParent();
+ DWARFDIE parent_pos_die = udt.m_die.GetParent();
+ bool match = true;
+ bool done = false;
+ while (!done && match && parent_arg_die && parent_pos_die) {
+ const dw_tag_t parent_arg_tag = parent_arg_die.Tag();
+ const dw_tag_t parent_pos_tag = parent_pos_die.Tag();
+ if (parent_arg_tag == parent_pos_tag) {
+ switch (parent_arg_tag) {
+ case DW_TAG_class_type:
+ case DW_TAG_structure_type:
+ case DW_TAG_union_type:
+ case DW_TAG_namespace: {
+ const char *parent_arg_die_name = parent_arg_die.GetName();
+ if (parent_arg_die_name ==
+ nullptr) // Anonymous (i.e. no-name) struct
+ {
+ match = false;
+ } else {
+ const char *parent_pos_die_name = parent_pos_die.GetName();
+ if (parent_pos_die_name == nullptr ||
+ ((parent_arg_die_name != parent_pos_die_name) &&
+ strcmp(parent_arg_die_name, parent_pos_die_name)))
match = false;
- } else {
- const char *parent_pos_die_name = parent_pos_die.GetName();
- if (parent_pos_die_name == nullptr ||
- ((parent_arg_die_name != parent_pos_die_name) &&
- strcmp(parent_arg_die_name, parent_pos_die_name)))
- match = false;
- }
- } break;
-
- case DW_TAG_compile_unit:
- case DW_TAG_partial_unit:
- done = true;
- break;
- default:
- break;
}
+ } break;
+
+ case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
+ done = true;
+ break;
+ default:
+ break;
}
- parent_arg_die = parent_arg_die.GetParent();
- parent_pos_die = parent_pos_die.GetParent();
}
+ parent_arg_die = parent_arg_die.GetParent();
+ parent_pos_die = parent_pos_die.GetParent();
+ }
- if (match) {
- entry = udt;
- return true;
- }
+ if (match) {
+ entry = udt;
+ return true;
}
}
}
>From 40b87f037911bf738d0e3cb670485dac33d5b079 Mon Sep 17 00:00:00 2001
From: Zequan Wu <zequanwu at google.com>
Date: Fri, 3 May 2024 16:26:19 -0400
Subject: [PATCH 5/7] address comments
---
.../SymbolFile/DWARF/DWARFASTParserClang.cpp | 28 +++++++++----------
.../SymbolFile/DWARF/SymbolFileDWARF.cpp | 2 +-
2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 0db2e7984d13e..0f8beaa8363ed 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -158,21 +158,21 @@ static bool
IsForwardDeclaration(const lldb_private::plugin::dwarf::DWARFDIE &die,
const ParsedDWARFTypeAttributes &attrs,
LanguageType cu_language) {
- 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.
+ if (attrs.is_forward_declaration)
return true;
- }
- return attrs.is_forward_declaration;
+
+ // 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.
+ return attrs.byte_size && *attrs.byte_size == 0 && attrs.name &&
+ !die.HasChildren() && cu_language == eLanguageTypeObjC;
}
TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 10b9ae7d5ab4e..8b3d8b8c8903a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1632,7 +1632,7 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
}
// Once we start resolving this type, remove it from the forward
- // declaration map in case anyone child members or other types require this
+ // declaration map in case anyone's child members or other types require this
// type to get resolved.
DWARFDIE dwarf_die = GetDIE(die_it->second);
GetForwardDeclCompilerTypeToDIE().erase(die_it);
>From 0481675dcda0da45b5a66a5208bbc80f61d04b79 Mon Sep 17 00:00:00 2001
From: Zequan Wu <zequanwu at google.com>
Date: Mon, 6 May 2024 11:10:20 -0400
Subject: [PATCH 6/7] add a test
---
.../SymbolFile/DWARF/DWARFASTParserClang.cpp | 9 ++---
.../delayed-definition-die-searching.test | 40 +++++++++++++++++++
2 files changed, 44 insertions(+), 5 deletions(-)
create mode 100644 lldb/test/Shell/SymbolFile/DWARF/delayed-definition-die-searching.test
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 1908a1bfffa89..7cd1626f553c3 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -154,10 +154,9 @@ static bool TagIsRecordType(dw_tag_t tag) {
}
}
-static bool
-IsForwardDeclaration(const lldb_private::plugin::dwarf::DWARFDIE &die,
- const ParsedDWARFTypeAttributes &attrs,
- LanguageType cu_language) {
+static bool IsForwardDeclaration(const DWARFDIE &die,
+ const ParsedDWARFTypeAttributes &attrs,
+ LanguageType cu_language) {
if (attrs.is_forward_declaration)
return true;
@@ -172,7 +171,7 @@ IsForwardDeclaration(const lldb_private::plugin::dwarf::DWARFDIE &die,
// Note that there is no DW_AT_declaration and there are no children,
// and the byte size is zero.
return attrs.byte_size && *attrs.byte_size == 0 && attrs.name &&
- !die.HasChildren() && cu_language == eLanguageTypeObjC;
+ !die.HasChildren() && cu_language == eLanguageTypeObjC;
}
TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
diff --git a/lldb/test/Shell/SymbolFile/DWARF/delayed-definition-die-searching.test b/lldb/test/Shell/SymbolFile/DWARF/delayed-definition-die-searching.test
new file mode 100644
index 0000000000000..3f5293d04ccce
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/DWARF/delayed-definition-die-searching.test
@@ -0,0 +1,40 @@
+# Test definition DIE searching is delayed until complete type is required.
+
+# RUN: split-file %s %t
+# RUN: %clangxx_host %t/main.cpp %t/t1_def.cpp -g -gsimple-template-names -o %t.out
+# RUN: %lldb -b %t.out -s %t/lldb.cmd | FileCheck %s
+
+# CHECK: (lldb) p v1
+# CHECK-NEXT: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_structure_type (DW_TAG_structure_type) name = 't2'
+# CHECK-NEXT: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_structure_type (DW_TAG_structure_type) name = 't1'
+# CHECK-NEXT: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_base_type (DW_TAG_base_type) name = 'int'
+# CHECK-NEXT: DW_TAG_structure_type (DW_TAG_structure_type) 't2' resolving forward declaration...
+# CHECK-NEXT: (t2<t1<int> >) {}
+# CHECK-NEXT: (lldb) p v2
+# CHECK-NEXT: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_structure_type (DW_TAG_structure_type) name = 't1'
+# CHECK-NEXT: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_base_type (DW_TAG_base_type) name = 'int'
+# CHECK-NEXT: DW_TAG_structure_type (DW_TAG_structure_type) 't1' resolving forward declaration...
+# CHECK-NEXT: (t1<int>) {}
+
+#--- lldb.cmd
+log enable dwarf comp
+p v1
+p v2
+
+#--- template.h
+template<typename T>
+struct t1 {
+};
+template<typename T>
+struct t2 {
+};
+
+#--- main.cpp
+#include "template.h"
+t2<t1<int>> v1; // this CU doesn't have definition DIE for t1<int>, but only declaration DIE for it.
+int main() {
+}
+
+#--- t1_def.cpp
+#include "template.h"
+t1<int> v2; // this CU contains definition DIE for t1<int>.
>From 4f2fbfbad4b8560990266be36b394e65b3373b91 Mon Sep 17 00:00:00 2001
From: Zequan Wu <zequanwu at google.com>
Date: Tue, 7 May 2024 11:21:19 -0400
Subject: [PATCH 7/7] Use CHECK instead of CHECK-NEXT
---
.../delayed-definition-die-searching.test | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/lldb/test/Shell/SymbolFile/DWARF/delayed-definition-die-searching.test b/lldb/test/Shell/SymbolFile/DWARF/delayed-definition-die-searching.test
index 3f5293d04ccce..6fe6819f66e3e 100644
--- a/lldb/test/Shell/SymbolFile/DWARF/delayed-definition-die-searching.test
+++ b/lldb/test/Shell/SymbolFile/DWARF/delayed-definition-die-searching.test
@@ -5,16 +5,16 @@
# RUN: %lldb -b %t.out -s %t/lldb.cmd | FileCheck %s
# CHECK: (lldb) p v1
-# CHECK-NEXT: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_structure_type (DW_TAG_structure_type) name = 't2'
-# CHECK-NEXT: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_structure_type (DW_TAG_structure_type) name = 't1'
-# CHECK-NEXT: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_base_type (DW_TAG_base_type) name = 'int'
-# CHECK-NEXT: DW_TAG_structure_type (DW_TAG_structure_type) 't2' resolving forward declaration...
-# CHECK-NEXT: (t2<t1<int> >) {}
-# CHECK-NEXT: (lldb) p v2
-# CHECK-NEXT: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_structure_type (DW_TAG_structure_type) name = 't1'
-# CHECK-NEXT: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_base_type (DW_TAG_base_type) name = 'int'
-# CHECK-NEXT: DW_TAG_structure_type (DW_TAG_structure_type) 't1' resolving forward declaration...
-# CHECK-NEXT: (t1<int>) {}
+# CHECK: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_structure_type (DW_TAG_structure_type) name = 't2'
+# CHECK: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_structure_type (DW_TAG_structure_type) name = 't1'
+# CHECK: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_base_type (DW_TAG_base_type) name = 'int'
+# CHECK: DW_TAG_structure_type (DW_TAG_structure_type) 't2' resolving forward declaration...
+# CHECK: (t2<t1<int> >) {}
+# CHECK: (lldb) p v2
+# CHECK: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_structure_type (DW_TAG_structure_type) name = 't1'
+# CHECK: DWARFASTParserClang::ParseTypeFromDWARF{{.*}}DW_TAG_base_type (DW_TAG_base_type) name = 'int'
+# CHECK: DW_TAG_structure_type (DW_TAG_structure_type) 't1' resolving forward declaration...
+# CHECK: (t1<int>) {}
#--- lldb.cmd
log enable dwarf comp
More information about the lldb-commits
mailing list