[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:
Raphael Isemann 2019-12-04 09:38:49 +01:00
parent 3b47e6efb9
commit 4d37f18b29
2 changed files with 509 additions and 462 deletions

View File

@ -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.

View File

@ -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,