Skip to content

Commit b0f4f55

Browse files
committed
Write LF_POINTER CodeView types for pointers to member functions or data
Translate DW_TAG_ptr_to_member_type DIEs into special extended LF_POINTER CodeView types. gcc/ * dwarf2codeview.cc (struct codeview_custom_type): Add new fields to lf_pointer struct in union. (write_lf_pointer): Write containing_class and ptr_to_mem_type if applicable. (get_type_num_subroutine_type): Write correct containing_class_type if this is a pointer to a member function. (get_type_num_ptr_to_member_type): New function. (get_type_num): Call get_type_num_ptr_to_member_type. * dwarf2codeview.h (CV_PTR_MODE_MASK, CV_PTR_MODE_PMEM): Define. (CV_PTR_MODE_PMFUNC, CV_PMTYPE_D_Single, CV_PMTYPE_F_Single): Likewise.
1 parent 7ac2407 commit b0f4f55

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

Diff for: gcc/dwarf2codeview.cc

+103
Original file line numberDiff line numberDiff line change
@@ -1270,6 +1270,8 @@ struct codeview_custom_type
12701270
{
12711271
uint32_t base_type;
12721272
uint32_t attributes;
1273+
uint32_t containing_class;
1274+
uint16_t ptr_to_mem_type;
12731275
} lf_pointer;
12741276
struct
12751277
{
@@ -3393,6 +3395,10 @@ write_lf_pointer (codeview_custom_type *t)
33933395
uint16_t kind;
33943396
uint32_t base_type;
33953397
uint32_t attributes;
3398+
(following only if CV_PTR_MODE_PMEM or CV_PTR_MODE_PMFUNC in attributes)
3399+
uint32_t containing_class;
3400+
uint16_t ptr_to_mem_type;
3401+
uint16_t padding;
33963402
} ATTRIBUTE_PACKED;
33973403
*/
33983404

@@ -3414,6 +3420,20 @@ write_lf_pointer (codeview_custom_type *t)
34143420
fprint_whex (asm_out_file, t->lf_pointer.attributes);
34153421
putc ('\n', asm_out_file);
34163422

3423+
if ((t->lf_pointer.attributes & CV_PTR_MODE_MASK) == CV_PTR_MODE_PMEM
3424+
|| (t->lf_pointer.attributes & CV_PTR_MODE_MASK) == CV_PTR_MODE_PMFUNC)
3425+
{
3426+
fputs (integer_asm_op (4, false), asm_out_file);
3427+
fprint_whex (asm_out_file, t->lf_pointer.containing_class);
3428+
putc ('\n', asm_out_file);
3429+
3430+
fputs (integer_asm_op (2, false), asm_out_file);
3431+
fprint_whex (asm_out_file, t->lf_pointer.ptr_to_mem_type);
3432+
putc ('\n', asm_out_file);
3433+
3434+
write_cv_padding (2);
3435+
}
3436+
34173437
asm_fprintf (asm_out_file, "%LLcv_type%x_end:\n", t->num);
34183438
}
34193439

@@ -5886,6 +5906,30 @@ get_type_num_subroutine_type (dw_die_ref type, bool in_struct,
58865906
return_type = T_VOID;
58875907
}
58885908

5909+
/* Handle pointer to member function. */
5910+
if (containing_class_type == 0)
5911+
{
5912+
dw_die_ref obj_ptr = get_AT_ref (type, DW_AT_object_pointer);
5913+
5914+
if (obj_ptr)
5915+
{
5916+
dw_die_ref obj_ptr_type = get_AT_ref (obj_ptr, DW_AT_type);
5917+
5918+
if (obj_ptr_type
5919+
&& dw_get_die_tag (obj_ptr_type) == DW_TAG_pointer_type)
5920+
{
5921+
dw_die_ref cont_class = get_AT_ref (obj_ptr_type, DW_AT_type);
5922+
5923+
if (dw_get_die_tag (cont_class) == DW_TAG_const_type)
5924+
cont_class = get_AT_ref (cont_class, DW_AT_type);
5925+
5926+
containing_class_type = get_type_num (cont_class, in_struct,
5927+
false);
5928+
this_type = get_type_num (obj_ptr_type, in_struct, false);
5929+
}
5930+
}
5931+
}
5932+
58895933
/* Count the arguments. */
58905934

58915935
first_child = dw_get_die_child (type);
@@ -6121,6 +6165,61 @@ get_type_num_array_type (dw_die_ref type, bool in_struct)
61216165
return element_type;
61226166
}
61236167

6168+
/* Translate a DW_TAG_ptr_to_member_type DIE, that is a pointer to member
6169+
function or field, into an LF_POINTER record. */
6170+
6171+
static uint32_t
6172+
get_type_num_ptr_to_member_type (dw_die_ref type, bool in_struct)
6173+
{
6174+
uint32_t base_type_num;
6175+
uint32_t containing_class;
6176+
dw_die_ref base_type;
6177+
codeview_custom_type *ct;
6178+
6179+
base_type = get_AT_ref (type, DW_AT_type);
6180+
6181+
base_type_num = get_type_num (base_type, in_struct, false);
6182+
if (base_type_num == 0)
6183+
return 0;
6184+
6185+
containing_class = get_type_num (get_AT_ref (type, DW_AT_containing_type),
6186+
in_struct, false);
6187+
6188+
ct = (codeview_custom_type *) xmalloc (sizeof (codeview_custom_type));
6189+
6190+
ct->next = NULL;
6191+
ct->kind = LF_POINTER;
6192+
ct->lf_pointer.base_type = base_type_num;
6193+
6194+
if (TARGET_64BIT)
6195+
{
6196+
ct->lf_pointer.attributes = CV_PTR_64;
6197+
ct->lf_pointer.attributes |= 8 << 13;
6198+
}
6199+
else
6200+
{
6201+
ct->lf_pointer.attributes = CV_PTR_NEAR32;
6202+
ct->lf_pointer.attributes |= 4 << 13;
6203+
}
6204+
6205+
ct->lf_pointer.containing_class = containing_class;
6206+
6207+
if (base_type && dw_get_die_tag (base_type) == DW_TAG_subroutine_type)
6208+
{
6209+
ct->lf_pointer.attributes |= CV_PTR_MODE_PMFUNC;
6210+
ct->lf_pointer.ptr_to_mem_type = CV_PMTYPE_F_Single;
6211+
}
6212+
else
6213+
{
6214+
ct->lf_pointer.attributes |= CV_PTR_MODE_PMEM;
6215+
ct->lf_pointer.ptr_to_mem_type = CV_PMTYPE_D_Single;
6216+
}
6217+
6218+
add_custom_type (ct);
6219+
6220+
return ct->num;
6221+
}
6222+
61246223
/* Process a DIE representing a type definition, add a CodeView type if
61256224
necessary, and return its number. If it's something we can't handle, return
61266225
0. We keep a hash table so that we're not adding the same type multiple
@@ -6198,6 +6297,10 @@ get_type_num (dw_die_ref type, bool in_struct, bool no_fwd_ref)
61986297
num = get_type_num_subroutine_type (type, in_struct, 0, 0, 0);
61996298
break;
62006299

6300+
case DW_TAG_ptr_to_member_type:
6301+
num = get_type_num_ptr_to_member_type (type, in_struct);
6302+
break;
6303+
62016304
default:
62026305
num = 0;
62036306
break;

Diff for: gcc/dwarf2codeview.h

+9
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,18 @@ along with GCC; see the file COPYING3. If not see
5555
/* LF_POINTER attributes. */
5656
#define CV_PTR_NEAR32 0x0a
5757
#define CV_PTR_64 0x0c
58+
59+
/* enum CV_ptrmode_e in cvinfo.h, shifted by 5 for the lfPointerAttr bitfield */
60+
#define CV_PTR_MODE_MASK 0xe0
5861
#define CV_PTR_MODE_LVREF 0x20
62+
#define CV_PTR_MODE_PMEM 0x40
63+
#define CV_PTR_MODE_PMFUNC 0x60
5964
#define CV_PTR_MODE_RVREF 0x80
6065

66+
/* enum CV_pmtype_e in in cvinfo.h */
67+
#define CV_PMTYPE_D_Single 0x01
68+
#define CV_PMTYPE_F_Single 0x05
69+
6170
/* LF_MODIFIER values. */
6271
#define MOD_const 0x1
6372
#define MOD_volatile 0x2

0 commit comments

Comments
 (0)