Sync to wine-0.9.60:

- Rob Shearman <rob@codeweavers.com> Wed, 26 Mar 2008
widl: Support using context handles as the binding handle in client functions.

- Rob Shearman <rob@codeweavers.com> Thu, 27 Mar 2008
widl: Use is_string_type for detecting strings in write_typeformatstring_var to make it consistent with write_remoting_arg.

- Rob Shearman <rob@codeweavers.com> Thu, 27 Mar 2008
widl: Add support for generic binding handles.

- Rob Shearman <rob@codeweavers.com> Thu, 27 Mar 2008
widl: Fix detection of non-pointer context handles.

- Rob Shearman <rob@codeweavers.com> Thu, 27 Mar 2008
widl: Make sure that string types are always written out by write_string_tfs and not write_simple_pointer.

- Rob Shearman <rob@codeweavers.com> Mon, 31 Mar 2008
widl: Parse typedefs of function pointers.

- Rob Shearman <rob@codeweavers.com> Tue, 1 Apr 2008
widl: Be more strict about where semicolons can appear in IDL files.

- Rob Shearman <rob@codeweavers.com> Wed, 2 Apr 2008
widl: Add a function to get the return type of a parsed function.

- Rob Shearman <rob@codeweavers.com> Wed, 2 Apr 2008
widl: Store function and function pointer types completely within type_t type.

- Rob Shearman <rob@codeweavers.com> Wed, 2 Apr 2008
widl: Support parsing calling conventions for function identifiers.

- Rob Shearman <rob@codeweavers.com> Wed, 2 Apr 2008
widl: Support __fastcall and __pascal calling conventions.

- Rob Shearman <rob@codeweavers.com> Wed, 2 Apr 2008
widl: Add a newline between function prototypes for non-object interfaces.

- Rob Shearman <rob@codeweavers.com> Wed, 2 Apr 2008
widl: Fix the writing out of function pointers with more than one level of indirection.

- Rob Shearman <rob@codeweavers.com> Wed, 2 Apr 2008
widl: Turn on verbose errors, which gives a little more information in the case of a syntax error.

- Dan Hipschman <dsh@linux.ucla.edu> Thu, 3 Apr 2008
widl: Fix a mistake in an ordered list (keywords).


svn path=/trunk/; revision=36829
This commit is contained in:
Eric Kohl 2008-10-19 12:30:41 +00:00
parent c2a9e1f979
commit 0690324f95
18 changed files with 2458 additions and 1913 deletions

View file

@ -26,7 +26,7 @@ reactos/tools/wpp # Synced to Wine-0_9_5
reactos/tools/winebuild # Synced to Wine-20071217 reactos/tools/winebuild # Synced to Wine-20071217
reactos/tools/wmc # Synced to Wine-20071201 reactos/tools/wmc # Synced to Wine-20071201
reactos/tools/wrc # Synced to Wine-0_9_53 reactos/tools/wrc # Synced to Wine-0_9_53
reactos/tools/widl # Synced to Wine-0_9_58 reactos/tools/widl # Synced to Wine-0_9_59
The following libraries are shared with Wine. The following libraries are shared with Wine.

View file

@ -70,6 +70,20 @@ static void check_pointers(const func_t *func)
} }
} }
const var_t* get_context_handle_var(const func_t* func)
{
const var_t* var;
if (!func->args)
return NULL;
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
if (is_attr(var->attrs, ATTR_IN) && is_context_handle(var->type))
return var;
return NULL;
}
static void write_function_stubs(type_t *iface, unsigned int *proc_offset) static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
{ {
const func_t *func; const func_t *func;
@ -85,13 +99,21 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
{ {
const var_t *def = func->def; const var_t *def = func->def;
const var_t* explicit_handle_var; const var_t* explicit_handle_var;
const var_t* explicit_generic_handle_var = NULL;
const var_t* context_handle_var = NULL;
int has_full_pointer = is_full_pointer_function(func); int has_full_pointer = is_full_pointer_function(func);
/* check for a defined binding handle */ /* check for a defined binding handle */
explicit_handle_var = get_explicit_handle_var(func); explicit_handle_var = get_explicit_handle_var(func);
if (!explicit_handle_var)
{
explicit_generic_handle_var = get_explicit_generic_handle_var(func);
if (!explicit_generic_handle_var)
context_handle_var = get_context_handle_var(func);
}
if (explicit_handle) if (explicit_handle)
{ {
if (!explicit_handle_var) if (!explicit_handle_var && !explicit_generic_handle_var && !context_handle_var)
{ {
error("%s() does not define an explicit binding handle!\n", def->name); error("%s() does not define an explicit binding handle!\n", def->name);
return; return;
@ -106,8 +128,8 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
} }
} }
write_type_decl_left(client, def->type); write_type_decl_left(client, get_func_return_type(func));
if (needs_space_after(def->type)) if (needs_space_after(get_func_return_type(func)))
fprintf(client, " "); fprintf(client, " ");
write_prefix_name(client, prefix_client, def); write_prefix_name(client, prefix_client, def);
fprintf(client, "(\n"); fprintf(client, "(\n");
@ -124,19 +146,19 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
indent++; indent++;
/* declare return value '_RetVal' */ /* declare return value '_RetVal' */
if (!is_void(def->type)) if (!is_void(get_func_return_type(func)))
{ {
print_client(""); print_client("");
write_type_decl_left(client, def->type); write_type_decl_left(client, get_func_return_type(func));
fprintf(client, " _RetVal;\n"); fprintf(client, " _RetVal;\n");
} }
if (implicit_handle || explicit_handle_var) if (implicit_handle || explicit_handle_var || explicit_generic_handle_var || context_handle_var)
print_client("RPC_BINDING_HANDLE _Handle = 0;\n"); print_client("RPC_BINDING_HANDLE _Handle = 0;\n");
print_client("RPC_MESSAGE _RpcMessage;\n"); print_client("RPC_MESSAGE _RpcMessage;\n");
print_client("MIDL_STUB_MESSAGE _StubMsg;\n"); print_client("MIDL_STUB_MESSAGE _StubMsg;\n");
if (!is_void(def->type) && decl_indirect(def->type)) if (!is_void(get_func_return_type(func)) && decl_indirect(get_func_return_type(func)))
{ {
print_client("void *_p_%s = &%s;\n", print_client("void *_p_%s = &%s;\n",
"_RetVal", "_RetVal"); "_RetVal", "_RetVal");
@ -172,6 +194,25 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
print_client("_Handle = %s;\n", explicit_handle_var->name); print_client("_Handle = %s;\n", explicit_handle_var->name);
fprintf(client, "\n"); fprintf(client, "\n");
} }
else if (explicit_generic_handle_var)
{
print_client("_Handle = %s_bind(%s);\n",
get_explicit_generic_handle_type(explicit_generic_handle_var)->name,
explicit_generic_handle_var->name);
fprintf(client, "\n");
}
else if (context_handle_var)
{
/* if the context_handle attribute appears in the chain of types
* without pointers being followed, then the context handle must
* be direct, otherwise it is a pointer */
int is_ch_ptr = is_aliaschain_attr(context_handle_var->type, ATTR_CONTEXTHANDLE) ? FALSE : TRUE;
print_client("if (%s%s != 0)\n", is_ch_ptr ? "*" : "", context_handle_var->name);
indent++;
print_client("_Handle = NDRCContextBinding(%s%s);\n", is_ch_ptr ? "*" : "", context_handle_var->name);
indent--;
fprintf(client, "\n");
}
write_remoting_arguments(client, indent, func, PASS_IN, PHASE_BUFFERSIZE); write_remoting_arguments(client, indent, func, PASS_IN, PHASE_BUFFERSIZE);
@ -179,7 +220,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
indent++; indent++;
print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n");
print_client("_StubMsg.BufferLength,\n"); print_client("_StubMsg.BufferLength,\n");
if (implicit_handle || explicit_handle_var) if (implicit_handle || explicit_handle_var || explicit_generic_handle_var || context_handle_var)
print_client("_Handle);\n"); print_client("_Handle);\n");
else else
print_client("%s__MIDL_AutoBindHandle);\n", iface->name); print_client("%s__MIDL_AutoBindHandle);\n", iface->name);
@ -220,11 +261,11 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
write_remoting_arguments(client, indent, func, PASS_OUT, PHASE_UNMARSHAL); write_remoting_arguments(client, indent, func, PASS_OUT, PHASE_UNMARSHAL);
/* unmarshal return value */ /* unmarshal return value */
if (!is_void(def->type)) if (!is_void(get_func_return_type(func)))
{ {
if (decl_indirect(def->type)) if (decl_indirect(get_func_return_type(func)))
print_client("MIDL_memset(&%s, 0, sizeof(%s));\n", "_RetVal", "_RetVal"); print_client("MIDL_memset(&%s, 0, sizeof(%s));\n", "_RetVal", "_RetVal");
else if (is_ptr(def->type) || is_array(def->type)) else if (is_ptr(get_func_return_type(func)) || is_array(get_func_return_type(func)))
print_client("%s = 0;\n", "_RetVal"); print_client("%s = 0;\n", "_RetVal");
write_remoting_arguments(client, indent, func, PASS_RETURN, PHASE_UNMARSHAL); write_remoting_arguments(client, indent, func, PASS_RETURN, PHASE_UNMARSHAL);
} }
@ -233,10 +274,10 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
if (func->args) if (func->args)
{ {
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
*proc_offset += get_size_procformatstring_var(var); *proc_offset += get_size_procformatstring_type(var->name, var->type, var->attrs);
} }
if (!is_void(def->type)) if (!is_void(get_func_return_type(func)))
*proc_offset += get_size_procformatstring_var(def); *proc_offset += get_size_procformatstring_type("return value", get_func_return_type(func), NULL);
else else
*proc_offset += 2; /* FC_END and FC_PAD */ *proc_offset += 2; /* FC_END and FC_PAD */
@ -254,13 +295,24 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
print_client("NdrFreeBuffer((PMIDL_STUB_MESSAGE)&_StubMsg);\n"); print_client("NdrFreeBuffer((PMIDL_STUB_MESSAGE)&_StubMsg);\n");
if (!implicit_handle && explicit_generic_handle_var)
{
fprintf(client, "\n");
print_client("if (_Handle)\n");
indent++;
print_client("%s_unbind(%s, _Handle);\n",
get_explicit_generic_handle_type(explicit_generic_handle_var)->name,
explicit_generic_handle_var->name);
indent--;
}
indent--; indent--;
print_client("}\n"); print_client("}\n");
print_client("RpcEndFinally\n"); print_client("RpcEndFinally\n");
/* emit return code */ /* emit return code */
if (!is_void(def->type)) if (!is_void(get_func_return_type(func)))
{ {
fprintf(client, "\n"); fprintf(client, "\n");
print_client("return _RetVal;\n"); print_client("return _RetVal;\n");

View file

@ -34,9 +34,12 @@
#include "parser.h" #include "parser.h"
#include "header.h" #include "header.h"
typedef struct _user_type_t generic_handle_t;
static int indentation = 0; static int indentation = 0;
user_type_list_t user_type_list = LIST_INIT(user_type_list); user_type_list_t user_type_list = LIST_INIT(user_type_list);
static context_handle_list_t context_handle_list = LIST_INIT(context_handle_list); static context_handle_list_t context_handle_list = LIST_INIT(context_handle_list);
static struct list generic_handle_list = LIST_INIT(generic_handle_list);
static void indent(FILE *h, int delta) static void indent(FILE *h, int delta)
{ {
@ -66,6 +69,19 @@ int is_ptrchain_attr(const var_t *var, enum attr_type t)
} }
} }
int is_aliaschain_attr(const type_t *type, enum attr_type attr)
{
const type_t *t = type;
for (;;)
{
if (is_attr(t->attrs, attr))
return 1;
else if (t->kind == TKIND_ALIAS)
t = t->orig;
else return 0;
}
}
int is_attr(const attr_list_t *list, enum attr_type t) int is_attr(const attr_list_t *list, enum attr_type t)
{ {
const attr_t *attr; const attr_t *attr;
@ -211,7 +227,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
else fprintf(h, "enum {\n"); else fprintf(h, "enum {\n");
t->written = TRUE; t->written = TRUE;
indentation++; indentation++;
write_enums(h, t->fields); write_enums(h, t->fields_or_args);
indent(h, -1); indent(h, -1);
fprintf(h, "}"); fprintf(h, "}");
} }
@ -229,7 +245,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
else fprintf(h, "struct {\n"); else fprintf(h, "struct {\n");
t->written = TRUE; t->written = TRUE;
indentation++; indentation++;
write_fields(h, t->fields); write_fields(h, t->fields_or_args);
indent(h, -1); indent(h, -1);
fprintf(h, "}"); fprintf(h, "}");
} }
@ -241,7 +257,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
else fprintf(h, "union {\n"); else fprintf(h, "union {\n");
t->written = TRUE; t->written = TRUE;
indentation++; indentation++;
write_fields(h, t->fields); write_fields(h, t->fields_or_args);
indent(h, -1); indent(h, -1);
fprintf(h, "}"); fprintf(h, "}");
} }
@ -280,14 +296,37 @@ void write_type_right(FILE *h, type_t *t, int is_field)
void write_type_v(FILE *h, type_t *t, int is_field, int declonly, void write_type_v(FILE *h, type_t *t, int is_field, int declonly,
const char *fmt, va_list args) const char *fmt, va_list args)
{ {
type_t *pt;
int ptr_level = 0;
if (!h) return; if (!h) return;
for (pt = t; is_ptr(pt); pt = pt->ref, ptr_level++)
;
if (pt->type == RPC_FC_FUNCTION) {
int i;
const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
if (!callconv) callconv = "";
write_type_left(h, pt->ref, declonly);
fputc(' ', h);
if (ptr_level) fputc('(', h);
fprintf(h, "%s ", callconv);
for (i = 0; i < ptr_level; i++)
fputc('*', h);
} else
write_type_left(h, t, declonly); write_type_left(h, t, declonly);
if (fmt) { if (fmt) {
if (needs_space_after(t)) if (needs_space_after(t))
fprintf(h, " "); fputc(' ', h);
vfprintf(h, fmt, args); vfprintf(h, fmt, args);
} }
if (pt->type == RPC_FC_FUNCTION) {
if (ptr_level) fputc(')', h);
fputc('(', h);
write_args(h, pt->fields_or_args, NULL, 0, FALSE);
fputc(')', h);
} else
write_type_right(h, t, is_field); write_type_right(h, t, is_field);
} }
@ -330,7 +369,18 @@ static int context_handle_registered(const char *name)
return 0; return 0;
} }
void check_for_user_types_and_context_handles(const var_list_t *list) static int generic_handle_registered(const char *name)
{
generic_handle_t *gh;
LIST_FOR_EACH_ENTRY(gh, &generic_handle_list, generic_handle_t, entry)
if (!strcmp(name, gh->name))
return 1;
return 0;
}
/* check for types which require additional prototypes to be generated in the
* header */
void check_for_additional_prototype_types(const var_list_t *list)
{ {
const var_t *v; const var_t *v;
@ -352,6 +402,16 @@ void check_for_user_types_and_context_handles(const var_list_t *list)
/* don't carry on parsing fields within this type */ /* don't carry on parsing fields within this type */
break; break;
} }
if (type->type != RPC_FC_BIND_PRIMITIVE && is_attr(type->attrs, ATTR_HANDLE)) {
if (!generic_handle_registered(name))
{
generic_handle_t *gh = xmalloc(sizeof(*gh));
gh->name = xstrdup(name);
list_add_tail(&generic_handle_list, &gh->entry);
}
/* don't carry on parsing fields within this type */
break;
}
if (is_attr(type->attrs, ATTR_WIREMARSHAL)) { if (is_attr(type->attrs, ATTR_WIREMARSHAL)) {
if (!user_type_registered(name)) if (!user_type_registered(name))
{ {
@ -365,7 +425,7 @@ void check_for_user_types_and_context_handles(const var_list_t *list)
} }
else else
{ {
check_for_user_types_and_context_handles(type->fields); check_for_additional_prototype_types(type->fields_or_args);
} }
} }
} }
@ -394,6 +454,17 @@ void write_context_handle_rundowns(void)
} }
} }
void write_generic_handle_routines(void)
{
generic_handle_t *gh;
LIST_FOR_EACH_ENTRY(gh, &generic_handle_list, generic_handle_t, entry)
{
const char *name = gh->name;
fprintf(header, "handle_t __RPC_USER %s_bind(%s);\n", name, name);
fprintf(header, "void __RPC_USER %s_unbind(%s, handle_t);\n", name, name);
}
}
void write_typedef(type_t *type) void write_typedef(type_t *type)
{ {
fprintf(header, "typedef "); fprintf(header, "typedef ");
@ -524,11 +595,34 @@ const var_t* get_explicit_handle_var(const func_t* func)
return NULL; return NULL;
} }
const type_t* get_explicit_generic_handle_type(const var_t* var)
{
const type_t *t;
for (t = var->type; is_ptr(t); t = t->ref)
if (t->type != RPC_FC_BIND_PRIMITIVE && is_attr(t->attrs, ATTR_HANDLE))
return t;
return NULL;
}
const var_t* get_explicit_generic_handle_var(const func_t* func)
{
const var_t* var;
if (!func->args)
return NULL;
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
if (get_explicit_generic_handle_type(var))
return var;
return NULL;
}
int has_out_arg_or_return(const func_t *func) int has_out_arg_or_return(const func_t *func)
{ {
const var_t *var; const var_t *var;
if (!is_void(func->def->type)) if (!is_void(get_func_return_type(func)))
return 1; return 1;
if (!func->args) if (!func->args)
@ -619,16 +713,6 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
} }
else fprintf(h, ","); else fprintf(h, ",");
} }
if (arg->args)
{
write_type_decl_left(h, arg->type);
fprintf(h, " (STDMETHODCALLTYPE *");
write_name(h,arg);
fprintf(h, ")(");
write_args(h, arg->args, NULL, 0, FALSE);
fprintf(h, ")");
}
else
write_type_decl(h, arg->type, "%s", arg->name); write_type_decl(h, arg->type, "%s", arg->name);
count++; count++;
} }
@ -647,7 +731,7 @@ static void write_cpp_method_def(const type_t *iface)
if (!is_callas(def->attrs)) { if (!is_callas(def->attrs)) {
indent(header, 0); indent(header, 0);
fprintf(header, "virtual "); fprintf(header, "virtual ");
write_type_decl_left(header, def->type); write_type_decl_left(header, get_func_return_type(cur));
fprintf(header, " STDMETHODCALLTYPE "); fprintf(header, " STDMETHODCALLTYPE ");
write_name(header, def); write_name(header, def);
fprintf(header, "(\n"); fprintf(header, "(\n");
@ -672,7 +756,7 @@ static void do_write_c_method_def(const type_t *iface, const char *name)
const var_t *def = cur->def; const var_t *def = cur->def;
if (!is_callas(def->attrs)) { if (!is_callas(def->attrs)) {
indent(header, 0); indent(header, 0);
write_type_decl_left(header, def->type); write_type_decl_left(header, get_func_return_type(cur));
fprintf(header, " (STDMETHODCALLTYPE *"); fprintf(header, " (STDMETHODCALLTYPE *");
write_name(header, def); write_name(header, def);
fprintf(header, ")(\n"); fprintf(header, ")(\n");
@ -704,7 +788,7 @@ static void write_method_proto(const type_t *iface)
if (!is_local(def->attrs)) { if (!is_local(def->attrs)) {
/* proxy prototype */ /* proxy prototype */
write_type_decl_left(header, def->type); write_type_decl_left(header, get_func_return_type(cur));
fprintf(header, " CALLBACK %s_", iface->name); fprintf(header, " CALLBACK %s_", iface->name);
write_name(header, def); write_name(header, def);
fprintf(header, "_Proxy(\n"); fprintf(header, "_Proxy(\n");
@ -744,14 +828,14 @@ void write_locals(FILE *fp, const type_t *iface, int body)
if (&m->entry != iface->funcs) { if (&m->entry != iface->funcs) {
const var_t *mdef = m->def; const var_t *mdef = m->def;
/* proxy prototype - use local prototype */ /* proxy prototype - use local prototype */
write_type_decl_left(fp, mdef->type); write_type_decl_left(fp, get_func_return_type(m));
fprintf(fp, " CALLBACK %s_", iface->name); fprintf(fp, " CALLBACK %s_", iface->name);
write_name(fp, mdef); write_name(fp, mdef);
fprintf(fp, "_Proxy(\n"); fprintf(fp, "_Proxy(\n");
write_args(fp, m->args, iface->name, 1, TRUE); write_args(fp, m->args, iface->name, 1, TRUE);
fprintf(fp, ")"); fprintf(fp, ")");
if (body) { if (body) {
type_t *rt = mdef->type; type_t *rt = get_func_return_type(m);
fprintf(fp, "\n{\n"); fprintf(fp, "\n{\n");
fprintf(fp, " %s\n", comment); fprintf(fp, " %s\n", comment);
if (rt->name && strcmp(rt->name, "HRESULT") == 0) if (rt->name && strcmp(rt->name, "HRESULT") == 0)
@ -768,7 +852,7 @@ void write_locals(FILE *fp, const type_t *iface, int body)
else else
fprintf(fp, ";\n"); fprintf(fp, ";\n");
/* stub prototype - use remotable prototype */ /* stub prototype - use remotable prototype */
write_type_decl_left(fp, def->type); write_type_decl_left(fp, get_func_return_type(cur));
fprintf(fp, " __RPC_STUB %s_", iface->name); fprintf(fp, " __RPC_STUB %s_", iface->name);
write_name(fp, mdef); write_name(fp, mdef);
fprintf(fp, "_Stub(\n"); fprintf(fp, "_Stub(\n");
@ -791,7 +875,7 @@ static void write_function_proto(const type_t *iface, const func_t *fun, const c
var_t *def = fun->def; var_t *def = fun->def;
/* FIXME: do we need to handle call_as? */ /* FIXME: do we need to handle call_as? */
write_type_decl_left(header, def->type); write_type_decl_left(header, get_func_return_type(fun));
fprintf(header, " "); fprintf(header, " ");
write_prefix_name(header, prefix, def); write_prefix_name(header, prefix, def);
fprintf(header, "(\n"); fprintf(header, "(\n");
@ -799,7 +883,7 @@ static void write_function_proto(const type_t *iface, const func_t *fun, const c
write_args(header, fun->args, iface->name, 0, TRUE); write_args(header, fun->args, iface->name, 0, TRUE);
else else
fprintf(header, " void"); fprintf(header, " void");
fprintf(header, ");\n"); fprintf(header, ");\n\n");
} }
static void write_function_protos(const type_t *iface) static void write_function_protos(const type_t *iface)
@ -807,6 +891,8 @@ static void write_function_protos(const type_t *iface)
const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE); int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE);
const var_t* explicit_handle_var; const var_t* explicit_handle_var;
const var_t* explicit_generic_handle_var = NULL;
const var_t* context_handle_var = NULL;
const func_t *cur; const func_t *cur;
int prefixes_differ = strcmp(prefix_client, prefix_server); int prefixes_differ = strcmp(prefix_client, prefix_server);
@ -817,8 +903,14 @@ static void write_function_protos(const type_t *iface)
/* check for a defined binding handle */ /* check for a defined binding handle */
explicit_handle_var = get_explicit_handle_var(cur); explicit_handle_var = get_explicit_handle_var(cur);
if (!explicit_handle_var)
{
explicit_generic_handle_var = get_explicit_generic_handle_var(cur);
if (!explicit_generic_handle_var)
context_handle_var = get_context_handle_var(cur);
}
if (explicit_handle) { if (explicit_handle) {
if (!explicit_handle_var) { if (!explicit_handle_var && !explicit_generic_handle_var && !context_handle_var) {
error("%s() does not define an explicit binding handle!\n", def->name); error("%s() does not define an explicit binding handle!\n", def->name);
return; return;
} }

View file

@ -24,6 +24,7 @@
#include "widltypes.h" #include "widltypes.h"
extern int is_ptrchain_attr(const var_t *var, enum attr_type t); extern int is_ptrchain_attr(const var_t *var, enum attr_type t);
extern int is_aliaschain_attr(const type_t *var, enum attr_type t);
extern int is_attr(const attr_list_t *list, enum attr_type t); extern int is_attr(const attr_list_t *list, enum attr_type t);
extern void *get_attrp(const attr_list_t *list, enum attr_type t); extern void *get_attrp(const attr_list_t *list, enum attr_type t);
extern unsigned long get_attrv(const attr_list_t *list, enum attr_type t); extern unsigned long get_attrv(const attr_list_t *list, enum attr_type t);
@ -61,7 +62,11 @@ extern void write_externdef(const var_t *v);
extern void write_library(const char *name, const attr_list_t *attr); extern void write_library(const char *name, const attr_list_t *attr);
extern void write_user_types(void); extern void write_user_types(void);
extern void write_context_handle_rundowns(void); extern void write_context_handle_rundowns(void);
extern void write_generic_handle_routines(void);
extern const var_t* get_explicit_handle_var(const func_t* func); extern const var_t* get_explicit_handle_var(const func_t* func);
extern const type_t* get_explicit_generic_handle_type(const var_t* var);
extern const var_t* get_explicit_generic_handle_var(const func_t* func);
extern const var_t* get_context_handle_var(const func_t* func);
extern int has_out_arg_or_return(const func_t *func); extern int has_out_arg_or_return(const func_t *func);
extern void write_guid(FILE *f, const char *guid_prefix, const char *name, extern void write_guid(FILE *f, const char *guid_prefix, const char *name,
const UUID *uuid); const UUID *uuid);
@ -78,17 +83,25 @@ static inline int last_array(const type_t *type)
static inline int is_string_type(const attr_list_t *attrs, const type_t *type) static inline int is_string_type(const attr_list_t *attrs, const type_t *type)
{ {
return ((is_attr(attrs, ATTR_STRING) || is_attr(type->attrs, ATTR_STRING)) return ((is_attr(attrs, ATTR_STRING) || is_aliaschain_attr(type, ATTR_STRING))
&& (last_ptr(type) || last_array(type))); && (last_ptr(type) || last_array(type)));
} }
static inline int is_context_handle(const type_t *type) static inline int is_context_handle(const type_t *type)
{ {
const type_t *t; if (is_attr(type->attrs, ATTR_CONTEXTHANDLE))
for (t = type; is_ptr(t); t = t->ref)
if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
return 1; return 1;
return 0;
for (;;)
{
if (is_attr(type->attrs, ATTR_CONTEXTHANDLE))
return 1;
else if (type->kind == TKIND_ALIAS)
type = type->orig;
else if (is_ptr(type))
type = type->ref;
else return 0;
}
} }
#endif #endif

View file

@ -39,6 +39,7 @@ int parser_lex(void);
extern int import_stack_ptr; extern int import_stack_ptr;
int do_import(char *fname); int do_import(char *fname);
void abort_import(void); void abort_import(void);
void pop_import(void);
#define parse_only import_stack_ptr #define parse_only import_stack_ptr

View file

@ -79,8 +79,6 @@ struct {
} import_stack[MAX_IMPORT_DEPTH]; } import_stack[MAX_IMPORT_DEPTH];
int import_stack_ptr = 0; int import_stack_ptr = 0;
static void pop_import(void);
UUID *parse_uuid(const char *u) UUID *parse_uuid(const char *u)
{ {
UUID* uuid = xmalloc(sizeof(UUID)); UUID* uuid = xmalloc(sizeof(UUID));
@ -166,10 +164,8 @@ SAFEARRAY{ws}*/\( return tSAFEARRAY;
<INITIAL,ATTR>\>\> return SHR; <INITIAL,ATTR>\>\> return SHR;
<INITIAL,ATTR>. return yytext[0]; <INITIAL,ATTR>. return yytext[0];
<<EOF>> { <<EOF>> {
if (import_stack_ptr) { if (import_stack_ptr)
pop_import();
return aEOF; return aEOF;
}
else yyterminate(); else yyterminate();
} }
%% %%
@ -190,13 +186,19 @@ static const struct keyword keywords[] = {
{"FALSE", tFALSE}, {"FALSE", tFALSE},
{"TRUE", tTRUE}, {"TRUE", tTRUE},
{"__cdecl", tCDECL}, {"__cdecl", tCDECL},
{"__fastcall", tFASTCALL},
{"__int64", tINT64}, {"__int64", tINT64},
{"__pascal", tPASCAL},
{"__stdcall", tSTDCALL}, {"__stdcall", tSTDCALL},
{"_cdecl", tCDECL},
{"_fastcall", tFASTCALL},
{"_pascal", tPASCAL},
{"_stdcall", tSTDCALL}, {"_stdcall", tSTDCALL},
{"boolean", tBOOLEAN}, {"boolean", tBOOLEAN},
{"byte", tBYTE}, {"byte", tBYTE},
{"callback", tCALLBACK}, {"callback", tCALLBACK},
{"case", tCASE}, {"case", tCASE},
{"cdecl", tCDECL},
{"char", tCHAR}, {"char", tCHAR},
{"coclass", tCOCLASS}, {"coclass", tCOCLASS},
{"code", tCODE}, {"code", tCODE},
@ -221,11 +223,13 @@ static const struct keyword keywords[] = {
{"long", tLONG}, {"long", tLONG},
{"methods", tMETHODS}, {"methods", tMETHODS},
{"module", tMODULE}, {"module", tMODULE},
{"pascal", tPASCAL},
{"properties", tPROPERTIES}, {"properties", tPROPERTIES},
{"short", tSHORT}, {"short", tSHORT},
{"signed", tSIGNED}, {"signed", tSIGNED},
{"sizeof", tSIZEOF}, {"sizeof", tSIZEOF},
{"small", tSMALL}, {"small", tSMALL},
{"stdcall", tSTDCALL},
{"struct", tSTRUCT}, {"struct", tSTRUCT},
{"switch", tSWITCH}, {"switch", tSWITCH},
{"typedef", tTYPEDEF}, {"typedef", tTYPEDEF},
@ -367,7 +371,7 @@ static char *get_buffered_cstring(void)
return xstrdup(cbuffer); return xstrdup(cbuffer);
} }
static void pop_import(void) void pop_import(void)
{ {
int ptr = import_stack_ptr-1; int ptr = import_stack_ptr-1;

File diff suppressed because it is too large Load diff

View file

@ -80,89 +80,91 @@
tEXPLICITHANDLE = 306, tEXPLICITHANDLE = 306,
tEXTERN = 307, tEXTERN = 307,
tFALSE = 308, tFALSE = 308,
tFLOAT = 309, tFASTCALL = 309,
tHANDLE = 310, tFLOAT = 310,
tHANDLET = 311, tHANDLE = 311,
tHELPCONTEXT = 312, tHANDLET = 312,
tHELPFILE = 313, tHELPCONTEXT = 313,
tHELPSTRING = 314, tHELPFILE = 314,
tHELPSTRINGCONTEXT = 315, tHELPSTRING = 315,
tHELPSTRINGDLL = 316, tHELPSTRINGCONTEXT = 316,
tHIDDEN = 317, tHELPSTRINGDLL = 317,
tHYPER = 318, tHIDDEN = 318,
tID = 319, tHYPER = 319,
tIDEMPOTENT = 320, tID = 320,
tIIDIS = 321, tIDEMPOTENT = 321,
tIMMEDIATEBIND = 322, tIIDIS = 322,
tIMPLICITHANDLE = 323, tIMMEDIATEBIND = 323,
tIMPORT = 324, tIMPLICITHANDLE = 324,
tIMPORTLIB = 325, tIMPORT = 325,
tIN = 326, tIMPORTLIB = 326,
tINLINE = 327, tIN = 327,
tINPUTSYNC = 328, tINLINE = 328,
tINT = 329, tINPUTSYNC = 329,
tINT64 = 330, tINT = 330,
tINTERFACE = 331, tINT64 = 331,
tLCID = 332, tINTERFACE = 332,
tLENGTHIS = 333, tLCID = 333,
tLIBRARY = 334, tLENGTHIS = 334,
tLOCAL = 335, tLIBRARY = 335,
tLONG = 336, tLOCAL = 336,
tMETHODS = 337, tLONG = 337,
tMODULE = 338, tMETHODS = 338,
tNONBROWSABLE = 339, tMODULE = 339,
tNONCREATABLE = 340, tNONBROWSABLE = 340,
tNONEXTENSIBLE = 341, tNONCREATABLE = 341,
tOBJECT = 342, tNONEXTENSIBLE = 342,
tODL = 343, tOBJECT = 343,
tOLEAUTOMATION = 344, tODL = 344,
tOPTIONAL = 345, tOLEAUTOMATION = 345,
tOUT = 346, tOPTIONAL = 346,
tPOINTERDEFAULT = 347, tOUT = 347,
tPROPERTIES = 348, tPASCAL = 348,
tPROPGET = 349, tPOINTERDEFAULT = 349,
tPROPPUT = 350, tPROPERTIES = 350,
tPROPPUTREF = 351, tPROPGET = 351,
tPTR = 352, tPROPPUT = 352,
tPUBLIC = 353, tPROPPUTREF = 353,
tRANGE = 354, tPTR = 354,
tREADONLY = 355, tPUBLIC = 355,
tREF = 356, tRANGE = 356,
tREQUESTEDIT = 357, tREADONLY = 357,
tRESTRICTED = 358, tREF = 358,
tRETVAL = 359, tREQUESTEDIT = 359,
tSAFEARRAY = 360, tRESTRICTED = 360,
tSHORT = 361, tRETVAL = 361,
tSIGNED = 362, tSAFEARRAY = 362,
tSINGLE = 363, tSHORT = 363,
tSIZEIS = 364, tSIGNED = 364,
tSIZEOF = 365, tSINGLE = 365,
tSMALL = 366, tSIZEIS = 366,
tSOURCE = 367, tSIZEOF = 367,
tSTDCALL = 368, tSMALL = 368,
tSTRICTCONTEXTHANDLE = 369, tSOURCE = 369,
tSTRING = 370, tSTDCALL = 370,
tSTRUCT = 371, tSTRICTCONTEXTHANDLE = 371,
tSWITCH = 372, tSTRING = 372,
tSWITCHIS = 373, tSTRUCT = 373,
tSWITCHTYPE = 374, tSWITCH = 374,
tTRANSMITAS = 375, tSWITCHIS = 375,
tTRUE = 376, tSWITCHTYPE = 376,
tTYPEDEF = 377, tTRANSMITAS = 377,
tUNION = 378, tTRUE = 378,
tUNIQUE = 379, tTYPEDEF = 379,
tUNSIGNED = 380, tUNION = 380,
tUUID = 381, tUNIQUE = 381,
tV1ENUM = 382, tUNSIGNED = 382,
tVARARG = 383, tUUID = 383,
tVERSION = 384, tV1ENUM = 384,
tVOID = 385, tVARARG = 385,
tWCHAR = 386, tVERSION = 386,
tWIREMARSHAL = 387, tVOID = 387,
CAST = 388, tWCHAR = 388,
PPTR = 389, tWIREMARSHAL = 389,
NEG = 390, CAST = 390,
ADDRESSOF = 391 PPTR = 391,
NEG = 392,
ADDRESSOF = 393
}; };
#endif #endif
/* Tokens. */ /* Tokens. */
@ -217,95 +219,97 @@
#define tEXPLICITHANDLE 306 #define tEXPLICITHANDLE 306
#define tEXTERN 307 #define tEXTERN 307
#define tFALSE 308 #define tFALSE 308
#define tFLOAT 309 #define tFASTCALL 309
#define tHANDLE 310 #define tFLOAT 310
#define tHANDLET 311 #define tHANDLE 311
#define tHELPCONTEXT 312 #define tHANDLET 312
#define tHELPFILE 313 #define tHELPCONTEXT 313
#define tHELPSTRING 314 #define tHELPFILE 314
#define tHELPSTRINGCONTEXT 315 #define tHELPSTRING 315
#define tHELPSTRINGDLL 316 #define tHELPSTRINGCONTEXT 316
#define tHIDDEN 317 #define tHELPSTRINGDLL 317
#define tHYPER 318 #define tHIDDEN 318
#define tID 319 #define tHYPER 319
#define tIDEMPOTENT 320 #define tID 320
#define tIIDIS 321 #define tIDEMPOTENT 321
#define tIMMEDIATEBIND 322 #define tIIDIS 322
#define tIMPLICITHANDLE 323 #define tIMMEDIATEBIND 323
#define tIMPORT 324 #define tIMPLICITHANDLE 324
#define tIMPORTLIB 325 #define tIMPORT 325
#define tIN 326 #define tIMPORTLIB 326
#define tINLINE 327 #define tIN 327
#define tINPUTSYNC 328 #define tINLINE 328
#define tINT 329 #define tINPUTSYNC 329
#define tINT64 330 #define tINT 330
#define tINTERFACE 331 #define tINT64 331
#define tLCID 332 #define tINTERFACE 332
#define tLENGTHIS 333 #define tLCID 333
#define tLIBRARY 334 #define tLENGTHIS 334
#define tLOCAL 335 #define tLIBRARY 335
#define tLONG 336 #define tLOCAL 336
#define tMETHODS 337 #define tLONG 337
#define tMODULE 338 #define tMETHODS 338
#define tNONBROWSABLE 339 #define tMODULE 339
#define tNONCREATABLE 340 #define tNONBROWSABLE 340
#define tNONEXTENSIBLE 341 #define tNONCREATABLE 341
#define tOBJECT 342 #define tNONEXTENSIBLE 342
#define tODL 343 #define tOBJECT 343
#define tOLEAUTOMATION 344 #define tODL 344
#define tOPTIONAL 345 #define tOLEAUTOMATION 345
#define tOUT 346 #define tOPTIONAL 346
#define tPOINTERDEFAULT 347 #define tOUT 347
#define tPROPERTIES 348 #define tPASCAL 348
#define tPROPGET 349 #define tPOINTERDEFAULT 349
#define tPROPPUT 350 #define tPROPERTIES 350
#define tPROPPUTREF 351 #define tPROPGET 351
#define tPTR 352 #define tPROPPUT 352
#define tPUBLIC 353 #define tPROPPUTREF 353
#define tRANGE 354 #define tPTR 354
#define tREADONLY 355 #define tPUBLIC 355
#define tREF 356 #define tRANGE 356
#define tREQUESTEDIT 357 #define tREADONLY 357
#define tRESTRICTED 358 #define tREF 358
#define tRETVAL 359 #define tREQUESTEDIT 359
#define tSAFEARRAY 360 #define tRESTRICTED 360
#define tSHORT 361 #define tRETVAL 361
#define tSIGNED 362 #define tSAFEARRAY 362
#define tSINGLE 363 #define tSHORT 363
#define tSIZEIS 364 #define tSIGNED 364
#define tSIZEOF 365 #define tSINGLE 365
#define tSMALL 366 #define tSIZEIS 366
#define tSOURCE 367 #define tSIZEOF 367
#define tSTDCALL 368 #define tSMALL 368
#define tSTRICTCONTEXTHANDLE 369 #define tSOURCE 369
#define tSTRING 370 #define tSTDCALL 370
#define tSTRUCT 371 #define tSTRICTCONTEXTHANDLE 371
#define tSWITCH 372 #define tSTRING 372
#define tSWITCHIS 373 #define tSTRUCT 373
#define tSWITCHTYPE 374 #define tSWITCH 374
#define tTRANSMITAS 375 #define tSWITCHIS 375
#define tTRUE 376 #define tSWITCHTYPE 376
#define tTYPEDEF 377 #define tTRANSMITAS 377
#define tUNION 378 #define tTRUE 378
#define tUNIQUE 379 #define tTYPEDEF 379
#define tUNSIGNED 380 #define tUNION 380
#define tUUID 381 #define tUNIQUE 381
#define tV1ENUM 382 #define tUNSIGNED 382
#define tVARARG 383 #define tUUID 383
#define tVERSION 384 #define tV1ENUM 384
#define tVOID 385 #define tVARARG 385
#define tWCHAR 386 #define tVERSION 386
#define tWIREMARSHAL 387 #define tVOID 387
#define CAST 388 #define tWCHAR 388
#define PPTR 389 #define tWIREMARSHAL 389
#define NEG 390 #define CAST 390
#define ADDRESSOF 391 #define PPTR 391
#define NEG 392
#define ADDRESSOF 393
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
#line 136 "parser.y" #line 139 "parser.y"
typedef union YYSTYPE { typedef union YYSTYPE {
attr_t *attr; attr_t *attr;
attr_list_t *attr_list; attr_list_t *attr_list;
@ -329,7 +333,7 @@ typedef union YYSTYPE {
interface_info_t ifinfo; interface_info_t ifinfo;
} YYSTYPE; } YYSTYPE;
/* Line 1447 of yacc.c. */ /* Line 1447 of yacc.c. */
#line 333 "parser.tab.h" #line 337 "parser.tab.h"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_TRIVIAL 1

View file

@ -63,7 +63,10 @@
# endif # endif
#endif #endif
#define YYERROR_VERBOSE
unsigned char pointer_default = RPC_FC_UP; unsigned char pointer_default = RPC_FC_UP;
static int is_object_interface = FALSE;
typedef struct list typelist_t; typedef struct list typelist_t;
struct typenode { struct typenode {
@ -92,7 +95,7 @@ static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, exp
static type_t *make_type(unsigned char type, type_t *ref); static type_t *make_type(unsigned char type, type_t *ref);
static expr_list_t *append_expr(expr_list_t *list, expr_t *expr); static expr_list_t *append_expr(expr_list_t *list, expr_t *expr);
static array_dims_t *append_array(array_dims_t *list, expr_t *expr); static array_dims_t *append_array(array_dims_t *list, expr_t *expr);
static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr, int top); static void set_type(var_t *v, type_t *type, const pident_t *pident, array_dims_t *arr, int top);
static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface); static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface);
static ifref_t *make_ifref(type_t *iface); static ifref_t *make_ifref(type_t *iface);
static var_list_t *append_var(var_list_t *list, var_t *var); static var_list_t *append_var(var_list_t *list, var_t *var);
@ -180,6 +183,7 @@ static void check_all_user_types(ifref_list_t *ifaces);
%token tENTRY tENUM tERRORSTATUST %token tENTRY tENUM tERRORSTATUST
%token tEXPLICITHANDLE tEXTERN %token tEXPLICITHANDLE tEXTERN
%token tFALSE %token tFALSE
%token tFASTCALL
%token tFLOAT %token tFLOAT
%token tHANDLE %token tHANDLE
%token tHANDLET %token tHANDLET
@ -207,6 +211,7 @@ static void check_all_user_types(ifref_list_t *ifaces);
%token tOBJECT tODL tOLEAUTOMATION %token tOBJECT tODL tOLEAUTOMATION
%token tOPTIONAL %token tOPTIONAL
%token tOUT %token tOUT
%token tPASCAL
%token tPOINTERDEFAULT %token tPOINTERDEFAULT
%token tPROPERTIES %token tPROPERTIES
%token tPROPGET tPROPPUT tPROPPUTREF %token tPROPGET tPROPPUT tPROPPUTREF
@ -259,14 +264,15 @@ static void check_all_user_types(ifref_list_t *ifaces);
%type <var> arg field s_field case enum constdef externdef %type <var> arg field s_field case enum constdef externdef
%type <var_list> m_args no_args args fields cases enums enum_list dispint_props %type <var_list> m_args no_args args fields cases enums enum_list dispint_props
%type <var> m_ident t_ident ident %type <var> m_ident t_ident ident
%type <pident> p_ident pident %type <pident> pident func_ident direct_ident
%type <pident_list> pident_list %type <pident_list> pident_list
%type <func> funcdef %type <func> funcdef
%type <func_list> int_statements dispint_meths %type <func_list> int_statements dispint_meths
%type <type> coclass coclasshdr coclassdef %type <type> coclass coclasshdr coclassdef
%type <num> pointer_type version %type <num> pointer_type version
%type <str> libraryhdr %type <str> libraryhdr callconv
%type <uuid> uuid_string %type <uuid> uuid_string
%type <num> import_start
%left ',' %left ','
%right '?' ':' %right '?' ':'
@ -328,8 +334,11 @@ int_statements: { $$ = NULL; }
| int_statements statement { $$ = $1; } | int_statements statement { $$ = $1; }
; ;
statement: ';' {} semicolon_opt:
| constdef ';' { if (!parse_only && do_header) { write_constdef($1); } } | ';'
;
statement: constdef ';' { if (!parse_only && do_header) { write_constdef($1); } }
| cppquote {} | cppquote {}
| enumdef ';' { if (!parse_only && do_header) { | enumdef ';' { if (!parse_only && do_header) {
write_type_def_or_decl(header, $1, FALSE, NULL); write_type_def_or_decl(header, $1, FALSE, NULL);
@ -354,12 +363,17 @@ statement: ';' {}
cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only && do_header) fprintf(header, "%s\n", $3); } cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only && do_header) fprintf(header, "%s\n", $3); }
; ;
import_start: tIMPORT aSTRING ';' { assert(yychar == YYEMPTY); import_start: tIMPORT aSTRING ';' { assert(yychar == YYEMPTY);
if (!do_import($2)) yychar = aEOF; } $$ = do_import($2);
; if (!$$) yychar = aEOF;
import: import_start imp_statements aEOF {} }
; ;
importlib: tIMPORTLIB '(' aSTRING ')' { if(!parse_only) add_importlib($3); } import: import_start imp_statements aEOF
{ if ($1) pop_import(); }
;
importlib: tIMPORTLIB '(' aSTRING ')'
semicolon_opt { if(!parse_only) add_importlib($3); }
; ;
libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; } libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; }
@ -369,7 +383,8 @@ library_start: attributes libraryhdr '{' { if (!parse_only) start_typelib($2, $1
if (!parse_only && do_idfile) write_libid($2, $1); if (!parse_only && do_idfile) write_libid($2, $1);
} }
; ;
librarydef: library_start imp_statements '}' { if (!parse_only) end_typelib(); } librarydef: library_start imp_statements '}'
semicolon_opt { if (!parse_only) end_typelib(); }
; ;
m_args: { $$ = NULL; } m_args: { $$ = NULL; }
@ -387,24 +402,13 @@ args: arg { check_arg($1); $$ = append_var( NULL, $1 ); }
/* split into two rules to get bison to resolve a tVOID conflict */ /* split into two rules to get bison to resolve a tVOID conflict */
arg: attributes type pident array { $$ = $3->var; arg: attributes type pident array { $$ = $3->var;
$$->attrs = $1; $$->attrs = $1;
set_type($$, $2, $3->ptr_level, $4, TRUE); set_type($$, $2, $3, $4, TRUE);
free($3); free($3);
} }
| type pident array { $$ = $2->var; | type pident array { $$ = $2->var;
set_type($$, $1, $2->ptr_level, $3, TRUE); set_type($$, $1, $2, $3, TRUE);
free($2); free($2);
} }
| attributes type pident '(' m_args ')' { $$ = $3->var;
$$->attrs = $1;
set_type($$, $2, $3->ptr_level - 1, NULL, TRUE);
free($3);
$$->args = $5;
}
| type pident '(' m_args ')' { $$ = $2->var;
set_type($$, $1, $2->ptr_level - 1, NULL, TRUE);
free($2);
$$->args = $4;
}
; ;
array: { $$ = NULL; } array: { $$ = NULL; }
@ -519,8 +523,10 @@ uuid_string:
$$ = parse_uuid($1); } $$ = parse_uuid($1); }
; ;
callconv: callconv: tCDECL { $$ = $<str>1; }
| tSTDCALL | tFASTCALL { $$ = $<str>1; }
| tPASCAL { $$ = $<str>1; }
| tSTDCALL { $$ = $<str>1; }
; ;
cases: { $$ = NULL; } cases: { $$ = NULL; }
@ -538,7 +544,7 @@ case: tCASE expr ':' field { attr_t *a = make_attrp(ATTR_CASE, append_expr(
; ;
constdef: tCONST type ident '=' expr_const { $$ = reg_const($3); constdef: tCONST type ident '=' expr_const { $$ = reg_const($3);
set_type($$, $2, 0, NULL, FALSE); set_type($$, $2, NULL, NULL, FALSE);
$$->eval = $5; $$->eval = $5;
} }
; ;
@ -572,7 +578,7 @@ enum: ident '=' expr_const { $$ = reg_const($1);
enumdef: tENUM t_ident '{' enums '}' { $$ = get_typev(RPC_FC_ENUM16, $2, tsENUM); enumdef: tENUM t_ident '{' enums '}' { $$ = get_typev(RPC_FC_ENUM16, $2, tsENUM);
$$->kind = TKIND_ENUM; $$->kind = TKIND_ENUM;
$$->fields = $4; $$->fields_or_args = $4;
$$->defined = TRUE; $$->defined = TRUE;
if(in_typelib) if(in_typelib)
add_typelib_entry($$); add_typelib_entry($$);
@ -632,7 +638,7 @@ expr_const: expr { $$ = $1;
; ;
externdef: tEXTERN tCONST type ident { $$ = $4; externdef: tEXTERN tCONST type ident { $$ = $4;
set_type($$, $3, 0, NULL, FALSE); set_type($$, $3, NULL, NULL, FALSE);
} }
; ;
@ -648,18 +654,18 @@ field: s_field ';' { $$ = $1; }
s_field: m_attributes type pident array { $$ = $3->var; s_field: m_attributes type pident array { $$ = $3->var;
$$->attrs = $1; $$->attrs = $1;
set_type($$, $2, $3->ptr_level, $4, FALSE); set_type($$, $2, $3, $4, FALSE);
free($3); free($3);
} }
; ;
funcdef: funcdef:
m_attributes type callconv pident m_attributes type pident { var_t *v = $3->var;
'(' m_args ')' { var_t *v = $4->var; var_list_t *args = $3->args;
v->attrs = $1; v->attrs = $1;
set_type(v, $2, $4->ptr_level, NULL, FALSE); set_type(v, $2, $3, NULL, FALSE);
free($4); free($3);
$$ = make_func(v, $6); $$ = make_func(v, args);
if (is_attr(v->attrs, ATTR_IN)) { if (is_attr(v->attrs, ATTR_IN)) {
error_loc("inapplicable attribute [in] for function '%s'\n",$$->def->name); error_loc("inapplicable attribute [in] for function '%s'\n",$$->def->name);
} }
@ -738,7 +744,8 @@ coclasshdr: attributes coclass { $$ = $2;
} }
; ;
coclassdef: coclasshdr '{' coclass_ints '}' { $$ = $1; coclassdef: coclasshdr '{' coclass_ints '}' semicolon_opt
{ $$ = $1;
$$->ifaces = $3; $$->ifaces = $3;
$$->defined = TRUE; $$->defined = TRUE;
} }
@ -757,6 +764,7 @@ dispinterface: tDISPINTERFACE aIDENTIFIER { $$ = get_type(0, $2, 0); $$->kind =
; ;
dispinterfacehdr: attributes dispinterface { attr_t *attrs; dispinterfacehdr: attributes dispinterface { attr_t *attrs;
is_object_interface = TRUE;
$$ = $2; $$ = $2;
if ($$->defined) error_loc("multiple definition error\n"); if ($$->defined) error_loc("multiple definition error\n");
attrs = make_attr(ATTR_DISPINTERFACE); attrs = make_attr(ATTR_DISPINTERFACE);
@ -780,14 +788,14 @@ dispinterfacedef: dispinterfacehdr '{'
dispint_props dispint_props
dispint_meths dispint_meths
'}' { $$ = $1; '}' { $$ = $1;
$$->fields = $3; $$->fields_or_args = $3;
$$->funcs = $4; $$->funcs = $4;
if (!parse_only && do_header) write_dispinterface($$); if (!parse_only && do_header) write_dispinterface($$);
if (!parse_only && do_idfile) write_diid($$); if (!parse_only && do_idfile) write_diid($$);
} }
| dispinterfacehdr | dispinterfacehdr
'{' interface ';' '}' { $$ = $1; '{' interface ';' '}' { $$ = $1;
$$->fields = $3->fields; $$->fields_or_args = $3->fields_or_args;
$$->funcs = $3->funcs; $$->funcs = $3->funcs;
if (!parse_only && do_header) write_dispinterface($$); if (!parse_only && do_header) write_dispinterface($$);
if (!parse_only && do_idfile) write_diid($$); if (!parse_only && do_idfile) write_diid($$);
@ -806,6 +814,7 @@ interfacehdr: attributes interface { $$.interface = $2;
$$.old_pointer_default = pointer_default; $$.old_pointer_default = pointer_default;
if (is_attr($1, ATTR_POINTERDEFAULT)) if (is_attr($1, ATTR_POINTERDEFAULT))
pointer_default = get_attrv($1, ATTR_POINTERDEFAULT); pointer_default = get_attrv($1, ATTR_POINTERDEFAULT);
is_object_interface = is_object($1);
if ($2->defined) error_loc("multiple definition error\n"); if ($2->defined) error_loc("multiple definition error\n");
$2->attrs = $1; $2->attrs = $1;
$2->defined = TRUE; $2->defined = TRUE;
@ -814,7 +823,7 @@ interfacehdr: attributes interface { $$.interface = $2;
; ;
interfacedef: interfacehdr inherit interfacedef: interfacehdr inherit
'{' int_statements '}' { $$ = $1.interface; '{' int_statements '}' semicolon_opt { $$ = $1.interface;
$$->ref = $2; $$->ref = $2;
$$->funcs = $4; $$->funcs = $4;
compute_method_indexes($$); compute_method_indexes($$);
@ -826,7 +835,8 @@ interfacedef: interfacehdr inherit
/* MIDL is able to import the definition of a base class from inside the /* MIDL is able to import the definition of a base class from inside the
* definition of a derived class, I'll try to support it with this rule */ * definition of a derived class, I'll try to support it with this rule */
| interfacehdr ':' aIDENTIFIER | interfacehdr ':' aIDENTIFIER
'{' import int_statements '}' { $$ = $1.interface; '{' import int_statements '}'
semicolon_opt { $$ = $1.interface;
$$->ref = find_type2($3, 0); $$->ref = find_type2($3, 0);
if (!$$->ref) error_loc("base class '%s' not found in import\n", $3); if (!$$->ref) error_loc("base class '%s' not found in import\n", $3);
$$->funcs = $6; $$->funcs = $6;
@ -836,7 +846,7 @@ interfacedef: interfacehdr inherit
if (!parse_only && do_idfile) write_iid($$); if (!parse_only && do_idfile) write_iid($$);
pointer_default = $1.old_pointer_default; pointer_default = $1.old_pointer_default;
} }
| dispinterfacedef { $$ = $1; } | dispinterfacedef semicolon_opt { $$ = $1; }
; ;
interfacedec: interfacedec:
@ -853,19 +863,35 @@ modulehdr: attributes module { $$ = $2;
} }
; ;
moduledef: modulehdr '{' int_statements '}' { $$ = $1; moduledef: modulehdr '{' int_statements '}'
semicolon_opt { $$ = $1;
$$->funcs = $3; $$->funcs = $3;
/* FIXME: if (!parse_only && do_header) write_module($$); */ /* FIXME: if (!parse_only && do_header) write_module($$); */
} }
; ;
p_ident: '*' pident %prec PPTR { $$ = $2; $$->ptr_level++; } pident: '*' pident %prec PPTR { $$ = $2; $$->ptr_level++; }
| tCONST p_ident { $$ = $2; /* FIXME */ } | tCONST pident { $$ = $2; /* FIXME */ }
| callconv pident { $$ = $2;
if ($$->callconv) parser_warning("multiple calling conventions %s, %s for function %s\n", $$->callconv, $1, $$->var->name);
$$->callconv = $1;
}
| direct_ident
; ;
pident: ident { $$ = make_pident($1); } func_ident: direct_ident '(' m_args ')'
| p_ident { $$ = $1;
$1->args = $3;
$1->is_func = TRUE;
}
;
direct_ident: ident { $$ = make_pident($1); }
| '(' pident ')' { $$ = $2; } | '(' pident ')' { $$ = $2; }
| func_ident { $$ = $1;
$$->func_ptr_level = $$->ptr_level;
$$->ptr_level = 0;
}
; ;
pident_list: pident_list:
@ -883,7 +909,7 @@ structdef: tSTRUCT t_ident '{' fields '}' { $$ = get_typev(RPC_FC_STRUCT, $2, ts
/* overwrite RPC_FC_STRUCT with a more exact type */ /* overwrite RPC_FC_STRUCT with a more exact type */
$$->type = get_struct_type( $4 ); $$->type = get_struct_type( $4 );
$$->kind = TKIND_RECORD; $$->kind = TKIND_RECORD;
$$->fields = $4; $$->fields_or_args = $4;
$$->defined = TRUE; $$->defined = TRUE;
if(in_typelib) if(in_typelib)
add_typelib_entry($$); add_typelib_entry($$);
@ -910,7 +936,7 @@ typedef: tTYPEDEF m_attributes type pident_list { reg_typedefs($3, $4, $2);
uniondef: tUNION t_ident '{' fields '}' { $$ = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, $2, tsUNION); uniondef: tUNION t_ident '{' fields '}' { $$ = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, $2, tsUNION);
$$->kind = TKIND_UNION; $$->kind = TKIND_UNION;
$$->fields = $4; $$->fields_or_args = $4;
$$->defined = TRUE; $$->defined = TRUE;
} }
| tUNION t_ident | tUNION t_ident
@ -921,10 +947,10 @@ uniondef: tUNION t_ident '{' fields '}' { $$ = get_typev(RPC_FC_NON_ENCAPSULATE
if (!u) u = make_var( xstrdup("tagged_union") ); if (!u) u = make_var( xstrdup("tagged_union") );
u->type = make_type(RPC_FC_NON_ENCAPSULATED_UNION, NULL); u->type = make_type(RPC_FC_NON_ENCAPSULATED_UNION, NULL);
u->type->kind = TKIND_UNION; u->type->kind = TKIND_UNION;
u->type->fields = $9; u->type->fields_or_args = $9;
u->type->defined = TRUE; u->type->defined = TRUE;
$$->fields = append_var( $$->fields, $5 ); $$->fields_or_args = append_var( $$->fields_or_args, $5 );
$$->fields = append_var( $$->fields, u ); $$->fields_or_args = append_var( $$->fields_or_args, u );
$$->defined = TRUE; $$->defined = TRUE;
} }
; ;
@ -1289,7 +1315,7 @@ static type_t *make_type(unsigned char type, type_t *ref)
t->attrs = NULL; t->attrs = NULL;
t->orig = NULL; t->orig = NULL;
t->funcs = NULL; t->funcs = NULL;
t->fields = NULL; t->fields_or_args = NULL;
t->ifaces = NULL; t->ifaces = NULL;
t->dim = 0; t->dim = 0;
t->size_is = NULL; t->size_is = NULL;
@ -1308,7 +1334,7 @@ static type_t *make_type(unsigned char type, type_t *ref)
return t; return t;
} }
static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr, static void set_type(var_t *v, type_t *type, const pident_t *pident, array_dims_t *arr,
int top) int top)
{ {
expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS); expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS);
@ -1318,6 +1344,7 @@ static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr,
int sizeless, has_varconf; int sizeless, has_varconf;
expr_t *dim; expr_t *dim;
type_t *atype, **ptype; type_t *atype, **ptype;
int ptr_level = (pident ? pident->ptr_level : 0);
v->type = type; v->type = type;
@ -1348,6 +1375,21 @@ static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr,
error("%s: pointer attribute applied to non-pointer type\n", v->name); error("%s: pointer attribute applied to non-pointer type\n", v->name);
} }
if (pident && pident->is_func) {
int func_ptr_level = pident->func_ptr_level;
v->type = make_type(RPC_FC_FUNCTION, v->type);
v->type->fields_or_args = pident->args;
if (pident->callconv)
v->type->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, pident->callconv));
else if (is_object_interface) {
static char *stdmethodcalltype;
if (!stdmethodcalltype) stdmethodcalltype = strdup("STDMETHODCALLTYPE");
v->type->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, stdmethodcalltype));
}
for (; func_ptr_level > 0; func_ptr_level--)
v->type = make_type(ptr_type, v->type);
}
sizeless = FALSE; sizeless = FALSE;
if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry) if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry)
{ {
@ -1499,7 +1541,6 @@ static var_t *make_var(char *name)
var_t *v = xmalloc(sizeof(var_t)); var_t *v = xmalloc(sizeof(var_t));
v->name = name; v->name = name;
v->type = NULL; v->type = NULL;
v->args = NULL;
v->attrs = NULL; v->attrs = NULL;
v->eval = NULL; v->eval = NULL;
return v; return v;
@ -1520,7 +1561,11 @@ static pident_t *make_pident(var_t *var)
{ {
pident_t *p = xmalloc(sizeof(*p)); pident_t *p = xmalloc(sizeof(*p));
p->var = var; p->var = var;
p->is_func = FALSE;
p->ptr_level = 0; p->ptr_level = 0;
p->func_ptr_level = 0;
p->args = NULL;
p->callconv = NULL;
return p; return p;
} }
@ -1621,7 +1666,7 @@ static void fix_type(type_t *t)
if (t->kind == TKIND_ALIAS && is_incomplete(t)) { if (t->kind == TKIND_ALIAS && is_incomplete(t)) {
type_t *ot = t->orig; type_t *ot = t->orig;
fix_type(ot); fix_type(ot);
t->fields = ot->fields; t->fields_or_args = ot->fields_or_args;
t->defined = ot->defined; t->defined = ot->defined;
} }
} }
@ -1691,6 +1736,20 @@ static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *a
cptr++; cptr++;
} }
} }
if (pident->is_func) {
int func_ptr_level = pident->func_ptr_level;
cur = make_type(RPC_FC_FUNCTION, cur);
cur->fields_or_args = pident->args;
if (pident->callconv)
cur->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, pident->callconv));
else if (is_object_interface) {
static char *stdmethodcalltype;
if (!stdmethodcalltype) stdmethodcalltype = strdup("STDMETHODCALLTYPE");
cur->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, stdmethodcalltype));
}
for (; func_ptr_level > 0; func_ptr_level--)
cur = make_type(pointer_default, cur);
}
cur = alias(cur, name->name); cur = alias(cur, name->name);
cur->attrs = attrs; cur->attrs = attrs;
if (ptr_type) if (ptr_type)
@ -2072,7 +2131,7 @@ static void check_all_user_types(ifref_list_t *ifrefs)
{ {
const func_list_t *fs = ifref->iface->funcs; const func_list_t *fs = ifref->iface->funcs;
if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry) if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry)
check_for_user_types_and_context_handles(f->args); check_for_additional_prototype_types(f->args);
} }
} }

View file

@ -559,8 +559,6 @@ struct {
} import_stack[MAX_IMPORT_DEPTH]; } import_stack[MAX_IMPORT_DEPTH];
int import_stack_ptr = 0; int import_stack_ptr = 0;
static void pop_import(void);
UUID *parse_uuid(const char *u) UUID *parse_uuid(const char *u)
{ {
UUID* uuid = xmalloc(sizeof(UUID)); UUID* uuid = xmalloc(sizeof(UUID));
@ -586,7 +584,7 @@ UUID *parse_uuid(const char *u)
* The flexer starts here * The flexer starts here
************************************************************************** **************************************************************************
*/ */
#line 590 "parser.yy.c" #line 588 "parser.yy.c"
/* Macros after this point can all be overridden by user definitions in /* Macros after this point can all be overridden by user definitions in
* section 1. * section 1.
@ -740,9 +738,9 @@ YY_DECL
register char *yy_cp, *yy_bp; register char *yy_cp, *yy_bp;
register int yy_act; register int yy_act;
#line 111 "parser.l" #line 109 "parser.l"
#line 746 "parser.yy.c" #line 744 "parser.yy.c"
if ( yy_init ) if ( yy_init )
{ {
@ -828,12 +826,12 @@ do_action: /* This label is used only to access EOF actions. */
case 1: case 1:
YY_RULE_SETUP YY_RULE_SETUP
#line 112 "parser.l" #line 110 "parser.l"
yy_push_state(PP_LINE); yy_push_state(PP_LINE);
YY_BREAK YY_BREAK
case 2: case 2:
YY_RULE_SETUP YY_RULE_SETUP
#line 113 "parser.l" #line 111 "parser.l"
{ {
int lineno; int lineno;
char *cptr, *fname; char *cptr, *fname;
@ -856,12 +854,12 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 3: case 3:
YY_RULE_SETUP YY_RULE_SETUP
#line 132 "parser.l" #line 130 "parser.l"
yy_push_state(QUOTE); cbufidx = 0; yy_push_state(QUOTE); cbufidx = 0;
YY_BREAK YY_BREAK
case 4: case 4:
YY_RULE_SETUP YY_RULE_SETUP
#line 133 "parser.l" #line 131 "parser.l"
{ {
yy_pop_state(); yy_pop_state();
parser_lval.str = get_buffered_cstring(); parser_lval.str = get_buffered_cstring();
@ -869,40 +867,40 @@ YY_RULE_SETUP
} }
YY_BREAK YY_BREAK
case 5: case 5:
#line 139 "parser.l" #line 137 "parser.l"
case 6: case 6:
YY_RULE_SETUP YY_RULE_SETUP
#line 139 "parser.l" #line 137 "parser.l"
addcchar(yytext[1]); addcchar(yytext[1]);
YY_BREAK YY_BREAK
case 7: case 7:
YY_RULE_SETUP YY_RULE_SETUP
#line 140 "parser.l" #line 138 "parser.l"
addcchar('\\'); addcchar(yytext[1]); addcchar('\\'); addcchar(yytext[1]);
YY_BREAK YY_BREAK
case 8: case 8:
YY_RULE_SETUP YY_RULE_SETUP
#line 141 "parser.l" #line 139 "parser.l"
addcchar(yytext[0]); addcchar(yytext[0]);
YY_BREAK YY_BREAK
case 9: case 9:
YY_RULE_SETUP YY_RULE_SETUP
#line 142 "parser.l" #line 140 "parser.l"
yy_push_state(ATTR); return '['; yy_push_state(ATTR); return '[';
YY_BREAK YY_BREAK
case 10: case 10:
YY_RULE_SETUP YY_RULE_SETUP
#line 143 "parser.l" #line 141 "parser.l"
yy_pop_state(); return ']'; yy_pop_state(); return ']';
YY_BREAK YY_BREAK
case 11: case 11:
YY_RULE_SETUP YY_RULE_SETUP
#line 144 "parser.l" #line 142 "parser.l"
return attr_token(yytext); return attr_token(yytext);
YY_BREAK YY_BREAK
case 12: case 12:
YY_RULE_SETUP YY_RULE_SETUP
#line 145 "parser.l" #line 143 "parser.l"
{ {
parser_lval.uuid = parse_uuid(yytext); parser_lval.uuid = parse_uuid(yytext);
return aUUID; return aUUID;
@ -910,7 +908,7 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 13: case 13:
YY_RULE_SETUP YY_RULE_SETUP
#line 149 "parser.l" #line 147 "parser.l"
{ {
parser_lval.num = strtoul(yytext, NULL, 0); parser_lval.num = strtoul(yytext, NULL, 0);
return aHEXNUM; return aHEXNUM;
@ -918,7 +916,7 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 14: case 14:
YY_RULE_SETUP YY_RULE_SETUP
#line 153 "parser.l" #line 151 "parser.l"
{ {
parser_lval.num = strtoul(yytext, NULL, 0); parser_lval.num = strtoul(yytext, NULL, 0);
return aNUM; return aNUM;
@ -926,7 +924,7 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 15: case 15:
YY_RULE_SETUP YY_RULE_SETUP
#line 157 "parser.l" #line 155 "parser.l"
{ {
parser_lval.dbl = strtod(yytext, NULL); parser_lval.dbl = strtod(yytext, NULL);
return aDOUBLE; return aDOUBLE;
@ -937,58 +935,56 @@ case 16:
yy_c_buf_p = yy_cp -= 1; yy_c_buf_p = yy_cp -= 1;
YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_DO_BEFORE_ACTION; /* set up yytext again */
YY_RULE_SETUP YY_RULE_SETUP
#line 161 "parser.l" #line 159 "parser.l"
return tSAFEARRAY; return tSAFEARRAY;
YY_BREAK YY_BREAK
case 17: case 17:
YY_RULE_SETUP YY_RULE_SETUP
#line 162 "parser.l" #line 160 "parser.l"
return kw_token(yytext); return kw_token(yytext);
YY_BREAK YY_BREAK
case 18: case 18:
YY_RULE_SETUP YY_RULE_SETUP
#line 163 "parser.l" #line 161 "parser.l"
line_number++; line_number++;
YY_BREAK YY_BREAK
case 19: case 19:
YY_RULE_SETUP YY_RULE_SETUP
#line 164 "parser.l" #line 162 "parser.l"
YY_BREAK YY_BREAK
case 20: case 20:
YY_RULE_SETUP YY_RULE_SETUP
#line 165 "parser.l" #line 163 "parser.l"
return SHL; return SHL;
YY_BREAK YY_BREAK
case 21: case 21:
YY_RULE_SETUP YY_RULE_SETUP
#line 166 "parser.l" #line 164 "parser.l"
return SHR; return SHR;
YY_BREAK YY_BREAK
case 22: case 22:
YY_RULE_SETUP YY_RULE_SETUP
#line 167 "parser.l" #line 165 "parser.l"
return yytext[0]; return yytext[0];
YY_BREAK YY_BREAK
case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(INITIAL):
case YY_STATE_EOF(QUOTE): case YY_STATE_EOF(QUOTE):
case YY_STATE_EOF(ATTR): case YY_STATE_EOF(ATTR):
case YY_STATE_EOF(PP_LINE): case YY_STATE_EOF(PP_LINE):
#line 168 "parser.l" #line 166 "parser.l"
{ {
if (import_stack_ptr) { if (import_stack_ptr)
pop_import();
return aEOF; return aEOF;
}
else yyterminate(); else yyterminate();
} }
YY_BREAK YY_BREAK
case 23: case 23:
YY_RULE_SETUP YY_RULE_SETUP
#line 175 "parser.l" #line 171 "parser.l"
ECHO; ECHO;
YY_BREAK YY_BREAK
#line 992 "parser.yy.c" #line 988 "parser.yy.c"
case YY_END_OF_BUFFER: case YY_END_OF_BUFFER:
{ {
@ -1874,7 +1870,7 @@ int main()
return 0; return 0;
} }
#endif #endif
#line 175 "parser.l" #line 171 "parser.l"
#ifndef parser_wrap #ifndef parser_wrap
@ -1893,13 +1889,19 @@ static const struct keyword keywords[] = {
{"FALSE", tFALSE}, {"FALSE", tFALSE},
{"TRUE", tTRUE}, {"TRUE", tTRUE},
{"__cdecl", tCDECL}, {"__cdecl", tCDECL},
{"__fastcall", tFASTCALL},
{"__int64", tINT64}, {"__int64", tINT64},
{"__pascal", tPASCAL},
{"__stdcall", tSTDCALL}, {"__stdcall", tSTDCALL},
{"_cdecl", tCDECL},
{"_fastcall", tFASTCALL},
{"_pascal", tPASCAL},
{"_stdcall", tSTDCALL}, {"_stdcall", tSTDCALL},
{"boolean", tBOOLEAN}, {"boolean", tBOOLEAN},
{"byte", tBYTE}, {"byte", tBYTE},
{"callback", tCALLBACK}, {"callback", tCALLBACK},
{"case", tCASE}, {"case", tCASE},
{"cdecl", tCDECL},
{"char", tCHAR}, {"char", tCHAR},
{"coclass", tCOCLASS}, {"coclass", tCOCLASS},
{"code", tCODE}, {"code", tCODE},
@ -1924,11 +1926,13 @@ static const struct keyword keywords[] = {
{"long", tLONG}, {"long", tLONG},
{"methods", tMETHODS}, {"methods", tMETHODS},
{"module", tMODULE}, {"module", tMODULE},
{"pascal", tPASCAL},
{"properties", tPROPERTIES}, {"properties", tPROPERTIES},
{"short", tSHORT}, {"short", tSHORT},
{"signed", tSIGNED}, {"signed", tSIGNED},
{"sizeof", tSIZEOF}, {"sizeof", tSIZEOF},
{"small", tSMALL}, {"small", tSMALL},
{"stdcall", tSTDCALL},
{"struct", tSTRUCT}, {"struct", tSTRUCT},
{"switch", tSWITCH}, {"switch", tSWITCH},
{"typedef", tTYPEDEF}, {"typedef", tTYPEDEF},
@ -2070,7 +2074,7 @@ static char *get_buffered_cstring(void)
return xstrdup(cbuffer); return xstrdup(cbuffer);
} }
static void pop_import(void) void pop_import(void)
{ {
int ptr = import_stack_ptr-1; int ptr = import_stack_ptr-1;

View file

@ -251,11 +251,11 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
unsigned int proc_offset) unsigned int proc_offset)
{ {
var_t *def = cur->def; var_t *def = cur->def;
int has_ret = !is_void(def->type); int has_ret = !is_void(get_func_return_type(cur));
int has_full_pointer = is_full_pointer_function(cur); int has_full_pointer = is_full_pointer_function(cur);
indent = 0; indent = 0;
write_type_decl_left(proxy, def->type); write_type_decl_left(proxy, get_func_return_type(cur));
print_proxy( " STDMETHODCALLTYPE %s_", iface->name); print_proxy( " STDMETHODCALLTYPE %s_", iface->name);
write_name(proxy, def); write_name(proxy, def);
print_proxy( "_Proxy(\n"); print_proxy( "_Proxy(\n");
@ -266,13 +266,13 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
/* local variables */ /* local variables */
if (has_ret) { if (has_ret) {
print_proxy( "" ); print_proxy( "" );
write_type_decl_left(proxy, def->type); write_type_decl_left(proxy, get_func_return_type(cur));
print_proxy( " _RetVal;\n"); print_proxy( " _RetVal;\n");
} }
print_proxy( "RPC_MESSAGE _RpcMessage;\n" ); print_proxy( "RPC_MESSAGE _RpcMessage;\n" );
print_proxy( "MIDL_STUB_MESSAGE _StubMsg;\n" ); print_proxy( "MIDL_STUB_MESSAGE _StubMsg;\n" );
if (has_ret) { if (has_ret) {
if (decl_indirect(def->type)) if (decl_indirect(get_func_return_type(cur)))
print_proxy("void *_p_%s = &%s;\n", print_proxy("void *_p_%s = &%s;\n",
"_RetVal", "_RetVal"); "_RetVal", "_RetVal");
} }
@ -315,9 +315,9 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
if (has_ret) if (has_ret)
{ {
if (decl_indirect(def->type)) if (decl_indirect(get_func_return_type(cur)))
print_proxy("MIDL_memset(&%s, 0, sizeof(%s));\n", "_RetVal", "_RetVal"); print_proxy("MIDL_memset(&%s, 0, sizeof(%s));\n", "_RetVal", "_RetVal");
else if (is_ptr(def->type) || is_array(def->type)) else if (is_ptr(get_func_return_type(cur)) || is_array(get_func_return_type(cur)))
print_proxy("%s = 0;\n", "_RetVal"); print_proxy("%s = 0;\n", "_RetVal");
write_remoting_arguments(proxy, indent, cur, PASS_RETURN, PHASE_UNMARSHAL); write_remoting_arguments(proxy, indent, cur, PASS_RETURN, PHASE_UNMARSHAL);
} }
@ -359,7 +359,7 @@ static void gen_stub(type_t *iface, const func_t *cur, const char *cas,
{ {
var_t *def = cur->def; var_t *def = cur->def;
const var_t *arg; const var_t *arg;
int has_ret = !is_void(def->type); int has_ret = !is_void(get_func_return_type(cur));
int has_full_pointer = is_full_pointer_function(cur); int has_full_pointer = is_full_pointer_function(cur);
indent = 0; indent = 0;
@ -431,13 +431,17 @@ static void gen_stub(type_t *iface, const func_t *cur, const char *cas,
write_remoting_arguments(proxy, indent, cur, PASS_OUT, PHASE_BUFFERSIZE); write_remoting_arguments(proxy, indent, cur, PASS_OUT, PHASE_BUFFERSIZE);
if (!is_void(get_func_return_type(cur)))
write_remoting_arguments(proxy, indent, cur, PASS_RETURN, PHASE_BUFFERSIZE);
print_proxy("NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg);\n"); print_proxy("NdrStubGetBuffer(This, _pRpcChannelBuffer, &_StubMsg);\n");
write_remoting_arguments(proxy, indent, cur, PASS_OUT, PHASE_MARSHAL); write_remoting_arguments(proxy, indent, cur, PASS_OUT, PHASE_MARSHAL);
fprintf(proxy, "\n"); fprintf(proxy, "\n");
if (has_ret) /* marshall the return value */
print_phase_basetype(proxy, indent, PHASE_MARSHAL, PASS_RETURN, def, "_RetVal"); if (!is_void(get_func_return_type(cur)))
write_remoting_arguments(proxy, indent, cur, PASS_RETURN, PHASE_MARSHAL);
indent--; indent--;
print_proxy("}\n"); print_proxy("}\n");

View file

@ -60,13 +60,21 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry ) LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry )
{ {
const var_t *def = func->def; const var_t *def = func->def;
const var_t* context_handle_var = NULL;
const var_t* explicit_generic_handle_var = NULL;
int has_full_pointer = is_full_pointer_function(func); int has_full_pointer = is_full_pointer_function(func);
/* check for a defined binding handle */ /* check for a defined binding handle */
explicit_handle_var = get_explicit_handle_var(func); explicit_handle_var = get_explicit_handle_var(func);
if (!explicit_handle_var)
{
explicit_generic_handle_var = get_explicit_generic_handle_var(func);
if (!explicit_generic_handle_var)
context_handle_var = get_context_handle_var(func);
}
if (explicit_handle) if (explicit_handle)
{ {
if (!explicit_handle_var) if (!explicit_handle_var && !explicit_generic_handle_var && !context_handle_var)
{ {
error("%s() does not define an explicit binding handle!\n", def->name); error("%s() does not define an explicit binding handle!\n", def->name);
return; return;
@ -164,7 +172,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
assign_stub_out_args(server, indent, func); assign_stub_out_args(server, indent, func);
/* Call the real server function */ /* Call the real server function */
if (!is_void(def->type)) if (!is_void(get_func_return_type(func)))
print_server("_RetVal = "); print_server("_RetVal = ");
else else
print_server(""); print_server("");
@ -184,9 +192,13 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
fprintf(server, ",\n"); fprintf(server, ",\n");
if (is_context_handle(var->type)) if (is_context_handle(var->type))
{ {
/* if the context_handle attribute appears in the chain of types
* without pointers being followed, then the context handle must
* be direct, otherwise it is a pointer */
int is_ch_ptr = is_aliaschain_attr(var->type, ATTR_CONTEXTHANDLE) ? FALSE : TRUE;
print_server("("); print_server("(");
write_type_decl_left(server, var->type); write_type_decl_left(server, var->type);
fprintf(server, ")%sNDRSContextValue(%s)", is_ptr(var->type) ? "" : "*", var->name); fprintf(server, ")%sNDRSContextValue(%s)", is_ch_ptr ? "" : "*", var->name);
} }
else else
{ {
@ -208,7 +220,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
{ {
write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_BUFFERSIZE); write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_BUFFERSIZE);
if (!is_void(def->type)) if (!is_void(get_func_return_type(func)))
write_remoting_arguments(server, indent, func, PASS_RETURN, PHASE_BUFFERSIZE); write_remoting_arguments(server, indent, func, PASS_RETURN, PHASE_BUFFERSIZE);
print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n"); print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n");
@ -227,7 +239,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_MARSHAL); write_remoting_arguments(server, indent, func, PASS_OUT, PHASE_MARSHAL);
/* marshall the return value */ /* marshall the return value */
if (!is_void(def->type)) if (!is_void(get_func_return_type(func)))
write_remoting_arguments(server, indent, func, PASS_RETURN, PHASE_MARSHAL); write_remoting_arguments(server, indent, func, PASS_RETURN, PHASE_MARSHAL);
indent--; indent--;

View file

@ -58,6 +58,9 @@ static size_t write_struct_tfs(FILE *file, type_t *type, const char *name, unsig
static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type, static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
const char *name, int write_ptr, unsigned int *tfsoff); const char *name, int write_ptr, unsigned int *tfsoff);
static const var_t *find_array_or_string_in_struct(const type_t *type); static const var_t *find_array_or_string_in_struct(const type_t *type);
static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
type_t *type,
const char *name, unsigned int *typestring_offset);
const char *string_of_type(unsigned char type) const char *string_of_type(unsigned char type)
{ {
@ -165,7 +168,7 @@ static int type_has_pointers(const type_t *type)
else if (is_struct(type->type)) else if (is_struct(type->type))
{ {
const var_t *field; const var_t *field;
if (type->fields) LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) if (type->fields_or_args) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
{ {
if (type_has_pointers(field->type)) if (type_has_pointers(field->type))
return TRUE; return TRUE;
@ -177,11 +180,11 @@ static int type_has_pointers(const type_t *type)
const var_t *field; const var_t *field;
if (type->type == RPC_FC_ENCAPSULATED_UNION) if (type->type == RPC_FC_ENCAPSULATED_UNION)
{ {
const var_t *uv = LIST_ENTRY(list_tail(type->fields), const var_t, entry); const var_t *uv = LIST_ENTRY(list_tail(type->fields_or_args), const var_t, entry);
fields = uv->type->fields; fields = uv->type->fields_or_args;
} }
else else
fields = type->fields; fields = type->fields_or_args;
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
{ {
if (field->type && type_has_pointers(field->type)) if (field->type && type_has_pointers(field->type))
@ -205,7 +208,7 @@ static int type_has_full_pointer(const type_t *type)
else if (is_struct(type->type)) else if (is_struct(type->type))
{ {
const var_t *field; const var_t *field;
if (type->fields) LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) if (type->fields_or_args) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
{ {
if (type_has_full_pointer(field->type)) if (type_has_full_pointer(field->type))
return TRUE; return TRUE;
@ -217,11 +220,11 @@ static int type_has_full_pointer(const type_t *type)
const var_t *field; const var_t *field;
if (type->type == RPC_FC_ENCAPSULATED_UNION) if (type->type == RPC_FC_ENCAPSULATED_UNION)
{ {
const var_t *uv = LIST_ENTRY(list_tail(type->fields), const var_t, entry); const var_t *uv = LIST_ENTRY(list_tail(type->fields_or_args), const var_t, entry);
fields = uv->type->fields; fields = uv->type->fields_or_args;
} }
else else
fields = type->fields; fields = type->fields_or_args;
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry ) if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
{ {
if (field->type && type_has_full_pointer(field->type)) if (field->type && type_has_full_pointer(field->type))
@ -415,8 +418,8 @@ void write_parameters_init(FILE *file, int indent, const func_t *func)
{ {
const var_t *var; const var_t *var;
if (!is_void(func->def->type)) if (!is_void(get_func_return_type(func)))
write_var_init(file, indent, func->def->type, "_RetVal"); write_var_init(file, indent, get_func_return_type(func), "_RetVal");
if (!func->args) if (!func->args)
return; return;
@ -490,14 +493,16 @@ int decl_indirect(const type_t *t)
&& !is_array(t)); && !is_array(t));
} }
static size_t write_procformatstring_var(FILE *file, int indent, static size_t write_procformatstring_type(FILE *file, int indent,
const var_t *var, int is_return) const char *name,
const type_t *type,
const attr_list_t *attrs,
int is_return)
{ {
size_t size; size_t size;
const type_t *type = var->type;
int is_in = is_attr(var->attrs, ATTR_IN); int is_in = is_attr(attrs, ATTR_IN);
int is_out = is_attr(var->attrs, ATTR_OUT); int is_out = is_attr(attrs, ATTR_OUT);
if (!is_in && !is_out) is_in = TRUE; if (!is_in && !is_out) is_in = TRUE;
@ -520,7 +525,7 @@ static size_t write_procformatstring_var(FILE *file, int indent,
} }
else else
{ {
error("Unknown/unsupported type: %s (0x%02x)\n", var->name, type->type); error("Unknown/unsupported type: %s (0x%02x)\n", name, type->type);
size = 0; size = 0;
} }
} }
@ -570,18 +575,17 @@ void write_procformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t
if (func->args) if (func->args)
{ {
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
write_procformatstring_var(file, indent, var, FALSE); write_procformatstring_type(file, indent, var->name, var->type, var->attrs, FALSE);
} }
/* emit return value data */ /* emit return value data */
var = func->def; if (is_void(get_func_return_type(func)))
if (is_void(var->type))
{ {
print_file(file, indent, "0x5b, /* FC_END */\n"); print_file(file, indent, "0x5b, /* FC_END */\n");
print_file(file, indent, "0x5c, /* FC_PAD */\n"); print_file(file, indent, "0x5c, /* FC_PAD */\n");
} }
else else
write_procformatstring_var(file, indent, var, TRUE); write_procformatstring_type(file, indent, "return value", get_func_return_type(func), NULL, TRUE);
} }
} }
} }
@ -706,7 +710,7 @@ static size_t write_conf_or_var_desc(FILE *file, const type_t *structure,
size_t offset = 0; size_t offset = 0;
const var_t *var; const var_t *var;
if (structure->fields) LIST_FOR_EACH_ENTRY( var, structure->fields, const var_t, entry ) if (structure->fields_or_args) LIST_FOR_EACH_ENTRY( var, structure->fields_or_args, const var_t, entry )
{ {
unsigned int align = 0; unsigned int align = 0;
/* FIXME: take alignment into account */ /* FIXME: take alignment into account */
@ -921,11 +925,11 @@ size_t type_memsize(const type_t *t, unsigned int *align)
case RPC_FC_CSTRUCT: case RPC_FC_CSTRUCT:
case RPC_FC_PSTRUCT: case RPC_FC_PSTRUCT:
case RPC_FC_BOGUS_STRUCT: case RPC_FC_BOGUS_STRUCT:
size = fields_memsize(t->fields, align); size = fields_memsize(t->fields_or_args, align);
break; break;
case RPC_FC_ENCAPSULATED_UNION: case RPC_FC_ENCAPSULATED_UNION:
case RPC_FC_NON_ENCAPSULATED_UNION: case RPC_FC_NON_ENCAPSULATED_UNION:
size = union_memsize(t->fields, align); size = union_memsize(t->fields_or_args, align);
break; break;
case RPC_FC_SMFARRAY: case RPC_FC_SMFARRAY:
case RPC_FC_LGFARRAY: case RPC_FC_LGFARRAY:
@ -945,7 +949,7 @@ size_t type_memsize(const type_t *t, unsigned int *align)
int is_full_pointer_function(const func_t *func) int is_full_pointer_function(const func_t *func)
{ {
const var_t *var; const var_t *var;
if (type_has_full_pointer(func->def->type)) if (type_has_full_pointer(get_func_return_type(func)))
return TRUE; return TRUE;
if (!func->args) if (!func->args)
return FALSE; return FALSE;
@ -981,27 +985,13 @@ static unsigned int write_nonsimple_pointer(FILE *file, const type_t *type, size
return 4; return 4;
} }
static unsigned char conf_string_type_of_char_type(unsigned char t)
{
switch (t)
{
case RPC_FC_BYTE:
case RPC_FC_CHAR:
return RPC_FC_C_CSTRING;
case RPC_FC_WCHAR:
return RPC_FC_C_WSTRING;
}
error("string_type_of_char_type: unrecognized type %d\n", t);
return 0;
}
static unsigned int write_simple_pointer(FILE *file, const type_t *type) static unsigned int write_simple_pointer(FILE *file, const type_t *type)
{ {
unsigned char fc unsigned char fc = type->ref->type;
= is_string_type(type->attrs, type) /* for historical reasons, write_simple_pointer also handled string types,
? conf_string_type_of_char_type(type->ref->type) * but no longer does. catch bad uses of the function with this check */
: type->ref->type; if (is_string_type(type->attrs, type))
error("write_simple_pointer: can't handle type %s which is a string type\n", type->name);
print_file(file, 2, "0x%02x, 0x8,\t/* %s [simple_pointer] */\n", print_file(file, 2, "0x%02x, 0x8,\t/* %s [simple_pointer] */\n",
type->type, string_of_type(type->type)); type->type, string_of_type(type->type));
print_file(file, 2, "0x%02x,\t/* %s */\n", fc, string_of_type(fc)); print_file(file, 2, "0x%02x,\t/* %s */\n", fc, string_of_type(fc));
@ -1157,7 +1147,7 @@ static void write_end(FILE *file, unsigned int *tfsoff)
static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff) static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff)
{ {
unsigned int offset = 0; unsigned int offset = 0;
var_list_t *fs = type->fields; var_list_t *fs = type->fields_or_args;
var_t *f; var_t *f;
if (fs) LIST_FOR_EACH_ENTRY(f, fs, var_t, entry) if (fs) LIST_FOR_EACH_ENTRY(f, fs, var_t, entry)
@ -1202,7 +1192,12 @@ static int write_no_repeat_pointer_descriptions(
*typestring_offset += 6; *typestring_offset += 6;
if (is_ptr(type)) if (is_ptr(type))
{
if (is_string_type(type->attrs, type))
write_string_tfs(file, NULL, type, NULL, typestring_offset);
else
write_pointer_tfs(file, type, typestring_offset); write_pointer_tfs(file, type, typestring_offset);
}
else else
{ {
unsigned absoff = type->typestring_offset; unsigned absoff = type->typestring_offset;
@ -1226,7 +1221,7 @@ static int write_no_repeat_pointer_descriptions(
if (is_non_complex_struct(type)) if (is_non_complex_struct(type))
{ {
const var_t *v; const var_t *v;
LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) LIST_FOR_EACH_ENTRY( v, type->fields_or_args, const var_t, entry )
written += write_no_repeat_pointer_descriptions( written += write_no_repeat_pointer_descriptions(
file, v->type, file, v->type,
offset_in_memory, offset_in_buffer, typestring_offset); offset_in_memory, offset_in_buffer, typestring_offset);
@ -1268,7 +1263,9 @@ static int write_pointer_description_offsets(
} }
*typestring_offset += 4; *typestring_offset += 4;
if (processed(type->ref) || is_base_type(type->ref->type)) if (is_string_type(attrs, type))
write_string_tfs(file, NULL, type, NULL, typestring_offset);
else if (processed(type->ref) || is_base_type(type->ref->type))
write_pointer_tfs(file, type, typestring_offset); write_pointer_tfs(file, type, typestring_offset);
else else
error("write_pointer_description_offsets: type format string unknown\n"); error("write_pointer_description_offsets: type format string unknown\n");
@ -1286,7 +1283,7 @@ static int write_pointer_description_offsets(
{ {
/* otherwise search for interesting fields to parse */ /* otherwise search for interesting fields to parse */
const var_t *v; const var_t *v;
LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) LIST_FOR_EACH_ENTRY( v, type->fields_or_args, const var_t, entry )
{ {
written += write_pointer_description_offsets( written += write_pointer_description_offsets(
file, v->attrs, v->type, offset_in_memory, offset_in_buffer, file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
@ -1349,7 +1346,7 @@ static int write_fixed_array_pointer_descriptions(
else if (is_struct(type->type)) else if (is_struct(type->type))
{ {
const var_t *v; const var_t *v;
LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) LIST_FOR_EACH_ENTRY( v, type->fields_or_args, const var_t, entry )
{ {
pointer_count += write_fixed_array_pointer_descriptions( pointer_count += write_fixed_array_pointer_descriptions(
file, v->attrs, v->type, offset_in_memory, offset_in_buffer, file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
@ -1460,7 +1457,7 @@ static int write_varying_array_pointer_descriptions(
else if (is_struct(type->type)) else if (is_struct(type->type))
{ {
const var_t *v; const var_t *v;
LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry ) LIST_FOR_EACH_ENTRY( v, type->fields_or_args, const var_t, entry )
{ {
pointer_count += write_varying_array_pointer_descriptions( pointer_count += write_varying_array_pointer_descriptions(
file, v->attrs, v->type, offset_in_memory, offset_in_buffer, file, v->attrs, v->type, offset_in_memory, offset_in_buffer,
@ -1535,18 +1532,18 @@ int is_declptr(const type_t *t)
static size_t write_string_tfs(FILE *file, const attr_list_t *attrs, static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
type_t *type, type_t *type,
const char *name, unsigned int *typestring_offset, const char *name, unsigned int *typestring_offset)
int toplevel)
{ {
size_t start_offset; size_t start_offset;
unsigned char rtype; unsigned char rtype;
if (toplevel && is_declptr(type)) if (is_declptr(type))
{ {
unsigned char flag = is_conformant_array(type) ? 0 : RPC_FC_P_SIMPLEPOINTER; unsigned char flag = is_conformant_array(type) ? 0 : RPC_FC_P_SIMPLEPOINTER;
int pointer_type = is_ptr(type) ? type->type : get_attrv(attrs, ATTR_POINTERTYPE); int pointer_type = is_ptr(type) ? type->type : get_attrv(attrs, ATTR_POINTERTYPE);
if (!pointer_type) if (!pointer_type)
pointer_type = RPC_FC_RP; pointer_type = RPC_FC_RP;
print_start_tfs_comment(file, type, *typestring_offset);
print_file(file, 2,"0x%x, 0x%x,\t/* %s%s */\n", print_file(file, 2,"0x%x, 0x%x,\t/* %s%s */\n",
pointer_type, flag, string_of_type(pointer_type), pointer_type, flag, string_of_type(pointer_type),
flag ? " [simple_pointer]" : ""); flag ? " [simple_pointer]" : "");
@ -1733,7 +1730,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type
static const var_t *find_array_or_string_in_struct(const type_t *type) static const var_t *find_array_or_string_in_struct(const type_t *type)
{ {
const var_t *last_field = LIST_ENTRY( list_tail(type->fields), const var_t, entry ); const var_t *last_field = LIST_ENTRY( list_tail(type->fields_or_args), const var_t, entry );
const type_t *ft = last_field->type; const type_t *ft = last_field->type;
if (ft->declarray && is_conformant_array(ft)) if (ft->declarray && is_conformant_array(ft))
@ -1753,7 +1750,7 @@ static void write_struct_members(FILE *file, const type_t *type,
int salign = -1; int salign = -1;
int padding; int padding;
if (type->fields) LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) if (type->fields_or_args) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
{ {
type_t *ft = field->type; type_t *ft = field->type;
if (!ft->declarray || !is_conformant_array(ft)) if (!ft->declarray || !is_conformant_array(ft))
@ -1819,7 +1816,7 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
error("structure size for %s exceeds %d bytes by %d bytes\n", error("structure size for %s exceeds %d bytes by %d bytes\n",
name, USHRT_MAX, total_size - USHRT_MAX); name, USHRT_MAX, total_size - USHRT_MAX);
if (type->fields) LIST_FOR_EACH_ENTRY(f, type->fields, var_t, entry) if (type->fields_or_args) LIST_FOR_EACH_ENTRY(f, type->fields_or_args, var_t, entry)
has_pointers |= write_embedded_types(file, f->attrs, f->type, f->name, has_pointers |= write_embedded_types(file, f->attrs, f->type, f->name,
FALSE, tfsoff); FALSE, tfsoff);
if (!has_pointers) has_pointers = type_has_pointers(type); if (!has_pointers) has_pointers = type_has_pointers(type);
@ -1828,7 +1825,7 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
if (array && !processed(array->type)) if (array && !processed(array->type))
array_offset array_offset
= is_attr(array->attrs, ATTR_STRING) = is_attr(array->attrs, ATTR_STRING)
? write_string_tfs(file, array->attrs, array->type, array->name, tfsoff, FALSE) ? write_string_tfs(file, array->attrs, array->type, array->name, tfsoff)
: write_array_tfs(file, array->attrs, array->type, array->name, tfsoff); : write_array_tfs(file, array->attrs, array->type, array->name, tfsoff);
corroff = *tfsoff; corroff = *tfsoff;
@ -1883,7 +1880,7 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
if (type->type == RPC_FC_BOGUS_STRUCT) if (type->type == RPC_FC_BOGUS_STRUCT)
{ {
const var_list_t *fs = type->fields; const var_list_t *fs = type->fields_or_args;
const var_t *f; const var_t *f;
type->ptrdesc = *tfsoff; type->ptrdesc = *tfsoff;
@ -1891,7 +1888,12 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
{ {
type_t *ft = f->type; type_t *ft = f->type;
if (is_ptr(ft)) if (is_ptr(ft))
{
if (is_string_type(f->attrs, ft))
write_string_tfs(file, f->attrs, ft, f->name, tfsoff);
else
write_pointer_tfs(file, ft, tfsoff); write_pointer_tfs(file, ft, tfsoff);
}
else if (!ft->declarray && is_conformant_array(ft)) else if (!ft->declarray && is_conformant_array(ft))
{ {
unsigned int absoff = ft->typestring_offset; unsigned int absoff = ft->typestring_offset;
@ -1988,11 +1990,11 @@ static size_t write_union_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
if (type->type == RPC_FC_ENCAPSULATED_UNION) if (type->type == RPC_FC_ENCAPSULATED_UNION)
{ {
const var_t *uv = LIST_ENTRY(list_tail(type->fields), const var_t, entry); const var_t *uv = LIST_ENTRY(list_tail(type->fields_or_args), const var_t, entry);
fields = uv->type->fields; fields = uv->type->fields_or_args;
} }
else else
fields = type->fields; fields = type->fields_or_args;
if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry) if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
{ {
@ -2008,7 +2010,7 @@ static size_t write_union_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
print_start_tfs_comment(file, type, start_offset); print_start_tfs_comment(file, type, start_offset);
if (type->type == RPC_FC_ENCAPSULATED_UNION) if (type->type == RPC_FC_ENCAPSULATED_UNION)
{ {
const var_t *sv = LIST_ENTRY(list_head(type->fields), const var_t, entry); const var_t *sv = LIST_ENTRY(list_head(type->fields_or_args), const var_t, entry);
const type_t *st = sv->type; const type_t *st = sv->type;
switch (st->type) switch (st->type)
@ -2181,8 +2183,8 @@ static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *f
return type->typestring_offset; return type->typestring_offset;
} }
if ((last_ptr(type) || last_array(type)) && is_ptrchain_attr(var, ATTR_STRING)) if (is_string_type(var->attrs, type))
return write_string_tfs(file, var->attrs, type, var->name, typeformat_offset, TRUE); return write_string_tfs(file, var->attrs, type, var->name, typeformat_offset);
if (is_array(type)) if (is_array(type))
{ {
@ -2286,6 +2288,10 @@ static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *ty
{ {
write_user_tfs(file, type, tfsoff); write_user_tfs(file, type, tfsoff);
} }
else if (is_string_type(attrs, type))
{
write_string_tfs(file, attrs, type, name, tfsoff);
}
else if (is_ptr(type)) else if (is_ptr(type))
{ {
type_t *ref = type->ref; type_t *ref = type->ref;
@ -2307,10 +2313,6 @@ static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *ty
retmask |= 1; retmask |= 1;
} }
} }
else if (last_array(type) && is_attr(attrs, ATTR_STRING))
{
write_string_tfs(file, attrs, type, name, tfsoff, FALSE);
}
else if (type->declarray && is_conformant_array(type)) else if (type->declarray && is_conformant_array(type))
; /* conformant arrays and strings are handled specially */ ; /* conformant arrays and strings are handled specially */
else if (is_array(type)) else if (is_array(type))
@ -2355,12 +2357,16 @@ static size_t process_tfs(FILE *file, const ifref_list_t *ifaces, type_pred_t pr
{ {
if (is_local(func->def->attrs)) continue; if (is_local(func->def->attrs)) continue;
if (!is_void(func->def->type)) if (!is_void(get_func_return_type(func)))
update_tfsoff(func->def->type, {
var_t v = *func->def;
v.type = get_func_return_type(func);
update_tfsoff(get_func_return_type(func),
write_typeformatstring_var( write_typeformatstring_var(
file, 2, NULL, func->def->type, file, 2, NULL, get_func_return_type(func),
func->def, &typeformat_offset), &v, &typeformat_offset),
file); file);
}
current_func = func; current_func = func;
if (func->args) if (func->args)
@ -2452,8 +2458,8 @@ static unsigned int get_required_buffer_size_type(
{ {
size_t size = 0; size_t size = 0;
const var_t *field; const var_t *field;
if (!type->fields) return 0; if (!type->fields_or_args) return 0;
LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
{ {
unsigned int alignment; unsigned int alignment;
size += get_required_buffer_size_type(field->type, field->name, size += get_required_buffer_size_type(field->type, field->name,
@ -2507,8 +2513,8 @@ static unsigned int get_required_buffer_size(const var_t *var, unsigned int *ali
const var_t *field; const var_t *field;
unsigned int size = 36; unsigned int size = 36;
if (!type->fields) return size; if (!type->fields_or_args) return size;
LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
{ {
unsigned int align; unsigned int align;
size += get_required_buffer_size_type( size += get_required_buffer_size_type(
@ -2537,8 +2543,8 @@ static unsigned int get_required_buffer_size(const var_t *var, unsigned int *ali
unsigned int size = 36; unsigned int size = 36;
const var_t *field; const var_t *field;
if (!type->fields) return size; if (!type->fields_or_args) return size;
LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry ) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
{ {
unsigned int align; unsigned int align;
size += get_required_buffer_size_type( size += get_required_buffer_size_type(
@ -2567,9 +2573,11 @@ static unsigned int get_function_buffer_size( const func_t *func, enum pass pass
} }
} }
if (pass == PASS_OUT && !is_void(func->def->type)) if (pass == PASS_OUT && !is_void(get_func_return_type(func)))
{ {
total_size += get_required_buffer_size(func->def, &alignment, PASS_RETURN); var_t v = *func->def;
v.type = get_func_return_type(func);
total_size += get_required_buffer_size(&v, &alignment, PASS_RETURN);
total_size += alignment; total_size += alignment;
} }
return total_size; return total_size;
@ -2778,9 +2786,13 @@ static void write_remoting_arg(FILE *file, int indent, const func_t *func,
{ {
if (pass == PASS_IN) if (pass == PASS_IN)
{ {
/* if the context_handle attribute appears in the chain of types
* without pointers being followed, then the context handle must
* be direct, otherwise it is a pointer */
int is_ch_ptr = is_aliaschain_attr(type, ATTR_CONTEXTHANDLE) ? FALSE : TRUE;
print_file(file, indent, "NdrClientContextMarshall(\n"); print_file(file, indent, "NdrClientContextMarshall(\n");
print_file(file, indent + 1, "&_StubMsg,\n"); print_file(file, indent + 1, "&_StubMsg,\n");
print_file(file, indent + 1, "(NDR_CCONTEXT)%s%s,\n", is_ptr(type) ? "*" : "", var->name); print_file(file, indent + 1, "(NDR_CCONTEXT)%s%s,\n", is_ch_ptr ? "*" : "", var->name);
print_file(file, indent + 1, "%s);\n", in_attr && out_attr ? "1" : "0"); print_file(file, indent + 1, "%s);\n", in_attr && out_attr ? "1" : "0");
} }
else else
@ -3008,6 +3020,7 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
{ {
var_t var; var_t var;
var = *func->def; var = *func->def;
var.type = get_func_return_type(func);
var.name = xstrdup( "_RetVal" ); var.name = xstrdup( "_RetVal" );
write_remoting_arg( file, indent, func, pass, phase, &var ); write_remoting_arg( file, indent, func, pass, phase, &var );
free( var.name ); free( var.name );
@ -3023,9 +3036,9 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
} }
size_t get_size_procformatstring_var(const var_t *var) size_t get_size_procformatstring_type(const char *name, const type_t *type, const attr_list_t *attrs)
{ {
return write_procformatstring_var(NULL, 0, var, FALSE); return write_procformatstring_type(NULL, 0, name, type, attrs, FALSE);
} }
@ -3037,13 +3050,13 @@ size_t get_size_procformatstring_func(const func_t *func)
/* argument list size */ /* argument list size */
if (func->args) if (func->args)
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry ) LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
size += get_size_procformatstring_var(var); size += get_size_procformatstring_type(var->name, var->type, var->attrs);
/* return value size */ /* return value size */
if (is_void(func->def->type)) if (is_void(get_func_return_type(func)))
size += 2; /* FC_END and FC_PAD */ size += 2; /* FC_END and FC_PAD */
else else
size += get_size_procformatstring_var(func->def); size += get_size_procformatstring_type("return value", get_func_return_type(func), NULL);
return size; return size;
} }
@ -3175,14 +3188,13 @@ void declare_stub_args( FILE *file, int indent, const func_t *func )
{ {
int in_attr, out_attr; int in_attr, out_attr;
int i = 0; int i = 0;
const var_t *def = func->def;
const var_t *var; const var_t *var;
/* declare return value '_RetVal' */ /* declare return value '_RetVal' */
if (!is_void(def->type)) if (!is_void(get_func_return_type(func)))
{ {
print_file(file, indent, ""); print_file(file, indent, "");
write_type_decl_left(file, def->type); write_type_decl_left(file, get_func_return_type(func));
fprintf(file, " _RetVal;\n"); fprintf(file, " _RetVal;\n");
} }
@ -3299,7 +3311,7 @@ int write_expr_eval_routines(FILE *file, const char *iface)
LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry) LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry)
{ {
const char *name = eval->structure->name; const char *name = eval->structure->name;
const var_list_t *fields = eval->structure->fields; const var_list_t *fields = eval->structure->fields_or_args;
result = 1; result = 1;
print_file(file, 0, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n", print_file(file, 0, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n",

View file

@ -43,7 +43,7 @@ void write_procformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t
void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred); void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred);
void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, enum pass pass, const var_t *var, const char *varname); void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, enum pass pass, const var_t *var, const char *varname);
void write_remoting_arguments(FILE *file, int indent, const func_t *func, enum pass pass, enum remoting_phase phase); void write_remoting_arguments(FILE *file, int indent, const func_t *func, enum pass pass, enum remoting_phase phase);
size_t get_size_procformatstring_var(const var_t *var); size_t get_size_procformatstring_type(const char *name, const type_t *type, const attr_list_t *attrs);
size_t get_size_procformatstring_func(const func_t *func); size_t get_size_procformatstring_func(const func_t *func);
size_t get_size_procformatstring(const ifref_list_t *ifaces, type_pred_t pred); size_t get_size_procformatstring(const ifref_list_t *ifaces, type_pred_t pred);
size_t get_size_typeformatstring(const ifref_list_t *ifaces, type_pred_t pred); size_t get_size_typeformatstring(const ifref_list_t *ifaces, type_pred_t pred);

View file

@ -601,6 +601,7 @@ int main(int argc,char *argv[])
fprintf(header, "/* Begin additional prototypes for all interfaces */\n"); fprintf(header, "/* Begin additional prototypes for all interfaces */\n");
fprintf(header, "\n"); fprintf(header, "\n");
write_user_types(); write_user_types();
write_generic_handle_routines();
write_context_handle_rundowns(); write_context_handle_rundowns();
fprintf(header, "\n"); fprintf(header, "\n");
fprintf(header, "/* End additional prototypes */\n"); fprintf(header, "/* End additional prototypes */\n");

View file

@ -1,7 +1,16 @@
Index: hash.c --- client.c 2008-09-27 21:56:02.000000000 +0200
=================================================================== +++ client.c 2008-09-27 20:49:05.000000000 +0200
--- hash.c (revision 32187) @@ -113,7 +113,7 @@
+++ hash.c (working copy) }
if (explicit_handle)
{
- if (!explicit_handle_var || !explicit_generic_handle_var || !context_handle_var)
+ if (!explicit_handle_var && !explicit_generic_handle_var && !context_handle_var)
{
error("%s() does not define an explicit binding handle!\n", def->name);
return;
--- hash.c 2008-09-27 21:56:02.000000000 +0200
+++ hash.c 2008-09-22 00:14:35.703125000 +0200
@@ -21,9 +21,7 @@ @@ -21,9 +21,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
@ -34,11 +43,170 @@ Index: hash.c
nOffset = 16; nOffset = 16;
pnLookup = Lookup_16; pnLookup = Lookup_16;
break; break;
Index: server.c --- header.c 2008-09-27 21:56:02.000000000 +0200
=================================================================== +++ header.c 2008-09-27 20:49:05.000000000 +0200
--- server.c (revision 32187) @@ -891,6 +891,8 @@
+++ server.c (working copy) const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
@@ -390,6 +390,7 @@ int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE);
const var_t* explicit_handle_var;
+ const var_t* explicit_generic_handle_var = NULL;
+ const var_t* context_handle_var = NULL;
const func_t *cur;
int prefixes_differ = strcmp(prefix_client, prefix_server);
@@ -901,8 +903,14 @@
/* check for a defined binding handle */
explicit_handle_var = get_explicit_handle_var(cur);
+ if (!explicit_handle_var)
+ {
+ explicit_generic_handle_var = get_explicit_generic_handle_var(cur);
+ if (!explicit_generic_handle_var)
+ context_handle_var = get_context_handle_var(cur);
+ }
if (explicit_handle) {
- if (!explicit_handle_var) {
+ if (!explicit_handle_var && !explicit_generic_handle_var && !context_handle_var) {
error("%s() does not define an explicit binding handle!\n", def->name);
return;
}
--- header.h 2008-09-27 21:56:02.000000000 +0200
+++ header.h 2008-09-23 21:14:50.781250000 +0200
@@ -66,6 +66,7 @@
extern const var_t* get_explicit_handle_var(const func_t* func);
extern const type_t* get_explicit_generic_handle_type(const var_t* var);
extern const var_t* get_explicit_generic_handle_var(const func_t* func);
+extern const var_t* get_context_handle_var(const func_t* func);
extern int has_out_arg_or_return(const func_t *func);
extern void write_guid(FILE *f, const char *guid_prefix, const char *name,
const UUID *uuid);
@@ -88,11 +89,19 @@
static inline int is_context_handle(const type_t *type)
{
- const type_t *t;
- for (t = type; is_ptr(t); t = t->ref)
- if (is_attr(t->attrs, ATTR_CONTEXTHANDLE))
+ if (is_attr(type->attrs, ATTR_CONTEXTHANDLE))
+ return 1;
+
+ for (;;)
+ {
+ if (is_attr(type->attrs, ATTR_CONTEXTHANDLE))
return 1;
- return 0;
+ else if (type->kind == TKIND_ALIAS)
+ type = type->orig;
+ else if (is_ptr(type))
+ type = type->ref;
+ else return 0;
+ }
}
#endif
--- proxy.c 2008-09-27 21:56:02.000000000 +0200
+++ proxy.c 2008-09-27 20:49:05.000000000 +0200
@@ -463,41 +463,45 @@
print_proxy("\n");
}
-static int write_proxy_methods(type_t *iface)
+static int write_proxy_methods(type_t *iface, int skip)
{
const func_t *cur;
int i = 0;
- if (iface->ref) i = write_proxy_methods(iface->ref);
+ if (iface->ref) i = write_proxy_methods(iface->ref, iface->ref->ref != NULL);
if (iface->funcs) LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) {
var_t *def = cur->def;
if (!is_callas(def->attrs)) {
if (i) fprintf(proxy, ",\n");
- print_proxy( "%s_", iface->name);
+ print_proxy( "%s%s_", skip ? "0\t/* " : "", iface->name);
write_name(proxy, def);
- fprintf(proxy, "_Proxy");
+ fprintf(proxy, "_Proxy%s", skip ? " */" : "");
i++;
}
}
return i;
}
-static int write_stub_methods(type_t *iface)
+static int write_stub_methods(type_t *iface, int skip)
{
const func_t *cur;
int i = 0;
- if (iface->ref) i = write_stub_methods(iface->ref);
+ if (iface->ref) i = write_stub_methods(iface->ref, TRUE);
else return i; /* skip IUnknown */
if (iface->funcs) LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry ) {
var_t *def = cur->def;
if (!is_local(def->attrs)) {
- if (i) fprintf(proxy,",\n");
- print_proxy( "%s_", iface->name);
- write_name(proxy, def);
- fprintf(proxy, "_Stub");
- i++;
+ if (skip)
+ print_proxy("STUB_FORWARDING_FUNCTION,\n");
+ else {
+ if (i) fprintf(proxy,",\n");
+ print_proxy( "%s_", iface->name);
+ write_name(proxy, def);
+ fprintf(proxy, "_Stub");
+ i++;
+ }
}
}
return i;
@@ -551,7 +555,7 @@
print_proxy( "},\n");
print_proxy( "{\n");
indent++;
- write_proxy_methods(iface);
+ write_proxy_methods(iface, FALSE);
fprintf(proxy, "\n");
indent--;
print_proxy( "}\n");
@@ -563,7 +567,7 @@
print_proxy( "static const PRPC_STUB_FUNCTION %s_table[] =\n", iface->name);
print_proxy( "{\n");
indent++;
- stubs = write_stub_methods(iface);
+ stubs = write_stub_methods(iface, FALSE);
fprintf(proxy, "\n");
indent--;
fprintf(proxy, "};\n");
--- server.c 2008-09-27 21:56:02.000000000 +0200
+++ server.c 2008-09-27 20:49:05.000000000 +0200
@@ -60,13 +60,21 @@
LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry )
{
const var_t *def = func->def;
+ const var_t* context_handle_var = NULL;
+ const var_t* explicit_generic_handle_var = NULL;
int has_full_pointer = is_full_pointer_function(func);
/* check for a defined binding handle */
explicit_handle_var = get_explicit_handle_var(func);
+ if (!explicit_handle_var)
+ {
+ explicit_generic_handle_var = get_explicit_generic_handle_var(func);
+ if (!explicit_generic_handle_var)
+ context_handle_var = get_context_handle_var(func);
+ }
if (explicit_handle)
{
- if (!explicit_handle_var)
+ if (!explicit_handle_var && !explicit_generic_handle_var && !context_handle_var)
{
error("%s() does not define an explicit binding handle!\n", def->name);
return;
@@ -399,6 +407,7 @@
print_server("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name); print_server("/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n", PACKAGE_VERSION, input_name);
print_server("#include <string.h>\n"); print_server("#include <string.h>\n");
fprintf(server, "\n"); fprintf(server, "\n");
@ -46,10 +214,8 @@ Index: server.c
print_server("#include \"%s\"\n", header_name); print_server("#include \"%s\"\n", header_name);
fprintf(server, "\n"); fprintf(server, "\n");
} }
Index: typelib.c --- typelib.c 2008-09-27 21:56:02.000000000 +0200
=================================================================== +++ typelib.c 2008-09-27 20:49:05.000000000 +0200
--- typelib.c (revision 32187)
+++ typelib.c (working copy)
@@ -35,8 +35,7 @@ @@ -35,8 +35,7 @@
#define NONAMELESSUNION #define NONAMELESSUNION
#define NONAMELESSSTRUCT #define NONAMELESSSTRUCT
@ -60,10 +226,41 @@ Index: typelib.c
#include "widl.h" #include "widl.h"
#include "utils.h" #include "utils.h"
Index: widl.c @@ -360,10 +359,10 @@
===================================================================
--- widl.c (revision 32187) file_name = wpp_find_include(importlib->name, NULL);
+++ widl.c (working copy) if(file_name) {
- fd = open(file_name, O_RDONLY);
+ fd = open(file_name, O_RDONLY | O_BINARY);
free(file_name);
}else {
- fd = open(importlib->name, O_RDONLY);
+ fd = open(importlib->name, O_RDONLY | O_BINARY);
}
if(fd < 0)
--- typelib_struct.h 2008-09-27 21:56:02.000000000 +0200
+++ typelib_struct.h 2008-09-22 00:14:35.703125000 +0200
@@ -302,7 +302,7 @@
*
*/
-#include "pshpack1.h"
+#include <host/pshpack1.h>
typedef struct {
/*00*/ DWORD SLTG_magic; /* 0x47544c53 == "SLTG" */
@@ -599,7 +599,7 @@
WORD typeofarray
*/
-#include "poppack.h"
+#include <host/poppack.h>
/*---------------------------END--------------------------------------------*/
#endif
--- widl.c 2008-09-27 21:56:02.000000000 +0200
+++ widl.c 2008-09-27 20:49:05.000000000 +0200
@@ -174,7 +174,7 @@ @@ -174,7 +174,7 @@
token = xstrdup(name); token = xstrdup(name);
for (i=0; token[i]; i++) { for (i=0; token[i]; i++) {
@ -84,7 +281,7 @@ Index: widl.c
start_cplusplus_guard(header); start_cplusplus_guard(header);
} }
@@ -606,7 +606,7 @@ @@ -607,7 +607,7 @@
fprintf(header, "/* End additional prototypes */\n"); fprintf(header, "/* End additional prototypes */\n");
fprintf(header, "\n"); fprintf(header, "\n");
end_cplusplus_guard(header); end_cplusplus_guard(header);
@ -92,10 +289,9 @@ Index: widl.c
+ fprintf(header, "#endif /* __%s__ */\n", header_token); + fprintf(header, "#endif /* __%s__ */\n", header_token);
fclose(header); fclose(header);
} }
Index: widltypes.h
=================================================================== --- widltypes.h 2008-09-27 21:56:02.000000000 +0200
--- widltypes.h (revision 32187) +++ widltypes.h 2008-09-26 19:42:52.859375000 +0200
+++ widltypes.h (working copy)
@@ -21,6 +21,13 @@ @@ -21,6 +21,13 @@
#ifndef __WIDL_WIDLTYPES_H #ifndef __WIDL_WIDLTYPES_H
#define __WIDL_WIDLTYPES_H #define __WIDL_WIDLTYPES_H
@ -110,7 +306,7 @@ Index: widltypes.h
#include <stdarg.h> #include <stdarg.h>
#include "guiddef.h" #include "guiddef.h"
#include "wine/rpcfc.h" #include "wine/rpcfc.h"
@@ -38,7 +38,9 @@ @@ -31,7 +38,9 @@
typedef GUID UUID; typedef GUID UUID;
#endif #endif
@ -119,11 +315,9 @@ Index: widltypes.h
+#endif +#endif
#define FALSE 0 #define FALSE 0
typedef struct _attr_t attr_t; #define RPC_FC_FUNCTION 0xfe
Index: write_msft.c --- write_msft.c 2008-09-27 21:56:02.000000000 +0200
=================================================================== +++ write_msft.c 2008-09-27 20:49:05.000000000 +0200
--- write_msft.c (revision 32187)
+++ write_msft.c (working copy)
@@ -40,10 +40,8 @@ @@ -40,10 +40,8 @@
#define NONAMELESSUNION #define NONAMELESSUNION
#define NONAMELESSSTRUCT #define NONAMELESSSTRUCT

View file

@ -43,6 +43,8 @@ typedef GUID UUID;
#endif #endif
#define FALSE 0 #define FALSE 0
#define RPC_FC_FUNCTION 0xfe
typedef struct _attr_t attr_t; typedef struct _attr_t attr_t;
typedef struct _expr_t expr_t; typedef struct _expr_t expr_t;
typedef struct _type_t type_t; typedef struct _type_t type_t;
@ -77,6 +79,7 @@ enum attr_type
ATTR_AUTO_HANDLE, ATTR_AUTO_HANDLE,
ATTR_BINDABLE, ATTR_BINDABLE,
ATTR_CALLAS, ATTR_CALLAS,
ATTR_CALLCONV, /* calling convention pseudo-attribute */
ATTR_CASE, ATTR_CASE,
ATTR_CONTEXTHANDLE, ATTR_CONTEXTHANDLE,
ATTR_CONTROL, ATTR_CONTROL,
@ -221,7 +224,7 @@ struct _type_t {
struct _type_t *ref; struct _type_t *ref;
const attr_list_t *attrs; const attr_list_t *attrs;
func_list_t *funcs; /* interfaces and modules */ func_list_t *funcs; /* interfaces and modules */
var_list_t *fields; /* interfaces, structures and enumerations */ var_list_t *fields_or_args; /* interfaces, structures, enumerations and functions (for args) */
ifref_list_t *ifaces; /* coclasses */ ifref_list_t *ifaces; /* coclasses */
unsigned long dim; /* array dimension */ unsigned long dim; /* array dimension */
expr_t *size_is, *length_is; expr_t *size_is, *length_is;
@ -242,7 +245,6 @@ struct _type_t {
struct _var_t { struct _var_t {
char *name; char *name;
type_t *type; type_t *type;
var_list_t *args; /* for function pointers */
attr_list_t *attrs; attr_list_t *attrs;
expr_t *eval; expr_t *eval;
@ -254,6 +256,12 @@ struct _pident_t {
var_t *var; var_t *var;
int ptr_level; int ptr_level;
int is_func;
/* levels of indirection for function pointers */
int func_ptr_level;
var_list_t *args;
char *callconv;
/* parser-internal */ /* parser-internal */
struct list entry; struct list entry;
}; };
@ -321,7 +329,7 @@ struct _user_type_t {
extern unsigned char pointer_default; extern unsigned char pointer_default;
extern user_type_list_t user_type_list; extern user_type_list_t user_type_list;
void check_for_user_types_and_context_handles(const var_list_t *list); void check_for_additional_prototype_types(const var_list_t *list);
void init_types(void); void init_types(void);
type_t *alloc_type(void); type_t *alloc_type(void);
@ -337,4 +345,9 @@ int cant_be_null(const var_t *v);
int is_struct(unsigned char tc); int is_struct(unsigned char tc);
int is_union(unsigned char tc); int is_union(unsigned char tc);
static inline type_t *get_func_return_type(const func_t *func)
{
return func->def->type->ref;
}
#endif #endif

View file

@ -1419,7 +1419,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int
/* fill out the basic type information */ /* fill out the basic type information */
typedata[0] = typedata_size | (index << 16); typedata[0] = typedata_size | (index << 16);
encode_var(typeinfo->typelib, func->def->type, func->def, &typedata[1], NULL, NULL, &decoded_size); encode_var(typeinfo->typelib, get_func_return_type(func), func->def, &typedata[1], NULL, NULL, &decoded_size);
typedata[2] = funcflags; typedata[2] = funcflags;
typedata[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft; typedata[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft;
typedata[4] = (next_idx << 16) | (callconv << 8) | (invokekind << 3) | funckind; typedata[4] = (next_idx << 16) | (callconv << 8) | (invokekind << 3) | funckind;
@ -1946,8 +1946,8 @@ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinte
if (dispinterface->funcs) if (dispinterface->funcs)
LIST_FOR_EACH_ENTRY( func, dispinterface->funcs, const func_t, entry ) idx++; LIST_FOR_EACH_ENTRY( func, dispinterface->funcs, const func_t, entry ) idx++;
if (dispinterface->fields) if (dispinterface->fields_or_args)
LIST_FOR_EACH_ENTRY( var, dispinterface->fields, var_t, entry ) LIST_FOR_EACH_ENTRY( var, dispinterface->fields_or_args, var_t, entry )
add_var_desc(msft_typeinfo, idx++, var); add_var_desc(msft_typeinfo, idx++, var);
if (dispinterface->funcs) if (dispinterface->funcs)
@ -2030,8 +2030,8 @@ static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure)
msft_typeinfo = create_msft_typeinfo(typelib, TKIND_RECORD, structure->name, structure->attrs); msft_typeinfo = create_msft_typeinfo(typelib, TKIND_RECORD, structure->name, structure->attrs);
msft_typeinfo->typeinfo->size = 0; msft_typeinfo->typeinfo->size = 0;
if (structure->fields) if (structure->fields_or_args)
LIST_FOR_EACH_ENTRY( cur, structure->fields, var_t, entry ) LIST_FOR_EACH_ENTRY( cur, structure->fields_or_args, var_t, entry )
add_var_desc(msft_typeinfo, idx++, cur); add_var_desc(msft_typeinfo, idx++, cur);
} }
@ -2045,8 +2045,8 @@ static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration)
msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ENUM, enumeration->name, enumeration->attrs); msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ENUM, enumeration->name, enumeration->attrs);
msft_typeinfo->typeinfo->size = 0; msft_typeinfo->typeinfo->size = 0;
if (enumeration->fields) if (enumeration->fields_or_args)
LIST_FOR_EACH_ENTRY( cur, enumeration->fields, var_t, entry ) LIST_FOR_EACH_ENTRY( cur, enumeration->fields_or_args, var_t, entry )
add_var_desc(msft_typeinfo, idx++, cur); add_var_desc(msft_typeinfo, idx++, cur);
} }