[Lldb-commits] [lldb] [lldb/DWARF] Don't start class definitions in ParseStructureLikeDIE (PR #96755)
Pavel Labath via lldb-commits
lldb-commits at lists.llvm.org
Wed Jun 26 05:07:02 PDT 2024
================
@@ -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
More information about the lldb-commits
mailing list