@@ -3185,18 +3185,15 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
3185
3185
const char *name = nullptr ;
3186
3186
const char *mangled = nullptr ;
3187
3187
Declaration decl;
3188
- uint32_t i;
3189
3188
DWARFFormValue type_die_form;
3190
3189
DWARFExpression location;
3191
3190
bool is_external = false ;
3192
3191
bool is_artificial = false ;
3193
- bool location_is_const_value_data = false ;
3194
- bool has_explicit_location = false ;
3195
- DWARFFormValue const_value;
3192
+ DWARFFormValue const_value_form, location_form;
3196
3193
Variable::RangeList scope_ranges;
3197
3194
// AccessType accessibility = eAccessNone;
3198
3195
3199
- for (i = 0 ; i < num_attributes; ++i) {
3196
+ for (size_t i = 0 ; i < num_attributes; ++i) {
3200
3197
dw_attr_t attr = attributes.AttributeAtIndex (i);
3201
3198
DWARFFormValue form_value;
3202
3199
@@ -3226,65 +3223,11 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
3226
3223
is_external = form_value.Boolean ();
3227
3224
break ;
3228
3225
case DW_AT_const_value:
3229
- // If we have already found a DW_AT_location attribute, ignore this
3230
- // attribute.
3231
- if (!has_explicit_location) {
3232
- location_is_const_value_data = true ;
3233
- // The constant value will be either a block, a data value or a
3234
- // string.
3235
- auto debug_info_data = die.GetData ();
3236
- if (DWARFFormValue::IsBlockForm (form_value.Form ())) {
3237
- // Retrieve the value as a block expression.
3238
- uint32_t block_offset =
3239
- form_value.BlockData () - debug_info_data.GetDataStart ();
3240
- uint32_t block_length = form_value.Unsigned ();
3241
- location = DWARFExpression (
3242
- module ,
3243
- DataExtractor (debug_info_data, block_offset, block_length),
3244
- die.GetCU ());
3245
- } else if (DWARFFormValue::IsDataForm (form_value.Form ())) {
3246
- // Constant value size does not have to match the size of the
3247
- // variable. We will fetch the size of the type after we create
3248
- // it.
3249
- const_value = form_value;
3250
- } else if (const char *str = form_value.AsCString ()) {
3251
- uint32_t string_length = strlen (str) + 1 ;
3252
- location = DWARFExpression (
3253
- module ,
3254
- DataExtractor (str, string_length,
3255
- die.GetCU ()->GetByteOrder (),
3256
- die.GetCU ()->GetAddressByteSize ()),
3257
- die.GetCU ());
3258
- }
3259
- }
3226
+ const_value_form = form_value;
3227
+ break ;
3228
+ case DW_AT_location:
3229
+ location_form = form_value;
3260
3230
break ;
3261
- case DW_AT_location: {
3262
- location_is_const_value_data = false ;
3263
- has_explicit_location = true ;
3264
- if (DWARFFormValue::IsBlockForm (form_value.Form ())) {
3265
- auto data = die.GetData ();
3266
-
3267
- uint32_t block_offset =
3268
- form_value.BlockData () - data.GetDataStart ();
3269
- uint32_t block_length = form_value.Unsigned ();
3270
- location = DWARFExpression (
3271
- module , DataExtractor (data, block_offset, block_length),
3272
- die.GetCU ());
3273
- } else {
3274
- DataExtractor data = die.GetCU ()->GetLocationData ();
3275
- dw_offset_t offset = form_value.Unsigned ();
3276
- if (form_value.Form () == DW_FORM_loclistx)
3277
- offset = die.GetCU ()->GetLoclistOffset (offset).getValueOr (-1 );
3278
- if (data.ValidOffset (offset)) {
3279
- data = DataExtractor (data, offset, data.GetByteSize () - offset);
3280
- location = DWARFExpression (module , data, die.GetCU ());
3281
- assert (func_low_pc != LLDB_INVALID_ADDRESS);
3282
- location.SetLocationListAddresses (
3283
- attributes.CompileUnitAtIndex (i)->GetBaseAddress (),
3284
- func_low_pc);
3285
- }
3286
- }
3287
- } break ;
3288
3231
case DW_AT_specification:
3289
3232
spec_die = form_value.Reference ();
3290
3233
break ;
@@ -3314,6 +3257,66 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
3314
3257
IsSwiftLanguage (sc.comp_unit ->GetLanguage ()))
3315
3258
mangled = NULL ;
3316
3259
3260
+ // Prefer DW_AT_location over DW_AT_const_value. Both can be emitted e.g.
3261
+ // for static constexpr member variables -- DW_AT_const_value will be
3262
+ // present in the class declaration and DW_AT_location in the DIE defining
3263
+ // the member.
3264
+ bool location_is_const_value_data = false ;
3265
+ bool has_explicit_location = false ;
3266
+ bool use_type_size_for_value = false ;
3267
+ if (location_form.IsValid ()) {
3268
+ has_explicit_location = true ;
3269
+ if (DWARFFormValue::IsBlockForm (location_form.Form ())) {
3270
+ const DWARFDataExtractor &data = die.GetData ();
3271
+
3272
+ uint32_t block_offset =
3273
+ location_form.BlockData () - data.GetDataStart ();
3274
+ uint32_t block_length = location_form.Unsigned ();
3275
+ location = DWARFExpression (
3276
+ module , DataExtractor (data, block_offset, block_length),
3277
+ die.GetCU ());
3278
+ } else {
3279
+ DataExtractor data = die.GetCU ()->GetLocationData ();
3280
+ dw_offset_t offset = location_form.Unsigned ();
3281
+ if (location_form.Form () == DW_FORM_loclistx)
3282
+ offset = die.GetCU ()->GetLoclistOffset (offset).getValueOr (-1 );
3283
+ if (data.ValidOffset (offset)) {
3284
+ data = DataExtractor (data, offset, data.GetByteSize () - offset);
3285
+ location = DWARFExpression (module , data, die.GetCU ());
3286
+ assert (func_low_pc != LLDB_INVALID_ADDRESS);
3287
+ location.SetLocationListAddresses (
3288
+ location_form.GetUnit ()->GetBaseAddress (), func_low_pc);
3289
+ }
3290
+ }
3291
+ } else if (const_value_form.IsValid ()) {
3292
+ location_is_const_value_data = true ;
3293
+ // The constant value will be either a block, a data value or a
3294
+ // string.
3295
+ const DWARFDataExtractor &debug_info_data = die.GetData ();
3296
+ if (DWARFFormValue::IsBlockForm (const_value_form.Form ())) {
3297
+ // Retrieve the value as a block expression.
3298
+ uint32_t block_offset =
3299
+ const_value_form.BlockData () - debug_info_data.GetDataStart ();
3300
+ uint32_t block_length = const_value_form.Unsigned ();
3301
+ location = DWARFExpression (
3302
+ module ,
3303
+ DataExtractor (debug_info_data, block_offset, block_length),
3304
+ die.GetCU ());
3305
+ } else if (DWARFFormValue::IsDataForm (const_value_form.Form ())) {
3306
+ // Constant value size does not have to match the size of the
3307
+ // variable. We will fetch the size of the type after we create
3308
+ // it.
3309
+ use_type_size_for_value = true ;
3310
+ } else if (const char *str = const_value_form.AsCString ()) {
3311
+ uint32_t string_length = strlen (str) + 1 ;
3312
+ location = DWARFExpression (
3313
+ module ,
3314
+ DataExtractor (str, string_length, die.GetCU ()->GetByteOrder (),
3315
+ die.GetCU ()->GetAddressByteSize ()),
3316
+ die.GetCU ());
3317
+ }
3318
+ }
3319
+
3317
3320
const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE (die);
3318
3321
const dw_tag_t parent_tag = die.GetParent ().Tag ();
3319
3322
bool is_static_member =
@@ -3493,12 +3496,12 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
3493
3496
}
3494
3497
3495
3498
if (symbol_context_scope) {
3496
- SymbolFileTypeSP type_sp (
3497
- new SymbolFileType ( *this , GetUID (type_die_form.Reference () )));
3499
+ auto type_sp = std::make_shared<SymbolFileType> (
3500
+ *this , GetUID (type_die_form.Reference ()));
3498
3501
3499
- if (const_value. Form () && type_sp && type_sp->GetType ())
3502
+ if (use_type_size_for_value && type_sp->GetType ())
3500
3503
location.UpdateValue (
3501
- const_value .Unsigned (),
3504
+ const_value_form .Unsigned (),
3502
3505
type_sp->GetType ()->GetByteSize (nullptr ).getValueOr (0 ),
3503
3506
die.GetCU ()->GetAddressByteSize ());
3504
3507
0 commit comments