labath created this revision.
labath added reviewers: teemperor, aprantl.
Herald added a reviewer: shafik.
Herald added a project: LLDB.
Unify the code for requiring a complete type and move it into a single
place. The only functional change is that the "cannot start a definition
of an incomplete type" is upgrated from a runtime error/warning to an
lldbassert. An plain assert might also be fine, since (AFAICT) this can
only happen in case of a programmer error.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D83199
Files:
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -219,6 +219,12 @@
ParsedDWARFTypeAttributes &attrs);
lldb::TypeSP ParsePointerToMemberType(const DWARFDIE &die,
const ParsedDWARFTypeAttributes &attrs);
+
+ /// Complete a type from debug info, or mark it as forcefully completed if
+ /// there is no of the type in the current Module. Call this function in
+ /// contexts where the usual C++ rules require a type to be complete (base
+ /// class, member, etc.).
+ void CompleteType(lldb_private::CompilerType type);
};
/// Parsed form of all attributes that are relevant for type reconstruction.
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1263,32 +1263,7 @@
if (attrs.byte_stride == 0 && attrs.bit_stride == 0)
attrs.byte_stride = element_type->GetByteSize().getValueOr(0);
CompilerType array_element_type = element_type->GetForwardCompilerType();
-
- if (TypeSystemClang::IsCXXClassType(array_element_type) &&
- !array_element_type.GetCompleteType()) {
- ModuleSP module_sp = die.GetModule();
-
- // Mark the class as complete, but we make a note of the fact that
- // this class is not _really_ complete so we can later search for a
- // definition in a different module.
- // Since we provide layout assistance, all ivars in this class and other
- // classes will be fine even if we are not able to find the definition
- // elsewhere.
- if (TypeSystemClang::StartTagDeclarationDefinition(array_element_type)) {
- TypeSystemClang::CompleteTagDeclarationDefinition(array_element_type);
- const auto *td =
- TypeSystemClang::GetQualType(array_element_type.GetOpaqueQualType())
- .getTypePtr()
- ->getAsTagDecl();
- m_ast.GetMetadata(td)->SetIsForcefullyCompleted();
- } else {
- module_sp->ReportError("DWARF DIE at 0x%8.8x was not able to "
- "start its definition.\nPlease file a "
- "bug and attach the file at the start "
- "of this error message",
- type_die.GetOffset());
- }
- }
+ CompleteType(array_element_type);
uint64_t array_element_bit_stride =
attrs.byte_stride * 8 + attrs.bit_stride;
@@ -1343,6 +1318,30 @@
return nullptr;
}
+void DWARFASTParserClang::CompleteType(CompilerType type) {
+ // Technically, enums can be incomplete too, but we don't handle those as they
+ // are emitted even under -flimit-debug-info.
+ if (!TypeSystemClang::IsCXXClassType(type))
+ return;
+
+ if (type.GetCompleteType())
+ return;
+
+ // No complete definition in this module. Mark the class as complete to
+ // satisfy local ast invariants, but make a note of the fact that
+ // it is not _really_ complete so we can later search for a definition in a
+ // different module.
+ // Since we provide layout assistance, layouts of types containing this class
+ // will be correct even if we are not able to find the definition elsewhere.
+ bool started = TypeSystemClang::StartTagDeclarationDefinition(type);
+ lldbassert(started && "Unable to start a class type definition.");
+ TypeSystemClang::CompleteTagDeclarationDefinition(type);
+ const auto *td = TypeSystemClang::GetQualType(type.GetOpaqueQualType())
+ .getTypePtr()
+ ->getAsTagDecl();
+ m_ast.GetMetadata(td)->SetIsForcefullyCompleted();
+}
+
TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType(
const SymbolContext &sc, const DWARFDIE &die, TypeSP type_sp) {
if (!type_sp)
@@ -2045,26 +2044,8 @@
for (const auto &base_class : bases) {
clang::TypeSourceInfo *type_source_info =
base_class->getTypeSourceInfo();
- if (type_source_info) {
- CompilerType base_class_type =
- m_ast.GetType(type_source_info->getType());
- if (!base_class_type.GetCompleteType()) {
- // We mark the class as complete to allow the TransferBaseClasses
- // call to succeed. But we make a note of the fact that this class
- // is not _really_ complete so we can later search for a definition
- // in a different module.
- if (TypeSystemClang::StartTagDeclarationDefinition(
- base_class_type)) {
- TypeSystemClang::CompleteTagDeclarationDefinition(
- base_class_type);
- const auto *td = TypeSystemClang::GetQualType(
- base_class_type.GetOpaqueQualType())
- .getTypePtr()
- ->getAsTagDecl();
- m_ast.GetMetadata(td)->SetIsForcefullyCompleted();
- }
- }
- }
+ if (type_source_info)
+ CompleteType(m_ast.GetType(type_source_info->getType()));
}
m_ast.TransferBaseClasses(clang_type.GetOpaqueQualType(),
@@ -2727,34 +2708,7 @@
}
}
- if (TypeSystemClang::IsCXXClassType(member_clang_type) &&
- !member_clang_type.GetCompleteType()) {
- // Mark the class as complete, but we make a note of the fact that
- // this class is not _really_ complete so we can later search for a
- // definition in a different module.
- // Since we provide layout assistance, all ivars in this class and
- // other classes will be fine even if we are not able to find the
- // definition elsewhere.
- if (TypeSystemClang::StartTagDeclarationDefinition(
- member_clang_type)) {
- TypeSystemClang::CompleteTagDeclarationDefinition(
- member_clang_type);
- const auto *td = TypeSystemClang::GetQualType(
- member_clang_type.GetOpaqueQualType())
- .getTypePtr()
- ->getAsTagDecl();
- m_ast.GetMetadata(td)->SetIsForcefullyCompleted();
- } else {
- module_sp->ReportError(
- "DWARF DIE at 0x%8.8x (class %s) has a member variable "
- "0x%8.8x (%s) whose type claims to be a C++ class but we "
- "were not able to start its definition.\nPlease file a "
- "bug and attach the file at the start of this error "
- "message",
- parent_die.GetOffset(), parent_die.GetName(), die.GetOffset(),
- name);
- }
- }
+ CompleteType(member_clang_type);
field_decl = TypeSystemClang::AddFieldToRecordType(
class_clang_type, name, member_clang_type, accessibility,
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits