@@ -3111,18 +3111,15 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
3111
3111
const char *name = nullptr ;
3112
3112
const char *mangled = nullptr ;
3113
3113
Declaration decl;
3114
- uint32_t i;
3115
3114
DWARFFormValue type_die_form;
3116
3115
DWARFExpression location;
3117
3116
bool is_external = false ;
3118
3117
bool is_artificial = false ;
3119
- bool location_is_const_value_data = false ;
3120
- bool has_explicit_location = false ;
3121
- DWARFFormValue const_value;
3118
+ DWARFFormValue const_value_form, location_form;
3122
3119
Variable::RangeList scope_ranges;
3123
3120
// AccessType accessibility = eAccessNone;
3124
3121
3125
- for (i = 0 ; i < num_attributes; ++i) {
3122
+ for (size_t i = 0 ; i < num_attributes; ++i) {
3126
3123
dw_attr_t attr = attributes.AttributeAtIndex (i);
3127
3124
DWARFFormValue form_value;
3128
3125
@@ -3152,65 +3149,11 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
3152
3149
is_external = form_value.Boolean ();
3153
3150
break ;
3154
3151
case DW_AT_const_value:
3155
- // If we have already found a DW_AT_location attribute, ignore this
3156
- // attribute.
3157
- if (!has_explicit_location) {
3158
- location_is_const_value_data = true ;
3159
- // The constant value will be either a block, a data value or a
3160
- // string.
3161
- auto debug_info_data = die.GetData ();
3162
- if (DWARFFormValue::IsBlockForm (form_value.Form ())) {
3163
- // Retrieve the value as a block expression.
3164
- uint32_t block_offset =
3165
- form_value.BlockData () - debug_info_data.GetDataStart ();
3166
- uint32_t block_length = form_value.Unsigned ();
3167
- location = DWARFExpression (
3168
- module,
3169
- DataExtractor (debug_info_data, block_offset, block_length),
3170
- die.GetCU ());
3171
- } else if (DWARFFormValue::IsDataForm (form_value.Form ())) {
3172
- // Constant value size does not have to match the size of the
3173
- // variable. We will fetch the size of the type after we create
3174
- // it.
3175
- const_value = form_value;
3176
- } else if (const char *str = form_value.AsCString ()) {
3177
- uint32_t string_length = strlen (str) + 1 ;
3178
- location = DWARFExpression (
3179
- module,
3180
- DataExtractor (str, string_length,
3181
- die.GetCU ()->GetByteOrder (),
3182
- die.GetCU ()->GetAddressByteSize ()),
3183
- die.GetCU ());
3184
- }
3185
- }
3152
+ const_value_form = form_value;
3153
+ break ;
3154
+ case DW_AT_location:
3155
+ location_form = form_value;
3186
3156
break ;
3187
- case DW_AT_location: {
3188
- location_is_const_value_data = false ;
3189
- has_explicit_location = true ;
3190
- if (DWARFFormValue::IsBlockForm (form_value.Form ())) {
3191
- auto data = die.GetData ();
3192
-
3193
- uint32_t block_offset =
3194
- form_value.BlockData () - data.GetDataStart ();
3195
- uint32_t block_length = form_value.Unsigned ();
3196
- location = DWARFExpression (
3197
- module, DataExtractor (data, block_offset, block_length),
3198
- die.GetCU ());
3199
- } else {
3200
- DataExtractor data = die.GetCU ()->GetLocationData ();
3201
- dw_offset_t offset = form_value.Unsigned ();
3202
- if (form_value.Form () == DW_FORM_loclistx)
3203
- offset = die.GetCU ()->GetLoclistOffset (offset).getValueOr (-1 );
3204
- if (data.ValidOffset (offset)) {
3205
- data = DataExtractor (data, offset, data.GetByteSize () - offset);
3206
- location = DWARFExpression (module, data, die.GetCU ());
3207
- assert (func_low_pc != LLDB_INVALID_ADDRESS);
3208
- location.SetLocationListAddresses (
3209
- attributes.CompileUnitAtIndex (i)->GetBaseAddress (),
3210
- func_low_pc);
3211
- }
3212
- }
3213
- } break ;
3214
3157
case DW_AT_specification:
3215
3158
spec_die = form_value.Reference ();
3216
3159
break ;
@@ -3236,6 +3179,66 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
3236
3179
}
3237
3180
}
3238
3181
3182
+ // Prefer DW_AT_location over DW_AT_const_value. Both can be emitted e.g.
3183
+ // for static constexpr member variables -- DW_AT_const_value will be
3184
+ // present in the class declaration and DW_AT_location in the DIE defining
3185
+ // the member.
3186
+ bool location_is_const_value_data = false ;
3187
+ bool has_explicit_location = false ;
3188
+ bool use_type_size_for_value = false ;
3189
+ if (location_form.IsValid ()) {
3190
+ has_explicit_location = true ;
3191
+ if (DWARFFormValue::IsBlockForm (location_form.Form ())) {
3192
+ const DWARFDataExtractor &data = die.GetData ();
3193
+
3194
+ uint32_t block_offset =
3195
+ location_form.BlockData () - data.GetDataStart ();
3196
+ uint32_t block_length = location_form.Unsigned ();
3197
+ location = DWARFExpression (
3198
+ module, DataExtractor (data, block_offset, block_length),
3199
+ die.GetCU ());
3200
+ } else {
3201
+ DataExtractor data = die.GetCU ()->GetLocationData ();
3202
+ dw_offset_t offset = location_form.Unsigned ();
3203
+ if (location_form.Form () == DW_FORM_loclistx)
3204
+ offset = die.GetCU ()->GetLoclistOffset (offset).getValueOr (-1 );
3205
+ if (data.ValidOffset (offset)) {
3206
+ data = DataExtractor (data, offset, data.GetByteSize () - offset);
3207
+ location = DWARFExpression (module, data, die.GetCU ());
3208
+ assert (func_low_pc != LLDB_INVALID_ADDRESS);
3209
+ location.SetLocationListAddresses (
3210
+ location_form.GetUnit ()->GetBaseAddress (), func_low_pc);
3211
+ }
3212
+ }
3213
+ } else if (const_value_form.IsValid ()) {
3214
+ location_is_const_value_data = true ;
3215
+ // The constant value will be either a block, a data value or a
3216
+ // string.
3217
+ const DWARFDataExtractor &debug_info_data = die.GetData ();
3218
+ if (DWARFFormValue::IsBlockForm (const_value_form.Form ())) {
3219
+ // Retrieve the value as a block expression.
3220
+ uint32_t block_offset =
3221
+ const_value_form.BlockData () - debug_info_data.GetDataStart ();
3222
+ uint32_t block_length = const_value_form.Unsigned ();
3223
+ location = DWARFExpression (
3224
+ module,
3225
+ DataExtractor (debug_info_data, block_offset, block_length),
3226
+ die.GetCU ());
3227
+ } else if (DWARFFormValue::IsDataForm (const_value_form.Form ())) {
3228
+ // Constant value size does not have to match the size of the
3229
+ // variable. We will fetch the size of the type after we create
3230
+ // it.
3231
+ use_type_size_for_value = true ;
3232
+ } else if (const char *str = const_value_form.AsCString ()) {
3233
+ uint32_t string_length = strlen (str) + 1 ;
3234
+ location = DWARFExpression (
3235
+ module,
3236
+ DataExtractor (str, string_length, die.GetCU ()->GetByteOrder (),
3237
+ die.GetCU ()->GetAddressByteSize ()),
3238
+ die.GetCU ());
3239
+ }
3240
+ }
3241
+
3239
3242
const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE (die);
3240
3243
const dw_tag_t parent_tag = die.GetParent ().Tag ();
3241
3244
bool is_static_member =
@@ -3415,12 +3418,12 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
3415
3418
}
3416
3419
3417
3420
if (symbol_context_scope) {
3418
- SymbolFileTypeSP type_sp (
3419
- new SymbolFileType ( *this , GetUID (type_die_form.Reference () )));
3421
+ auto type_sp = std::make_shared<SymbolFileType> (
3422
+ *this , GetUID (type_die_form.Reference ()));
3420
3423
3421
- if (const_value. Form () && type_sp && type_sp->GetType ())
3424
+ if (use_type_size_for_value && type_sp->GetType ())
3422
3425
location.UpdateValue (
3423
- const_value .Unsigned (),
3426
+ const_value_form .Unsigned (),
3424
3427
type_sp->GetType ()->GetByteSize (nullptr ).getValueOr (0 ),
3425
3428
die.GetCU ()->GetAddressByteSize ());
3426
3429
0 commit comments