Skip to content

Commit d048eab

Browse files
committed
[lldb][DWARFASTParserClang][NFC] Factor out unnamed bitfield creation into helper (llvm#108196)
This logic will need adjusting soon for llvm#108155 This patch pulls out the logic for detecting/creating unnamed bitfields out of `ParseSingleMember` to make the latter (in my opinion) more readable. Otherwise we have a large number of similarly named variables in scope. (cherry picked from commit f0c6d30)
1 parent 5842d95 commit d048eab

File tree

2 files changed

+70
-36
lines changed

2 files changed

+70
-36
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3024,7 +3024,6 @@ void DWARFASTParserClang::ParseSingleMember(
30243024
}
30253025

30263026
const uint64_t character_width = 8;
3027-
const uint64_t word_width = 32;
30283027
CompilerType member_clang_type = member_type->GetLayoutCompilerType();
30293028

30303029
const auto accessibility = attrs.accessibility == eAccessNone
@@ -3092,40 +3091,9 @@ void DWARFASTParserClang::ParseSingleMember(
30923091
detect_unnamed_bitfields =
30933092
die.GetCU()->Supports_unnamed_objc_bitfields();
30943093

3095-
if (detect_unnamed_bitfields) {
3096-
std::optional<FieldInfo> unnamed_field_info;
3097-
uint64_t last_field_end =
3098-
last_field_info.bit_offset + last_field_info.bit_size;
3099-
3100-
if (!last_field_info.IsBitfield()) {
3101-
// The last field was not a bit-field...
3102-
// but if it did take up the entire word then we need to extend
3103-
// last_field_end so the bit-field does not step into the last
3104-
// fields padding.
3105-
if (last_field_end != 0 && ((last_field_end % word_width) != 0))
3106-
last_field_end += word_width - (last_field_end % word_width);
3107-
}
3108-
3109-
if (ShouldCreateUnnamedBitfield(last_field_info, last_field_end,
3110-
this_field_info, layout_info)) {
3111-
unnamed_field_info = FieldInfo{};
3112-
unnamed_field_info->bit_size =
3113-
this_field_info.bit_offset - last_field_end;
3114-
unnamed_field_info->bit_offset = last_field_end;
3115-
}
3116-
3117-
if (unnamed_field_info) {
3118-
clang::FieldDecl *unnamed_bitfield_decl =
3119-
TypeSystemClang::AddFieldToRecordType(
3120-
class_clang_type, llvm::StringRef(),
3121-
m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint,
3122-
word_width),
3123-
accessibility, unnamed_field_info->bit_size);
3124-
3125-
layout_info.field_offsets.insert(std::make_pair(
3126-
unnamed_bitfield_decl, unnamed_field_info->bit_offset));
3127-
}
3128-
}
3094+
if (detect_unnamed_bitfields)
3095+
AddUnnamedBitfieldToRecordTypeIfNeeded(layout_info, class_clang_type,
3096+
last_field_info, this_field_info);
31293097

31303098
last_field_info = this_field_info;
31313099
last_field_info.SetIsBitfield(true);
@@ -3937,6 +3905,43 @@ bool DWARFASTParserClang::ShouldCreateUnnamedBitfield(
39373905
return true;
39383906
}
39393907

3908+
void DWARFASTParserClang::AddUnnamedBitfieldToRecordTypeIfNeeded(
3909+
ClangASTImporter::LayoutInfo &class_layout_info,
3910+
const CompilerType &class_clang_type, const FieldInfo &previous_field,
3911+
const FieldInfo &current_field) {
3912+
// TODO: get this value from target
3913+
const uint64_t word_width = 32;
3914+
uint64_t last_field_end = previous_field.bit_offset + previous_field.bit_size;
3915+
3916+
if (!previous_field.IsBitfield()) {
3917+
// The last field was not a bit-field...
3918+
// but if it did take up the entire word then we need to extend
3919+
// last_field_end so the bit-field does not step into the last
3920+
// fields padding.
3921+
if (last_field_end != 0 && ((last_field_end % word_width) != 0))
3922+
last_field_end += word_width - (last_field_end % word_width);
3923+
}
3924+
3925+
// Nothing to be done.
3926+
if (!ShouldCreateUnnamedBitfield(previous_field, last_field_end,
3927+
current_field, class_layout_info))
3928+
return;
3929+
3930+
// Place the unnamed bitfield into the gap between the previous field's end
3931+
// and the current field's start.
3932+
const uint64_t unnamed_bit_size = current_field.bit_offset - last_field_end;
3933+
const uint64_t unnamed_bit_offset = last_field_end;
3934+
3935+
clang::FieldDecl *unnamed_bitfield_decl =
3936+
TypeSystemClang::AddFieldToRecordType(
3937+
class_clang_type, llvm::StringRef(),
3938+
m_ast.GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width),
3939+
lldb::AccessType::eAccessPublic, unnamed_bit_size);
3940+
3941+
class_layout_info.field_offsets.insert(
3942+
std::make_pair(unnamed_bitfield_decl, unnamed_bit_offset));
3943+
}
3944+
39403945
void DWARFASTParserClang::ParseRustVariantPart(
39413946
DWARFDIE &die, const DWARFDIE &parent_die, CompilerType &class_clang_type,
39423947
const lldb::AccessType default_accesibility,

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
278278
FieldInfo() = default;
279279

280280
void SetIsBitfield(bool flag) { is_bitfield = flag; }
281-
bool IsBitfield() { return is_bitfield; }
281+
bool IsBitfield() const { return is_bitfield; }
282282

283283
void SetIsArtificial(bool flag) { is_artificial = flag; }
284284
bool IsArtificial() const { return is_artificial; }
@@ -330,6 +330,35 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
330330
FieldInfo const &this_field_info,
331331
lldb_private::ClangASTImporter::LayoutInfo const &layout_info) const;
332332

333+
/// Tries to detect whether \ref class_clang_type contained an unnamed
334+
/// bit-field between \ref previous_field and \ref current_field, and if
335+
/// so, adds a clang::FieldDecl representing that bit-field to
336+
/// \ref class_clang_type.
337+
///
338+
/// This is necessary because Clang (and GCC) doesn't emit a DW_TAG_member
339+
/// entry for unnamed bit-fields. So we derive it (with some exceptions),
340+
/// by checking whether there is a gap between where the storage of a
341+
/// DW_TAG_member ended and the subsequent DW_TAG_member began.
342+
///
343+
/// \param[in,out] layout_info Layout information of all decls parsed by the
344+
/// current parser. Will contain an entry for
345+
/// the unnamed bit-field if this function created
346+
/// one.
347+
///
348+
/// \param[in] class_clang_type The RecordType to which the unnamed bit-field
349+
/// will be added (if any).
350+
///
351+
/// \param[in] previous_field FieldInfo of the previous DW_TAG_member
352+
/// we parsed.
353+
///
354+
/// \param[in] current_field FieldInfo of the current DW_TAG_member
355+
/// being parsed.
356+
///
357+
void AddUnnamedBitfieldToRecordTypeIfNeeded(
358+
lldb_private::ClangASTImporter::LayoutInfo &class_layout_info,
359+
const lldb_private::CompilerType &class_clang_type,
360+
const FieldInfo &previous_field, const FieldInfo &current_field);
361+
333362
/// Parses a DW_TAG_APPLE_property DIE and appends the parsed data to the
334363
/// list of delayed Objective-C properties.
335364
///

0 commit comments

Comments
 (0)