@@ -3111,18 +3111,15 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
31113111 const char *name = nullptr ;
31123112 const char *mangled = nullptr ;
31133113 Declaration decl;
3114- uint32_t i;
31153114 DWARFFormValue type_die_form;
31163115 DWARFExpression location;
31173116 bool is_external = false ;
31183117 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;
31223119 Variable::RangeList scope_ranges;
31233120 // AccessType accessibility = eAccessNone;
31243121
3125- for (i = 0 ; i < num_attributes; ++i) {
3122+ for (size_t i = 0 ; i < num_attributes; ++i) {
31263123 dw_attr_t attr = attributes.AttributeAtIndex (i);
31273124 DWARFFormValue form_value;
31283125
@@ -3152,65 +3149,11 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
31523149 is_external = form_value.Boolean ();
31533150 break ;
31543151 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;
31863156 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 ;
32143157 case DW_AT_specification:
32153158 spec_die = form_value.Reference ();
32163159 break ;
@@ -3236,6 +3179,66 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
32363179 }
32373180 }
32383181
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+
32393242 const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE (die);
32403243 const dw_tag_t parent_tag = die.GetParent ().Tag ();
32413244 bool is_static_member =
@@ -3415,12 +3418,12 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
34153418 }
34163419
34173420 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 ()));
34203423
3421- if (const_value. Form () && type_sp && type_sp->GetType ())
3424+ if (use_type_size_for_value && type_sp->GetType ())
34223425 location.UpdateValue (
3423- const_value .Unsigned (),
3426+ const_value_form .Unsigned (),
34243427 type_sp->GetType ()->GetByteSize (nullptr ).getValueOr (0 ),
34253428 die.GetCU ()->GetAddressByteSize ());
34263429
0 commit comments