[Lldb-commits] [lldb] 37b8e5f - Revert "[lldb][DWARF] Delay struct/class/union definition DIE searching when parsing declaration DIEs. (#90663)"
Jim Ingham via lldb-commits
lldb-commits at lists.llvm.org
Mon May 13 17:47:55 PDT 2024
Author: Jim Ingham
Date: 2024-05-13T17:47:49-07:00
New Revision: 37b8e5feb1d065a7c474e6595bac6d2f65faeb51
URL: https://github.com/llvm/llvm-project/commit/37b8e5feb1d065a7c474e6595bac6d2f65faeb51
DIFF: https://github.com/llvm/llvm-project/commit/37b8e5feb1d065a7c474e6595bac6d2f65faeb51.diff
LOG: Revert "[lldb][DWARF] Delay struct/class/union definition DIE searching when parsing declaration DIEs. (#90663)"
This reverts commit 9a7262c2601874e5aa64c5db19746770212d4b44.
Added:
Modified:
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
Removed:
################################################################################
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
index e144cf0f9bd94..66db396279e06 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h
@@ -60,8 +60,6 @@ class DWARFASTParser {
virtual ConstString GetDIEClassTemplateParams(const DWARFDIE &die) = 0;
- virtual lldb_private::Type *FindDefinitionTypeForDIE(const DWARFDIE &die) = 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 2a46be9216121..034817c3b4fa1 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -154,26 +154,6 @@ static bool TagIsRecordType(dw_tag_t tag) {
}
}
-static bool IsForwardDeclaration(const DWARFDIE &die,
- const ParsedDWARFTypeAttributes &attrs,
- LanguageType cu_language) {
- if (attrs.is_forward_declaration)
- return true;
-
- // 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,
const DWARFDIE &die,
Log *log) {
@@ -269,9 +249,11 @@ 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.
-void DWARFASTParserClang::PrepareContextToReceiveMembers(
- clang::DeclContext *decl_ctx, const DWARFDIE &decl_ctx_die,
- const DWARFDIE &die, const char *type_name_cstr) {
+static void PrepareContextToReceiveMembers(TypeSystemClang &ast,
+ ClangASTImporter &ast_importer,
+ clang::DeclContext *decl_ctx,
+ 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.
@@ -286,8 +268,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 = m_ast.GetTypeForDecl(tag_decl_ctx);
- ClangASTImporter &ast_importer = GetClangASTImporter();
+ CompilerType type = ast.GetTypeForDecl(tag_decl_ctx);
if (type && ast_importer.CanImport(type)) {
auto qual_type = ClangUtil::GetQualType(type);
if (ast_importer.RequireCompleteType(qual_type))
@@ -298,13 +279,6 @@ void DWARFASTParserClang::PrepareContextToReceiveMembers(
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.
- 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
// forcefully complete the type to avoid crashes.
ForcefullyCompleteType(type);
@@ -646,11 +620,10 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
if (tag == DW_TAG_typedef) {
// DeclContext will be populated when the clang type is materialized in
// Type::ResolveCompilerType.
- DWARFDIE decl_ctx_die;
- clang::DeclContext *decl_ctx =
- GetClangDeclContextContainingDIE(die, &decl_ctx_die);
- PrepareContextToReceiveMembers(decl_ctx, decl_ctx_die, die,
- attrs.name.GetCString());
+ PrepareContextToReceiveMembers(
+ m_ast, GetClangASTImporter(),
+ GetClangDeclContextContainingDIE(die, nullptr), die,
+ attrs.name.GetCString());
if (attrs.type.IsValid()) {
// Try to parse a typedef from the (DWARF embedded in the) Clang
@@ -1130,6 +1103,32 @@ 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
@@ -1264,39 +1263,6 @@ 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();
- }
- }
- }
}
}
}
@@ -1669,93 +1635,6 @@ DWARFASTParserClang::GetCPlusPlusQualifiedName(const DWARFDIE &die) {
return qualified_name;
}
-lldb_private::Type *
-DWARFASTParserClang::FindDefinitionTypeForDIE(const DWARFDIE &die) {
- SymbolFileDWARF *dwarf = die.GetDWARF();
- ParsedDWARFTypeAttributes attrs(die);
- bool is_forward_declaration = IsForwardDeclaration(
- die, attrs, SymbolFileDWARF::GetLanguage(*die.GetCU()));
- if (!is_forward_declaration)
- return dwarf->GetDIEToType()[die.GetDIE()];
-
- const dw_tag_t tag = die.Tag();
- TypeSP type_sp;
- 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} ({3}) type \"{4}\" is an "
- "incomplete objc type, complete type is {5:x8}",
- static_cast<void *>(this), die.GetOffset(),
- DW_TAG_value_to_name(tag), 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 && 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 type_sp.get();
-}
-
TypeSP
DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
const DWARFDIE &die,
@@ -1767,10 +1646,14 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU());
Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
+ // UniqueDWARFASTType is large, so don't create a local variables on the
+ // stack, put it on the heap. This function is often called recursively and
+ // clang isn't good at sharing the stack space for variables in
diff erent
+ // blocks.
+ auto unique_ast_entry_up = std::make_unique<UniqueDWARFASTType>();
+
ConstString unique_typename(attrs.name);
Declaration unique_decl(attrs.decl);
- uint64_t byte_size = attrs.byte_size.value_or(0);
- attrs.is_forward_declaration = IsForwardDeclaration(die, attrs, cu_language);
if (attrs.name) {
if (Language::LanguageIsCPlusPlus(cu_language)) {
@@ -1783,42 +1666,14 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
unique_decl.Clear();
}
- if (UniqueDWARFASTType *unique_ast_entry_type =
- dwarf->GetUniqueDWARFASTTypeMap().Find(
- unique_typename, die, unique_decl, byte_size,
- attrs.is_forward_declaration)) {
- type_sp = unique_ast_entry_type->m_type_sp;
+ if (dwarf->GetUniqueDWARFASTTypeMap().Find(
+ unique_typename, die, unique_decl, attrs.byte_size.value_or(-1),
+ *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_type->m_die), die);
- if (!attrs.is_forward_declaration) {
- // 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_type->m_is_forward_declaration) {
- unique_ast_entry_type->m_die = die;
- unique_ast_entry_type->m_byte_size = byte_size;
- unique_ast_entry_type->m_declaration = unique_decl;
- unique_ast_entry_type->m_is_forward_declaration = false;
- // Need to update Type ID to refer to the definition DIE. because
- // it's used in 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(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();
- }
- }
+ GetCachedClangDeclContextForDIE(unique_ast_entry_up->m_die), die);
return type_sp;
}
}
@@ -1840,21 +1695,125 @@ 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.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} ({3}) type \"{4}\" is an "
+ "incomplete objc type, complete type is {5:x8}",
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), 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} ({3}) type \"{4}\" is a "
+ "forward declaration, trying to find complete type",
+ static_cast<void *>(this), die.GetOffset(), DW_TAG_value_to_name(tag),
+ 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} ({3}) type \"{4}\" is a "
+ "forward declaration, complete type is {5:x8}",
+ static_cast<void *>(this), die.GetOffset(),
+ DW_TAG_value_to_name(tag), 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);
- DWARFDIE decl_ctx_die;
- clang::DeclContext *decl_ctx =
- GetClangDeclContextContainingDIE(die, &decl_ctx_die);
+ bool clang_type_was_created = false;
+ clang::DeclContext *decl_ctx = GetClangDeclContextContainingDIE(die, nullptr);
- PrepareContextToReceiveMembers(decl_ctx, decl_ctx_die, die,
+ PrepareContextToReceiveMembers(m_ast, GetClangASTImporter(), decl_ctx, die,
attrs.name.GetCString());
if (attrs.accessibility == eAccessNone && decl_ctx) {
@@ -1893,17 +1852,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) {
+ if (!clang_type_was_created) {
+ clang_type_was_created = true;
clang_type = m_ast.CreateRecordType(
decl_ctx, GetOwningClangModule(die), attrs.accessibility,
attrs.name.GetCString(), tag_decl_kind, attrs.class_language, &metadata,
attrs.exports_symbols);
}
+
// 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.
@@ -1914,19 +1876,13 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
Type::ResolveState::Forward,
TypePayloadClang(OptionalClangModuleID(), attrs.is_complete_objc_class));
- // UniqueDWARFASTType is large, so don't create a local variables on the
- // stack, put it on the heap. This function is often called recursively and
- // clang isn't good at sharing the stack space for variables in
diff erent
- // blocks.
- auto unique_ast_entry_up = std::make_unique<UniqueDWARFASTType>();
// Add our type to the unique type map so we don't end up creating many
// copies of the same type over and over in the ASTContext for our
// module
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 = byte_size;
- unique_ast_entry_up->m_is_forward_declaration = attrs.is_forward_declaration;
+ unique_ast_entry_up->m_byte_size = attrs.byte_size.value_or(0);
dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename,
*unique_ast_entry_up);
@@ -1967,7 +1923,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
GetClangASTImporter().SetRecordLayout(record_decl, layout);
}
}
- } else {
+ } 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
@@ -1979,21 +1935,26 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
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);
}
}
- // 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!");
- 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/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 853b8ccc30369..8d4af203bb287 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 DWARFDIE &die,
- bool *type_is_new_ptr) override;
+ lldb::TypeSP
+ ParseTypeFromDWARF(const lldb_private::SymbolContext &sc,
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ bool *type_is_new_ptr) override;
- lldb_private::ConstString
- ConstructDemangledNameFromDWARF(const DWARFDIE &die) override;
+ lldb_private::ConstString ConstructDemangledNameFromDWARF(
+ const lldb_private::plugin::dwarf::DWARFDIE &die) override;
lldb_private::Function *
ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit,
- const DWARFDIE &die,
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
const lldb_private::AddressRange &func_range) override;
bool
- CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type,
+ CompleteTypeFromDWARF(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ lldb_private::Type *type,
lldb_private::CompilerType &compiler_type) override;
- lldb_private::CompilerDecl
- GetDeclForUIDFromDWARF(const DWARFDIE &die) override;
+ lldb_private::CompilerDecl GetDeclForUIDFromDWARF(
+ const lldb_private::plugin::dwarf::DWARFDIE &die) override;
void EnsureAllDIEsInDeclContextHaveBeenParsed(
lldb_private::CompilerDeclContext decl_context) override;
- lldb_private::CompilerDeclContext
- GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override;
+ lldb_private::CompilerDeclContext GetDeclContextForUIDFromDWARF(
+ const lldb_private::plugin::dwarf::DWARFDIE &die) override;
- lldb_private::CompilerDeclContext
- GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override;
+ lldb_private::CompilerDeclContext GetDeclContextContainingUIDFromDWARF(
+ const lldb_private::plugin::dwarf::DWARFDIE &die) override;
lldb_private::ClangASTImporter &GetClangASTImporter();
@@ -105,13 +105,8 @@ 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 DWARFDIE &die) 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;
+ lldb_private::ConstString GetDIEClassTemplateParams(
+ const lldb_private::plugin::dwarf::DWARFDIE &die) override;
protected:
/// Protected typedefs and members.
@@ -123,7 +118,8 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
const lldb_private::plugin::dwarf::DWARFDebugInfoEntry *,
clang::DeclContext *>
DIEToDeclContextMap;
- typedef std::multimap<const clang::DeclContext *, const DWARFDIE>
+ typedef std::multimap<const clang::DeclContext *,
+ const lldb_private::plugin::dwarf::DWARFDIE>
DeclContextToDIEMap;
typedef llvm::DenseMap<
const lldb_private::plugin::dwarf::DWARFDebugInfoEntry *,
@@ -141,11 +137,14 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
std::unique_ptr<lldb_private::ClangASTImporter> m_clang_ast_importer_up;
/// @}
- clang::DeclContext *GetDeclContextForBlock(const DWARFDIE &die);
+ clang::DeclContext *
+ GetDeclContextForBlock(const lldb_private::plugin::dwarf::DWARFDIE &die);
- clang::BlockDecl *ResolveBlockDIE(const DWARFDIE &die);
+ clang::BlockDecl *
+ ResolveBlockDIE(const lldb_private::plugin::dwarf::DWARFDIE &die);
- clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die);
+ clang::NamespaceDecl *
+ ResolveNamespaceDIE(const lldb_private::plugin::dwarf::DWARFDIE &die);
/// Returns the namespace decl that a DW_TAG_imported_declaration imports.
///
@@ -156,86 +155,96 @@ 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 DWARFDIE &die);
+ clang::NamespaceDecl *ResolveImportedDeclarationDIE(
+ const lldb_private::plugin::dwarf::DWARFDIE &die);
- bool ParseTemplateDIE(const DWARFDIE &die,
+ bool ParseTemplateDIE(const lldb_private::plugin::dwarf::DWARFDIE &die,
lldb_private::TypeSystemClang::TemplateParameterInfos
&template_param_infos);
bool ParseTemplateParameterInfos(
- const DWARFDIE &parent_die,
+ const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
lldb_private::TypeSystemClang::TemplateParameterInfos
&template_param_infos);
- std::string GetCPlusPlusQualifiedName(const DWARFDIE &die);
+ std::string
+ GetCPlusPlusQualifiedName(const lldb_private::plugin::dwarf::DWARFDIE &die);
bool ParseChildMembers(
- const DWARFDIE &die, lldb_private::CompilerType &class_compiler_type,
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ lldb_private::CompilerType &class_compiler_type,
std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
- std::vector<DWARFDIE> &member_function_dies,
- std::vector<DWARFDIE> &contained_type_dies,
+ std::vector<lldb_private::plugin::dwarf::DWARFDIE> &member_function_dies,
+ std::vector<lldb_private::plugin::dwarf::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 DWARFDIE &parent_die, bool skip_artificial,
- bool &is_static, bool &is_variadic,
+ const lldb_private::plugin::dwarf::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 DWARFDIE &parent_die);
+ size_t ParseChildEnumerators(
+ lldb_private::CompilerType &compiler_type, bool is_signed,
+ uint32_t enumerator_byte_size,
+ const lldb_private::plugin::dwarf::DWARFDIE &parent_die);
/// Parse a structure, class, or union type DIE.
- lldb::TypeSP ParseStructureLikeDIE(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die,
- ParsedDWARFTypeAttributes &attrs);
+ lldb::TypeSP
+ ParseStructureLikeDIE(const lldb_private::SymbolContext &sc,
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ ParsedDWARFTypeAttributes &attrs);
- clang::Decl *GetClangDeclForDIE(const DWARFDIE &die);
+ clang::Decl *
+ GetClangDeclForDIE(const lldb_private::plugin::dwarf::DWARFDIE &die);
- clang::DeclContext *GetClangDeclContextForDIE(const DWARFDIE &die);
+ clang::DeclContext *
+ GetClangDeclContextForDIE(const lldb_private::plugin::dwarf::DWARFDIE &die);
- clang::DeclContext *GetClangDeclContextContainingDIE(const DWARFDIE &die,
- DWARFDIE *decl_ctx_die);
- lldb_private::OptionalClangModuleID GetOwningClangModule(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);
- bool CopyUniqueClassMethodTypes(const DWARFDIE &src_class_die,
- const DWARFDIE &dst_class_die,
- lldb_private::Type *class_type,
- std::vector<DWARFDIE> &failures);
+ 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);
- clang::DeclContext *GetCachedClangDeclContextForDIE(const DWARFDIE &die);
+ clang::DeclContext *GetCachedClangDeclContextForDIE(
+ const lldb_private::plugin::dwarf::DWARFDIE &die);
- void LinkDeclContextToDIE(clang::DeclContext *decl_ctx, const DWARFDIE &die);
+ void LinkDeclContextToDIE(clang::DeclContext *decl_ctx,
+ const lldb_private::plugin::dwarf::DWARFDIE &die);
- void LinkDeclToDIE(clang::Decl *decl, const DWARFDIE &die);
+ void LinkDeclToDIE(clang::Decl *decl,
+ const lldb_private::plugin::dwarf::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 DWARFDIE &die, lldb::TypeSP type_sp);
+ lldb::TypeSP UpdateSymbolContextScopeForType(
+ const lldb_private::SymbolContext &sc,
+ const lldb_private::plugin::dwarf::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 DWARFDIE &die,
- lldb_private::Log *log);
+ lldb::TypeSP
+ ParseTypeFromClangModule(const lldb_private::SymbolContext &sc,
+ const lldb_private::plugin::dwarf::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 DWARFDIE &die);
-
- void PrepareContextToReceiveMembers(clang::DeclContext *decl_ctx,
- const DWARFDIE &decl_ctx_die,
- const DWARFDIE &die,
- const char *type_name_cstr);
+ lldb::ModuleSP
+ GetModuleForType(const lldb_private::plugin::dwarf::DWARFDIE &die);
static bool classof(const DWARFASTParser *Parser) {
return Parser->GetKind() == Kind::DWARFASTParserClang;
@@ -265,8 +274,10 @@ 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 DWARFDIE &die, const DWARFDIE &parent_die,
- lldb::ModuleSP module_sp);
+ explicit MemberAttributes(
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ const lldb_private::plugin::dwarf::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.
@@ -313,12 +324,15 @@ 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 DWARFDIE &die, const DWARFDIE &parent_die,
- const lldb_private::CompilerType &class_clang_type,
- DelayedPropertyList &delayed_properties);
+ 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
- ParseSingleMember(const DWARFDIE &die, const DWARFDIE &parent_die,
+ ParseSingleMember(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
const lldb_private::CompilerType &class_clang_type,
lldb::AccessType default_accessibility,
lldb_private::ClangASTImporter::LayoutInfo &layout_info,
@@ -336,25 +350,31 @@ 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 DWARFDIE &die, const MemberAttributes &attrs,
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ const MemberAttributes &attrs,
const lldb_private::CompilerType &class_clang_type);
- bool CompleteRecordType(const DWARFDIE &die, lldb_private::Type *type,
+ bool CompleteRecordType(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ lldb_private::Type *type,
lldb_private::CompilerType &clang_type);
- bool CompleteEnumType(const DWARFDIE &die, lldb_private::Type *type,
+ bool CompleteEnumType(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ lldb_private::Type *type,
lldb_private::CompilerType &clang_type);
- lldb::TypeSP ParseTypeModifier(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die,
- ParsedDWARFTypeAttributes &attrs);
+ lldb::TypeSP
+ ParseTypeModifier(const lldb_private::SymbolContext &sc,
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ ParsedDWARFTypeAttributes &attrs);
lldb::TypeSP ParseEnum(const lldb_private::SymbolContext &sc,
- const DWARFDIE &die, ParsedDWARFTypeAttributes &attrs);
- lldb::TypeSP ParseSubroutine(const DWARFDIE &die,
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ ParsedDWARFTypeAttributes &attrs);
+ lldb::TypeSP ParseSubroutine(const lldb_private::plugin::dwarf::DWARFDIE &die,
const ParsedDWARFTypeAttributes &attrs);
- lldb::TypeSP ParseArrayType(const DWARFDIE &die,
+ lldb::TypeSP ParseArrayType(const lldb_private::plugin::dwarf::DWARFDIE &die,
const ParsedDWARFTypeAttributes &attrs);
- lldb::TypeSP ParsePointerToMemberType(const DWARFDIE &die,
- const ParsedDWARFTypeAttributes &attrs);
+ lldb::TypeSP
+ ParsePointerToMemberType(const lldb_private::plugin::dwarf::DWARFDIE &die,
+ const ParsedDWARFTypeAttributes &attrs);
/// Parses a DW_TAG_inheritance DIE into a base/super class.
///
@@ -371,7 +391,8 @@ 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 DWARFDIE &die, const DWARFDIE &parent_die,
+ const lldb_private::plugin::dwarf::DWARFDIE &die,
+ const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
const lldb_private::CompilerType class_clang_type,
const lldb::AccessType default_accessibility,
const lldb::ModuleSP &module_sp,
@@ -388,7 +409,8 @@ 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(DWARFDIE &die, const DWARFDIE &parent_die,
+ ParseRustVariantPart(lldb_private::plugin::dwarf::DWARFDIE &die,
+ const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
lldb_private::CompilerType &class_clang_type,
const lldb::AccessType default_accesibility,
lldb_private::ClangASTImporter::LayoutInfo &layout_info);
@@ -398,9 +420,8 @@ 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 {
- typedef lldb_private::plugin::dwarf::DWARFDIE DWARFDIE;
-
- explicit ParsedDWARFTypeAttributes(const DWARFDIE &die);
+ explicit ParsedDWARFTypeAttributes(
+ const lldb_private::plugin::dwarf::DWARFDIE &die);
lldb::AccessType accessibility = lldb::eAccessNone;
bool is_artificial = false;
@@ -417,7 +438,7 @@ struct ParsedDWARFTypeAttributes {
const char *mangled_name = nullptr;
lldb_private::ConstString name;
lldb_private::Declaration decl;
- DWARFDIE object_pointer;
+ lldb_private::plugin::dwarf::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 5a07fd30fbf70..f6f152726bf74 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1632,33 +1632,27 @@ bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
return true;
}
- // Once we start resolving this type, remove it from the forward
- // 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);
- Type *type = nullptr;
- if (DWARFASTParser *dwarf_ast = GetDWARFParser(*dwarf_die.GetCU()))
- type = dwarf_ast->FindDefinitionTypeForDIE(dwarf_die);
- if (!type)
- return false;
-
- die_it = GetForwardDeclCompilerTypeToDIE().find(
- compiler_type_no_qualifiers.GetOpaqueQualType());
- if (die_it != GetForwardDeclCompilerTypeToDIE().end()) {
- dwarf_die = GetDIE(die_it->getSecond());
+ DWARFDIE dwarf_die = 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);
- }
- if (Log *log = GetLog(DWARFLog::DebugInfo | DWARFLog::TypeCompletion))
- GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
- log, "{0:x8}: {1} ({2}) '{3}' resolving forward declaration...",
- dwarf_die.GetID(), DW_TAG_value_to_name(dwarf_die.Tag()),
- dwarf_die.Tag(), 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 *type = GetDIEToType().lookup(dwarf_die.GetDIE());
+
+ Log *log = GetLog(DWARFLog::DebugInfo | DWARFLog::TypeCompletion);
+ if (log)
+ GetObjectFile()->GetModule()->LogMessageVerboseBacktrace(
+ log, "{0:x8}: {1} ({2}) '{3}' resolving forward declaration...",
+ dwarf_die.GetID(), DW_TAG_value_to_name(dwarf_die.Tag()),
+ dwarf_die.Tag(), type->GetName().AsCString());
+ assert(compiler_type);
+ if (DWARFASTParser *dwarf_ast = GetDWARFParser(*dwarf_die.GetCU()))
+ return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type, compiler_type);
+ }
+ return false;
}
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 94aa810680c52..7282c08c6857c 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -533,12 +533,8 @@ 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;
llvm::DenseMap<dw_offset_t, std::unique_ptr<SupportFileList>>
m_type_unit_support_files;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
index 4762356034cab..223518f0ae824 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp
@@ -13,67 +13,66 @@
using namespace lldb_private::dwarf;
using namespace lldb_private::plugin::dwarf;
-UniqueDWARFASTType *UniqueDWARFASTTypeList::Find(
- const DWARFDIE &die, const lldb_private::Declaration &decl,
- const int32_t byte_size, bool is_forward_declaration) {
- for (UniqueDWARFASTType &udt : m_collection) {
+bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die,
+ const lldb_private::Declaration &decl,
+ const int32_t byte_size,
+ UniqueDWARFASTType &entry) const {
+ for (const UniqueDWARFASTType &udt : m_collection) {
// Make sure the tags match
if (udt.m_die.Tag() == die.Tag()) {
- // 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)
- 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;
+ // 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
+ {
+ 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;
+ parent_arg_die = parent_arg_die.GetParent();
+ parent_pos_die = parent_pos_die.GetParent();
+ }
- case DW_TAG_compile_unit:
- case DW_TAG_partial_unit:
- done = true;
- break;
- default:
- break;
+ if (match) {
+ entry = udt;
+ return true;
}
}
- parent_arg_die = parent_arg_die.GetParent();
- parent_pos_die = parent_pos_die.GetParent();
- }
-
- if (match) {
- return &udt;
}
}
}
- return nullptr;
+ return false;
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
index 29e5c02dcbe17..bf3cbae55e5c7 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h
@@ -23,19 +23,31 @@ class UniqueDWARFASTType {
// Constructors and Destructors
UniqueDWARFASTType() : m_type_sp(), m_die(), m_declaration() {}
+ UniqueDWARFASTType(lldb::TypeSP &type_sp, const DWARFDIE &die,
+ const Declaration &decl, int32_t byte_size)
+ : m_type_sp(type_sp), m_die(die), m_declaration(decl),
+ m_byte_size(byte_size) {}
+
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_is_forward_declaration(rhs.m_is_forward_declaration) {}
+ m_declaration(rhs.m_declaration), m_byte_size(rhs.m_byte_size) {}
~UniqueDWARFASTType() = default;
+ UniqueDWARFASTType &operator=(const UniqueDWARFASTType &rhs) {
+ if (this != &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;
+ }
+ return *this;
+ }
+
lldb::TypeSP m_type_sp;
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 {
@@ -50,9 +62,8 @@ class UniqueDWARFASTTypeList {
m_collection.push_back(entry);
}
- UniqueDWARFASTType *Find(const DWARFDIE &die, const Declaration &decl,
- const int32_t byte_size,
- bool is_forward_declaration);
+ bool Find(const DWARFDIE &die, const Declaration &decl,
+ const int32_t byte_size, UniqueDWARFASTType &entry) const;
protected:
typedef std::vector<UniqueDWARFASTType> collection;
@@ -69,15 +80,14 @@ class UniqueDWARFASTTypeMap {
m_collection[name.GetCString()].Append(entry);
}
- UniqueDWARFASTType *Find(ConstString name, const DWARFDIE &die,
- const Declaration &decl, const int32_t byte_size,
- bool is_forward_declaration) {
+ bool Find(ConstString name, const DWARFDIE &die, const Declaration &decl,
+ const int32_t byte_size, UniqueDWARFASTType &entry) const {
const char *unique_name_cstr = name.GetCString();
- collection::iterator pos = m_collection.find(unique_name_cstr);
+ collection::const_iterator pos = m_collection.find(unique_name_cstr);
if (pos != m_collection.end()) {
- return pos->second.Find(die, decl, byte_size, is_forward_declaration);
+ return pos->second.Find(die, decl, byte_size, entry);
}
- return nullptr;
+ return false;
}
protected:
More information about the lldb-commits
mailing list