Skip to content

Commit 743c4fe

Browse files
authored
[lldb][DWARFASTParserClang][NFC] Extract static data member decl creation into helper (#72109)
This patch extracts the logic to create a static variable member decl into a helper. We will use this in an upcoming patch which will need to call exactly the same logic from a separate part of the DWARF parser.
1 parent 70ce047 commit 743c4fe

File tree

2 files changed

+94
-67
lines changed

2 files changed

+94
-67
lines changed

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

Lines changed: 54 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -2534,28 +2534,6 @@ DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
25342534
}
25352535

25362536
namespace {
2537-
/// Parsed form of all attributes that are relevant for parsing type members.
2538-
struct MemberAttributes {
2539-
explicit MemberAttributes(const DWARFDIE &die, const DWARFDIE &parent_die,
2540-
ModuleSP module_sp);
2541-
const char *name = nullptr;
2542-
/// Indicates how many bits into the word (according to the host endianness)
2543-
/// the low-order bit of the field starts. Can be negative.
2544-
int64_t bit_offset = 0;
2545-
/// Indicates the size of the field in bits.
2546-
size_t bit_size = 0;
2547-
uint64_t data_bit_offset = UINT64_MAX;
2548-
AccessType accessibility = eAccessNone;
2549-
std::optional<uint64_t> byte_size;
2550-
std::optional<DWARFFormValue> const_value_form;
2551-
DWARFFormValue encoding_form;
2552-
/// Indicates the byte offset of the word from the base address of the
2553-
/// structure.
2554-
uint32_t member_byte_offset = UINT32_MAX;
2555-
bool is_artificial = false;
2556-
bool is_declaration = false;
2557-
};
2558-
25592537
/// Parsed form of all attributes that are relevant for parsing Objective-C
25602538
/// properties.
25612539
struct PropertyAttributes {
@@ -2684,9 +2662,8 @@ std::vector<VariantMember> &VariantPart::members() { return this->_members; }
26842662

26852663
DiscriminantValue &VariantPart::discriminant() { return this->_discriminant; }
26862664

2687-
MemberAttributes::MemberAttributes(const DWARFDIE &die,
2688-
const DWARFDIE &parent_die,
2689-
ModuleSP module_sp) {
2665+
DWARFASTParserClang::MemberAttributes::MemberAttributes(
2666+
const DWARFDIE &die, const DWARFDIE &parent_die, ModuleSP module_sp) {
26902667
DWARFAttributes attributes = die.GetAttributes();
26912668
for (size_t i = 0; i < attributes.Size(); ++i) {
26922669
const dw_attr_t attr = attributes.AttributeAtIndex(i);
@@ -2908,13 +2885,63 @@ llvm::Expected<llvm::APInt> DWARFASTParserClang::ExtractIntFromFormValue(
29082885
return result;
29092886
}
29102887

2888+
void DWARFASTParserClang::CreateStaticMemberVariable(
2889+
const DWARFDIE &die, const MemberAttributes &attrs,
2890+
const lldb_private::CompilerType &class_clang_type) {
2891+
Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
2892+
assert(die.Tag() == DW_TAG_member);
2893+
2894+
Type *var_type = die.ResolveTypeUID(attrs.encoding_form.Reference());
2895+
2896+
if (!var_type)
2897+
return;
2898+
2899+
auto accessibility =
2900+
attrs.accessibility == eAccessNone ? eAccessPublic : attrs.accessibility;
2901+
2902+
CompilerType ct = var_type->GetForwardCompilerType();
2903+
clang::VarDecl *v = TypeSystemClang::AddVariableToRecordType(
2904+
class_clang_type, attrs.name, ct, accessibility);
2905+
if (!v) {
2906+
LLDB_LOG(log, "Failed to add variable to the record type");
2907+
return;
2908+
}
2909+
2910+
bool unused;
2911+
// TODO: Support float/double static members as well.
2912+
if (!ct.IsIntegerOrEnumerationType(unused))
2913+
return;
2914+
2915+
auto maybe_const_form_value = attrs.const_value_form;
2916+
2917+
// Newer versions of Clang don't emit the DW_AT_const_value
2918+
// on the declaration of an inline static data member. Instead
2919+
// it's attached to the definition DIE. If that's the case,
2920+
// try and fetch it.
2921+
if (!maybe_const_form_value) {
2922+
maybe_const_form_value = FindConstantOnVariableDefinition(die);
2923+
if (!maybe_const_form_value)
2924+
return;
2925+
}
2926+
2927+
llvm::Expected<llvm::APInt> const_value_or_err =
2928+
ExtractIntFromFormValue(ct, *maybe_const_form_value);
2929+
if (!const_value_or_err) {
2930+
LLDB_LOG_ERROR(log, const_value_or_err.takeError(),
2931+
"Failed to add const value to variable {1}: {0}",
2932+
v->getQualifiedNameAsString());
2933+
return;
2934+
}
2935+
2936+
TypeSystemClang::SetIntegerInitializerForVariable(v, *const_value_or_err);
2937+
}
2938+
29112939
void DWARFASTParserClang::ParseSingleMember(
29122940
const DWARFDIE &die, const DWARFDIE &parent_die,
29132941
const lldb_private::CompilerType &class_clang_type,
29142942
lldb::AccessType default_accessibility,
29152943
lldb_private::ClangASTImporter::LayoutInfo &layout_info,
29162944
FieldInfo &last_field_info) {
2917-
Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups);
29182945
// This function can only parse DW_TAG_member.
29192946
assert(die.Tag() == DW_TAG_member);
29202947

@@ -2940,47 +2967,7 @@ void DWARFASTParserClang::ParseSingleMember(
29402967
// can consistently detect them on both GCC and Clang without below heuristic.
29412968
if (attrs.member_byte_offset == UINT32_MAX &&
29422969
attrs.data_bit_offset == UINT64_MAX && attrs.is_declaration) {
2943-
Type *var_type = die.ResolveTypeUID(attrs.encoding_form.Reference());
2944-
if (var_type) {
2945-
const auto accessibility = attrs.accessibility == eAccessNone
2946-
? eAccessPublic
2947-
: attrs.accessibility;
2948-
CompilerType ct = var_type->GetForwardCompilerType();
2949-
clang::VarDecl *v = TypeSystemClang::AddVariableToRecordType(
2950-
class_clang_type, attrs.name, ct, accessibility);
2951-
if (!v) {
2952-
LLDB_LOG(log, "Failed to add variable to the record type");
2953-
return;
2954-
}
2955-
2956-
bool unused;
2957-
// TODO: Support float/double static members as well.
2958-
if (!ct.IsIntegerOrEnumerationType(unused))
2959-
return;
2960-
2961-
auto maybe_const_form_value = attrs.const_value_form;
2962-
2963-
// Newer versions of Clang don't emit the DW_AT_const_value
2964-
// on the declaration of an inline static data member. Instead
2965-
// it's attached to the definition DIE. If that's the case,
2966-
// try and fetch it.
2967-
if (!maybe_const_form_value) {
2968-
maybe_const_form_value = FindConstantOnVariableDefinition(die);
2969-
if (!maybe_const_form_value)
2970-
return;
2971-
}
2972-
2973-
llvm::Expected<llvm::APInt> const_value_or_err =
2974-
ExtractIntFromFormValue(ct, *maybe_const_form_value);
2975-
if (!const_value_or_err) {
2976-
LLDB_LOG_ERROR(log, const_value_or_err.takeError(),
2977-
"Failed to add const value to variable {1}: {0}",
2978-
v->getQualifiedNameAsString());
2979-
return;
2980-
}
2981-
2982-
TypeSystemClang::SetIntegerInitializerForVariable(v, *const_value_or_err);
2983-
}
2970+
CreateStaticMemberVariable(die, attrs, class_clang_type);
29842971
return;
29852972
}
29862973

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

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,30 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
271271
}
272272
};
273273

274+
/// Parsed form of all attributes that are relevant for parsing type members.
275+
struct MemberAttributes {
276+
explicit MemberAttributes(
277+
const lldb_private::plugin::dwarf::DWARFDIE &die,
278+
const lldb_private::plugin::dwarf::DWARFDIE &parent_die,
279+
lldb::ModuleSP module_sp);
280+
const char *name = nullptr;
281+
/// Indicates how many bits into the word (according to the host endianness)
282+
/// the low-order bit of the field starts. Can be negative.
283+
int64_t bit_offset = 0;
284+
/// Indicates the size of the field in bits.
285+
size_t bit_size = 0;
286+
uint64_t data_bit_offset = UINT64_MAX;
287+
lldb::AccessType accessibility = lldb::eAccessNone;
288+
std::optional<uint64_t> byte_size;
289+
std::optional<lldb_private::plugin::dwarf::DWARFFormValue> const_value_form;
290+
lldb_private::plugin::dwarf::DWARFFormValue encoding_form;
291+
/// Indicates the byte offset of the word from the base address of the
292+
/// structure.
293+
uint32_t member_byte_offset = UINT32_MAX;
294+
bool is_artificial = false;
295+
bool is_declaration = false;
296+
};
297+
274298
/// Returns 'true' if we should create an unnamed bitfield
275299
/// and add it to the parser's current AST.
276300
///
@@ -313,6 +337,22 @@ class DWARFASTParserClang : public lldb_private::plugin::dwarf::DWARFASTParser {
313337
lldb_private::ClangASTImporter::LayoutInfo &layout_info,
314338
FieldInfo &last_field_info);
315339

340+
/// If the specified 'die' represents a static data member, creates
341+
/// a 'clang::VarDecl' for it and attaches it to specified parent
342+
/// 'class_clang_type'.
343+
///
344+
/// \param[in] die The member declaration we want to create a
345+
/// clang::VarDecl for.
346+
///
347+
/// \param[in] attrs The parsed attributes for the specified 'die'.
348+
///
349+
/// \param[in] class_clang_type The parent RecordType of the static
350+
/// member this function will create.
351+
void CreateStaticMemberVariable(
352+
const lldb_private::plugin::dwarf::DWARFDIE &die,
353+
const MemberAttributes &attrs,
354+
const lldb_private::CompilerType &class_clang_type);
355+
316356
bool CompleteRecordType(const lldb_private::plugin::dwarf::DWARFDIE &die,
317357
lldb_private::Type *type,
318358
lldb_private::CompilerType &clang_type);

0 commit comments

Comments
 (0)