Author: Pavel Labath Date: 2020-07-07T11:37:55+02:00 New Revision: 2cdf108d329bda280948ad634aa0a070337a5f88
URL: https://github.com/llvm/llvm-project/commit/2cdf108d329bda280948ad634aa0a070337a5f88 DIFF: https://github.com/llvm/llvm-project/commit/2cdf108d329bda280948ad634aa0a070337a5f88.diff LOG: [lldb/DWARF] Add a utility function for (forceful) completion of types Summary: 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. Reviewers: teemperor, aprantl, shafik Subscribers: lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D83199 Added: Modified: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h Removed: ################################################################################ diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 0bd2d0c05c1b..7de88274ccf6 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1263,32 +1263,7 @@ TypeSP DWARFASTParserClang::ParseArrayType(const DWARFDIE &die, 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 diff erent 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,28 @@ TypeSP DWARFASTParserClang::ParsePointerToMemberType( 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 + // diff erent 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 clang::TagDecl *td = ClangUtil::GetAsTagDecl(type); + m_ast.GetMetadata(td)->SetIsForcefullyCompleted(); +} + TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType( const SymbolContext &sc, const DWARFDIE &die, TypeSP type_sp) { if (!type_sp) @@ -2045,26 +2042,8 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die, 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 diff erent 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 +2706,7 @@ void DWARFASTParserClang::ParseSingleMember( } } - 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 diff erent 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, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index 71d978536f8f..cb718a207d2d 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -219,6 +219,12 @@ class DWARFASTParserClang : public DWARFASTParser { 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. _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits