[Lldb-commits] [lldb] 7103753 - [lldb][NFC] Split out DW_TAG_inheritance parsing into own function
Raphael Isemann via lldb-commits
lldb-commits at lists.llvm.org
Wed Oct 13 04:15:17 PDT 2021
Author: Raphael Isemann
Date: 2021-10-13T13:14:57+02:00
New Revision: 7103753733a83602199958fb189d24f62c7400e8
URL: https://github.com/llvm/llvm-project/commit/7103753733a83602199958fb189d24f62c7400e8
DIFF: https://github.com/llvm/llvm-project/commit/7103753733a83602199958fb189d24f62c7400e8.diff
LOG: [lldb][NFC] Split out DW_TAG_inheritance parsing into own function
Just moving that block inside DWARFASTParserClang::ParseChildMembers into
its own function. Also early-exiting instead of a large if when
num_attributes is 0.
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 4af1c29ecb79f..bed3dcbe570de 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1406,6 +1406,123 @@ TypeSP DWARFASTParserClang::ParsePointerToMemberType(
return nullptr;
}
+void DWARFASTParserClang::ParseInheritance(
+ const DWARFDIE &die, const DWARFDIE &parent_die,
+ const CompilerType class_clang_type, const AccessType default_accessibility,
+ const lldb::ModuleSP &module_sp,
+ std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
+ ClangASTImporter::LayoutInfo &layout_info) {
+
+ TypeSystemClang *ast =
+ llvm::dyn_cast_or_null<TypeSystemClang>(class_clang_type.GetTypeSystem());
+ if (ast == nullptr)
+ return;
+
+ // TODO: implement DW_TAG_inheritance type parsing.
+ DWARFAttributes attributes;
+ const size_t num_attributes = die.GetAttributes(attributes);
+ if (num_attributes == 0)
+ return;
+
+ DWARFFormValue encoding_form;
+ AccessType accessibility = default_accessibility;
+ bool is_virtual = false;
+ bool is_base_of_class = true;
+ off_t member_byte_offset = 0;
+
+ for (uint32_t i = 0; i < num_attributes; ++i) {
+ const dw_attr_t attr = attributes.AttributeAtIndex(i);
+ DWARFFormValue form_value;
+ if (attributes.ExtractFormValueAtIndex(i, form_value)) {
+ switch (attr) {
+ case DW_AT_type:
+ encoding_form = form_value;
+ break;
+ case DW_AT_data_member_location:
+ if (form_value.BlockData()) {
+ Value initialValue(0);
+ Value memberOffset(0);
+ const DWARFDataExtractor &debug_info_data = die.GetData();
+ uint32_t block_length = form_value.Unsigned();
+ uint32_t block_offset =
+ form_value.BlockData() - debug_info_data.GetDataStart();
+ if (DWARFExpression::Evaluate(
+ nullptr, nullptr, module_sp,
+ DataExtractor(debug_info_data, block_offset, block_length),
+ die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr,
+ memberOffset, nullptr)) {
+ member_byte_offset = memberOffset.ResolveValue(nullptr).UInt();
+ }
+ } else {
+ // With DWARF 3 and later, if the value is an integer constant,
+ // this form value is the offset in bytes from the beginning of
+ // the containing entity.
+ member_byte_offset = form_value.Unsigned();
+ }
+ break;
+
+ case DW_AT_accessibility:
+ accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
+ break;
+
+ case DW_AT_virtuality:
+ is_virtual = form_value.Boolean();
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ Type *base_class_type = die.ResolveTypeUID(encoding_form.Reference());
+ if (base_class_type == nullptr) {
+ module_sp->ReportError("0x%8.8x: DW_TAG_inheritance failed to "
+ "resolve the base class at 0x%8.8x"
+ " from enclosing type 0x%8.8x. \nPlease file "
+ "a bug and attach the file at the start of "
+ "this error message",
+ die.GetOffset(),
+ encoding_form.Reference().GetOffset(),
+ parent_die.GetOffset());
+ return;
+ }
+
+ CompilerType base_class_clang_type = base_class_type->GetFullCompilerType();
+ assert(base_class_clang_type);
+ if (TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type)) {
+ ast->SetObjCSuperClass(class_clang_type, base_class_clang_type);
+ return;
+ }
+ std::unique_ptr<clang::CXXBaseSpecifier> result =
+ ast->CreateBaseClassSpecifier(base_class_clang_type.GetOpaqueQualType(),
+ accessibility, is_virtual,
+ is_base_of_class);
+ if (!result)
+ return;
+
+ base_classes.push_back(std::move(result));
+
+ if (is_virtual) {
+ // Do not specify any offset for virtual inheritance. The DWARF
+ // produced by clang doesn't give us a constant offset, but gives
+ // us a DWARF expressions that requires an actual object in memory.
+ // the DW_AT_data_member_location for a virtual base class looks
+ // like:
+ // DW_AT_data_member_location( DW_OP_dup, DW_OP_deref,
+ // DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref,
+ // DW_OP_plus )
+ // Given this, there is really no valid response we can give to
+ // clang for virtual base class offsets, and this should eventually
+ // be removed from LayoutRecordType() in the external
+ // AST source in clang.
+ } else {
+ layout_info.base_offsets.insert(std::make_pair(
+ ast->GetAsCXXRecordDecl(base_class_clang_type.GetOpaqueQualType()),
+ clang::CharUnits::fromQuantity(member_byte_offset)));
+ }
+}
+
TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType(
const SymbolContext &sc, const DWARFDIE &die, TypeSP type_sp) {
if (!type_sp)
@@ -2824,117 +2941,10 @@ bool DWARFASTParserClang::ParseChildMembers(
member_function_dies.push_back(die);
break;
- case DW_TAG_inheritance: {
- // TODO: implement DW_TAG_inheritance type parsing
- DWARFAttributes attributes;
- const size_t num_attributes = die.GetAttributes(attributes);
- if (num_attributes > 0) {
- DWARFFormValue encoding_form;
- AccessType accessibility = default_accessibility;
- bool is_virtual = false;
- bool is_base_of_class = true;
- off_t member_byte_offset = 0;
- uint32_t i;
- for (i = 0; i < num_attributes; ++i) {
- const dw_attr_t attr = attributes.AttributeAtIndex(i);
- DWARFFormValue form_value;
- if (attributes.ExtractFormValueAtIndex(i, form_value)) {
- switch (attr) {
- case DW_AT_type:
- encoding_form = form_value;
- break;
- case DW_AT_data_member_location:
- if (form_value.BlockData()) {
- Value initialValue(0);
- Value memberOffset(0);
- const DWARFDataExtractor &debug_info_data = die.GetData();
- uint32_t block_length = form_value.Unsigned();
- uint32_t block_offset =
- form_value.BlockData() - debug_info_data.GetDataStart();
- if (DWARFExpression::Evaluate(
- nullptr, nullptr, module_sp,
- DataExtractor(debug_info_data, block_offset,
- block_length),
- die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr,
- memberOffset, nullptr)) {
- member_byte_offset =
- memberOffset.ResolveValue(nullptr).UInt();
- }
- } else {
- // With DWARF 3 and later, if the value is an integer constant,
- // this form value is the offset in bytes from the beginning of
- // the containing entity.
- member_byte_offset = form_value.Unsigned();
- }
- break;
-
- case DW_AT_accessibility:
- accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
- break;
-
- case DW_AT_virtuality:
- is_virtual = form_value.Boolean();
- break;
-
- case DW_AT_sibling:
- break;
-
- default:
- break;
- }
- }
- }
-
- Type *base_class_type = die.ResolveTypeUID(encoding_form.Reference());
- if (base_class_type == nullptr) {
- module_sp->ReportError("0x%8.8x: DW_TAG_inheritance failed to "
- "resolve the base class at 0x%8.8x"
- " from enclosing type 0x%8.8x. \nPlease file "
- "a bug and attach the file at the start of "
- "this error message",
- die.GetOffset(),
- encoding_form.Reference().GetOffset(),
- parent_die.GetOffset());
- break;
- }
-
- CompilerType base_class_clang_type =
- base_class_type->GetFullCompilerType();
- assert(base_class_clang_type);
- if (TypeSystemClang::IsObjCObjectOrInterfaceType(class_clang_type)) {
- ast->SetObjCSuperClass(class_clang_type, base_class_clang_type);
- } else {
- std::unique_ptr<clang::CXXBaseSpecifier> result =
- ast->CreateBaseClassSpecifier(
- base_class_clang_type.GetOpaqueQualType(), accessibility,
- is_virtual, is_base_of_class);
- if (!result)
- break;
-
- base_classes.push_back(std::move(result));
-
- if (is_virtual) {
- // Do not specify any offset for virtual inheritance. The DWARF
- // produced by clang doesn't give us a constant offset, but gives
- // us a DWARF expressions that requires an actual object in memory.
- // the DW_AT_data_member_location for a virtual base class looks
- // like:
- // DW_AT_data_member_location( DW_OP_dup, DW_OP_deref,
- // DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref,
- // DW_OP_plus )
- // Given this, there is really no valid response we can give to
- // clang for virtual base class offsets, and this should eventually
- // be removed from LayoutRecordType() in the external
- // AST source in clang.
- } else {
- layout_info.base_offsets.insert(std::make_pair(
- ast->GetAsCXXRecordDecl(
- base_class_clang_type.GetOpaqueQualType()),
- clang::CharUnits::fromQuantity(member_byte_offset)));
- }
- }
- }
- } break;
+ case DW_TAG_inheritance:
+ ParseInheritance(die, parent_die, class_clang_type, default_accessibility,
+ module_sp, base_classes, layout_info);
+ break;
default:
break;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index aa7276fed0a22..272723bb9ab2f 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -212,6 +212,28 @@ class DWARFASTParserClang : public DWARFASTParser {
ParsedDWARFTypeAttributes &attrs);
lldb::TypeSP ParsePointerToMemberType(const DWARFDIE &die,
const ParsedDWARFTypeAttributes &attrs);
+
+ /// Parses a DW_TAG_inheritance DIE into a base/super class.
+ ///
+ /// \param die The DW_TAG_inheritance DIE to parse.
+ /// \param parent_die The parent DIE of the given DIE.
+ /// \param class_clang_type The C++/Objective-C class representing parent_die.
+ /// For an Objective-C class this method sets the super class on success. For
+ /// a C++ class this will *not* add the result as a base class.
+ /// \param default_accessibility The default accessibility that is given to
+ /// base classes if they don't have an explicit accessibility set.
+ /// \param module_sp The current Module.
+ /// \param base_classes The list of C++ base classes that will be appended
+ /// with the parsed base class on success.
+ /// \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::CompilerType class_clang_type,
+ const lldb::AccessType default_accessibility,
+ const lldb::ModuleSP &module_sp,
+ std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
+ lldb_private::ClangASTImporter::LayoutInfo &layout_info);
};
/// Parsed form of all attributes that are relevant for type reconstruction.
More information about the lldb-commits
mailing list