[lldb][NFC] Extract single member parsing out of DWARFASTParserClang::ParseChildMembers
ParseChildMembers does a few things, only one part is actually parsing a single member. This extracts the member parsing logic into its own function. This commit just moves the code as-is into its own function and forwards the parameters/ local variables to it, which means it should be NFC. The only actual changes to the code are replacing 'break's (and one very curious 'continue' that behaves like a 'break') with 'return's.
This commit is contained in:
parent
3b47e6efb9
commit
4d37f18b29
|
|
@ -2448,38 +2448,23 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool DWARFASTParserClang::ParseChildMembers(
|
||||
const DWARFDIE &parent_die, CompilerType &class_clang_type,
|
||||
const LanguageType class_language,
|
||||
std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
|
||||
void DWARFASTParserClang::ParseSingleMember(
|
||||
const DWARFDIE &die, const DWARFDIE &parent_die,
|
||||
lldb_private::CompilerType &class_clang_type,
|
||||
const lldb::LanguageType class_language,
|
||||
std::vector<int> &member_accessibilities,
|
||||
std::vector<DWARFDIE> &member_function_dies,
|
||||
DelayedPropertyList &delayed_properties, AccessType &default_accessibility,
|
||||
bool &is_a_class, ClangASTImporter::LayoutInfo &layout_info) {
|
||||
if (!parent_die)
|
||||
return false;
|
||||
|
||||
lldb::AccessType &default_accessibility,
|
||||
DelayedPropertyList &delayed_properties,
|
||||
lldb_private::ClangASTImporter::LayoutInfo &layout_info,
|
||||
BitfieldInfo &last_field_info) {
|
||||
ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
|
||||
const dw_tag_t tag = die.Tag();
|
||||
// Get the parent byte size so we can verify any members will fit
|
||||
const uint64_t parent_byte_size =
|
||||
parent_die.GetAttributeValueAsUnsigned(DW_AT_byte_size, UINT64_MAX);
|
||||
const uint64_t parent_bit_size =
|
||||
parent_byte_size == UINT64_MAX ? UINT64_MAX : parent_byte_size * 8;
|
||||
|
||||
BitfieldInfo last_field_info;
|
||||
|
||||
ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
|
||||
ClangASTContext *ast =
|
||||
llvm::dyn_cast_or_null<ClangASTContext>(class_clang_type.GetTypeSystem());
|
||||
if (ast == nullptr)
|
||||
return false;
|
||||
|
||||
for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
|
||||
die = die.GetSibling()) {
|
||||
dw_tag_t tag = die.Tag();
|
||||
|
||||
switch (tag) {
|
||||
case DW_TAG_member:
|
||||
case DW_TAG_APPLE_property: {
|
||||
DWARFAttributes attributes;
|
||||
const size_t num_attributes = die.GetAttributes(attributes);
|
||||
if (num_attributes > 0) {
|
||||
|
|
@ -2536,12 +2521,10 @@ bool DWARFASTParserClang::ParseChildMembers(
|
|||
nullptr, // ExecutionContext *
|
||||
nullptr, // RegisterContext *
|
||||
module_sp,
|
||||
DataExtractor(debug_info_data, block_offset,
|
||||
block_length),
|
||||
DataExtractor(debug_info_data, block_offset, block_length),
|
||||
die.GetCU(), eRegisterKindDWARF, &initialValue, nullptr,
|
||||
memberOffset, nullptr)) {
|
||||
member_byte_offset =
|
||||
memberOffset.ResolveValue(nullptr).UInt();
|
||||
member_byte_offset = memberOffset.ResolveValue(nullptr).UInt();
|
||||
}
|
||||
} else {
|
||||
// With DWARF 3 and later, if the value is an integer constant,
|
||||
|
|
@ -2651,7 +2634,7 @@ bool DWARFASTParserClang::ParseChildMembers(
|
|||
class_clang_type, name, var_type->GetLayoutCompilerType(),
|
||||
accessibility);
|
||||
}
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_artificial) {
|
||||
|
|
@ -2665,8 +2648,7 @@ bool DWARFASTParserClang::ParseChildMembers(
|
|||
member_accessibilities.push_back(accessibility);
|
||||
|
||||
uint64_t field_bit_offset =
|
||||
(member_byte_offset == UINT32_MAX ? 0
|
||||
: (member_byte_offset * 8));
|
||||
(member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
|
||||
if (bit_size > 0) {
|
||||
|
||||
BitfieldInfo this_field_info;
|
||||
|
|
@ -2714,10 +2696,9 @@ bool DWARFASTParserClang::ParseChildMembers(
|
|||
") member will be ignored. Please file a bug against the "
|
||||
"compiler and include the preprocessed output for %s\n",
|
||||
die.GetID(), DW_TAG_value_to_name(tag), name,
|
||||
this_field_info.bit_offset,
|
||||
GetUnitName(parent_die).c_str());
|
||||
this_field_info.bit_offset, GetUnitName(parent_die).c_str());
|
||||
this_field_info.Clear();
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the field bit offset we will report for layout
|
||||
|
|
@ -2780,8 +2761,7 @@ bool DWARFASTParserClang::ParseChildMembers(
|
|||
anon_field_info.bit_size =
|
||||
this_field_info.bit_offset % character_width;
|
||||
anon_field_info.bit_offset =
|
||||
this_field_info.bit_offset -
|
||||
anon_field_info.bit_size;
|
||||
this_field_info.bit_offset - anon_field_info.bit_size;
|
||||
} else // case 2
|
||||
{
|
||||
anon_field_info.bit_size =
|
||||
|
|
@ -2795,8 +2775,8 @@ bool DWARFASTParserClang::ParseChildMembers(
|
|||
clang::FieldDecl *unnamed_bitfield_decl =
|
||||
ClangASTContext::AddFieldToRecordType(
|
||||
class_clang_type, llvm::StringRef(),
|
||||
m_ast.GetBuiltinTypeForEncodingAndBitSize(
|
||||
eEncodingSint, word_width),
|
||||
m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint,
|
||||
word_width),
|
||||
accessibility, anon_field_info.bit_size);
|
||||
|
||||
layout_info.field_offsets.insert(std::make_pair(
|
||||
|
|
@ -2808,8 +2788,7 @@ bool DWARFASTParserClang::ParseChildMembers(
|
|||
last_field_info.Clear();
|
||||
}
|
||||
|
||||
CompilerType member_clang_type =
|
||||
member_type->GetLayoutCompilerType();
|
||||
CompilerType member_clang_type = member_type->GetLayoutCompilerType();
|
||||
if (!member_clang_type.IsCompleteType())
|
||||
member_clang_type.GetCompleteType();
|
||||
|
||||
|
|
@ -2824,8 +2803,8 @@ bool DWARFASTParserClang::ParseChildMembers(
|
|||
uint64_t member_array_size;
|
||||
bool member_array_is_incomplete;
|
||||
|
||||
if (member_clang_type.IsArrayType(
|
||||
&member_array_element_type, &member_array_size,
|
||||
if (member_clang_type.IsArrayType(&member_array_element_type,
|
||||
&member_array_size,
|
||||
&member_array_is_incomplete) &&
|
||||
!member_array_is_incomplete) {
|
||||
uint64_t parent_byte_size =
|
||||
|
|
@ -2840,13 +2819,12 @@ bool DWARFASTParserClang::ParseChildMembers(
|
|||
"0x%8.8" PRIx64
|
||||
": DW_TAG_member '%s' refers to type 0x%8.8x"
|
||||
" which extends beyond the bounds of 0x%8.8" PRIx64,
|
||||
die.GetID(), name,
|
||||
encoding_form.Reference().GetOffset(),
|
||||
die.GetID(), name, encoding_form.Reference().GetOffset(),
|
||||
parent_die.GetID());
|
||||
}
|
||||
|
||||
member_clang_type = m_ast.CreateArrayType(
|
||||
member_array_element_type, 0, false);
|
||||
member_clang_type =
|
||||
m_ast.CreateArrayType(member_array_element_type, 0, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2859,16 +2837,16 @@ bool DWARFASTParserClang::ParseChildMembers(
|
|||
"0x%8.8x (%s) whose type is a forward declaration, not a "
|
||||
"complete definition.\nTry compiling the source file "
|
||||
"with -fstandalone-debug",
|
||||
parent_die.GetOffset(), parent_die.GetName(),
|
||||
die.GetOffset(), name);
|
||||
parent_die.GetOffset(), parent_die.GetName(), die.GetOffset(),
|
||||
name);
|
||||
else
|
||||
module_sp->ReportError(
|
||||
"DWARF DIE at 0x%8.8x (class %s) has a member variable "
|
||||
"0x%8.8x (%s) whose type is a forward declaration, not a "
|
||||
"complete definition.\nPlease file a bug against the "
|
||||
"compiler and include the preprocessed output for %s",
|
||||
parent_die.GetOffset(), parent_die.GetName(),
|
||||
die.GetOffset(), name, GetUnitName(parent_die).c_str());
|
||||
parent_die.GetOffset(), parent_die.GetName(), die.GetOffset(),
|
||||
name, GetUnitName(parent_die).c_str());
|
||||
// We have no choice other than to pretend that the member
|
||||
// class is complete. If we don't do this, clang will crash
|
||||
// when trying to layout the class. Since we provide layout
|
||||
|
|
@ -2885,8 +2863,8 @@ bool DWARFASTParserClang::ParseChildMembers(
|
|||
"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);
|
||||
parent_die.GetOffset(), parent_die.GetName(), die.GetOffset(),
|
||||
name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2901,8 +2879,7 @@ bool DWARFASTParserClang::ParseChildMembers(
|
|||
} else {
|
||||
if (name)
|
||||
module_sp->ReportError(
|
||||
"0x%8.8" PRIx64
|
||||
": DW_TAG_member '%s' refers to type 0x%8.8x"
|
||||
"0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8x"
|
||||
" which was unable to be parsed",
|
||||
die.GetID(), name, encoding_form.Reference().GetOffset());
|
||||
else
|
||||
|
|
@ -2924,9 +2901,8 @@ bool DWARFASTParserClang::ParseChildMembers(
|
|||
ClangASTMetadata metadata;
|
||||
metadata.SetUserID(die.GetID());
|
||||
delayed_properties.push_back(DelayedAddObjCClassProperty(
|
||||
class_clang_type, prop_name,
|
||||
member_type->GetLayoutCompilerType(), ivar_decl,
|
||||
prop_setter_name, prop_getter_name, prop_attributes,
|
||||
class_clang_type, prop_name, member_type->GetLayoutCompilerType(),
|
||||
ivar_decl, prop_setter_name, prop_getter_name, prop_attributes,
|
||||
&metadata));
|
||||
|
||||
if (ivar_decl)
|
||||
|
|
@ -2934,7 +2910,38 @@ bool DWARFASTParserClang::ParseChildMembers(
|
|||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
bool DWARFASTParserClang::ParseChildMembers(
|
||||
const DWARFDIE &parent_die, CompilerType &class_clang_type,
|
||||
const LanguageType class_language,
|
||||
std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
|
||||
std::vector<int> &member_accessibilities,
|
||||
std::vector<DWARFDIE> &member_function_dies,
|
||||
DelayedPropertyList &delayed_properties, AccessType &default_accessibility,
|
||||
bool &is_a_class, ClangASTImporter::LayoutInfo &layout_info) {
|
||||
if (!parent_die)
|
||||
return false;
|
||||
|
||||
BitfieldInfo last_field_info;
|
||||
|
||||
ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
|
||||
ClangASTContext *ast =
|
||||
llvm::dyn_cast_or_null<ClangASTContext>(class_clang_type.GetTypeSystem());
|
||||
if (ast == nullptr)
|
||||
return false;
|
||||
|
||||
for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid();
|
||||
die = die.GetSibling()) {
|
||||
dw_tag_t tag = die.Tag();
|
||||
|
||||
switch (tag) {
|
||||
case DW_TAG_member:
|
||||
case DW_TAG_APPLE_property:
|
||||
ParseSingleMember(die, parent_die, class_clang_type, class_language,
|
||||
member_accessibilities, default_accessibility,
|
||||
delayed_properties, layout_info, last_field_info);
|
||||
break;
|
||||
|
||||
case DW_TAG_subprogram:
|
||||
// Let the type parsing code handle this one for us.
|
||||
|
|
|
|||
|
|
@ -170,6 +170,46 @@ protected:
|
|||
lldb::ModuleSP GetModuleForType(const DWARFDIE &die);
|
||||
|
||||
private:
|
||||
struct BitfieldInfo {
|
||||
uint64_t bit_size;
|
||||
uint64_t bit_offset;
|
||||
|
||||
BitfieldInfo()
|
||||
: bit_size(LLDB_INVALID_ADDRESS), bit_offset(LLDB_INVALID_ADDRESS) {}
|
||||
|
||||
void Clear() {
|
||||
bit_size = LLDB_INVALID_ADDRESS;
|
||||
bit_offset = LLDB_INVALID_ADDRESS;
|
||||
}
|
||||
|
||||
bool IsValid() const {
|
||||
return (bit_size != LLDB_INVALID_ADDRESS) &&
|
||||
(bit_offset != LLDB_INVALID_ADDRESS);
|
||||
}
|
||||
|
||||
bool NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const {
|
||||
if (IsValid()) {
|
||||
// This bitfield info is valid, so any subsequent bitfields must not
|
||||
// overlap and must be at a higher bit offset than any previous bitfield
|
||||
// + size.
|
||||
return (bit_size + bit_offset) <= next_bit_offset;
|
||||
} else {
|
||||
// If the this BitfieldInfo is not valid, then any offset isOK
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void
|
||||
ParseSingleMember(const DWARFDIE &die, const DWARFDIE &parent_die,
|
||||
lldb_private::CompilerType &class_clang_type,
|
||||
const lldb::LanguageType class_language,
|
||||
std::vector<int> &member_accessibilities,
|
||||
lldb::AccessType &default_accessibility,
|
||||
DelayedPropertyList &delayed_properties,
|
||||
lldb_private::ClangASTImporter::LayoutInfo &layout_info,
|
||||
BitfieldInfo &last_field_info);
|
||||
|
||||
bool CompleteRecordType(const DWARFDIE &die, lldb_private::Type *type,
|
||||
lldb_private::CompilerType &clang_type);
|
||||
bool CompleteEnumType(const DWARFDIE &die, lldb_private::Type *type,
|
||||
|
|
|
|||
Loading…
Reference in New Issue