@@ -12578,7 +12578,8 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
TYPE_TARGET_TYPE (this_type),
TYPE_FIELDS (this_type),
TYPE_NFIELDS (this_type),
- TYPE_VARARGS (this_type));
+ TYPE_VARARGS (this_type),
+ TYPE_CALLING_CONVENTION (this_type));
/* Handle static member functions.
Dwarf2 has no clean way to discern C++ static and non-static
@@ -12782,7 +12783,8 @@ quirk_gcc_member_function_pointer (struct type *type, struct objfile *objfile)
new_type = alloc_type (objfile);
smash_to_method_type (new_type, domain_type, TYPE_TARGET_TYPE (pfn_type),
TYPE_FIELDS (pfn_type), TYPE_NFIELDS (pfn_type),
- TYPE_VARARGS (pfn_type));
+ TYPE_VARARGS (pfn_type),
+ TYPE_CALLING_CONVENTION (pfn_type));
smash_to_methodptr_type (type, new_type);
}
@@ -13943,7 +13945,8 @@ read_tag_ptr_to_member_type (struct die_info *die, struct dwarf2_cu *cu)
smash_to_method_type (new_type, domain, TYPE_TARGET_TYPE (to_type),
TYPE_FIELDS (to_type), TYPE_NFIELDS (to_type),
- TYPE_VARARGS (to_type));
+ TYPE_VARARGS (to_type),
+ TYPE_CALLING_CONVENTION (to_type));
type = lookup_methodptr_type (new_type);
}
else
@@ -1174,7 +1174,7 @@ smash_to_methodptr_type (struct type *type, struct type *to_type)
void
smash_to_method_type (struct type *type, struct type *domain,
struct type *to_type, struct field *args,
- int nargs, int varargs)
+ int nargs, int varargs, unsigned int calling_convention)
{
smash_type (type);
TYPE_TARGET_TYPE (type) = to_type;
@@ -1185,6 +1185,8 @@ smash_to_method_type (struct type *type, struct type *domain,
TYPE_VARARGS (type) = 1;
TYPE_LENGTH (type) = 1; /* In practice, this is never needed. */
TYPE_CODE (type) = TYPE_CODE_METHOD;
+ INIT_FUNC_SPECIFIC (type);
+ TYPE_CALLING_CONVENTION (type) = calling_convention;
}
/* Return a typename for a struct/union/enum type without "struct ",
@@ -2082,6 +2084,7 @@ init_type (enum type_code code, int length, int flags,
TYPE_SPECIFIC_FIELD (type) = TYPE_SPECIFIC_FLOATFORMAT;
break;
case TYPE_CODE_FUNC:
+ case TYPE_CODE_METHOD:
INIT_FUNC_SPECIFIC (type);
break;
}
@@ -685,7 +685,7 @@ struct main_type
const struct floatformat **floatformat;
- /* * For TYPE_CODE_FUNC types, */
+ /* * For TYPE_CODE_FUNC and TYPE_CODE_METHOD types, */
struct func_type *func_stuff;
} type_specific;
@@ -982,7 +982,7 @@ struct gnat_aux_type
struct type* descriptive_type;
};
-/* * For TYPE_CODE_FUNC types. */
+/* * For TYPE_CODE_FUNC and TYPE_CODE_METHOD types. */
struct func_type
{
@@ -1598,7 +1598,8 @@ extern struct type *lookup_methodptr_type (struct type *);
extern void smash_to_method_type (struct type *type, struct type *domain,
struct type *to_type, struct field *args,
- int nargs, int varargs);
+ int nargs, int varargs,
+ unsigned int calling_convention);
extern void smash_to_memberptr_type (struct type *, struct type *,
struct type *);
@@ -45,6 +45,9 @@
#include "remote.h"
#include "exceptions.h"
#include "gdb_assert.h"
+#include "utils.h"
+#include "infcall.h"
+#include "dwarf2.h"
#include <string.h>
#include "i386-tdep.h"
@@ -2529,6 +2532,21 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
int i;
int write_pass;
int args_space = 0;
+ struct type *func_type = value_type (function);
+ int i386_windows_thiscall = 0;
+
+ if (func_type)
+ {
+ func_type = check_typedef (func_type);
+
+ if (TYPE_CODE (func_type) == TYPE_CODE_PTR)
+ func_type = check_typedef (TYPE_TARGET_TYPE (func_type));
+
+ if ((TYPE_CODE (func_type) == TYPE_CODE_METHOD
+ || TYPE_CODE (func_type) == TYPE_CODE_FUNC)
+ && TYPE_CALLING_CONVENTION (func_type) == DW_CC_GNU_thiscall_i386)
+ i386_windows_thiscall = 1;
+ }
/* Determine the total space required for arguments and struct
return address in a first pass (allowing for 16-byte-aligned
@@ -2551,7 +2569,7 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
args_space += 4;
}
- for (i = 0; i < nargs; i++)
+ for (i = i386_windows_thiscall; i < nargs; i++)
{
int len = TYPE_LENGTH (value_enclosing_type (args[i]));
@@ -2603,6 +2621,13 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
/* ...and fake a frame pointer. */
regcache_cooked_write (regcache, I386_EBP_REGNUM, buf);
+ if (i386_windows_thiscall)
+ {
+ /* ARGS[0] refers to the last argument which is the this pointer. */
+ regcache_cooked_write (regcache, I386_ECX_REGNUM,
+ value_contents_all (args[0]));
+ }
+
/* MarkK wrote: This "+ 8" is all over the place:
(i386_frame_this_id, i386_sigtramp_frame_this_id,
i386_dummy_id). It's there, since all frame unwinders for
@@ -1959,7 +1959,7 @@ again:
return error_type (pp, objfile);
type = dbx_alloc_type (typenums, objfile);
smash_to_method_type (type, domain, return_type, args,
- nargs, varargs);
+ nargs, varargs, 0);
}
break;
@@ -182,6 +182,7 @@ enum dwarf_calling_convention
DW_CC_GNU_renesas_sh = 0x40,
DW_CC_GNU_borland_fastcall_i386 = 0x41,
+ DW_CC_GNU_thiscall_i386 = 0x42,
/* This DW_CC_ value is not currently generated by any toolchain. It is
used internally to GDB to indicate OpenCL C functions that have been