@@ -1270,6 +1270,8 @@ struct codeview_custom_type
1270
1270
{
1271
1271
uint32_t base_type;
1272
1272
uint32_t attributes;
1273
+ uint32_t containing_class;
1274
+ uint16_t ptr_to_mem_type;
1273
1275
} lf_pointer;
1274
1276
struct
1275
1277
{
@@ -3393,6 +3395,10 @@ write_lf_pointer (codeview_custom_type *t)
3393
3395
uint16_t kind;
3394
3396
uint32_t base_type;
3395
3397
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;
3396
3402
} ATTRIBUTE_PACKED;
3397
3403
*/
3398
3404
@@ -3414,6 +3420,20 @@ write_lf_pointer (codeview_custom_type *t)
3414
3420
fprint_whex (asm_out_file, t->lf_pointer .attributes );
3415
3421
putc (' \n ' , asm_out_file);
3416
3422
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
+
3417
3437
asm_fprintf (asm_out_file, " %LLcv_type%x_end:\n " , t->num );
3418
3438
}
3419
3439
@@ -5886,6 +5906,30 @@ get_type_num_subroutine_type (dw_die_ref type, bool in_struct,
5886
5906
return_type = T_VOID;
5887
5907
}
5888
5908
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
+
5889
5933
/* Count the arguments. */
5890
5934
5891
5935
first_child = dw_get_die_child (type);
@@ -6121,6 +6165,61 @@ get_type_num_array_type (dw_die_ref type, bool in_struct)
6121
6165
return element_type;
6122
6166
}
6123
6167
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
+
6124
6223
/* Process a DIE representing a type definition, add a CodeView type if
6125
6224
necessary, and return its number. If it's something we can't handle, return
6126
6225
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)
6198
6297
num = get_type_num_subroutine_type (type, in_struct, 0 , 0 , 0 );
6199
6298
break ;
6200
6299
6300
+ case DW_TAG_ptr_to_member_type:
6301
+ num = get_type_num_ptr_to_member_type (type, in_struct);
6302
+ break ;
6303
+
6201
6304
default :
6202
6305
num = 0 ;
6203
6306
break ;
0 commit comments