char *reg;
struct parsed_type type;
struct parsed_proto *pp; // fptr or struct
- void *datap;
unsigned int is_saved:1; // not set here, for tool use
+ void **push_refs;
+ int push_ref_cnt;
};
struct parsed_proto {
struct parsed_type ret_type;
struct parsed_type type;
};
- struct parsed_proto_arg arg[16];
+ struct parsed_proto_arg arg[32];
int argc;
int argc_stack;
int argc_reg;
"HRGN",
"HRSRC",
"HKEY",
+ "HKL",
"HMENU",
+ "HMONITOR",
"HWAVEOUT",
"HWND",
"PAPPBARDATA",
"REFCLSID",
"REFGUID",
"REFIID",
+ "SC_HANDLE",
+ "SERVICE_STATUS_HANDLE",
"HOOKPROC",
"DLGPROC",
"TIMERPROC",
static const char *ignored_keywords[] = {
"extern",
+ "static",
"WINBASEAPI",
"WINUSERAPI",
"WINGDIAPI",
return -1;
}
+ if (xarg >= ARRAY_SIZE(pp->arg)) {
+ printf("%s:%d:%zd: too many args\n",
+ hdrfn, hdrfline, (p - protostr) + 1);
+ return -1;
+ }
+
arg = &pp->arg[xarg];
xarg++;
if (pp1->argc != pp2->argc || pp1->argc_reg != pp2->argc_reg)
return 1;
- else {
- for (i = 0; i < pp1->argc; i++) {
- if ((pp1->arg[i].reg != NULL) != (pp2->arg[i].reg != NULL))
- return 1;
-
- if ((pp1->arg[i].reg != NULL)
- && !IS(pp1->arg[i].reg, pp2->arg[i].reg))
- {
- return 1;
- }
+ if (pp1->is_stdcall != pp2->is_stdcall)
+ return 1;
+
+ // because of poor void return detection, return is not
+ // checked for now to avoid heaps of false positives
+
+ for (i = 0; i < pp1->argc; i++) {
+ if ((pp1->arg[i].reg != NULL) != (pp2->arg[i].reg != NULL))
+ return 1;
+
+ if ((pp1->arg[i].reg != NULL)
+ && !IS(pp1->arg[i].reg, pp2->arg[i].reg))
+ {
+ return 1;
}
}
return 0;
}
+static inline int pp_compatible_func(
+ const struct parsed_proto *pp_site,
+ const struct parsed_proto *pp_callee)
+{
+ if (pp_cmp_func(pp_site, pp_callee) == 0)
+ return 1;
+
+ if (pp_site->argc_stack == 0 && pp_site->is_fastcall
+ && pp_callee->argc_stack == 0
+ && (pp_callee->is_fastcall || pp_callee->argc_reg == 0)
+ && pp_site->argc_reg > pp_callee->argc_reg)
+ /* fascall compatible callee doesn't use all args -> ok */
+ return 1;
+
+ return 0;
+}
+
static inline void pp_print(char *buf, size_t buf_size,
const struct parsed_proto *pp)
{
int i;
for (i = 0; i < pp->argc; i++) {
- if (pp->arg[i].reg != NULL)
- free(pp->arg[i].reg);
- if (pp->arg[i].type.name != NULL)
- free(pp->arg[i].type.name);
- if (pp->arg[i].pp != NULL)
- free(pp->arg[i].pp);
+ free(pp->arg[i].reg);
+ free(pp->arg[i].type.name);
+ free(pp->arg[i].pp);
+ free(pp->arg[i].push_refs);
}
if (pp->ret_type.name != NULL)
free(pp->ret_type.name);