================ @@ -2192,87 +2097,82 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die, ClangASTImporter::LayoutInfo layout_info; std::vector<DWARFDIE> contained_type_dies; - if (die.HasChildren()) { - const bool type_is_objc_object_or_interface = - TypeSystemClang::IsObjCObjectOrInterfaceType(clang_type); - if (type_is_objc_object_or_interface) { - // For objective C we don't start the definition when the class is - // created. - TypeSystemClang::StartTagDeclarationDefinition(clang_type); - } - - AccessType default_accessibility = eAccessNone; - if (tag == DW_TAG_structure_type) { - default_accessibility = eAccessPublic; - } else if (tag == DW_TAG_union_type) { - default_accessibility = eAccessPublic; - } else if (tag == DW_TAG_class_type) { - default_accessibility = eAccessPrivate; - } - - std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases; - // Parse members and base classes first - std::vector<DWARFDIE> member_function_dies; - - DelayedPropertyList delayed_properties; - ParseChildMembers(die, clang_type, bases, member_function_dies, - contained_type_dies, delayed_properties, - default_accessibility, layout_info); - - // Now parse any methods if there were any... - for (const DWARFDIE &die : member_function_dies) - dwarf->ResolveType(die); - - if (type_is_objc_object_or_interface) { - ConstString class_name(clang_type.GetTypeName()); - if (class_name) { - dwarf->GetObjCMethods(class_name, [&](DWARFDIE method_die) { - method_die.ResolveType(); - return true; - }); + if (die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0)) + return false; // No definition, cannot complete. - for (DelayedAddObjCClassProperty &property : delayed_properties) - property.Finalize(); - } - } + // Start the definition if the type is not being defined already. This can + // happen (e.g.) when adding nested types to a class type -- see + // PrepareContextToReceiveMembers. + if (!clang_type.IsBeingDefined()) + TypeSystemClang::StartTagDeclarationDefinition(clang_type); - if (!bases.empty()) { - // Make sure all base classes refer to complete types and not forward - // declarations. If we don't do this, clang will crash with an - // assertion in the call to clang_type.TransferBaseClasses() - for (const auto &base_class : bases) { - clang::TypeSourceInfo *type_source_info = - base_class->getTypeSourceInfo(); - if (type_source_info) - TypeSystemClang::RequireCompleteType( - m_ast.GetType(type_source_info->getType())); - } + AccessType default_accessibility = eAccessNone; + if (tag == DW_TAG_structure_type) { + default_accessibility = eAccessPublic; + } else if (tag == DW_TAG_union_type) { + default_accessibility = eAccessPublic; + } else if (tag == DW_TAG_class_type) { + default_accessibility = eAccessPrivate; + } + + std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases; + // Parse members and base classes first + std::vector<DWARFDIE> member_function_dies; - m_ast.TransferBaseClasses(clang_type.GetOpaqueQualType(), - std::move(bases)); + DelayedPropertyList delayed_properties; + ParseChildMembers(die, clang_type, bases, member_function_dies, + contained_type_dies, delayed_properties, + default_accessibility, layout_info); + + // Now parse any methods if there were any... + for (const DWARFDIE &die : member_function_dies) + dwarf->ResolveType(die); + + if (TypeSystemClang::IsObjCObjectOrInterfaceType(clang_type)) { + ConstString class_name(clang_type.GetTypeName()); + if (class_name) { + dwarf->GetObjCMethods(class_name, [&](DWARFDIE method_die) { + method_die.ResolveType(); + return true; + }); + + for (DelayedAddObjCClassProperty &property : delayed_properties) + property.Finalize(); } } + if (!bases.empty()) { + // Make sure all base classes refer to complete types and not forward + // declarations. If we don't do this, clang will crash with an + // assertion in the call to clang_type.TransferBaseClasses() + for (const auto &base_class : bases) { + clang::TypeSourceInfo *type_source_info = base_class->getTypeSourceInfo(); + if (type_source_info) + TypeSystemClang::RequireCompleteType( + m_ast.GetType(type_source_info->getType())); + } + + m_ast.TransferBaseClasses(clang_type.GetOpaqueQualType(), std::move(bases)); + } + m_ast.AddMethodOverridesForCXXRecordType(clang_type.GetOpaqueQualType()); TypeSystemClang::BuildIndirectFields(clang_type); TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); - if (!layout_info.field_offsets.empty() || !layout_info.base_offsets.empty() || - !layout_info.vbase_offsets.empty()) { ---------------- labath wrote:
The removal of these checks compensates for the deletion of lines 1914--1930. I've traced the checks back to at least 2012 (2508b9b8d3e291c3dd6414547c68ec2bdf35428f) without a clear indication of why they are necessary. The way I see it, the only way this can matter is of a compiler does not provide member offsets for members/base classes, but does provide a overall size of the type. I don't know why would anyone do that, and I suspect this remained unnoticed because we simply never hit this place for empty classes (because we were eagerly completing those in ParseTypeFromDWARF). https://github.com/llvm/llvm-project/pull/96755 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits