[WIDL] Sync with Wine Staging 4.0. CORE-15682

This commit is contained in:
Amine Khaldi 2019-01-29 13:18:09 +01:00
parent 64040f7c9f
commit 22c8b4bf12
27 changed files with 4502 additions and 3735 deletions

View file

@ -83,7 +83,7 @@ if(NOT CMAKE_CROSSCOMPILING)
if(MSVC) if(MSVC)
if(ARCH STREQUAL "i386") if(ARCH STREQUAL "i386")
add_definitions(/D_X86_ /DWIN32 /D_WINDOWS) add_definitions(/D_X86_ /D__i386__ /DWIN32 /D_WINDOWS)
endif() endif()
if(MSVC_VERSION GREATER 1699) if(MSVC_VERSION GREATER 1699)
add_definitions(/D_ALLOW_KEYWORD_MACROS) add_definitions(/D_ALLOW_KEYWORD_MACROS)

View file

@ -16,7 +16,7 @@ wine-patches@winehq.com and ros-dev@reactos.org
The following build tools are shared with Wine. The following build tools are shared with Wine.
reactos/sdk/tools/unicode # Synced to WineStaging-3.3 reactos/sdk/tools/unicode # Synced to WineStaging-3.3
reactos/sdk/tools/widl # Synced to WineStaging-3.3 reactos/sdk/tools/widl # Synced to WineStaging-4.0
reactos/sdk/tools/wpp # Synced to WineStaging-2.9 reactos/sdk/tools/wpp # Synced to WineStaging-2.9
The following libraries are shared with Wine. The following libraries are shared with Wine.

View file

@ -0,0 +1 @@
#include "../psdk/ndrtypes.h"

View file

@ -91,7 +91,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
print_client("MIDL_STUB_MESSAGE _StubMsg;\n"); print_client("MIDL_STUB_MESSAGE _StubMsg;\n");
if (handle_var) if (handle_var)
{ {
if (explicit_fc == RPC_FC_BIND_GENERIC) if (explicit_fc == FC_BIND_GENERIC)
print_client("%s %s;\n", print_client("%s %s;\n",
get_explicit_generic_handle_type(handle_var)->name, handle_var->name ); get_explicit_generic_handle_type(handle_var)->name, handle_var->name );
print_client("RPC_BINDING_HANDLE _Handle;\n"); print_client("RPC_BINDING_HANDLE _Handle;\n");
@ -113,7 +113,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
print_client("NdrFreeBuffer(&__frame->_StubMsg);\n"); print_client("NdrFreeBuffer(&__frame->_StubMsg);\n");
if (explicit_fc == RPC_FC_BIND_GENERIC) if (explicit_fc == FC_BIND_GENERIC)
{ {
fprintf(client, "\n"); fprintf(client, "\n");
print_client("if (__frame->_Handle)\n"); print_client("if (__frame->_Handle)\n");
@ -144,7 +144,7 @@ static void write_function_stub( const type_t *iface, const var_t *func,
if (handle_var) if (handle_var)
{ {
print_client( "__frame->_Handle = 0;\n" ); print_client( "__frame->_Handle = 0;\n" );
if (explicit_fc == RPC_FC_BIND_GENERIC) if (explicit_fc == FC_BIND_GENERIC)
print_client("__frame->%s = %s;\n", handle_var->name, handle_var->name ); print_client("__frame->%s = %s;\n", handle_var->name, handle_var->name );
} }
if (has_ret && decl_indirect(retval->type)) if (has_ret && decl_indirect(retval->type))
@ -180,16 +180,16 @@ static void write_function_stub( const type_t *iface, const var_t *func,
switch (explicit_fc) switch (explicit_fc)
{ {
case RPC_FC_BIND_PRIMITIVE: case FC_BIND_PRIMITIVE:
print_client("__frame->_Handle = %s;\n", handle_var->name); print_client("__frame->_Handle = %s;\n", handle_var->name);
fprintf(client, "\n"); fprintf(client, "\n");
break; break;
case RPC_FC_BIND_GENERIC: case FC_BIND_GENERIC:
print_client("__frame->_Handle = %s_bind(%s);\n", print_client("__frame->_Handle = %s_bind(%s);\n",
get_explicit_generic_handle_type(handle_var)->name, handle_var->name); get_explicit_generic_handle_type(handle_var)->name, handle_var->name);
fprintf(client, "\n"); fprintf(client, "\n");
break; break;
case RPC_FC_BIND_CONTEXT: case FC_BIND_CONTEXT:
{ {
/* if the context_handle attribute appears in the chain of types /* if the context_handle attribute appears in the chain of types
* without pointers being followed, then the context handle must * without pointers being followed, then the context handle must
@ -287,6 +287,68 @@ static void write_function_stub( const type_t *iface, const var_t *func,
fprintf(client, "\n"); fprintf(client, "\n");
} }
static void write_serialize_function(FILE *file, const type_t *type, const type_t *iface,
const char *func_name, const char *ret_type)
{
enum stub_mode mode = get_stub_mode();
static int emited_pickling_info;
if (iface && !type->typestring_offset)
{
/* FIXME: Those are mostly basic types. They should be implemented
* using NdrMesSimpleType* functions */
if (ret_type) warning("Serialization of type %s is not supported\n", type->name);
return;
}
if (!emited_pickling_info && iface && mode != MODE_Os)
{
fprintf(file, "static const MIDL_TYPE_PICKLING_INFO __MIDL_TypePicklingInfo =\n");
fprintf(file, "{\n");
fprintf(file, " 0x33205054,\n");
fprintf(file, " 0x3,\n");
fprintf(file, " 0,\n");
fprintf(file, " 0,\n");
fprintf(file, " 0\n");
fprintf(file, "};\n");
fprintf(file, "\n");
emited_pickling_info = 1;
}
/* FIXME: Assuming explicit handle */
fprintf(file, "%s __cdecl %s_%s(handle_t IDL_handle, %s *IDL_type)%s\n",
ret_type ? ret_type : "void", type->name, func_name, type->name, iface ? "" : ";");
if (!iface) return; /* declaration only */
fprintf(file, "{\n");
fprintf(file, " %sNdrMesType%s%s(\n", ret_type ? "return " : "", func_name,
mode != MODE_Os ? "2" : "");
fprintf(file, " IDL_handle,\n");
if (mode != MODE_Os)
fprintf(file, " (MIDL_TYPE_PICKLING_INFO*)&__MIDL_TypePicklingInfo,\n");
fprintf(file, " &%s_StubDesc,\n", iface->name);
fprintf(file, " (PFORMAT_STRING)&__MIDL_TypeFormatString.Format[%u],\n",
type->typestring_offset);
fprintf(file, " IDL_type);\n");
fprintf(file, "}\n");
fprintf(file, "\n");
}
void write_serialize_functions(FILE *file, const type_t *type, const type_t *iface)
{
if (is_attr(type->attrs, ATTR_ENCODE))
{
write_serialize_function(file, type, iface, "AlignSize", "SIZE_T");
write_serialize_function(file, type, iface, "Encode", NULL);
}
if (is_attr(type->attrs, ATTR_DECODE))
{
write_serialize_function(file, type, iface, "Decode", NULL);
write_serialize_function(file, type, iface, "Free", 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 statement_t *stmt; const statement_t *stmt;
@ -296,11 +358,30 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
if (!implicit_handle) if (!implicit_handle)
print_client("static RPC_BINDING_HANDLE %s__MIDL_AutoBindHandle;\n\n", iface->name); print_client("static RPC_BINDING_HANDLE %s__MIDL_AutoBindHandle;\n\n", iface->name);
STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) ) LIST_FOR_EACH_ENTRY( stmt, type_iface_get_stmts(iface), const statement_t, entry )
{
switch (stmt->type)
{
case STMT_DECLARATION:
{ {
const var_t *func = stmt->u.var; const var_t *func = stmt->u.var;
if (stmt->u.var->stgclass != STG_NONE
|| type_get_type_detect_alias(stmt->u.var->type) != TYPE_FUNCTION)
continue;
write_function_stub( iface, func, method_count++, *proc_offset ); write_function_stub( iface, func, method_count++, *proc_offset );
*proc_offset += get_size_procformatstring_func( iface, func ); *proc_offset += get_size_procformatstring_func( iface, func );
break;
}
case STMT_TYPEDEF:
{
const type_list_t *type_entry;
for (type_entry = stmt->u.type_list; type_entry; type_entry = type_entry->next)
write_serialize_functions(client, type_entry->type, iface);
break;
}
default:
break;
}
} }
} }
@ -438,7 +519,7 @@ static void write_client_ifaces(const statement_list_t *stmts, int expr_eval_rou
{ {
if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_INTERFACE) if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_INTERFACE)
{ {
int has_func = 0; int needs_stub = 0;
const statement_t *stmt2; const statement_t *stmt2;
type_t *iface = stmt->u.type; type_t *iface = stmt->u.type;
if (!need_stub(iface)) if (!need_stub(iface))
@ -449,13 +530,31 @@ static void write_client_ifaces(const statement_list_t *stmts, int expr_eval_rou
fprintf(client, " */\n"); fprintf(client, " */\n");
fprintf(client, "\n"); fprintf(client, "\n");
STATEMENTS_FOR_EACH_FUNC(stmt2, type_iface_get_stmts(iface)) LIST_FOR_EACH_ENTRY(stmt2, type_iface_get_stmts(iface), const statement_t, entry)
{ {
has_func = 1; if (stmt2->type == STMT_DECLARATION && stmt2->u.var->stgclass == STG_NONE &&
type_get_type_detect_alias(stmt2->u.var->type) == TYPE_FUNCTION)
{
needs_stub = 1;
break; break;
} }
if (stmt2->type == STMT_TYPEDEF)
if (has_func) {
const type_list_t *type_entry;
for (type_entry = stmt2->u.type_list; type_entry; type_entry = type_entry->next)
{
if (is_attr(type_entry->type->attrs, ATTR_ENCODE)
|| is_attr(type_entry->type->attrs, ATTR_DECODE))
{
needs_stub = 1;
break;
}
}
if (needs_stub)
break;
}
}
if (needs_stub)
{ {
write_implicithandledecl(iface); write_implicithandledecl(iface);
@ -528,26 +627,6 @@ void write_client(const statement_list_t *stmts)
if (!client) if (!client)
return; return;
if (do_win32 && do_win64)
{
fprintf(client, "#ifndef _WIN64\n\n");
pointer_size = 4;
write_client_routines( stmts ); write_client_routines( stmts );
fprintf(client, "\n#else /* _WIN64 */\n\n");
pointer_size = 8;
write_client_routines( stmts );
fprintf(client, "\n#endif /* _WIN64 */\n");
}
else if (do_win32)
{
pointer_size = 4;
write_client_routines( stmts );
}
else if (do_win64)
{
pointer_size = 8;
write_client_routines( stmts );
}
fclose(client); fclose(client);
} }

View file

@ -50,6 +50,7 @@ static int is_integer_type(const type_t *type)
case TYPE_BASIC_INT64: case TYPE_BASIC_INT64:
case TYPE_BASIC_INT: case TYPE_BASIC_INT:
case TYPE_BASIC_INT3264: case TYPE_BASIC_INT3264:
case TYPE_BASIC_LONG:
case TYPE_BASIC_CHAR: case TYPE_BASIC_CHAR:
case TYPE_BASIC_HYPER: case TYPE_BASIC_HYPER:
case TYPE_BASIC_BYTE: case TYPE_BASIC_BYTE:
@ -82,6 +83,7 @@ static int is_signed_integer_type(const type_t *type)
case TYPE_BASIC_INT64: case TYPE_BASIC_INT64:
case TYPE_BASIC_INT: case TYPE_BASIC_INT:
case TYPE_BASIC_INT3264: case TYPE_BASIC_INT3264:
case TYPE_BASIC_LONG:
return type_basic_get_sign(type) < 0; return type_basic_get_sign(type) < 0;
case TYPE_BASIC_CHAR: case TYPE_BASIC_CHAR:
return TRUE; return TRUE;
@ -519,11 +521,11 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
break; break;
case EXPR_STRLIT: case EXPR_STRLIT:
result.is_temporary = TRUE; result.is_temporary = TRUE;
result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL); result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL);
break; break;
case EXPR_WSTRLIT: case EXPR_WSTRLIT:
result.is_temporary = TRUE; result.is_temporary = TRUE;
result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL); result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL);
break; break;
case EXPR_CHARCONST: case EXPR_CHARCONST:
result.is_temporary = TRUE; result.is_temporary = TRUE;
@ -573,7 +575,7 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
expr_loc->attr ? expr_loc->attr : ""); expr_loc->attr ? expr_loc->attr : "");
result.is_variable = FALSE; result.is_variable = FALSE;
result.is_temporary = TRUE; result.is_temporary = TRUE;
result.type = type_new_pointer(RPC_FC_UP, result.type, NULL); result.type = type_new_pointer(FC_UP, result.type, NULL);
break; break;
case EXPR_PPTR: case EXPR_PPTR:
result = resolve_expression(expr_loc, cont_type, e->ref); result = resolve_expression(expr_loc, cont_type, e->ref);

View file

@ -285,6 +285,15 @@ int needs_space_after(type_t *t)
(!is_ptr(t) && (!is_array(t) || !type_array_is_decl_as_ptr(t) || t->name))); (!is_ptr(t) && (!is_array(t) || !type_array_is_decl_as_ptr(t) || t->name)));
} }
static void write_pointer_left(FILE *h, type_t *ref)
{
if (needs_space_after(ref))
fprintf(h, " ");
if (!type_is_alias(ref) && is_array(ref) && !type_array_is_decl_as_ptr(ref))
fprintf(h, "(");
fprintf(h, "*");
}
void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly) void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
{ {
const char *name; const char *name;
@ -341,10 +350,12 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
else fprintf(h, "union %s", t->name ? t->name : ""); else fprintf(h, "union %s", t->name ? t->name : "");
break; break;
case TYPE_POINTER: case TYPE_POINTER:
{
write_type_left(h, type_pointer_get_ref(t), name_type, declonly); write_type_left(h, type_pointer_get_ref(t), name_type, declonly);
fprintf(h, "%s*", needs_space_after(type_pointer_get_ref(t)) ? " " : ""); write_pointer_left(h, type_pointer_get_ref(t));
if (is_attr(t->attrs, ATTR_CONST)) fprintf(h, "const "); if (is_attr(t->attrs, ATTR_CONST)) fprintf(h, "const ");
break; break;
}
case TYPE_ARRAY: case TYPE_ARRAY:
if (t->name && type_array_is_decl_as_ptr(t)) if (t->name && type_array_is_decl_as_ptr(t))
fprintf(h, "%s", t->name); fprintf(h, "%s", t->name);
@ -352,12 +363,13 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
{ {
write_type_left(h, type_array_get_element(t), name_type, declonly); write_type_left(h, type_array_get_element(t), name_type, declonly);
if (type_array_is_decl_as_ptr(t)) if (type_array_is_decl_as_ptr(t))
fprintf(h, "%s*", needs_space_after(type_array_get_element(t)) ? " " : ""); write_pointer_left(h, type_array_get_element(t));
} }
break; break;
case TYPE_BASIC: case TYPE_BASIC:
if (type_basic_get_type(t) != TYPE_BASIC_INT32 && if (type_basic_get_type(t) != TYPE_BASIC_INT32 &&
type_basic_get_type(t) != TYPE_BASIC_INT64 && type_basic_get_type(t) != TYPE_BASIC_INT64 &&
type_basic_get_type(t) != TYPE_BASIC_LONG &&
type_basic_get_type(t) != TYPE_BASIC_HYPER) type_basic_get_type(t) != TYPE_BASIC_HYPER)
{ {
if (type_basic_get_sign(t) < 0) fprintf(h, "signed "); if (type_basic_get_sign(t) < 0) fprintf(h, "signed ");
@ -377,6 +389,12 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
case TYPE_BASIC_ERROR_STATUS_T: fprintf(h, "error_status_t"); break; case TYPE_BASIC_ERROR_STATUS_T: fprintf(h, "error_status_t"); break;
case TYPE_BASIC_HANDLE: fprintf(h, "handle_t"); break; case TYPE_BASIC_HANDLE: fprintf(h, "handle_t"); break;
case TYPE_BASIC_INT32: case TYPE_BASIC_INT32:
if (type_basic_get_sign(t) > 0)
fprintf(h, "UINT32");
else
fprintf(h, "INT32");
break;
case TYPE_BASIC_LONG:
if (type_basic_get_sign(t) > 0) if (type_basic_get_sign(t) > 0)
fprintf(h, "ULONG"); fprintf(h, "ULONG");
else else
@ -419,23 +437,36 @@ void write_type_left(FILE *h, type_t *t, enum name_type name_type, int declonly)
void write_type_right(FILE *h, type_t *t, int is_field) void write_type_right(FILE *h, type_t *t, int is_field)
{ {
if (!h) return; if (!h) return;
if (type_is_alias(t)) return;
switch (type_get_type(t)) switch (type_get_type(t))
{ {
case TYPE_ARRAY: case TYPE_ARRAY:
if (!type_array_is_decl_as_ptr(t)) {
type_t *elem = type_array_get_element(t);
if (type_array_is_decl_as_ptr(t))
{
if (!type_is_alias(elem) && is_array(elem) && !type_array_is_decl_as_ptr(elem))
fprintf(h, ")");
}
else
{ {
if (is_conformant_array(t)) if (is_conformant_array(t))
{
fprintf(h, "[%s]", is_field ? "1" : ""); fprintf(h, "[%s]", is_field ? "1" : "");
t = type_array_get_element(t); else
}
for ( ;
type_get_type(t) == TYPE_ARRAY && !type_array_is_decl_as_ptr(t);
t = type_array_get_element(t))
fprintf(h, "[%u]", type_array_get_dim(t)); fprintf(h, "[%u]", type_array_get_dim(t));
} }
write_type_right(h, elem, FALSE);
break; break;
}
case TYPE_POINTER:
{
type_t *ref = type_pointer_get_ref(t);
if (!type_is_alias(ref) && is_array(ref) && !type_array_is_decl_as_ptr(ref))
fprintf(h, ")");
write_type_right(h, ref, FALSE);
break;
}
case TYPE_BITFIELD: case TYPE_BITFIELD:
fprintf(h, " : %u", type_bitfield_get_bits(t)->cval); fprintf(h, " : %u", type_bitfield_get_bits(t)->cval);
break; break;
@ -450,7 +481,6 @@ void write_type_right(FILE *h, type_t *t, int is_field)
case TYPE_COCLASS: case TYPE_COCLASS:
case TYPE_FUNCTION: case TYPE_FUNCTION:
case TYPE_INTERFACE: case TYPE_INTERFACE:
case TYPE_POINTER:
break; break;
} }
} }
@ -686,6 +716,47 @@ void check_for_additional_prototype_types(const var_list_t *list)
} }
} }
static int write_serialize_function_decl(FILE *header, const type_t *type)
{
write_serialize_functions(header, type, NULL);
return 1;
}
static int serializable_exists(FILE *header, const type_t *type)
{
return 0;
}
static int for_each_serializable(const statement_list_t *stmts, FILE *header,
int (*proc)(FILE*, const type_t*))
{
statement_t *stmt, *iface_stmt;
statement_list_t *iface_stmts;
const type_list_t *type_entry;
if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, statement_t, entry )
{
if (stmt->type != STMT_TYPE || type_get_type(stmt->u.type) != TYPE_INTERFACE)
continue;
iface_stmts = type_iface_get_stmts(stmt->u.type);
if (iface_stmts) LIST_FOR_EACH_ENTRY( iface_stmt, iface_stmts, statement_t, entry )
{
if (iface_stmt->type != STMT_TYPEDEF) continue;
for (type_entry = iface_stmt->u.type_list; type_entry; type_entry = type_entry->next)
{
if (!is_attr(type_entry->type->attrs, ATTR_ENCODE)
&& !is_attr(type_entry->type->attrs, ATTR_DECODE))
continue;
if (!proc(header, type_entry->type))
return 0;
}
}
}
return 1;
}
static void write_user_types(FILE *header) static void write_user_types(FILE *header)
{ {
user_type_t *ut; user_type_t *ut;
@ -805,17 +876,17 @@ const var_t *get_func_handle_var( const type_t *iface, const var_t *func,
if (!is_attr( var->attrs, ATTR_IN ) && is_attr( var->attrs, ATTR_OUT )) continue; if (!is_attr( var->attrs, ATTR_IN ) && is_attr( var->attrs, ATTR_OUT )) continue;
if (type_get_type( var->type ) == TYPE_BASIC && type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE) if (type_get_type( var->type ) == TYPE_BASIC && type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE)
{ {
*explicit_fc = RPC_FC_BIND_PRIMITIVE; *explicit_fc = FC_BIND_PRIMITIVE;
return var; return var;
} }
if (get_explicit_generic_handle_type( var )) if (get_explicit_generic_handle_type( var ))
{ {
*explicit_fc = RPC_FC_BIND_GENERIC; *explicit_fc = FC_BIND_GENERIC;
return var; return var;
} }
if (is_context_handle( var->type )) if (is_context_handle( var->type ))
{ {
*explicit_fc = RPC_FC_BIND_CONTEXT; *explicit_fc = FC_BIND_CONTEXT;
return var; return var;
} }
} }
@ -824,13 +895,13 @@ const var_t *get_func_handle_var( const type_t *iface, const var_t *func,
{ {
if (type_get_type( var->type ) == TYPE_BASIC && if (type_get_type( var->type ) == TYPE_BASIC &&
type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE) type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE)
*implicit_fc = RPC_FC_BIND_PRIMITIVE; *implicit_fc = FC_BIND_PRIMITIVE;
else else
*implicit_fc = RPC_FC_BIND_GENERIC; *implicit_fc = FC_BIND_GENERIC;
return var; return var;
} }
*implicit_fc = RPC_FC_AUTO_HANDLE; *implicit_fc = FC_AUTO_HANDLE;
return NULL; return NULL;
} }
@ -1276,7 +1347,7 @@ static void write_locals(FILE *fp, const type_t *iface, int body)
if (cas) { if (cas) {
const statement_t *stmt2 = NULL; const statement_t *stmt2 = NULL;
STATEMENTS_FOR_EACH_FUNC(stmt2, type_iface_get_stmts(iface)) STATEMENTS_FOR_EACH_FUNC(stmt2, type_iface_get_stmts(iface))
if (!strcmp(stmt2->u.var->name, cas->name)) if (!strcmp(get_name(stmt2->u.var), cas->name))
break; break;
if (&stmt2->entry != type_iface_get_stmts(iface)) { if (&stmt2->entry != type_iface_get_stmts(iface)) {
const var_t *m = stmt2->u.var; const var_t *m = stmt2->u.var;
@ -1596,8 +1667,13 @@ static void write_forward_decls(FILE *header, const statement_list_t *stmts)
case STMT_TYPE: case STMT_TYPE:
if (type_get_type(stmt->u.type) == TYPE_INTERFACE) if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
{ {
if (is_object(stmt->u.type) || is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE)) type_t *iface = stmt->u.type;
write_forward(header, stmt->u.type); if (is_object(iface) || is_attr(iface->attrs, ATTR_DISPINTERFACE))
{
write_forward(header, iface);
if (iface->details.iface->async_iface)
write_forward(header, iface->details.iface->async_iface);
}
} }
else if (type_get_type(stmt->u.type) == TYPE_COCLASS) else if (type_get_type(stmt->u.type) == TYPE_COCLASS)
write_coclass_forward(header, stmt->u.type); write_coclass_forward(header, stmt->u.type);
@ -1632,12 +1708,18 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
if (type_get_type(stmt->u.type) == TYPE_INTERFACE) if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
{ {
type_t *iface = stmt->u.type; type_t *iface = stmt->u.type;
type_t *async_iface = iface->details.iface->async_iface;
if (is_object(iface)) is_object_interface++; if (is_object(iface)) is_object_interface++;
if (is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE) || is_object(stmt->u.type)) if (is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE) || is_object(stmt->u.type))
{ {
write_com_interface_start(header, iface); write_com_interface_start(header, iface);
write_header_stmts(header, type_iface_get_stmts(iface), stmt->u.type, TRUE); write_header_stmts(header, type_iface_get_stmts(iface), stmt->u.type, TRUE);
write_com_interface_end(header, iface); write_com_interface_end(header, iface);
if (async_iface)
{
write_com_interface_start(header, async_iface);
write_com_interface_end(header, async_iface);
}
} }
else else
{ {
@ -1717,6 +1799,7 @@ void write_header(const statement_list_t *stmts)
} }
fprintf(header, "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n\n", PACKAGE_VERSION, input_name); fprintf(header, "/*** Autogenerated by WIDL %s from %s - Do not edit ***/\n\n", PACKAGE_VERSION, input_name);
fprintf(header, "#ifdef _WIN32\n");
fprintf(header, "#ifndef __REQUIRED_RPCNDR_H_VERSION__\n"); fprintf(header, "#ifndef __REQUIRED_RPCNDR_H_VERSION__\n");
fprintf(header, "#define __REQUIRED_RPCNDR_H_VERSION__ 475\n"); fprintf(header, "#define __REQUIRED_RPCNDR_H_VERSION__ 475\n");
fprintf(header, "#endif\n\n"); fprintf(header, "#endif\n\n");
@ -1726,7 +1809,10 @@ void write_header(const statement_list_t *stmts)
fprintf(header, "#endif\n\n"); fprintf(header, "#endif\n\n");
fprintf(header, "#include <rpc.h>\n" ); fprintf(header, "#include <rpc.h>\n" );
fprintf(header, "#include <rpcndr.h>\n\n" ); fprintf(header, "#include <rpcndr.h>\n" );
if (!for_each_serializable(stmts, NULL, serializable_exists))
fprintf(header, "#include <midles.h>\n" );
fprintf(header, "#endif\n\n");
fprintf(header, "#ifndef COM_NO_WINDOWS_H\n"); fprintf(header, "#ifndef COM_NO_WINDOWS_H\n");
fprintf(header, "#include <windows.h>\n"); fprintf(header, "#include <windows.h>\n");
@ -1748,6 +1834,7 @@ void write_header(const statement_list_t *stmts)
fprintf(header, "/* Begin additional prototypes for all interfaces */\n"); fprintf(header, "/* Begin additional prototypes for all interfaces */\n");
fprintf(header, "\n"); fprintf(header, "\n");
for_each_serializable(stmts, header, write_serialize_function_decl);
write_user_types(header); write_user_types(header);
write_generic_handle_routines(header); write_generic_handle_routines(header);
write_context_handle_rundowns(header); write_context_handle_rundowns(header);

View file

@ -48,13 +48,14 @@ extern int need_proxy_delegation(const statement_list_t *stmts);
extern int need_inline_stubs_file(const statement_list_t *stmts); extern int need_inline_stubs_file(const statement_list_t *stmts);
extern const var_t *is_callas(const attr_list_t *list); extern const var_t *is_callas(const attr_list_t *list);
extern void write_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent); extern void write_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent);
extern void write_array(FILE *h, array_dims_t *v, int field);
extern const type_t* get_explicit_generic_handle_type(const var_t* var); extern const type_t* get_explicit_generic_handle_type(const var_t* var);
extern const var_t *get_func_handle_var( const type_t *iface, const var_t *func, extern const var_t *get_func_handle_var( const type_t *iface, const var_t *func,
unsigned char *explicit_fc, unsigned char *implicit_fc ); unsigned char *explicit_fc, unsigned char *implicit_fc );
extern int has_out_arg_or_return(const var_t *func); extern int has_out_arg_or_return(const var_t *func);
extern int is_const_decl(const var_t *var); extern int is_const_decl(const var_t *var);
extern void write_serialize_functions(FILE *file, const type_t *type, const type_t *iface);
static inline int is_ptr(const type_t *t) static inline int is_ptr(const type_t *t)
{ {
return type_get_type(t) == TYPE_POINTER; return type_get_type(t) == TYPE_POINTER;

View file

@ -76,6 +76,8 @@ static int cbufalloc = 0;
static int kw_token(const char *kw); static int kw_token(const char *kw);
static int attr_token(const char *kw); static int attr_token(const char *kw);
static void switch_to_acf(void);
static warning_list_t *disabled_warnings = NULL; static warning_list_t *disabled_warnings = NULL;
#define MAX_IMPORT_DEPTH 20 #define MAX_IMPORT_DEPTH 20
@ -227,7 +229,12 @@ SAFEARRAY{ws}*/\( return tSAFEARRAY;
<<EOF>> { <<EOF>> {
if (import_stack_ptr) if (import_stack_ptr)
return aEOF; return aEOF;
else yyterminate(); if (acf_name)
{
switch_to_acf();
return aACF;
}
yyterminate();
} }
%% %%
@ -250,6 +257,7 @@ static const struct keyword keywords[] = {
{"TRUE", tTRUE}, {"TRUE", tTRUE},
{"__cdecl", tCDECL}, {"__cdecl", tCDECL},
{"__fastcall", tFASTCALL}, {"__fastcall", tFASTCALL},
{"__int32", tINT32},
{"__int3264", tINT3264}, {"__int3264", tINT3264},
{"__int64", tINT64}, {"__int64", tINT64},
{"__pascal", tPASCAL}, {"__pascal", tPASCAL},
@ -562,6 +570,38 @@ void abort_import(void)
unlink(import_stack[ptr].temp_name); unlink(import_stack[ptr].temp_name);
} }
static void switch_to_acf(void)
{
int ptr = import_stack_ptr;
int ret, fd;
char *name;
FILE *f;
assert(import_stack_ptr == 0);
input_name = acf_name;
acf_name = NULL;
line_number = 1;
name = xstrdup( "widl.XXXXXX" );
if((fd = mkstemps( name, 0 )) == -1)
error("Could not generate a temp name from %s\n", name);
temp_name = name;
if (!(f = fdopen(fd, "wt")))
error("Could not open fd %s for writing\n", name);
ret = wpp_parse(input_name, f);
fclose(f);
if (ret) exit(1);
if((f = fopen(temp_name, "r")) == NULL)
error_loc("Unable to open %s\n", temp_name);
import_stack[ptr].state = YY_CURRENT_BUFFER;
yy_switch_to_buffer(yy_create_buffer(f, YY_BUF_SIZE));
}
static void warning_disable(int warning) static void warning_disable(int warning)
{ {
warning_t *warning_entry; warning_t *warning_entry;

File diff suppressed because it is too large Load diff

View file

@ -30,8 +30,8 @@
This special exception was added by the Free Software Foundation in This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */ version 2.2 of Bison. */
#ifndef YY_PARSER_E_REACTOSSYNC_GCC_HOST_TOOLS_SDK_TOOLS_WIDL_PARSER_TAB_H_INCLUDED #ifndef YY_PARSER_E_REACTOSSYNC_MSVC_HOST_TOOLS_SDK_TOOLS_WIDL_PARSER_TAB_H_INCLUDED
# define YY_PARSER_E_REACTOSSYNC_GCC_HOST_TOOLS_SDK_TOOLS_WIDL_PARSER_TAB_H_INCLUDED # define YY_PARSER_E_REACTOSSYNC_MSVC_HOST_TOOLS_SDK_TOOLS_WIDL_PARSER_TAB_H_INCLUDED
/* Debug traces. */ /* Debug traces. */
#ifndef YYDEBUG #ifndef YYDEBUG
# define YYDEBUG 0 # define YYDEBUG 0
@ -56,179 +56,181 @@ extern int parser_debug;
aSQSTRING = 266, aSQSTRING = 266,
aUUID = 267, aUUID = 267,
aEOF = 268, aEOF = 268,
SHL = 269, aACF = 269,
SHR = 270, SHL = 270,
MEMBERPTR = 271, SHR = 271,
EQUALITY = 272, MEMBERPTR = 272,
INEQUALITY = 273, EQUALITY = 273,
GREATEREQUAL = 274, INEQUALITY = 274,
LESSEQUAL = 275, GREATEREQUAL = 275,
LOGICALOR = 276, LESSEQUAL = 276,
LOGICALAND = 277, LOGICALOR = 277,
ELLIPSIS = 278, LOGICALAND = 278,
tAGGREGATABLE = 279, ELLIPSIS = 279,
tALLOCATE = 280, tAGGREGATABLE = 280,
tANNOTATION = 281, tALLOCATE = 281,
tAPPOBJECT = 282, tANNOTATION = 282,
tASYNC = 283, tAPPOBJECT = 283,
tASYNCUUID = 284, tASYNC = 284,
tAUTOHANDLE = 285, tASYNCUUID = 285,
tBINDABLE = 286, tAUTOHANDLE = 286,
tBOOLEAN = 287, tBINDABLE = 287,
tBROADCAST = 288, tBOOLEAN = 288,
tBYTE = 289, tBROADCAST = 289,
tBYTECOUNT = 290, tBYTE = 290,
tCALLAS = 291, tBYTECOUNT = 291,
tCALLBACK = 292, tCALLAS = 292,
tCASE = 293, tCALLBACK = 293,
tCDECL = 294, tCASE = 294,
tCHAR = 295, tCDECL = 295,
tCOCLASS = 296, tCHAR = 296,
tCODE = 297, tCOCLASS = 297,
tCOMMSTATUS = 298, tCODE = 298,
tCONST = 299, tCOMMSTATUS = 299,
tCONTEXTHANDLE = 300, tCONST = 300,
tCONTEXTHANDLENOSERIALIZE = 301, tCONTEXTHANDLE = 301,
tCONTEXTHANDLESERIALIZE = 302, tCONTEXTHANDLENOSERIALIZE = 302,
tCONTROL = 303, tCONTEXTHANDLESERIALIZE = 303,
tCPPQUOTE = 304, tCONTROL = 304,
tDECODE = 305, tCPPQUOTE = 305,
tDEFAULT = 306, tDECODE = 306,
tDEFAULTBIND = 307, tDEFAULT = 307,
tDEFAULTCOLLELEM = 308, tDEFAULTBIND = 308,
tDEFAULTVALUE = 309, tDEFAULTCOLLELEM = 309,
tDEFAULTVTABLE = 310, tDEFAULTVALUE = 310,
tDISABLECONSISTENCYCHECK = 311, tDEFAULTVTABLE = 311,
tDISPLAYBIND = 312, tDISABLECONSISTENCYCHECK = 312,
tDISPINTERFACE = 313, tDISPLAYBIND = 313,
tDLLNAME = 314, tDISPINTERFACE = 314,
tDOUBLE = 315, tDLLNAME = 315,
tDUAL = 316, tDOUBLE = 316,
tENABLEALLOCATE = 317, tDUAL = 317,
tENCODE = 318, tENABLEALLOCATE = 318,
tENDPOINT = 319, tENCODE = 319,
tENTRY = 320, tENDPOINT = 320,
tENUM = 321, tENTRY = 321,
tERRORSTATUST = 322, tENUM = 322,
tEXPLICITHANDLE = 323, tERRORSTATUST = 323,
tEXTERN = 324, tEXPLICITHANDLE = 324,
tFALSE = 325, tEXTERN = 325,
tFASTCALL = 326, tFALSE = 326,
tFAULTSTATUS = 327, tFASTCALL = 327,
tFLOAT = 328, tFAULTSTATUS = 328,
tFORCEALLOCATE = 329, tFLOAT = 329,
tHANDLE = 330, tFORCEALLOCATE = 330,
tHANDLET = 331, tHANDLE = 331,
tHELPCONTEXT = 332, tHANDLET = 332,
tHELPFILE = 333, tHELPCONTEXT = 333,
tHELPSTRING = 334, tHELPFILE = 334,
tHELPSTRINGCONTEXT = 335, tHELPSTRING = 335,
tHELPSTRINGDLL = 336, tHELPSTRINGCONTEXT = 336,
tHIDDEN = 337, tHELPSTRINGDLL = 337,
tHYPER = 338, tHIDDEN = 338,
tID = 339, tHYPER = 339,
tIDEMPOTENT = 340, tID = 340,
tIGNORE = 341, tIDEMPOTENT = 341,
tIIDIS = 342, tIGNORE = 342,
tIMMEDIATEBIND = 343, tIIDIS = 343,
tIMPLICITHANDLE = 344, tIMMEDIATEBIND = 344,
tIMPORT = 345, tIMPLICITHANDLE = 345,
tIMPORTLIB = 346, tIMPORT = 346,
tIN = 347, tIMPORTLIB = 347,
tIN_LINE = 348, tIN = 348,
tINLINE = 349, tIN_LINE = 349,
tINPUTSYNC = 350, tINLINE = 350,
tINT = 351, tINPUTSYNC = 351,
tINT3264 = 352, tINT = 352,
tINT64 = 353, tINT32 = 353,
tINTERFACE = 354, tINT3264 = 354,
tLCID = 355, tINT64 = 355,
tLENGTHIS = 356, tINTERFACE = 356,
tLIBRARY = 357, tLCID = 357,
tLICENSED = 358, tLENGTHIS = 358,
tLOCAL = 359, tLIBRARY = 359,
tLONG = 360, tLICENSED = 360,
tMAYBE = 361, tLOCAL = 361,
tMESSAGE = 362, tLONG = 362,
tMETHODS = 363, tMAYBE = 363,
tMODULE = 364, tMESSAGE = 364,
tNAMESPACE = 365, tMETHODS = 365,
tNOCODE = 366, tMODULE = 366,
tNONBROWSABLE = 367, tNAMESPACE = 367,
tNONCREATABLE = 368, tNOCODE = 368,
tNONEXTENSIBLE = 369, tNONBROWSABLE = 369,
tNOTIFY = 370, tNONCREATABLE = 370,
tNOTIFYFLAG = 371, tNONEXTENSIBLE = 371,
tNULL = 372, tNOTIFY = 372,
tOBJECT = 373, tNOTIFYFLAG = 373,
tODL = 374, tNULL = 374,
tOLEAUTOMATION = 375, tOBJECT = 375,
tOPTIMIZE = 376, tODL = 376,
tOPTIONAL = 377, tOLEAUTOMATION = 377,
tOUT = 378, tOPTIMIZE = 378,
tPARTIALIGNORE = 379, tOPTIONAL = 379,
tPASCAL = 380, tOUT = 380,
tPOINTERDEFAULT = 381, tPARTIALIGNORE = 381,
tPRAGMA_WARNING = 382, tPASCAL = 382,
tPROGID = 383, tPOINTERDEFAULT = 383,
tPROPERTIES = 384, tPRAGMA_WARNING = 384,
tPROPGET = 385, tPROGID = 385,
tPROPPUT = 386, tPROPERTIES = 386,
tPROPPUTREF = 387, tPROPGET = 387,
tPROXY = 388, tPROPPUT = 388,
tPTR = 389, tPROPPUTREF = 389,
tPUBLIC = 390, tPROXY = 390,
tRANGE = 391, tPTR = 391,
tREADONLY = 392, tPUBLIC = 392,
tREF = 393, tRANGE = 393,
tREGISTER = 394, tREADONLY = 394,
tREPRESENTAS = 395, tREF = 395,
tREQUESTEDIT = 396, tREGISTER = 396,
tRESTRICTED = 397, tREPRESENTAS = 397,
tRETVAL = 398, tREQUESTEDIT = 398,
tSAFEARRAY = 399, tRESTRICTED = 399,
tSHORT = 400, tRETVAL = 400,
tSIGNED = 401, tSAFEARRAY = 401,
tSIZEIS = 402, tSHORT = 402,
tSIZEOF = 403, tSIGNED = 403,
tSMALL = 404, tSIZEIS = 404,
tSOURCE = 405, tSIZEOF = 405,
tSTATIC = 406, tSMALL = 406,
tSTDCALL = 407, tSOURCE = 407,
tSTRICTCONTEXTHANDLE = 408, tSTATIC = 408,
tSTRING = 409, tSTDCALL = 409,
tSTRUCT = 410, tSTRICTCONTEXTHANDLE = 410,
tSWITCH = 411, tSTRING = 411,
tSWITCHIS = 412, tSTRUCT = 412,
tSWITCHTYPE = 413, tSWITCH = 413,
tTHREADING = 414, tSWITCHIS = 414,
tTRANSMITAS = 415, tSWITCHTYPE = 415,
tTRUE = 416, tTHREADING = 416,
tTYPEDEF = 417, tTRANSMITAS = 417,
tUIDEFAULT = 418, tTRUE = 418,
tUNION = 419, tTYPEDEF = 419,
tUNIQUE = 420, tUIDEFAULT = 420,
tUNSIGNED = 421, tUNION = 421,
tUSESGETLASTERROR = 422, tUNIQUE = 422,
tUSERMARSHAL = 423, tUNSIGNED = 423,
tUUID = 424, tUSESGETLASTERROR = 424,
tV1ENUM = 425, tUSERMARSHAL = 425,
tVARARG = 426, tUUID = 426,
tVERSION = 427, tV1ENUM = 427,
tVIPROGID = 428, tVARARG = 428,
tVOID = 429, tVERSION = 429,
tWCHAR = 430, tVIPROGID = 430,
tWIREMARSHAL = 431, tVOID = 431,
tAPARTMENT = 432, tWCHAR = 432,
tNEUTRAL = 433, tWIREMARSHAL = 433,
tSINGLE = 434, tAPARTMENT = 434,
tFREE = 435, tNEUTRAL = 435,
tBOTH = 436, tSINGLE = 436,
CAST = 437, tFREE = 437,
PPTR = 438, tBOTH = 438,
POS = 439, CAST = 439,
NEG = 440, PPTR = 440,
ADDRESSOF = 441 POS = 441,
NEG = 442,
ADDRESSOF = 443
}; };
#endif #endif
@ -237,14 +239,13 @@ extern int parser_debug;
typedef union YYSTYPE YYSTYPE; typedef union YYSTYPE YYSTYPE;
union YYSTYPE union YYSTYPE
{ {
#line 138 "parser.y" /* yacc.c:1909 */ #line 144 "parser.y" /* yacc.c:1909 */
attr_t *attr; attr_t *attr;
attr_list_t *attr_list; attr_list_t *attr_list;
str_list_t *str_list; str_list_t *str_list;
expr_t *expr; expr_t *expr;
expr_list_t *expr_list; expr_list_t *expr_list;
array_dims_t *array_dims;
type_t *type; type_t *type;
var_t *var; var_t *var;
var_list_t *var_list; var_list_t *var_list;
@ -266,7 +267,7 @@ union YYSTYPE
struct _decl_spec_t *declspec; struct _decl_spec_t *declspec;
enum storage_class stgclass; enum storage_class stgclass;
#line 270 "parser.tab.h" /* yacc.c:1909 */ #line 271 "parser.tab.h" /* yacc.c:1909 */
}; };
# define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_DECLARED 1
@ -277,4 +278,4 @@ extern YYSTYPE parser_lval;
int parser_parse (void); int parser_parse (void);
#endif /* !YY_PARSER_E_REACTOSSYNC_GCC_HOST_TOOLS_SDK_TOOLS_WIDL_PARSER_TAB_H_INCLUDED */ #endif /* !YY_PARSER_E_REACTOSSYNC_MSVC_HOST_TOOLS_SDK_TOOLS_WIDL_PARSER_TAB_H_INCLUDED */

View file

@ -38,7 +38,7 @@
#include "expr.h" #include "expr.h"
#include "typetree.h" #include "typetree.h"
static unsigned char pointer_default = RPC_FC_UP; static unsigned char pointer_default = FC_UP;
typedef struct list typelist_t; typedef struct list typelist_t;
struct typenode { struct typenode {
@ -72,7 +72,7 @@ static attr_t *make_attr(enum attr_type type);
static attr_t *make_attrv(enum attr_type type, unsigned int val); static attr_t *make_attrv(enum attr_type type, unsigned int val);
static attr_t *make_attrp(enum attr_type type, void *val); static attr_t *make_attrp(enum attr_type type, void *val);
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 type_t *append_array(type_t *chain, expr_t *expr);
static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl, int top); static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl, int top);
static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls); static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls);
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);
@ -82,7 +82,7 @@ static declarator_list_t *append_declarator(declarator_list_t *list, declarator_
static declarator_t *make_declarator(var_t *var); static declarator_t *make_declarator(var_t *var);
static type_t *make_safearray(type_t *type); static type_t *make_safearray(type_t *type);
static typelib_t *make_library(const char *name, const attr_list_t *attrs); static typelib_t *make_library(const char *name, const attr_list_t *attrs);
static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type); static type_t *append_chain_type(type_t *chain, type_t *type);
static warning_list_t *append_warning(warning_list_t *, int); static warning_list_t *append_warning(warning_list_t *, int);
static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs); static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
@ -113,6 +113,8 @@ const char *get_attr_display_name(enum attr_type type);
static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func); static void add_explicit_handle_if_necessary(const type_t *iface, var_t *func);
static void check_def(const type_t *t); static void check_def(const type_t *t);
static void check_async_uuid(type_t *iface);
static statement_t *make_statement(enum statement_type type); static statement_t *make_statement(enum statement_type type);
static statement_t *make_statement_type_decl(type_t *type); static statement_t *make_statement_type_decl(type_t *type);
static statement_t *make_statement_reference(type_t *type); static statement_t *make_statement_reference(type_t *type);
@ -134,6 +136,10 @@ static struct namespace global_namespace = {
static struct namespace *current_namespace = &global_namespace; static struct namespace *current_namespace = &global_namespace;
#ifndef __REACTOS__
static typelib_t *current_typelib;
#endif
%} %}
%union { %union {
attr_t *attr; attr_t *attr;
@ -141,7 +147,6 @@ static struct namespace *current_namespace = &global_namespace;
str_list_t *str_list; str_list_t *str_list;
expr_t *expr; expr_t *expr;
expr_list_t *expr_list; expr_list_t *expr_list;
array_dims_t *array_dims;
type_t *type; type_t *type;
var_t *var; var_t *var;
var_list_t *var_list; var_list_t *var_list;
@ -170,7 +175,7 @@ static struct namespace *current_namespace = &global_namespace;
%token <dbl> aDOUBLE %token <dbl> aDOUBLE
%token <str> aSTRING aWSTRING aSQSTRING %token <str> aSTRING aWSTRING aSQSTRING
%token <uuid> aUUID %token <uuid> aUUID
%token aEOF %token aEOF aACF
%token SHL SHR %token SHL SHR
%token MEMBERPTR %token MEMBERPTR
%token EQUALITY INEQUALITY %token EQUALITY INEQUALITY
@ -207,7 +212,7 @@ static struct namespace *current_namespace = &global_namespace;
%token tIMPORT tIMPORTLIB %token tIMPORT tIMPORTLIB
%token tIN tIN_LINE tINLINE %token tIN tIN_LINE tINLINE
%token tINPUTSYNC %token tINPUTSYNC
%token tINT tINT3264 tINT64 %token tINT tINT32 tINT3264 tINT64
%token tINTERFACE %token tINTERFACE
%token tLCID %token tLCID
%token tLENGTHIS tLIBRARY %token tLENGTHIS tLIBRARY
@ -263,8 +268,9 @@ static struct namespace *current_namespace = &global_namespace;
%token tWCHAR tWIREMARSHAL %token tWCHAR tWIREMARSHAL
%token tAPARTMENT tNEUTRAL tSINGLE tFREE tBOTH %token tAPARTMENT tNEUTRAL tSINGLE tFREE tBOTH
%type <attr> attribute type_qualifier function_specifier %type <attr> attribute type_qualifier function_specifier acf_attribute
%type <attr_list> m_attributes attributes attrib_list m_type_qual_list %type <attr_list> m_attributes attributes attrib_list m_type_qual_list
%type <attr_list> acf_attributes acf_attribute_list
%type <str_list> str_list %type <str_list> str_list
%type <expr> m_expr expr expr_const expr_int_const array m_bitfield %type <expr> m_expr expr expr_const expr_int_const array m_bitfield
%type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const %type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
@ -318,7 +324,7 @@ static struct namespace *current_namespace = &global_namespace;
%% %%
input: gbl_statements { fix_incomplete(); input: gbl_statements m_acf { fix_incomplete();
check_statements($1, FALSE); check_statements($1, FALSE);
check_all_user_types($1); check_all_user_types($1);
write_header($1); write_header($1);
@ -327,11 +333,16 @@ input: gbl_statements { fix_incomplete();
write_client($1); write_client($1);
write_server($1); write_server($1);
write_regscript($1); write_regscript($1);
#ifndef __REACTOS__
write_typelib_regscript($1);
#endif
write_dlldata($1); write_dlldata($1);
write_local_stubs($1); write_local_stubs($1);
} }
; ;
m_acf: /* empty */ | aACF acf_statements
gbl_statements: { $$ = NULL; } gbl_statements: { $$ = NULL; }
| gbl_statements namespacedef '{' { push_namespace($2); } gbl_statements '}' | gbl_statements namespacedef '{' { push_namespace($2); } gbl_statements '}'
{ pop_namespace($2); $$ = append_statements($1, $5); } { pop_namespace($2); $$ = append_statements($1, $5); }
@ -425,21 +436,33 @@ import: import_start imp_statements aEOF { $$ = $1->name;
; ;
importlib: tIMPORTLIB '(' aSTRING ')' importlib: tIMPORTLIB '(' aSTRING ')'
/* ifdef __REACTOS__ */
semicolon_opt { $$ = $3; if(!parse_only) add_importlib($3); } semicolon_opt { $$ = $3; if(!parse_only) add_importlib($3); }
/* else
semicolon_opt { $$ = $3; if(!parse_only) add_importlib($3, current_typelib); }
*/
; ;
libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; } libraryhdr: tLIBRARY aIDENTIFIER { $$ = $2; }
| tLIBRARY aKNOWNTYPE { $$ = $2; } | tLIBRARY aKNOWNTYPE { $$ = $2; }
; ;
library_start: attributes libraryhdr '{' { $$ = make_library($2, check_library_attrs($2, $1)); library_start: attributes libraryhdr '{' { $$ = make_library($2, check_library_attrs($2, $1));
/* ifdef __REACTOS__ */
if (!parse_only) start_typelib($$); if (!parse_only) start_typelib($$);
/* else
if (!parse_only && do_typelib) current_typelib = $$;
*/
} }
; ;
librarydef: library_start imp_statements '}' librarydef: library_start imp_statements '}'
/* ifdef __REACTOS__ */
semicolon_opt { $$ = $1; semicolon_opt { $$ = $1;
$$->stmts = $2; $$->stmts = $2;
if (!parse_only) end_typelib(); if (!parse_only) end_typelib();
} }
/* else
semicolon_opt { $$ = $1; $$->stmts = $2; }
*/
; ;
m_args: { $$ = NULL; } m_args: { $$ = NULL; }
@ -468,8 +491,8 @@ arg: attributes decl_spec m_any_declarator { if ($2->stgclass != STG_NONE && $
; ;
array: '[' expr ']' { $$ = $2; array: '[' expr ']' { $$ = $2;
if (!$$->is_const) if (!$$->is_const || $$->cval <= 0)
error_loc("array dimension is not an integer constant\n"); error_loc("array dimension is not a positive integer constant\n");
} }
| '[' '*' ']' { $$ = make_expr(EXPR_VOID); } | '[' '*' ']' { $$ = make_expr(EXPR_VOID); }
| '[' ']' { $$ = make_expr(EXPR_VOID); } | '[' ']' { $$ = make_expr(EXPR_VOID); }
@ -816,10 +839,11 @@ m_int:
int_std: tINT { $$ = type_new_int(TYPE_BASIC_INT, 0); } int_std: tINT { $$ = type_new_int(TYPE_BASIC_INT, 0); }
| tSHORT m_int { $$ = type_new_int(TYPE_BASIC_INT16, 0); } | tSHORT m_int { $$ = type_new_int(TYPE_BASIC_INT16, 0); }
| tSMALL { $$ = type_new_int(TYPE_BASIC_INT8, 0); } | tSMALL { $$ = type_new_int(TYPE_BASIC_INT8, 0); }
| tLONG m_int { $$ = type_new_int(TYPE_BASIC_INT32, 0); } | tLONG m_int { $$ = type_new_int(TYPE_BASIC_LONG, 0); }
| tHYPER m_int { $$ = type_new_int(TYPE_BASIC_HYPER, 0); } | tHYPER m_int { $$ = type_new_int(TYPE_BASIC_HYPER, 0); }
| tINT64 { $$ = type_new_int(TYPE_BASIC_INT64, 0); } | tINT64 { $$ = type_new_int(TYPE_BASIC_INT64, 0); }
| tCHAR { $$ = type_new_int(TYPE_BASIC_CHAR, 0); } | tCHAR { $$ = type_new_int(TYPE_BASIC_CHAR, 0); }
| tINT32 { $$ = type_new_int(TYPE_BASIC_INT32, 0); }
| tINT3264 { $$ = type_new_int(TYPE_BASIC_INT3264, 0); } | tINT3264 { $$ = type_new_int(TYPE_BASIC_INT3264, 0); }
; ;
@ -909,6 +933,7 @@ interfacedef: interfacehdr inherit
if($$ == $2) if($$ == $2)
error_loc("Interface can't inherit from itself\n"); error_loc("Interface can't inherit from itself\n");
type_interface_define($$, $2, $4); type_interface_define($$, $2, $4);
check_async_uuid($$);
pointer_default = $1.old_pointer_default; pointer_default = $1.old_pointer_default;
} }
/* 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
@ -977,7 +1002,7 @@ decl_spec_no_type:
declarator: declarator:
'*' m_type_qual_list declarator %prec PPTR '*' m_type_qual_list declarator %prec PPTR
{ $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); } { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
| callconv declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1)); | callconv declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); } else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
| direct_declarator | direct_declarator
@ -986,9 +1011,9 @@ declarator:
direct_declarator: direct_declarator:
ident { $$ = make_declarator($1); } ident { $$ = make_declarator($1); }
| '(' declarator ')' { $$ = $2; } | '(' declarator ')' { $$ = $2; }
| direct_declarator array { $$ = $1; $$->array = append_array($$->array, $2); } | direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); }
| direct_declarator '(' m_args ')' { $$ = $1; | direct_declarator '(' m_args ')' { $$ = $1;
$$->func_type = append_ptrchain_type($$->type, type_new_function($3)); $$->func_type = append_chain_type($$->type, type_new_function($3));
$$->type = NULL; $$->type = NULL;
} }
; ;
@ -996,7 +1021,7 @@ direct_declarator:
/* abstract declarator */ /* abstract declarator */
abstract_declarator: abstract_declarator:
'*' m_type_qual_list m_abstract_declarator %prec PPTR '*' m_type_qual_list m_abstract_declarator %prec PPTR
{ $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); } { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
| callconv m_abstract_declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1)); | callconv m_abstract_declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); } else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
| abstract_direct_declarator | abstract_direct_declarator
@ -1005,7 +1030,7 @@ abstract_declarator:
/* abstract declarator without accepting direct declarator */ /* abstract declarator without accepting direct declarator */
abstract_declarator_no_direct: abstract_declarator_no_direct:
'*' m_type_qual_list m_any_declarator %prec PPTR '*' m_type_qual_list m_any_declarator %prec PPTR
{ $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); } { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
| callconv m_any_declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1)); | callconv m_any_declarator { $$ = $2; if ($$->func_type) $$->func_type->attrs = append_attr($$->func_type->attrs, make_attrp(ATTR_CALLCONV, $1));
else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); } else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
; ;
@ -1018,16 +1043,16 @@ m_abstract_declarator: { $$ = make_declarator(NULL); }
/* abstract direct declarator */ /* abstract direct declarator */
abstract_direct_declarator: abstract_direct_declarator:
'(' abstract_declarator_no_direct ')' { $$ = $2; } '(' abstract_declarator_no_direct ')' { $$ = $2; }
| abstract_direct_declarator array { $$ = $1; $$->array = append_array($$->array, $2); } | abstract_direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); }
| array { $$ = make_declarator(NULL); $$->array = append_array($$->array, $1); } | array { $$ = make_declarator(NULL); $$->type = append_array($$->type, $1); }
| '(' m_args ')' | '(' m_args ')'
{ $$ = make_declarator(NULL); { $$ = make_declarator(NULL);
$$->func_type = append_ptrchain_type($$->type, type_new_function($2)); $$->func_type = append_chain_type($$->type, type_new_function($2));
$$->type = NULL; $$->type = NULL;
} }
| abstract_direct_declarator '(' m_args ')' | abstract_direct_declarator '(' m_args ')'
{ $$ = $1; { $$ = $1;
$$->func_type = append_ptrchain_type($$->type, type_new_function($3)); $$->func_type = append_chain_type($$->type, type_new_function($3));
$$->type = NULL; $$->type = NULL;
} }
; ;
@ -1035,7 +1060,7 @@ abstract_direct_declarator:
/* abstract or non-abstract declarator */ /* abstract or non-abstract declarator */
any_declarator: any_declarator:
'*' m_type_qual_list m_any_declarator %prec PPTR '*' m_type_qual_list m_any_declarator %prec PPTR
{ $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); } { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
| callconv m_any_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); } | callconv m_any_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
| any_direct_declarator | any_direct_declarator
; ;
@ -1043,7 +1068,7 @@ any_declarator:
/* abstract or non-abstract declarator without accepting direct declarator */ /* abstract or non-abstract declarator without accepting direct declarator */
any_declarator_no_direct: any_declarator_no_direct:
'*' m_type_qual_list m_any_declarator %prec PPTR '*' m_type_qual_list m_any_declarator %prec PPTR
{ $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); } { $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
| callconv m_any_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); } | callconv m_any_declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
; ;
@ -1058,16 +1083,16 @@ m_any_declarator: { $$ = make_declarator(NULL); }
any_direct_declarator: any_direct_declarator:
ident { $$ = make_declarator($1); } ident { $$ = make_declarator($1); }
| '(' any_declarator_no_direct ')' { $$ = $2; } | '(' any_declarator_no_direct ')' { $$ = $2; }
| any_direct_declarator array { $$ = $1; $$->array = append_array($$->array, $2); } | any_direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); }
| array { $$ = make_declarator(NULL); $$->array = append_array($$->array, $1); } | array { $$ = make_declarator(NULL); $$->type = append_array($$->type, $1); }
| '(' m_args ')' | '(' m_args ')'
{ $$ = make_declarator(NULL); { $$ = make_declarator(NULL);
$$->func_type = append_ptrchain_type($$->type, type_new_function($2)); $$->func_type = append_chain_type($$->type, type_new_function($2));
$$->type = NULL; $$->type = NULL;
} }
| any_direct_declarator '(' m_args ')' | any_direct_declarator '(' m_args ')'
{ $$ = $1; { $$ = $1;
$$->func_type = append_ptrchain_type($$->type, type_new_function($3)); $$->func_type = append_chain_type($$->type, type_new_function($3));
$$->type = NULL; $$->type = NULL;
} }
; ;
@ -1107,9 +1132,9 @@ threading_type:
; ;
pointer_type: pointer_type:
tREF { $$ = RPC_FC_RP; } tREF { $$ = FC_RP; }
| tUNIQUE { $$ = RPC_FC_UP; } | tUNIQUE { $$ = FC_UP; }
| tPTR { $$ = RPC_FC_FP; } | tPTR { $$ = FC_FP; }
; ;
structdef: tSTRUCT t_ident '{' fields '}' { $$ = type_new_struct($2, current_namespace, TRUE, $4); } structdef: tSTRUCT t_ident '{' fields '}' { $$ = type_new_struct($2, current_namespace, TRUE, $4); }
@ -1147,6 +1172,40 @@ version:
| aHEXNUM { $$ = $1; } | aHEXNUM { $$ = $1; }
; ;
acf_statements
: /* empty */
| acf_interface acf_statements
acf_int_statements
: /* empty */
| acf_int_statement acf_int_statements
acf_int_statement
: tTYPEDEF acf_attributes aKNOWNTYPE ';'
{ type_t *type = find_type_or_error($3, 0);
type->attrs = append_attr_list(type->attrs, $2);
}
acf_interface
: acf_attributes tINTERFACE aKNOWNTYPE '{' acf_int_statements '}'
{ type_t *iface = find_type_or_error2($3, 0);
if (type_get_type(iface) != TYPE_INTERFACE)
error_loc("%s is not an interface\n", iface->name);
iface->attrs = append_attr_list(iface->attrs, $1);
}
acf_attributes
: /* empty */ { $$ = NULL; };
| '[' acf_attribute_list ']' { $$ = $2; };
acf_attribute_list
: acf_attribute { $$ = append_attr(NULL, $1); }
| acf_attribute_list ',' acf_attribute { $$ = append_attr($1, $3); }
acf_attribute
: tENCODE { $$ = make_attr(ATTR_ENCODE); }
| tDECODE { $$ = make_attr(ATTR_DECODE); }
| tEXPLICITHANDLE { $$ = make_attr(ATTR_EXPLICIT_HANDLE); }
%% %%
static void decl_builtin_basic(const char *name, enum type_basic_type type) static void decl_builtin_basic(const char *name, enum type_basic_type type)
@ -1236,10 +1295,13 @@ static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_lis
return new_list; return new_list;
} }
static attr_list_t *dupattrs(const attr_list_t *list) typedef int (*map_attrs_filter_t)(attr_list_t*,const attr_t*);
static attr_list_t *map_attrs(const attr_list_t *list, map_attrs_filter_t filter)
{ {
attr_list_t *new_list; attr_list_t *new_list;
const attr_t *attr; const attr_t *attr;
attr_t *new_attr;
if (!list) return NULL; if (!list) return NULL;
@ -1247,7 +1309,8 @@ static attr_list_t *dupattrs(const attr_list_t *list)
list_init( new_list ); list_init( new_list );
LIST_FOR_EACH_ENTRY(attr, list, const attr_t, entry) LIST_FOR_EACH_ENTRY(attr, list, const attr_t, entry)
{ {
attr_t *new_attr = xmalloc(sizeof(*new_attr)); if (filter && !filter(new_list, attr)) continue;
new_attr = xmalloc(sizeof(*new_attr));
*new_attr = *attr; *new_attr = *attr;
list_add_tail(new_list, &new_attr->entry); list_add_tail(new_list, &new_attr->entry);
} }
@ -1297,7 +1360,7 @@ static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t
{ {
attr_list_t *attrs; attr_list_t *attrs;
declspec->type = duptype(type, 1); declspec->type = duptype(type, 1);
attrs = dupattrs(type->attrs); attrs = map_attrs(type->attrs, NULL);
declspec->type->attrs = append_attr_list(attrs, declspec->attrs); declspec->type->attrs = append_attr_list(attrs, declspec->attrs);
declspec->attrs = NULL; declspec->attrs = NULL;
} }
@ -1341,16 +1404,19 @@ static expr_list_t *append_expr(expr_list_t *list, expr_t *expr)
return list; return list;
} }
static array_dims_t *append_array(array_dims_t *list, expr_t *expr) static type_t *append_array(type_t *chain, expr_t *expr)
{ {
if (!expr) return list; type_t *array;
if (!list)
{ if (!expr)
list = xmalloc( sizeof(*list) ); return chain;
list_init( list );
} /* An array is always a reference pointer unless explicitly marked otherwise
list_add_tail( list, &expr->entry ); * (regardless of what the default pointer attribute is). */
return list; array = type_new_array(NULL, NULL, FALSE, expr->is_const ? expr->cval : 0,
expr->is_const ? NULL : expr, NULL, FC_RP);
return append_chain_type(chain, array);
} }
static struct list type_pool = LIST_INIT(type_pool); static struct list type_pool = LIST_INIT(type_pool);
@ -1406,6 +1472,7 @@ static int is_allowed_range_type(const type_t *type)
case TYPE_BASIC_INT64: case TYPE_BASIC_INT64:
case TYPE_BASIC_INT: case TYPE_BASIC_INT:
case TYPE_BASIC_INT3264: case TYPE_BASIC_INT3264:
case TYPE_BASIC_LONG:
case TYPE_BASIC_BYTE: case TYPE_BASIC_BYTE:
case TYPE_BASIC_CHAR: case TYPE_BASIC_CHAR:
case TYPE_BASIC_WCHAR: case TYPE_BASIC_WCHAR:
@ -1423,16 +1490,32 @@ static int is_allowed_range_type(const type_t *type)
} }
} }
static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type) static type_t *get_array_or_ptr_ref(type_t *type)
{ {
type_t *ptrchain_type; if (is_ptr(type))
if (!ptrchain) return type_pointer_get_ref(type);
else if (is_array(type))
return type_array_get_element(type);
return NULL;
}
static type_t *append_chain_type(type_t *chain, type_t *type)
{
type_t *chain_type;
if (!chain)
return type; return type;
for (ptrchain_type = ptrchain; type_pointer_get_ref(ptrchain_type); ptrchain_type = type_pointer_get_ref(ptrchain_type)) for (chain_type = chain; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
; ;
assert(ptrchain_type->type_type == TYPE_POINTER);
ptrchain_type->details.pointer.ref = type; if (is_ptr(chain_type))
return ptrchain; chain_type->details.pointer.ref = type;
else if (is_array(chain_type))
chain_type->details.array.elem = type;
else
assert(0);
return chain;
} }
static warning_list_t *append_warning(warning_list_t *list, int num) static warning_list_t *append_warning(warning_list_t *list, int num)
@ -1456,10 +1539,8 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
var_t *v = decl->var; var_t *v = decl->var;
expr_list_t *sizes = get_attrp(attrs, ATTR_SIZEIS); expr_list_t *sizes = get_attrp(attrs, ATTR_SIZEIS);
expr_list_t *lengs = get_attrp(attrs, ATTR_LENGTHIS); expr_list_t *lengs = get_attrp(attrs, ATTR_LENGTHIS);
int sizeless;
expr_t *dim; expr_t *dim;
type_t **ptype; type_t **ptype;
array_dims_t *arr = decl ? decl->array : NULL;
type_t *func_type = decl ? decl->func_type : NULL; type_t *func_type = decl ? decl->func_type : NULL;
type_t *type = decl_spec->type; type_t *type = decl_spec->type;
@ -1478,13 +1559,13 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
} }
/* add type onto the end of the pointers in pident->type */ /* add type onto the end of the pointers in pident->type */
v->type = append_ptrchain_type(decl ? decl->type : NULL, type); v->type = append_chain_type(decl ? decl->type : NULL, type);
v->stgclass = decl_spec->stgclass; v->stgclass = decl_spec->stgclass;
v->attrs = attrs; v->attrs = attrs;
/* check for pointer attribute being applied to non-pointer, non-array /* check for pointer attribute being applied to non-pointer, non-array
* type */ * type */
if (!arr) if (!is_array(v->type))
{ {
int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE); int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE);
const type_t *ptr = NULL; const type_t *ptr = NULL;
@ -1501,12 +1582,12 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
} }
if (is_ptr(ptr)) if (is_ptr(ptr))
{ {
if (ptr_attr && ptr_attr != RPC_FC_UP && if (ptr_attr && ptr_attr != FC_UP &&
type_get_type(type_pointer_get_ref(ptr)) == TYPE_INTERFACE) type_get_type(type_pointer_get_ref(ptr)) == TYPE_INTERFACE)
warning_loc_info(&v->loc_info, warning_loc_info(&v->loc_info,
"%s: pointer attribute applied to interface " "%s: pointer attribute applied to interface "
"pointer type has no effect\n", v->name); "pointer type has no effect\n", v->name);
if (!ptr_attr && top && (*pt)->details.pointer.def_fc != RPC_FC_RP) if (!ptr_attr && top && (*pt)->details.pointer.def_fc != FC_RP)
{ {
/* FIXME: this is a horrible hack to cope with the issue that we /* FIXME: this is a horrible hack to cope with the issue that we
* store an offset to the typeformat string in the type object, but * store an offset to the typeformat string in the type object, but
@ -1523,17 +1604,24 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
{ {
type_t *t = type; type_t *t = type;
if (!is_ptr(v->type) && !arr) if (!is_ptr(v->type) && !is_array(v->type))
error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n", error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n",
v->name); v->name);
while (is_ptr(t)) for (;;)
{
if (is_ptr(t))
t = type_pointer_get_ref(t); t = type_pointer_get_ref(t);
else if (is_array(t))
t = type_array_get_element(t);
else
break;
}
if (type_get_type(t) != TYPE_BASIC && if (type_get_type(t) != TYPE_BASIC &&
(get_basic_fc(t) != RPC_FC_CHAR && (get_basic_fc(t) != FC_CHAR &&
get_basic_fc(t) != RPC_FC_BYTE && get_basic_fc(t) != FC_BYTE &&
get_basic_fc(t) != RPC_FC_WCHAR)) get_basic_fc(t) != FC_WCHAR))
{ {
error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n", error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n",
v->name); v->name);
@ -1550,36 +1638,6 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
error_loc("'%s': [range] attribute applied to non-integer type\n", error_loc("'%s': [range] attribute applied to non-integer type\n",
v->name); v->name);
ptype = &v->type;
sizeless = FALSE;
if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry)
{
if (sizeless)
error_loc("%s: only the first array dimension can be unspecified\n", v->name);
if (dim->is_const)
{
if (dim->cval <= 0)
error_loc("%s: array dimension must be positive\n", v->name);
/* FIXME: should use a type_memsize that allows us to pass in a pointer size */
if (0)
{
unsigned int size = type_memsize(v->type);
if (0xffffffffu / size < dim->cval)
error_loc("%s: total array size is too large\n", v->name);
}
}
else
sizeless = TRUE;
*ptype = type_new_array(NULL, *ptype, FALSE,
dim->is_const ? dim->cval : 0,
dim->is_const ? NULL : dim, NULL,
pointer_default);
}
ptype = &v->type; ptype = &v->type;
if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry) if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry)
{ {
@ -1739,6 +1797,18 @@ var_t *make_var(char *name)
return v; return v;
} }
static var_t *copy_var(var_t *src, char *name, map_attrs_filter_t attr_filter)
{
var_t *v = xmalloc(sizeof(var_t));
v->name = name;
v->type = src->type;
v->attrs = map_attrs(src->attrs, attr_filter);
v->eval = src->eval;
v->stgclass = src->stgclass;
v->loc_info = src->loc_info;
return v;
}
static declarator_list_t *append_declarator(declarator_list_t *list, declarator_t *d) static declarator_list_t *append_declarator(declarator_list_t *list, declarator_t *d)
{ {
if (!d) return list; if (!d) return list;
@ -1756,7 +1826,6 @@ static declarator_t *make_declarator(var_t *var)
d->var = var ? var : make_var(NULL); d->var = var ? var : make_var(NULL);
d->type = NULL; d->type = NULL;
d->func_type = NULL; d->func_type = NULL;
d->array = NULL;
d->bits = NULL; d->bits = NULL;
return d; return d;
} }
@ -1764,7 +1833,7 @@ static declarator_t *make_declarator(var_t *var)
static type_t *make_safearray(type_t *type) static type_t *make_safearray(type_t *type)
{ {
return type_new_array(NULL, type_new_alias(type, "SAFEARRAY"), TRUE, 0, return type_new_array(NULL, type_new_alias(type, "SAFEARRAY"), TRUE, 0,
NULL, NULL, RPC_FC_RP); NULL, NULL, FC_RP);
} }
static typelib_t *make_library(const char *name, const attr_list_t *attrs) static typelib_t *make_library(const char *name, const attr_list_t *attrs)
@ -2415,6 +2484,7 @@ static int is_allowed_conf_type(const type_t *type)
case TYPE_BASIC_INT32: case TYPE_BASIC_INT32:
case TYPE_BASIC_INT64: case TYPE_BASIC_INT64:
case TYPE_BASIC_INT: case TYPE_BASIC_INT:
case TYPE_BASIC_LONG:
case TYPE_BASIC_CHAR: case TYPE_BASIC_CHAR:
case TYPE_BASIC_HYPER: case TYPE_BASIC_HYPER:
case TYPE_BASIC_BYTE: case TYPE_BASIC_BYTE:
@ -2755,6 +2825,87 @@ static void check_functions(const type_t *iface, int is_inside_library)
} }
} }
static char *concat_str(const char *prefix, const char *str)
{
char *ret = xmalloc(strlen(prefix) + strlen(str) + 1);
strcpy(ret, prefix);
strcat(ret, str);
return ret;
}
static int async_iface_attrs(attr_list_t *attrs, const attr_t *attr)
{
switch(attr->type)
{
case ATTR_UUID:
return 0;
case ATTR_ASYNCUUID:
append_attr(attrs, make_attrp(ATTR_UUID, attr->u.pval));
return 0;
default:
return 1;
}
}
static int arg_in_attrs(attr_list_t *attrs, const attr_t *attr)
{
return attr->type != ATTR_OUT && attr->type != ATTR_RETVAL;
}
static int arg_out_attrs(attr_list_t *attrs, const attr_t *attr)
{
return attr->type != ATTR_IN;
}
static void check_async_uuid(type_t *iface)
{
statement_list_t *stmts = NULL;
statement_t *stmt;
type_t *async_iface;
type_t *inherit;
if (!is_attr(iface->attrs, ATTR_ASYNCUUID)) return;
inherit = iface->details.iface->inherit;
if (inherit && strcmp(inherit->name, "IUnknown"))
inherit = inherit->details.iface->async_iface;
if (!inherit)
error_loc("async_uuid applied to an interface with incompatible parent\n");
async_iface = get_type(TYPE_INTERFACE, concat_str("Async", iface->name), iface->namespace, 0);
async_iface->attrs = map_attrs(iface->attrs, async_iface_attrs);
STATEMENTS_FOR_EACH_FUNC( stmt, type_iface_get_stmts(iface) )
{
var_t *begin_func, *finish_func, *func = stmt->u.var, *arg;
var_list_t *begin_args = NULL, *finish_args = NULL, *args;
args = func->type->details.function->args;
if (args) LIST_FOR_EACH_ENTRY(arg, args, var_t, entry)
{
if (is_attr(arg->attrs, ATTR_IN) || !is_attr(arg->attrs, ATTR_OUT))
begin_args = append_var(begin_args, copy_var(arg, strdup(arg->name), arg_in_attrs));
if (is_attr(arg->attrs, ATTR_OUT))
finish_args = append_var(finish_args, copy_var(arg, strdup(arg->name), arg_out_attrs));
}
begin_func = copy_var(func, concat_str("Begin_", func->name), NULL);
begin_func->type = type_new_function(begin_args);
begin_func->type->attrs = func->attrs;
begin_func->type->details.function->retval = func->type->details.function->retval;
stmts = append_statement(stmts, make_statement_declaration(begin_func));
finish_func = copy_var(func, concat_str("Finish_", func->name), NULL);
finish_func->type = type_new_function(finish_args);
finish_func->type->attrs = func->attrs;
finish_func->type->details.function->retval = func->type->details.function->retval;
stmts = append_statement(stmts, make_statement_declaration(finish_func));
}
type_interface_define(async_iface, inherit, stmts);
iface->details.iface->async_iface = async_iface->details.iface->async_iface = async_iface;
}
static void check_statements(const statement_list_t *stmts, int is_inside_library) static void check_statements(const statement_list_t *stmts, int is_inside_library)
{ {
const statement_t *stmt; const statement_t *stmt;

View file

@ -764,6 +764,8 @@ static int cbufalloc = 0;
static int kw_token(const char *kw); static int kw_token(const char *kw);
static int attr_token(const char *kw); static int attr_token(const char *kw);
static void switch_to_acf(void);
static warning_list_t *disabled_warnings = NULL; static warning_list_t *disabled_warnings = NULL;
#define MAX_IMPORT_DEPTH 20 #define MAX_IMPORT_DEPTH 20
@ -813,7 +815,7 @@ UUID *parse_uuid(const char *u)
* The flexer starts here * The flexer starts here
************************************************************************** **************************************************************************
*/ */
#line 817 "parser.yy.c" #line 819 "parser.yy.c"
#define INITIAL 0 #define INITIAL 0
#define QUOTE 1 #define QUOTE 1
@ -1010,9 +1012,9 @@ YY_DECL
register char *yy_cp, *yy_bp; register char *yy_cp, *yy_bp;
register int yy_act; register int yy_act;
#line 130 "parser.l" #line 132 "parser.l"
#line 1016 "parser.yy.c" #line 1018 "parser.yy.c"
if ( !(yy_init) ) if ( !(yy_init) )
{ {
@ -1094,17 +1096,17 @@ do_action: /* This label is used only to access EOF actions. */
case 1: case 1:
YY_RULE_SETUP YY_RULE_SETUP
#line 131 "parser.l" #line 133 "parser.l"
yy_push_state(PP_PRAGMA); yy_push_state(PP_PRAGMA);
YY_BREAK YY_BREAK
case 2: case 2:
YY_RULE_SETUP YY_RULE_SETUP
#line 132 "parser.l" #line 134 "parser.l"
yy_push_state(PP_LINE); yy_push_state(PP_LINE);
YY_BREAK YY_BREAK
case 3: case 3:
YY_RULE_SETUP YY_RULE_SETUP
#line 133 "parser.l" #line 135 "parser.l"
{ {
int lineno; int lineno;
char *cptr, *fname; char *cptr, *fname;
@ -1126,12 +1128,12 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 4: case 4:
YY_RULE_SETUP YY_RULE_SETUP
#line 151 "parser.l" #line 153 "parser.l"
yyless(9); yy_pop_state(); return tCPPQUOTE; yyless(9); yy_pop_state(); return tCPPQUOTE;
YY_BREAK YY_BREAK
case 5: case 5:
YY_RULE_SETUP YY_RULE_SETUP
#line 152 "parser.l" #line 154 "parser.l"
{ {
if(import_stack_ptr) { if(import_stack_ptr) {
if(!winrt_mode) if(!winrt_mode)
@ -1151,22 +1153,22 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 6: case 6:
YY_RULE_SETUP YY_RULE_SETUP
#line 168 "parser.l" #line 170 "parser.l"
parser_lval.str = xstrdup(parser_text); yy_pop_state(); return aPRAGMA; parser_lval.str = xstrdup(parser_text); yy_pop_state(); return aPRAGMA;
YY_BREAK YY_BREAK
case 7: case 7:
YY_RULE_SETUP YY_RULE_SETUP
#line 169 "parser.l" #line 171 "parser.l"
return tPRAGMA_WARNING; return tPRAGMA_WARNING;
YY_BREAK YY_BREAK
case 8: case 8:
YY_RULE_SETUP YY_RULE_SETUP
#line 170 "parser.l" #line 172 "parser.l"
yy_push_state(QUOTE); cbufidx = 0; yy_push_state(QUOTE); cbufidx = 0;
YY_BREAK YY_BREAK
case 9: case 9:
YY_RULE_SETUP YY_RULE_SETUP
#line 171 "parser.l" #line 173 "parser.l"
{ {
yy_pop_state(); yy_pop_state();
parser_lval.str = get_buffered_cstring(); parser_lval.str = get_buffered_cstring();
@ -1175,12 +1177,12 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 10: case 10:
YY_RULE_SETUP YY_RULE_SETUP
#line 176 "parser.l" #line 178 "parser.l"
yy_push_state(WSTRQUOTE); cbufidx = 0; yy_push_state(WSTRQUOTE); cbufidx = 0;
YY_BREAK YY_BREAK
case 11: case 11:
YY_RULE_SETUP YY_RULE_SETUP
#line 177 "parser.l" #line 179 "parser.l"
{ {
yy_pop_state(); yy_pop_state();
parser_lval.str = get_buffered_cstring(); parser_lval.str = get_buffered_cstring();
@ -1189,12 +1191,12 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 12: case 12:
YY_RULE_SETUP YY_RULE_SETUP
#line 182 "parser.l" #line 184 "parser.l"
yy_push_state(SQUOTE); cbufidx = 0; yy_push_state(SQUOTE); cbufidx = 0;
YY_BREAK YY_BREAK
case 13: case 13:
YY_RULE_SETUP YY_RULE_SETUP
#line 183 "parser.l" #line 185 "parser.l"
{ {
yy_pop_state(); yy_pop_state();
parser_lval.str = get_buffered_cstring(); parser_lval.str = get_buffered_cstring();
@ -1202,45 +1204,45 @@ YY_RULE_SETUP
} }
YY_BREAK YY_BREAK
case 14: case 14:
#line 189 "parser.l" #line 191 "parser.l"
case 15: case 15:
YY_RULE_SETUP YY_RULE_SETUP
#line 189 "parser.l" #line 191 "parser.l"
addcchar(parser_text[1]); addcchar(parser_text[1]);
YY_BREAK YY_BREAK
case 16: case 16:
YY_RULE_SETUP YY_RULE_SETUP
#line 190 "parser.l" #line 192 "parser.l"
addcchar(parser_text[1]); addcchar(parser_text[1]);
YY_BREAK YY_BREAK
case 17: case 17:
YY_RULE_SETUP YY_RULE_SETUP
#line 191 "parser.l" #line 193 "parser.l"
addcchar('\\'); addcchar(parser_text[1]); addcchar('\\'); addcchar(parser_text[1]);
YY_BREAK YY_BREAK
case 18: case 18:
YY_RULE_SETUP YY_RULE_SETUP
#line 192 "parser.l" #line 194 "parser.l"
addcchar(parser_text[0]); addcchar(parser_text[0]);
YY_BREAK YY_BREAK
case 19: case 19:
YY_RULE_SETUP YY_RULE_SETUP
#line 193 "parser.l" #line 195 "parser.l"
yy_push_state(ATTR); return '['; yy_push_state(ATTR); return '[';
YY_BREAK YY_BREAK
case 20: case 20:
YY_RULE_SETUP YY_RULE_SETUP
#line 194 "parser.l" #line 196 "parser.l"
yy_pop_state(); return ']'; yy_pop_state(); return ']';
YY_BREAK YY_BREAK
case 21: case 21:
YY_RULE_SETUP YY_RULE_SETUP
#line 195 "parser.l" #line 197 "parser.l"
return attr_token(parser_text); return attr_token(parser_text);
YY_BREAK YY_BREAK
case 22: case 22:
YY_RULE_SETUP YY_RULE_SETUP
#line 196 "parser.l" #line 198 "parser.l"
{ {
parser_lval.uuid = parse_uuid(parser_text); parser_lval.uuid = parse_uuid(parser_text);
return aUUID; return aUUID;
@ -1248,7 +1250,7 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 23: case 23:
YY_RULE_SETUP YY_RULE_SETUP
#line 200 "parser.l" #line 202 "parser.l"
{ {
parser_lval.num = xstrtoul(parser_text, NULL, 0); parser_lval.num = xstrtoul(parser_text, NULL, 0);
return aHEXNUM; return aHEXNUM;
@ -1256,7 +1258,7 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 24: case 24:
YY_RULE_SETUP YY_RULE_SETUP
#line 204 "parser.l" #line 206 "parser.l"
{ {
parser_lval.num = xstrtoul(parser_text, NULL, 0); parser_lval.num = xstrtoul(parser_text, NULL, 0);
return aNUM; return aNUM;
@ -1264,7 +1266,7 @@ YY_RULE_SETUP
YY_BREAK YY_BREAK
case 25: case 25:
YY_RULE_SETUP YY_RULE_SETUP
#line 208 "parser.l" #line 210 "parser.l"
{ {
parser_lval.dbl = strtod(parser_text, NULL); parser_lval.dbl = strtod(parser_text, NULL);
return aDOUBLE; return aDOUBLE;
@ -1275,78 +1277,78 @@ case 26:
(yy_c_buf_p) = yy_cp -= 1; (yy_c_buf_p) = yy_cp -= 1;
YY_DO_BEFORE_ACTION; /* set up parser_text again */ YY_DO_BEFORE_ACTION; /* set up parser_text again */
YY_RULE_SETUP YY_RULE_SETUP
#line 212 "parser.l" #line 214 "parser.l"
return tSAFEARRAY; return tSAFEARRAY;
YY_BREAK YY_BREAK
case 27: case 27:
YY_RULE_SETUP YY_RULE_SETUP
#line 213 "parser.l" #line 215 "parser.l"
return kw_token(parser_text); return kw_token(parser_text);
YY_BREAK YY_BREAK
case 28: case 28:
/* rule 28 can match eol */ /* rule 28 can match eol */
YY_RULE_SETUP YY_RULE_SETUP
#line 214 "parser.l" #line 216 "parser.l"
line_number++; line_number++;
YY_BREAK YY_BREAK
case 29: case 29:
YY_RULE_SETUP YY_RULE_SETUP
#line 215 "parser.l" #line 217 "parser.l"
YY_BREAK YY_BREAK
case 30: case 30:
YY_RULE_SETUP YY_RULE_SETUP
#line 216 "parser.l" #line 218 "parser.l"
return SHL; return SHL;
YY_BREAK YY_BREAK
case 31: case 31:
YY_RULE_SETUP YY_RULE_SETUP
#line 217 "parser.l" #line 219 "parser.l"
return SHR; return SHR;
YY_BREAK YY_BREAK
case 32: case 32:
YY_RULE_SETUP YY_RULE_SETUP
#line 218 "parser.l" #line 220 "parser.l"
return MEMBERPTR; return MEMBERPTR;
YY_BREAK YY_BREAK
case 33: case 33:
YY_RULE_SETUP YY_RULE_SETUP
#line 219 "parser.l" #line 221 "parser.l"
return EQUALITY; return EQUALITY;
YY_BREAK YY_BREAK
case 34: case 34:
YY_RULE_SETUP YY_RULE_SETUP
#line 220 "parser.l" #line 222 "parser.l"
return INEQUALITY; return INEQUALITY;
YY_BREAK YY_BREAK
case 35: case 35:
YY_RULE_SETUP YY_RULE_SETUP
#line 221 "parser.l" #line 223 "parser.l"
return GREATEREQUAL; return GREATEREQUAL;
YY_BREAK YY_BREAK
case 36: case 36:
YY_RULE_SETUP YY_RULE_SETUP
#line 222 "parser.l" #line 224 "parser.l"
return LESSEQUAL; return LESSEQUAL;
YY_BREAK YY_BREAK
case 37: case 37:
YY_RULE_SETUP YY_RULE_SETUP
#line 223 "parser.l" #line 225 "parser.l"
return LOGICALOR; return LOGICALOR;
YY_BREAK YY_BREAK
case 38: case 38:
YY_RULE_SETUP YY_RULE_SETUP
#line 224 "parser.l" #line 226 "parser.l"
return LOGICALAND; return LOGICALAND;
YY_BREAK YY_BREAK
case 39: case 39:
YY_RULE_SETUP YY_RULE_SETUP
#line 225 "parser.l" #line 227 "parser.l"
return ELLIPSIS; return ELLIPSIS;
YY_BREAK YY_BREAK
case 40: case 40:
YY_RULE_SETUP YY_RULE_SETUP
#line 226 "parser.l" #line 228 "parser.l"
return parser_text[0]; return parser_text[0];
YY_BREAK YY_BREAK
case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(INITIAL):
@ -1356,19 +1358,24 @@ case YY_STATE_EOF(ATTR):
case YY_STATE_EOF(PP_LINE): case YY_STATE_EOF(PP_LINE):
case YY_STATE_EOF(PP_PRAGMA): case YY_STATE_EOF(PP_PRAGMA):
case YY_STATE_EOF(SQUOTE): case YY_STATE_EOF(SQUOTE):
#line 227 "parser.l" #line 229 "parser.l"
{ {
if (import_stack_ptr) if (import_stack_ptr)
return aEOF; return aEOF;
else yyterminate(); if (acf_name)
{
switch_to_acf();
return aACF;
}
yyterminate();
} }
YY_BREAK YY_BREAK
case 41: case 41:
YY_RULE_SETUP YY_RULE_SETUP
#line 232 "parser.l" #line 239 "parser.l"
ECHO; ECHO;
YY_BREAK YY_BREAK
#line 1372 "parser.yy.c" #line 1379 "parser.yy.c"
case YY_END_OF_BUFFER: case YY_END_OF_BUFFER:
{ {
@ -2367,7 +2374,7 @@ void parser_free (void * ptr )
#define YYTABLES_NAME "yytables" #define YYTABLES_NAME "yytables"
#line 231 "parser.l" #line 238 "parser.l"
@ -2390,6 +2397,7 @@ static const struct keyword keywords[] = {
{"TRUE", tTRUE}, {"TRUE", tTRUE},
{"__cdecl", tCDECL}, {"__cdecl", tCDECL},
{"__fastcall", tFASTCALL}, {"__fastcall", tFASTCALL},
{"__int32", tINT32},
{"__int3264", tINT3264}, {"__int3264", tINT3264},
{"__int64", tINT64}, {"__int64", tINT64},
{"__pascal", tPASCAL}, {"__pascal", tPASCAL},
@ -2702,6 +2710,38 @@ void abort_import(void)
unlink(import_stack[ptr].temp_name); unlink(import_stack[ptr].temp_name);
} }
static void switch_to_acf(void)
{
int ptr = import_stack_ptr;
int ret, fd;
char *name;
FILE *f;
assert(import_stack_ptr == 0);
input_name = acf_name;
acf_name = NULL;
line_number = 1;
name = xstrdup( "widl.XXXXXX" );
if((fd = mkstemps( name, 0 )) == -1)
error("Could not generate a temp name from %s\n", name);
temp_name = name;
if (!(f = fdopen(fd, "wt")))
error("Could not open fd %s for writing\n", name);
ret = wpp_parse(input_name, f);
fclose(f);
if (ret) exit(1);
if((f = fopen(temp_name, "r")) == NULL)
error_loc("Unable to open %s\n", temp_name);
import_stack[ptr].state = YY_CURRENT_BUFFER;
parser__switch_to_buffer(parser__create_buffer(f,YY_BUF_SIZE));
}
static void warning_disable(int warning) static void warning_disable(int warning)
{ {
warning_t *warning_entry; warning_t *warning_entry;

View file

@ -317,7 +317,7 @@ extern int parser_lex (void);
#undef YY_DECL #undef YY_DECL
#endif #endif
#line 231 "parser.l" #line 238 "parser.l"
#line 324 "parser.yy.h" #line 324 "parser.yy.h"

View file

@ -116,7 +116,13 @@ static void clear_output_vars( const var_list_t *args )
if (type_get_type(type_pointer_get_ref(arg->type)) == TYPE_BASIC) continue; if (type_get_type(type_pointer_get_ref(arg->type)) == TYPE_BASIC) continue;
if (type_get_type(type_pointer_get_ref(arg->type)) == TYPE_ENUM) continue; if (type_get_type(type_pointer_get_ref(arg->type)) == TYPE_ENUM) continue;
} }
print_proxy( "if (%s) MIDL_memset( %s, 0, sizeof( *%s ));\n", arg->name, arg->name, arg->name ); print_proxy( "if (%s) MIDL_memset( %s, 0, ", arg->name, arg->name );
if (is_array(arg->type) && type_array_has_conformance(arg->type))
{
write_expr( proxy, type_array_get_conformance(arg->type), 1, 1, NULL, NULL, "" );
fprintf( proxy, " * " );
}
fprintf( proxy, "sizeof( *%s ));\n", arg->name );
} }
} }
@ -158,7 +164,7 @@ static void free_variable( const var_t *arg, const char *local_var_prefix )
break; break;
case TGT_STRUCT: case TGT_STRUCT:
if (get_struct_fc(type) != RPC_FC_STRUCT) if (get_struct_fc(type) != FC_STRUCT)
print_proxy("/* FIXME: %s code for %s struct type 0x%x missing */\n", __FUNCTION__, arg->name, get_struct_fc(type) ); print_proxy("/* FIXME: %s code for %s struct type 0x%x missing */\n", __FUNCTION__, arg->name, get_struct_fc(type) );
break; break;
@ -680,7 +686,8 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
/* proxy vtable */ /* proxy vtable */
print_proxy( "static %sCINTERFACE_PROXY_VTABLE(%d) _%sProxyVtbl =\n", print_proxy( "static %sCINTERFACE_PROXY_VTABLE(%d) _%sProxyVtbl =\n",
need_delegation_indirect(iface) ? "" : "const ", count, iface->name); (get_stub_mode() != MODE_Os || need_delegation_indirect(iface)) ? "" : "const ",
count, iface->name);
print_proxy( "{\n"); print_proxy( "{\n");
indent++; indent++;
print_proxy( "{\n"); print_proxy( "{\n");
@ -759,7 +766,9 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
print_proxy( "},\n"); print_proxy( "},\n");
print_proxy( "{\n"); print_proxy( "{\n");
indent++; indent++;
print_proxy( "CStdStubBuffer_%s\n", need_delegation_indirect(iface) ? "DELEGATING_METHODS" : "METHODS"); print_proxy( "%s_%s\n",
iface->details.iface->async_iface == iface ? "CStdAsyncStubBuffer" : "CStdStubBuffer",
need_delegation_indirect(iface) ? "DELEGATING_METHODS" : "METHODS");
indent--; indent--;
print_proxy( "}\n"); print_proxy( "}\n");
indent--; indent--;
@ -855,8 +864,13 @@ static void write_proxy_stmts(const statement_list_t *stmts, unsigned int *proc_
{ {
if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_INTERFACE) if (stmt->type == STMT_TYPE && type_get_type(stmt->u.type) == TYPE_INTERFACE)
{ {
if (need_proxy(stmt->u.type)) type_t *iface = stmt->u.type;
write_proxy(stmt->u.type, proc_offset); if (need_proxy(iface))
{
write_proxy(iface, proc_offset);
if (iface->details.iface->async_iface)
write_proxy(iface->details.iface->async_iface, proc_offset);
}
} }
} }
} }
@ -884,6 +898,12 @@ static void build_iface_list( const statement_list_t *stmts, type_t **ifaces[],
{ {
*ifaces = xrealloc( *ifaces, (*count + 1) * sizeof(**ifaces) ); *ifaces = xrealloc( *ifaces, (*count + 1) * sizeof(**ifaces) );
(*ifaces)[(*count)++] = iface; (*ifaces)[(*count)++] = iface;
if (iface->details.iface->async_iface)
{
iface = iface->details.iface->async_iface;
*ifaces = xrealloc( *ifaces, (*count + 1) * sizeof(**ifaces) );
(*ifaces)[(*count)++] = iface;
}
} }
} }
} }
@ -905,6 +925,7 @@ static void write_proxy_routines(const statement_list_t *stmts)
unsigned int proc_offset = 0; unsigned int proc_offset = 0;
char *file_id = proxy_token; char *file_id = proxy_token;
int i, count, have_baseiid = 0; int i, count, have_baseiid = 0;
unsigned int table_version;
type_t **interfaces; type_t **interfaces;
const type_t * delegate_to; const type_t * delegate_to;
@ -950,7 +971,7 @@ static void write_proxy_routines(const statement_list_t *stmts)
write_stubdesc(expr_eval_routines); write_stubdesc(expr_eval_routines);
print_proxy( "#if !defined(__RPC_WIN%u__)\n", pointer_size == 8 ? 64 : 32); print_proxy( "#if !defined(__RPC_WIN%u__)\n", pointer_size == 8 ? 64 : 32);
print_proxy( "#error Currently only Wine and WIN32 are supported.\n"); print_proxy( "#error Invalid build platform for this proxy.\n");
print_proxy( "#endif\n"); print_proxy( "#endif\n");
print_proxy( "\n"); print_proxy( "\n");
write_procformatstring(proxy, stmts, need_proxy); write_procformatstring(proxy, stmts, need_proxy);
@ -1016,6 +1037,26 @@ static void write_proxy_routines(const statement_list_t *stmts)
fprintf(proxy, "}\n"); fprintf(proxy, "}\n");
fprintf(proxy, "\n"); fprintf(proxy, "\n");
table_version = get_stub_mode() == MODE_Oif ? 2 : 1;
for (i = 0; i < count; i++)
{
if (interfaces[i]->details.iface->async_iface != interfaces[i]) continue;
if (table_version != 6)
{
fprintf(proxy, "static const IID *_AsyncInterfaceTable[] =\n");
fprintf(proxy, "{\n");
table_version = 6;
}
fprintf(proxy, " &IID_%s,\n", interfaces[i]->name);
fprintf(proxy, " (IID*)(LONG_PTR)-1,\n");
}
if (table_version == 6)
{
fprintf(proxy, " 0\n");
fprintf(proxy, "};\n");
fprintf(proxy, "\n");
}
fprintf(proxy, "const ExtendedProxyFileInfo %s_ProxyFileInfo DECLSPEC_HIDDEN =\n", file_id); fprintf(proxy, "const ExtendedProxyFileInfo %s_ProxyFileInfo DECLSPEC_HIDDEN =\n", file_id);
fprintf(proxy, "{\n"); fprintf(proxy, "{\n");
fprintf(proxy, " (const PCInterfaceProxyVtblList*)_%s_ProxyVtblList,\n", file_id); fprintf(proxy, " (const PCInterfaceProxyVtblList*)_%s_ProxyVtblList,\n", file_id);
@ -1025,8 +1066,8 @@ static void write_proxy_routines(const statement_list_t *stmts)
else fprintf(proxy, " 0,\n"); else fprintf(proxy, " 0,\n");
fprintf(proxy, " _%s_IID_Lookup,\n", file_id); fprintf(proxy, " _%s_IID_Lookup,\n", file_id);
fprintf(proxy, " %d,\n", count); fprintf(proxy, " %d,\n", count);
fprintf(proxy, " %d,\n", get_stub_mode() == MODE_Oif ? 2 : 1); fprintf(proxy, " %u,\n", table_version);
fprintf(proxy, " 0,\n"); fprintf(proxy, " %s,\n", table_version == 6 ? "_AsyncInterfaceTable" : "0");
fprintf(proxy, " 0,\n"); fprintf(proxy, " 0,\n");
fprintf(proxy, " 0,\n"); fprintf(proxy, " 0,\n");
fprintf(proxy, " 0\n"); fprintf(proxy, " 0\n");
@ -1041,26 +1082,6 @@ void write_proxies(const statement_list_t *stmts)
init_proxy(stmts); init_proxy(stmts);
if(!proxy) return; if(!proxy) return;
if (do_win32 && do_win64)
{
fprintf(proxy, "\n#ifndef _WIN64\n\n");
pointer_size = 4;
write_proxy_routines( stmts ); write_proxy_routines( stmts );
fprintf(proxy, "\n#else /* _WIN64 */\n\n");
pointer_size = 8;
write_proxy_routines( stmts );
fprintf(proxy, "\n#endif /* _WIN64 */\n");
}
else if (do_win32)
{
pointer_size = 4;
write_proxy_routines( stmts );
}
else if (do_win64)
{
pointer_size = 8;
write_proxy_routines( stmts );
}
fclose(proxy); fclose(proxy);
} }

View file

@ -34,6 +34,9 @@
#include "parser.h" #include "parser.h"
#include "header.h" #include "header.h"
#include "typegen.h" #include "typegen.h"
#ifndef __REACTOS__
#include "typelib.h"
#endif
static int indent; static int indent;
@ -273,6 +276,31 @@ void write_regscript( const statement_list_t *stmts )
} }
} }
#ifndef __REACTOS__
void write_typelib_regscript( const statement_list_t *stmts )
{
const statement_t *stmt;
unsigned int count = 0;
if (!do_typelib) return;
if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
{
if (stmt->type != STMT_LIBRARY) continue;
if (count && !strendswith( typelib_name, ".res" ))
error( "Cannot store multiple typelibs into %s\n", typelib_name );
else
{
if (do_old_typelib)
create_sltg_typelib( stmt->u.lib );
else
create_msft_typelib( stmt->u.lib );
}
count++;
}
if (count && strendswith( typelib_name, ".res" )) flush_output_resources( typelib_name );
}
#endif
void output_typelib_regscript( const typelib_t *typelib ) void output_typelib_regscript( const typelib_t *typelib )
{ {
const UUID *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID ); const UUID *typelib_uuid = get_attrp( typelib->attrs, ATTR_UUID );
@ -281,6 +309,9 @@ void output_typelib_regscript( const typelib_t *typelib )
unsigned int version = get_attrv( typelib->attrs, ATTR_VERSION ); unsigned int version = get_attrv( typelib->attrs, ATTR_VERSION );
unsigned int flags = 0; unsigned int flags = 0;
char id_part[12] = ""; char id_part[12] = "";
#ifndef __REACTOS__
char *resname = typelib_name;
#endif
expr_t *expr; expr_t *expr;
if (is_attr( typelib->attrs, ATTR_RESTRICTED )) flags |= 1; /* LIBFLAG_FRESTRICTED */ if (is_attr( typelib->attrs, ATTR_RESTRICTED )) flags |= 1; /* LIBFLAG_FRESTRICTED */
@ -298,10 +329,19 @@ void output_typelib_regscript( const typelib_t *typelib )
MAJORVERSION(version), MINORVERSION(version), descr ? descr : typelib->name ); MAJORVERSION(version), MINORVERSION(version), descr ? descr : typelib->name );
put_str( indent++, "{\n" ); put_str( indent++, "{\n" );
expr = get_attrp( typelib->attrs, ATTR_ID ); expr = get_attrp( typelib->attrs, ATTR_ID );
#ifdef __REACTOS__
if (expr) if (expr)
sprintf(id_part, "\\%d", expr->cval); sprintf(id_part, "\\%d", expr->cval);
#else
if (expr)
{
sprintf(id_part, "\\%d", expr->cval);
resname = xmalloc( strlen(typelib_name) + 20 );
sprintf(resname, "%s\\%d", typelib_name, expr->cval);
}
#endif
put_str( indent, "'%x' { %s = s '%%MODULE%%%s' }\n", put_str( indent, "'%x' { %s = s '%%MODULE%%%s' }\n",
lcid_expr ? lcid_expr->cval : 0, typelib_kind == SYS_WIN64 ? "win64" : "win32", id_part ); lcid_expr ? lcid_expr->cval : 0, pointer_size == 8 ? "win64" : "win32", id_part );
put_str( indent, "FLAGS = s '%u'\n", flags ); put_str( indent, "FLAGS = s '%u'\n", flags );
put_str( --indent, "}\n" ); put_str( --indent, "}\n" );
put_str( --indent, "}\n" ); put_str( --indent, "}\n" );
@ -319,6 +359,9 @@ void output_typelib_regscript( const typelib_t *typelib )
write_progids( typelib->stmts ); write_progids( typelib->stmts );
put_str( --indent, "}\n" ); put_str( --indent, "}\n" );
#ifdef __REACTOS__
add_output_to_resources( "WINE_REGISTRY", typelib_name ); add_output_to_resources( "WINE_REGISTRY", typelib_name );
#else
add_output_to_resources( "WINE_REGISTRY", resname );
#endif
} }

View file

@ -104,7 +104,7 @@ static void write_function_stub(const type_t *iface, const var_t *func, unsigned
write_parameters_init(server, indent, func, "__frame->"); write_parameters_init(server, indent, func, "__frame->");
if (explicit_fc == RPC_FC_BIND_PRIMITIVE) if (explicit_fc == FC_BIND_PRIMITIVE)
{ {
print_server("__frame->%s = _pRpcMessage->Handle;\n", handle_var->name); print_server("__frame->%s = _pRpcMessage->Handle;\n", handle_var->name);
fprintf(server, "\n"); fprintf(server, "\n");
@ -544,26 +544,6 @@ void write_server(const statement_list_t *stmts)
if (!server) if (!server)
return; return;
if (do_win32 && do_win64)
{
fprintf(server, "#ifndef _WIN64\n\n");
pointer_size = 4;
write_server_routines( stmts ); write_server_routines( stmts );
fprintf(server, "\n#else /* _WIN64 */\n\n");
pointer_size = 8;
write_server_routines( stmts );
fprintf(server, "\n#endif /* _WIN64 */\n");
}
else if (do_win32)
{
pointer_size = 4;
write_server_routines( stmts );
}
else if (do_win64)
{
pointer_size = 8;
write_server_routines( stmts );
}
fclose(server); fclose(server);
} }

File diff suppressed because it is too large Load diff

View file

@ -100,3 +100,4 @@ unsigned char get_basic_fc(const type_t *type);
unsigned char get_pointer_fc(const type_t *type, const attr_list_t *attrs, int toplevel_param); unsigned char get_pointer_fc(const type_t *type, const attr_list_t *attrs, int toplevel_param);
unsigned char get_struct_fc(const type_t *type); unsigned char get_struct_fc(const type_t *type);
enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *attrs, unsigned int flags); enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *attrs, unsigned int flags);
unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align);

View file

@ -48,7 +48,9 @@
#include "typelib_struct.h" #include "typelib_struct.h"
#include "typetree.h" #include "typetree.h"
#ifdef __REACTOS__
static typelib_t *typelib; static typelib_t *typelib;
#endif
/* List of oleauto types that should be recognized by name. /* List of oleauto types that should be recognized by name.
* (most of) these seem to be intrinsic types in mktyplib. * (most of) these seem to be intrinsic types in mktyplib.
@ -161,6 +163,7 @@ unsigned short get_type_vt(type_t *t)
else else
return VT_INT; return VT_INT;
case TYPE_BASIC_INT32: case TYPE_BASIC_INT32:
case TYPE_BASIC_LONG:
case TYPE_BASIC_ERROR_STATUS_T: case TYPE_BASIC_ERROR_STATUS_T:
if (type_basic_get_sign(t) > 0) if (type_basic_get_sign(t) > 0)
return VT_UI4; return VT_UI4;
@ -173,7 +176,7 @@ unsigned short get_type_vt(type_t *t)
else else
return VT_I8; return VT_I8;
case TYPE_BASIC_INT3264: case TYPE_BASIC_INT3264:
if (typelib_kind == SYS_WIN64) if (pointer_size == 8)
{ {
if (type_basic_get_sign(t) > 0) if (type_basic_get_sign(t) > 0)
return VT_UI8; return VT_UI8;
@ -204,10 +207,10 @@ unsigned short get_type_vt(type_t *t)
{ {
if (match(type_array_get_element(t)->name, "SAFEARRAY")) if (match(type_array_get_element(t)->name, "SAFEARRAY"))
return VT_SAFEARRAY; return VT_SAFEARRAY;
return VT_PTR;
} }
else else
error("get_type_vt: array types not supported\n"); return VT_CARRAY;
return VT_PTR;
case TYPE_INTERFACE: case TYPE_INTERFACE:
if(match(t->name, "IUnknown")) if(match(t->name, "IUnknown"))
@ -243,6 +246,7 @@ unsigned short get_type_vt(type_t *t)
return 0; return 0;
} }
#ifdef __REACTOS__
void start_typelib(typelib_t *typelib_type) void start_typelib(typelib_t *typelib_type)
{ {
if (!do_typelib) return; if (!do_typelib) return;
@ -253,11 +257,9 @@ void end_typelib(void)
{ {
if (!typelib) return; if (!typelib) return;
if (do_old_typelib)
create_sltg_typelib(typelib);
else
create_msft_typelib(typelib); create_msft_typelib(typelib);
} }
#endif
static void tlb_read(int fd, void *buf, int count) static void tlb_read(int fd, void *buf, int count)
{ {
@ -383,7 +385,11 @@ static void read_importlib(importlib_t *importlib)
close(fd); close(fd);
} }
#ifdef __REACTOS__
void add_importlib(const char *name) void add_importlib(const char *name)
#else
void add_importlib(const char *name, typelib_t *typelib)
#endif
{ {
importlib_t *importlib; importlib_t *importlib;

View file

@ -21,9 +21,13 @@
#ifndef __WIDL_TYPELIB_H #ifndef __WIDL_TYPELIB_H
#define __WIDL_TYPELIB_H #define __WIDL_TYPELIB_H
#ifdef __REACTOS__
extern void start_typelib(typelib_t *typelib_type); extern void start_typelib(typelib_t *typelib_type);
extern void end_typelib(void); extern void end_typelib(void);
extern void add_importlib(const char *name); extern void add_importlib(const char *name);
#else
extern void add_importlib(const char *name, typelib_t *typelib);
#endif
/* Copied from wtypes.h. Not included directly because that would create a /* Copied from wtypes.h. Not included directly because that would create a
* circular dependency (after all, wtypes.h is generated by widl...) */ * circular dependency (after all, wtypes.h is generated by widl...) */

View file

@ -377,6 +377,7 @@ static int is_valid_bitfield_type(const type_t *type)
case TYPE_BASIC_INT64: case TYPE_BASIC_INT64:
case TYPE_BASIC_INT: case TYPE_BASIC_INT:
case TYPE_BASIC_INT3264: case TYPE_BASIC_INT3264:
case TYPE_BASIC_LONG:
case TYPE_BASIC_CHAR: case TYPE_BASIC_CHAR:
case TYPE_BASIC_HYPER: case TYPE_BASIC_HYPER:
case TYPE_BASIC_BYTE: case TYPE_BASIC_BYTE:
@ -442,6 +443,8 @@ void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stm
iface->details.iface->disp_methods = NULL; iface->details.iface->disp_methods = NULL;
iface->details.iface->stmts = stmts; iface->details.iface->stmts = stmts;
iface->details.iface->inherit = inherit; iface->details.iface->inherit = inherit;
iface->details.iface->disp_inherit = NULL;
iface->details.iface->async_iface = NULL;
iface->defined = TRUE; iface->defined = TRUE;
compute_method_indexes(iface); compute_method_indexes(iface);
} }
@ -454,14 +457,24 @@ void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *met
iface->details.iface->stmts = NULL; iface->details.iface->stmts = NULL;
iface->details.iface->inherit = find_type("IDispatch", NULL, 0); iface->details.iface->inherit = find_type("IDispatch", NULL, 0);
if (!iface->details.iface->inherit) error_loc("IDispatch is undefined\n"); if (!iface->details.iface->inherit) error_loc("IDispatch is undefined\n");
iface->details.iface->disp_inherit = NULL;
iface->details.iface->async_iface = NULL;
iface->defined = TRUE; iface->defined = TRUE;
compute_method_indexes(iface); compute_method_indexes(iface);
} }
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface) void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
{ {
type_dispinterface_define(dispiface, iface->details.iface->disp_props, dispiface->details.iface = xmalloc(sizeof(*dispiface->details.iface));
iface->details.iface->disp_methods); dispiface->details.iface->disp_props = NULL;
dispiface->details.iface->disp_methods = NULL;
dispiface->details.iface->stmts = NULL;
dispiface->details.iface->inherit = find_type("IDispatch", NULL, 0);
if (!dispiface->details.iface->inherit) error_loc("IDispatch is undefined\n");
dispiface->details.iface->disp_inherit = iface;
dispiface->details.iface->async_iface = NULL;
dispiface->defined = TRUE;
compute_method_indexes(dispiface);
} }
void type_module_define(type_t *module, statement_list_t *stmts) void type_module_define(type_t *module, statement_list_t *stmts)

View file

@ -176,6 +176,13 @@ static inline var_list_t *type_dispiface_get_methods(const type_t *type)
return type->details.iface->disp_methods; return type->details.iface->disp_methods;
} }
static inline type_t *type_dispiface_get_inherit(const type_t *type)
{
type = type_get_real_type(type);
assert(type_get_type(type) == TYPE_INTERFACE);
return type->details.iface->disp_inherit;
}
static inline int type_is_defined(const type_t *type) static inline int type_is_defined(const type_t *type)
{ {
return type->defined; return type->defined;

View file

@ -43,14 +43,10 @@
#include "wine/wpp.h" #include "wine/wpp.h"
#include "header.h" #include "header.h"
/* future options to reserve characters for: */
/* A = ACF input filename */
/* J = do not search standard include path */
/* w = select win16/win32 output (?) */
static const char usage[] = static const char usage[] =
"Usage: widl [options...] infile.idl\n" "Usage: widl [options...] infile.idl\n"
" or: widl [options...] --dlldata-only name1 [name2...]\n" " or: widl [options...] --dlldata-only name1 [name2...]\n"
" --acf=file Use ACF file\n"
" -app_config Ignored, present for midl compatibility\n" " -app_config Ignored, present for midl compatibility\n"
" -b arch Set the target architecture\n" " -b arch Set the target architecture\n"
" -c Generate client stub\n" " -c Generate client stub\n"
@ -62,7 +58,7 @@ static const char usage[] =
" -H file Name of header file (default is infile.h)\n" " -H file Name of header file (default is infile.h)\n"
" -I path Set include search dir to path (multiple -I allowed)\n" " -I path Set include search dir to path (multiple -I allowed)\n"
" --local-stubs=file Write empty stubs for call_as/local methods to file\n" " --local-stubs=file Write empty stubs for call_as/local methods to file\n"
" -m32, -m64 Set the kind of typelib to build (Win32 or Win64)\n" " -m32, -m64 Set the target architecture (Win32 or Win64)\n"
" -N Do not preprocess input\n" " -N Do not preprocess input\n"
" --oldnames Use old naming conventions\n" " --oldnames Use old naming conventions\n"
" --oldtlb Use old typelib (SLTG) format\n" " --oldtlb Use old typelib (SLTG) format\n"
@ -73,6 +69,7 @@ static const char usage[] =
" --prefix-client=p Prefix names of client stubs with 'p'\n" " --prefix-client=p Prefix names of client stubs with 'p'\n"
" --prefix-server=p Prefix names of server functions with 'p'\n" " --prefix-server=p Prefix names of server functions with 'p'\n"
" -r Generate registration script\n" " -r Generate registration script\n"
" -robust Ignored, present for midl compatibility\n"
" --winrt Enable Windows Runtime mode\n" " --winrt Enable Windows Runtime mode\n"
" --ns_prefix Prefix namespaces with ABI namespace\n" " --ns_prefix Prefix namespaces with ABI namespace\n"
" -s Generate server stub\n" " -s Generate server stub\n"
@ -80,8 +77,7 @@ static const char usage[] =
" -u Generate interface identifiers file\n" " -u Generate interface identifiers file\n"
" -V Print version and exit\n" " -V Print version and exit\n"
" -W Enable pedantic warnings\n" " -W Enable pedantic warnings\n"
" --win32 Only generate 32-bit code\n" " --win32, --win64 Set the target architecture (Win32 or Win64)\n"
" --win64 Only generate 64-bit code\n"
" --win32-align n Set win32 structure alignment to 'n'\n" " --win32-align n Set win32 structure alignment to 'n'\n"
" --win64-align n Set win64 structure alignment to 'n'\n" " --win64-align n Set win64 structure alignment to 'n'\n"
"Debug level 'n' is a bitmask with following meaning:\n" "Debug level 'n' is a bitmask with following meaning:\n"
@ -96,6 +92,20 @@ static const char usage[] =
static const char version_string[] = "Wine IDL Compiler version " PACKAGE_VERSION "\n" static const char version_string[] = "Wine IDL Compiler version " PACKAGE_VERSION "\n"
"Copyright 2002 Ove Kaaven\n"; "Copyright 2002 Ove Kaaven\n";
#ifdef __i386__
enum target_cpu target_cpu = CPU_x86;
#elif defined(__x86_64__)
enum target_cpu target_cpu = CPU_x86_64;
#elif defined(__powerpc__)
enum target_cpu target_cpu = CPU_POWERPC;
#elif defined(__arm__)
enum target_cpu target_cpu = CPU_ARM;
#elif defined(__aarch64__)
enum target_cpu target_cpu = CPU_ARM64;
#else
#error Unsupported CPU
#endif
int debuglevel = DEBUGLEVEL_NONE; int debuglevel = DEBUGLEVEL_NONE;
int parser_debug, yy_flex_debug; int parser_debug, yy_flex_debug;
@ -113,8 +123,6 @@ int do_idfile = 0;
int do_dlldata = 0; int do_dlldata = 0;
static int no_preprocess = 0; static int no_preprocess = 0;
int old_names = 0; int old_names = 0;
int do_win32 = 1;
int do_win64 = 1;
int win32_packing = 8; int win32_packing = 8;
int win64_packing = 8; int win64_packing = 8;
int winrt_mode = 0; int winrt_mode = 0;
@ -123,6 +131,7 @@ static enum stub_mode stub_mode = MODE_Os;
char *input_name; char *input_name;
char *input_idl_name; char *input_idl_name;
char *acf_name;
char *header_name; char *header_name;
char *local_stubs_name; char *local_stubs_name;
char *header_token; char *header_token;
@ -146,49 +155,53 @@ int line_number = 1;
static FILE *idfile; static FILE *idfile;
unsigned int pointer_size = 0; unsigned int pointer_size = 0;
syskind_t typelib_kind = sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32;
time_t now; time_t now;
enum { enum {
OLDNAMES_OPTION = CHAR_MAX + 1, OLDNAMES_OPTION = CHAR_MAX + 1,
ACF_OPTION,
APP_CONFIG_OPTION,
DLLDATA_OPTION, DLLDATA_OPTION,
DLLDATA_ONLY_OPTION, DLLDATA_ONLY_OPTION,
LOCAL_STUBS_OPTION, LOCAL_STUBS_OPTION,
OLD_TYPELIB_OPTION,
PREFIX_ALL_OPTION, PREFIX_ALL_OPTION,
PREFIX_CLIENT_OPTION, PREFIX_CLIENT_OPTION,
PREFIX_SERVER_OPTION, PREFIX_SERVER_OPTION,
PRINT_HELP, PRINT_HELP,
RT_NS_PREFIX, RT_NS_PREFIX,
RT_OPTION, RT_OPTION,
ROBUST_OPTION,
WIN32_OPTION, WIN32_OPTION,
WIN64_OPTION, WIN64_OPTION,
WIN32_ALIGN_OPTION, WIN32_ALIGN_OPTION,
WIN64_ALIGN_OPTION, WIN64_ALIGN_OPTION
APP_CONFIG_OPTION,
OLD_TYPELIB_OPTION
}; };
static const char short_options[] = static const char short_options[] =
"b:cC:d:D:EhH:I:m:No:O:pP:rsS:tT:uU:VW"; "b:cC:d:D:EhH:I:m:No:O:pP:rsS:tT:uU:VW";
static const struct option long_options[] = { static const struct option long_options[] = {
{ "acf", 1, NULL, ACF_OPTION },
{ "app_config", 0, NULL, APP_CONFIG_OPTION },
{ "dlldata", 1, NULL, DLLDATA_OPTION }, { "dlldata", 1, NULL, DLLDATA_OPTION },
{ "dlldata-only", 0, NULL, DLLDATA_ONLY_OPTION }, { "dlldata-only", 0, NULL, DLLDATA_ONLY_OPTION },
{ "help", 0, NULL, PRINT_HELP }, { "help", 0, NULL, PRINT_HELP },
{ "local-stubs", 1, NULL, LOCAL_STUBS_OPTION }, { "local-stubs", 1, NULL, LOCAL_STUBS_OPTION },
{ "ns_prefix", 0, NULL, RT_NS_PREFIX }, { "ns_prefix", 0, NULL, RT_NS_PREFIX },
{ "oldnames", 0, NULL, OLDNAMES_OPTION }, { "oldnames", 0, NULL, OLDNAMES_OPTION },
{ "oldtlb", 0, NULL, OLD_TYPELIB_OPTION },
{ "output", 0, NULL, 'o' }, { "output", 0, NULL, 'o' },
{ "prefix-all", 1, NULL, PREFIX_ALL_OPTION }, { "prefix-all", 1, NULL, PREFIX_ALL_OPTION },
{ "prefix-client", 1, NULL, PREFIX_CLIENT_OPTION }, { "prefix-client", 1, NULL, PREFIX_CLIENT_OPTION },
{ "prefix-server", 1, NULL, PREFIX_SERVER_OPTION }, { "prefix-server", 1, NULL, PREFIX_SERVER_OPTION },
{ "robust", 0, NULL, ROBUST_OPTION },
{ "target", 0, NULL, 'b' },
{ "winrt", 0, NULL, RT_OPTION }, { "winrt", 0, NULL, RT_OPTION },
{ "win32", 0, NULL, WIN32_OPTION }, { "win32", 0, NULL, WIN32_OPTION },
{ "win64", 0, NULL, WIN64_OPTION }, { "win64", 0, NULL, WIN64_OPTION },
{ "win32-align", 1, NULL, WIN32_ALIGN_OPTION }, { "win32-align", 1, NULL, WIN32_ALIGN_OPTION },
{ "win64-align", 1, NULL, WIN64_ALIGN_OPTION }, { "win64-align", 1, NULL, WIN64_ALIGN_OPTION },
{ "app_config", 0, NULL, APP_CONFIG_OPTION },
{ "oldtlb", 0, NULL, OLD_TYPELIB_OPTION },
{ NULL, 0, NULL, 0 } { NULL, 0, NULL, 0 }
}; };
@ -266,19 +279,23 @@ static void set_target( const char *target )
static const struct static const struct
{ {
const char *name; const char *name;
syskind_t kind; enum target_cpu cpu;
} cpu_names[] = } cpu_names[] =
{ {
{ "i386", SYS_WIN32 }, { "i386", CPU_x86 },
{ "i486", SYS_WIN32 }, { "i486", CPU_x86 },
{ "i586", SYS_WIN32 }, { "i586", CPU_x86 },
{ "i686", SYS_WIN32 }, { "i686", CPU_x86 },
{ "i786", SYS_WIN32 }, { "i786", CPU_x86 },
{ "amd64", SYS_WIN64 }, { "amd64", CPU_x86_64 },
{ "x86_64", SYS_WIN64 }, { "x86_64", CPU_x86_64 },
{ "powerpc", SYS_WIN32 }, { "powerpc", CPU_POWERPC },
{ "arm", SYS_WIN32 }, { "arm", CPU_ARM },
{ "aarch64", SYS_WIN64 } { "armv5", CPU_ARM },
{ "armv6", CPU_ARM },
{ "armv7", CPU_ARM },
{ "arm64", CPU_ARM64 },
{ "aarch64", CPU_ARM64 },
}; };
unsigned int i; unsigned int i;
@ -292,7 +309,7 @@ static void set_target( const char *target )
{ {
if (!strcmp( cpu_names[i].name, spec )) if (!strcmp( cpu_names[i].name, spec ))
{ {
typelib_kind = cpu_names[i].kind; target_cpu = cpu_names[i].cpu;
free( spec ); free( spec );
return; return;
} }
@ -487,6 +504,11 @@ static void write_id_data_stmts(const statement_list_t *stmts)
uuid = get_attrp(type->attrs, ATTR_UUID); uuid = get_attrp(type->attrs, ATTR_UUID);
write_id_guid(idfile, "IID", is_attr(type->attrs, ATTR_DISPINTERFACE) ? "DIID" : "IID", write_id_guid(idfile, "IID", is_attr(type->attrs, ATTR_DISPINTERFACE) ? "DIID" : "IID",
type->name, uuid); type->name, uuid);
if (type->details.iface->async_iface)
{
uuid = get_attrp(type->details.iface->async_iface->attrs, ATTR_UUID);
write_id_guid(idfile, "IID", "IID", type->details.iface->async_iface->name, uuid);
}
} }
else if (type_get_type(type) == TYPE_COCLASS) else if (type_get_type(type) == TYPE_COCLASS)
{ {
@ -537,10 +559,15 @@ void write_id_data(const statement_list_t *stmts)
fprintf(idfile, "#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \\\n"); fprintf(idfile, "#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \\\n");
fprintf(idfile, " DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)\n\n"); fprintf(idfile, " DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)\n\n");
fprintf(idfile, "#elif defined(__cplusplus)\n\n");
fprintf(idfile, "#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \\\n");
fprintf(idfile, " EXTERN_C const type DECLSPEC_SELECTANY name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}\n\n");
fprintf(idfile, "#else\n\n"); fprintf(idfile, "#else\n\n");
fprintf(idfile, "#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \\\n"); fprintf(idfile, "#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \\\n");
fprintf(idfile, " const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}\n\n"); fprintf(idfile, " const type DECLSPEC_SELECTANY name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}\n\n");
fprintf(idfile, "#endif\n\n"); fprintf(idfile, "#endif\n\n");
start_cplusplus_guard(idfile); start_cplusplus_guard(idfile);
@ -605,12 +632,10 @@ int main(int argc,char *argv[])
use_abi_namespace = 1; use_abi_namespace = 1;
break; break;
case WIN32_OPTION: case WIN32_OPTION:
do_win32 = 1; pointer_size = 4;
do_win64 = 0;
break; break;
case WIN64_OPTION: case WIN64_OPTION:
do_win32 = 0; pointer_size = 8;
do_win64 = 1;
break; break;
case WIN32_ALIGN_OPTION: case WIN32_ALIGN_OPTION:
win32_packing = strtol(optarg, NULL, 0); win32_packing = strtol(optarg, NULL, 0);
@ -622,10 +647,16 @@ int main(int argc,char *argv[])
if(win64_packing != 2 && win64_packing != 4 && win64_packing != 8) if(win64_packing != 2 && win64_packing != 4 && win64_packing != 8)
error("Packing must be one of 2, 4 or 8\n"); error("Packing must be one of 2, 4 or 8\n");
break; break;
case ACF_OPTION:
acf_name = xstrdup(optarg);
break;
case APP_CONFIG_OPTION: case APP_CONFIG_OPTION:
/* widl does not distinguish between app_mode and default mode, /* widl does not distinguish between app_mode and default mode,
but we ignore this option for midl compatibility */ but we ignore this option for midl compatibility */
break; break;
case ROBUST_OPTION:
/* FIXME: Support robust option */
break;
case 'b': case 'b':
set_target( optarg ); set_target( optarg );
break; break;
@ -657,8 +688,8 @@ int main(int argc,char *argv[])
wpp_add_include_path(optarg); wpp_add_include_path(optarg);
break; break;
case 'm': case 'm':
if (!strcmp( optarg, "32" )) typelib_kind = SYS_WIN32; if (!strcmp( optarg, "32" )) pointer_size = 4;
else if (!strcmp( optarg, "64" )) typelib_kind = SYS_WIN64; else if (!strcmp( optarg, "64" )) pointer_size = 8;
break; break;
case 'N': case 'N':
no_preprocess = 1; no_preprocess = 1;
@ -725,6 +756,26 @@ int main(int argc,char *argv[])
wpp_add_include_path(DEFAULT_INCLUDE_DIR); wpp_add_include_path(DEFAULT_INCLUDE_DIR);
#endif #endif
switch (target_cpu)
{
case CPU_x86:
if (pointer_size == 8) target_cpu = CPU_x86_64;
else pointer_size = 4;
break;
case CPU_x86_64:
if (pointer_size == 4) target_cpu = CPU_x86;
else pointer_size = 8;
break;
case CPU_ARM64:
if (pointer_size == 4) error( "Cannot build 32-bit code for this CPU\n" );
pointer_size = 8;
break;
default:
if (pointer_size == 8) error( "Cannot build 64-bit code for this CPU\n" );
pointer_size = 4;
break;
}
/* if nothing specified, try to guess output type from the output file name */ /* if nothing specified, try to guess output type from the output file name */
if (output_name && do_everything && !do_header && !do_typelib && !do_proxies && if (output_name && do_everything && !do_header && !do_typelib && !do_proxies &&
!do_client && !do_server && !do_regscript && !do_idfile && !do_dlldata) !do_client && !do_server && !do_regscript && !do_idfile && !do_dlldata)

View file

@ -46,8 +46,6 @@ extern int do_regscript;
extern int do_idfile; extern int do_idfile;
extern int do_dlldata; extern int do_dlldata;
extern int old_names; extern int old_names;
extern int do_win32;
extern int do_win64;
extern int win32_packing; extern int win32_packing;
extern int win64_packing; extern int win64_packing;
extern int winrt_mode; extern int winrt_mode;
@ -55,6 +53,7 @@ extern int use_abi_namespace;
extern char *input_name; extern char *input_name;
extern char *input_idl_name; extern char *input_idl_name;
extern char *acf_name;
extern char *header_name; extern char *header_name;
extern char *header_token; extern char *header_token;
extern char *local_stubs_name; extern char *local_stubs_name;
@ -76,6 +75,13 @@ extern time_t now;
extern int line_number; extern int line_number;
extern int char_number; extern int char_number;
enum target_cpu
{
CPU_x86, CPU_x86_64, CPU_POWERPC, CPU_ARM, CPU_ARM64, CPU_LAST = CPU_ARM64
};
extern enum target_cpu target_cpu;
enum stub_mode enum stub_mode
{ {
MODE_Os, /* inline stubs */ MODE_Os, /* inline stubs */
@ -90,6 +96,9 @@ extern void write_proxies(const statement_list_t *stmts);
extern void write_client(const statement_list_t *stmts); extern void write_client(const statement_list_t *stmts);
extern void write_server(const statement_list_t *stmts); extern void write_server(const statement_list_t *stmts);
extern void write_regscript(const statement_list_t *stmts); extern void write_regscript(const statement_list_t *stmts);
#ifndef __REACTOS__
extern void write_typelib_regscript(const statement_list_t *stmts);
#endif
extern void output_typelib_regscript( const typelib_t *typelib ); extern void output_typelib_regscript( const typelib_t *typelib );
extern void write_local_stubs(const statement_list_t *stmts); extern void write_local_stubs(const statement_list_t *stmts);
extern void write_dlldata(const statement_list_t *stmts); extern void write_dlldata(const statement_list_t *stmts);

View file

@ -24,7 +24,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <assert.h> #include <assert.h>
#include "guiddef.h" #include "guiddef.h"
#include "wine/rpcfc.h" #include "ndrtypes.h"
#include "wine/list.h" #include "wine/list.h"
#ifndef UUID_DEFINED #ifndef UUID_DEFINED
@ -59,7 +59,6 @@ typedef struct list expr_list_t;
typedef struct list var_list_t; typedef struct list var_list_t;
typedef struct list declarator_list_t; typedef struct list declarator_list_t;
typedef struct list ifref_list_t; typedef struct list ifref_list_t;
typedef struct list array_dims_t;
typedef struct list user_type_list_t; typedef struct list user_type_list_t;
typedef struct list context_handle_list_t; typedef struct list context_handle_list_t;
typedef struct list generic_handle_list_t; typedef struct list generic_handle_list_t;
@ -266,6 +265,7 @@ enum type_basic_type
TYPE_BASIC_INT64, TYPE_BASIC_INT64,
TYPE_BASIC_INT, TYPE_BASIC_INT,
TYPE_BASIC_INT3264, TYPE_BASIC_INT3264,
TYPE_BASIC_LONG,
TYPE_BASIC_CHAR, TYPE_BASIC_CHAR,
TYPE_BASIC_HYPER, TYPE_BASIC_HYPER,
TYPE_BASIC_BYTE, TYPE_BASIC_BYTE,
@ -343,6 +343,8 @@ struct iface_details
var_list_t *disp_methods; var_list_t *disp_methods;
var_list_t *disp_props; var_list_t *disp_props;
struct _type_t *inherit; struct _type_t *inherit;
struct _type_t *disp_inherit;
struct _type_t *async_iface;
}; };
struct module_details struct module_details
@ -464,7 +466,6 @@ struct _declarator_t {
var_t *var; var_t *var;
type_t *type; type_t *type;
type_t *func_type; type_t *func_type;
array_dims_t *array;
expr_t *bits; expr_t *bits;
/* parser-internal */ /* parser-internal */
@ -552,7 +553,6 @@ typedef enum {
SYS_WIN64 SYS_WIN64
} syskind_t; } syskind_t;
extern syskind_t typelib_kind;
extern user_type_list_t user_type_list; extern user_type_list_t user_type_list;
extern context_handle_list_t context_handle_list; extern context_handle_list_t context_handle_list;
extern generic_handle_list_t generic_handle_list; extern generic_handle_list_t generic_handle_list;

View file

@ -57,6 +57,7 @@
#include "hash.h" #include "hash.h"
#include "typetree.h" #include "typetree.h"
#include "parser.h" #include "parser.h"
#include "typegen.h"
#ifdef __REACTOS__ #ifdef __REACTOS__
#define S_OK 0 #define S_OK 0
@ -791,8 +792,6 @@ static int encode_type(
int vt, /* [I] vt to encode */ int vt, /* [I] vt to encode */
type_t *type, /* [I] type */ type_t *type, /* [I] type */
int *encoded_type, /* [O] The encoded type description. */ int *encoded_type, /* [O] The encoded type description. */
int *width, /* [O] The width of the type, or NULL. */
int *alignment, /* [O] The alignment of the type, or NULL. */
int *decoded_size) /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */ int *decoded_size) /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */
{ {
int default_type; int default_type;
@ -805,8 +804,6 @@ static int encode_type(
chat("encode_type vt %d type %p\n", vt, type); chat("encode_type vt %d type %p\n", vt, type);
default_type = 0x80000000 | (vt << 16) | vt; default_type = 0x80000000 | (vt << 16) | vt;
if (!width) width = &scratch;
if (!alignment) alignment = &scratch;
if (!decoded_size) decoded_size = &scratch; if (!decoded_size) decoded_size = &scratch;
*decoded_size = 0; *decoded_size = 0;
@ -815,38 +812,20 @@ static int encode_type(
case VT_I1: case VT_I1:
case VT_UI1: case VT_UI1:
*encoded_type = default_type; *encoded_type = default_type;
*width = 1;
*alignment = 1;
break; break;
case VT_INT: case VT_INT:
*encoded_type = 0x80000000 | (VT_I4 << 16) | VT_INT; *encoded_type = 0x80000000 | (VT_I4 << 16) | VT_INT;
if ((typelib->typelib_header.varflags & 0x0f) == SYS_WIN16) {
*width = 2;
*alignment = 2;
} else {
*width = 4;
*alignment = 4;
}
break; break;
case VT_UINT: case VT_UINT:
*encoded_type = 0x80000000 | (VT_UI4 << 16) | VT_UINT; *encoded_type = 0x80000000 | (VT_UI4 << 16) | VT_UINT;
if ((typelib->typelib_header.varflags & 0x0f) == SYS_WIN16) {
*width = 2;
*alignment = 2;
} else {
*width = 4;
*alignment = 4;
}
break; break;
case VT_UI2: case VT_UI2:
case VT_I2: case VT_I2:
case VT_BOOL: case VT_BOOL:
*encoded_type = default_type; *encoded_type = default_type;
*width = 2;
*alignment = 2;
break; break;
case VT_I4: case VT_I4:
@ -855,56 +834,40 @@ static int encode_type(
case VT_ERROR: case VT_ERROR:
case VT_HRESULT: case VT_HRESULT:
*encoded_type = default_type; *encoded_type = default_type;
*width = 4;
*alignment = 4;
break; break;
case VT_R8: case VT_R8:
case VT_I8: case VT_I8:
case VT_UI8: case VT_UI8:
*encoded_type = default_type; *encoded_type = default_type;
*width = 8;
*alignment = 8;
break; break;
case VT_CY: case VT_CY:
case VT_DATE: case VT_DATE:
*encoded_type = default_type; *encoded_type = default_type;
*width = 8;
*alignment = 8;
break; break;
case VT_DECIMAL: case VT_DECIMAL:
*encoded_type = default_type; *encoded_type = default_type;
*width = 16;
*alignment = 8;
break; break;
case VT_VOID: case VT_VOID:
*encoded_type = 0x80000000 | (VT_EMPTY << 16) | vt; *encoded_type = 0x80000000 | (VT_EMPTY << 16) | vt;
*width = 0;
*alignment = 1;
break; break;
case VT_UNKNOWN: case VT_UNKNOWN:
case VT_DISPATCH: case VT_DISPATCH:
case VT_BSTR: case VT_BSTR:
*encoded_type = default_type; *encoded_type = default_type;
*width = pointer_size;
*alignment = 4;
break; break;
case VT_VARIANT: case VT_VARIANT:
*encoded_type = default_type; *encoded_type = default_type;
*width = 8 + 2 * pointer_size;
*alignment = 8;
break; break;
case VT_LPSTR: case VT_LPSTR:
case VT_LPWSTR: case VT_LPWSTR:
*encoded_type = 0xfffe0000 | vt; *encoded_type = 0xfffe0000 | vt;
*width = pointer_size;
*alignment = 4;
break; break;
case VT_PTR: case VT_PTR:
@ -920,14 +883,12 @@ static int encode_type(
next_vt = VT_VOID; next_vt = VT_VOID;
encode_type(typelib, next_vt, type_pointer_get_ref(type), encode_type(typelib, next_vt, type_pointer_get_ref(type),
&target_type, NULL, NULL, &child_size); &target_type, &child_size);
/* these types already have an implicit pointer, so we don't need to /* these types already have an implicit pointer, so we don't need to
* add another */ * add another */
if(next_vt == VT_DISPATCH || next_vt == VT_UNKNOWN) { if(next_vt == VT_DISPATCH || next_vt == VT_UNKNOWN) {
chat("encode_type: skipping ptr\n"); chat("encode_type: skipping ptr\n");
*encoded_type = target_type; *encoded_type = target_type;
*width = pointer_size;
*alignment = 4;
*decoded_size = child_size; *decoded_size = child_size;
break; break;
} }
@ -956,8 +917,6 @@ static int encode_type(
*encoded_type = typeoffset; *encoded_type = typeoffset;
*width = pointer_size;
*alignment = 4;
*decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size; *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size;
break; break;
} }
@ -967,7 +926,8 @@ static int encode_type(
type_t *element_type = type_alias_get_aliasee(type_array_get_element(type)); type_t *element_type = type_alias_get_aliasee(type_array_get_element(type));
int next_vt = get_type_vt(element_type); int next_vt = get_type_vt(element_type);
encode_type(typelib, next_vt, type_alias_get_aliasee(type_array_get_element(type)), &target_type, NULL, NULL, &child_size); encode_type(typelib, next_vt, type_alias_get_aliasee(type_array_get_element(type)),
&target_type, &child_size);
for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
@ -993,26 +953,39 @@ static int encode_type(
*encoded_type = typeoffset; *encoded_type = typeoffset;
*width = pointer_size;
*alignment = 4;
*decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size; *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size;
break; break;
} }
case VT_USERDEFINED: case VT_USERDEFINED:
{ {
importinfo_t *importinfo;
int typeinfo_offset; int typeinfo_offset;
if (type->typelib_idx > -1)
{
chat("encode_type: VT_USERDEFINED - found already defined type %s at %d\n",
type->name, type->typelib_idx);
typeinfo_offset = typelib->typelib_typeinfo_offsets[type->typelib_idx];
}
else if ((importinfo = find_importinfo(typelib, type->name)))
{
chat("encode_type: VT_USERDEFINED - found imported type %s in %s\n",
type->name, importinfo->importlib->name);
alloc_importinfo(typelib, importinfo);
typeinfo_offset = importinfo->offset | 0x1;
}
else
{
/* typedef'd types without public attribute aren't included in the typelib */ /* typedef'd types without public attribute aren't included in the typelib */
while (type->typelib_idx < 0 && type_is_alias(type) && !is_attr(type->attrs, ATTR_PUBLIC)) while (type_is_alias(type) && !is_attr(type->attrs, ATTR_PUBLIC))
type = type_alias_get_aliasee(type); type = type_alias_get_aliasee(type);
chat("encode_type: VT_USERDEFINED - type %p name = %s real type %d idx %d\n", type, chat("encode_type: VT_USERDEFINED - adding new type %s, real type %d\n",
type->name, type_get_type(type), type->typelib_idx); type->name, type_get_type(type));
if(type->typelib_idx == -1) { switch (type_get_type(type))
chat("encode_type: trying to ref not added type\n"); {
switch (type_get_type(type)) {
case TYPE_STRUCT: case TYPE_STRUCT:
add_structure_typeinfo(typelib, type); add_structure_typeinfo(typelib, type);
break; break;
@ -1032,9 +1005,9 @@ static int encode_type(
error("encode_type: VT_USERDEFINED - unhandled type %d\n", error("encode_type: VT_USERDEFINED - unhandled type %d\n",
type_get_type(type)); type_get_type(type));
} }
}
typeinfo_offset = typelib->typelib_typeinfo_offsets[type->typelib_idx]; typeinfo_offset = typelib->typelib_typeinfo_offsets[type->typelib_idx];
}
for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) { for (typeoffset = 0; typeoffset < typelib->typelib_segdir[MSFT_SEG_TYPEDESC].length; typeoffset += 8) {
typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset]; typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
if ((typedata[0] == ((0x7fff << 16) | VT_USERDEFINED)) && (typedata[1] == typeinfo_offset)) break; if ((typedata[0] == ((0x7fff << 16) | VT_USERDEFINED)) && (typedata[1] == typeinfo_offset)) break;
@ -1049,16 +1022,12 @@ static int encode_type(
} }
*encoded_type = typeoffset; *encoded_type = typeoffset;
*width = 0;
*alignment = 1;
break; break;
} }
default: default:
error("encode_type: unrecognized type %d.\n", vt); error("encode_type: unrecognized type %d.\n", vt);
*encoded_type = default_type; *encoded_type = default_type;
*width = 0;
*alignment = 1;
break; break;
} }
@ -1075,8 +1044,6 @@ static int encode_var(
type_t *type, /* [I] The type description to encode. */ type_t *type, /* [I] The type description to encode. */
var_t *var, /* [I] The var to encode. */ var_t *var, /* [I] The var to encode. */
int *encoded_type, /* [O] The encoded type description. */ int *encoded_type, /* [O] The encoded type description. */
int *width, /* [O] The width of the type, or NULL. */
int *alignment, /* [O] The alignment of the type, or NULL. */
int *decoded_size) /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */ int *decoded_size) /* [O] The total size of the unencoded TYPEDESCs, including nested descs. */
{ {
int typeoffset; int typeoffset;
@ -1086,8 +1053,6 @@ static int encode_var(
int vt; int vt;
int scratch; int scratch;
if (!width) width = &scratch;
if (!alignment) alignment = &scratch;
if (!decoded_size) decoded_size = &scratch; if (!decoded_size) decoded_size = &scratch;
*decoded_size = 0; *decoded_size = 0;
@ -1106,7 +1071,7 @@ static int encode_var(
++num_dims; ++num_dims;
chat("array with %d dimensions\n", num_dims); chat("array with %d dimensions\n", num_dims);
encode_var(typelib, atype, var, &target_type, width, alignment, NULL); encode_var(typelib, atype, var, &target_type, NULL);
arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(int), 0); arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(int), 0);
arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset]; arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];
@ -1132,7 +1097,6 @@ static int encode_var(
typedata[1] = arrayoffset; typedata[1] = arrayoffset;
*encoded_type = typeoffset; *encoded_type = typeoffset;
*width = *width * elements;
*decoded_size = 20 /*sizeof(ARRAYDESC)*/ + (num_dims - 1) * 8 /*sizeof(SAFEARRAYBOUND)*/; *decoded_size = 20 /*sizeof(ARRAYDESC)*/ + (num_dims - 1) * 8 /*sizeof(SAFEARRAYBOUND)*/;
return 0; return 0;
} }
@ -1141,15 +1105,12 @@ static int encode_var(
if (vt == VT_PTR) { if (vt == VT_PTR) {
type_t *ref = is_ptr(type) ? type_t *ref = is_ptr(type) ?
type_pointer_get_ref(type) : type_array_get_element(type); type_pointer_get_ref(type) : type_array_get_element(type);
int skip_ptr = encode_var(typelib, ref, var, int skip_ptr = encode_var(typelib, ref, var, &target_type, &child_size);
&target_type, NULL, NULL, &child_size);
if(skip_ptr == 2) { if(skip_ptr == 2) {
chat("encode_var: skipping ptr\n"); chat("encode_var: skipping ptr\n");
*encoded_type = target_type; *encoded_type = target_type;
*decoded_size = child_size; *decoded_size = child_size;
*width = pointer_size;
*alignment = 4;
return 0; return 0;
} }
@ -1163,7 +1124,7 @@ static int encode_var(
if (target_type & 0x80000000) { if (target_type & 0x80000000) {
mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF; mix_field = ((target_type >> 16) & 0x3fff) | VT_BYREF;
} else if (is_array(ref)) { } else if (get_type_vt(ref) == VT_SAFEARRAY) {
type_t *element_type = type_alias_get_aliasee(type_array_get_element(ref)); type_t *element_type = type_alias_get_aliasee(type_array_get_element(ref));
mix_field = get_type_vt(element_type) | VT_ARRAY | VT_BYREF; mix_field = get_type_vt(element_type) | VT_ARRAY | VT_BYREF;
} else { } else {
@ -1180,15 +1141,13 @@ static int encode_var(
*encoded_type = typeoffset; *encoded_type = typeoffset;
*width = pointer_size;
*alignment = 4;
*decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size; *decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size;
return 0; return 0;
} }
dump_type(type); dump_type(type);
encode_type(typelib, vt, type, encoded_type, width, alignment, decoded_size); encode_type(typelib, vt, type, encoded_type, decoded_size);
/* these types already have an implicit pointer, so we don't need to /* these types already have an implicit pointer, so we don't need to
* add another */ * add another */
if(vt == VT_DISPATCH || vt == VT_UNKNOWN) return 2; if(vt == VT_DISPATCH || vt == VT_UNKNOWN) return 2;
@ -1210,8 +1169,59 @@ static unsigned int get_ulong_val(unsigned int val, int vt)
return val; return val;
} }
static void write_value(msft_typelib_t* typelib, int *out, int vt, const void *value) static void write_int_value(msft_typelib_t *typelib, int *out, int vt, int value)
{ {
const unsigned int lv = get_ulong_val(value, vt);
if ((lv & 0x3ffffff) == lv) {
*out = 0x80000000;
*out |= vt << 26;
*out |= lv;
} else {
int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, 8, 0);
*((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt;
memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2], &value, 4);
*((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6]) = 0x5757;
*out = offset;
}
}
static void write_string_value(msft_typelib_t *typelib, int *out, const char *value)
{
int len = strlen(value), seg_len = (len + 6 + 3) & ~0x3;
int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, seg_len, 0);
*((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = VT_BSTR;
memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2], &len, sizeof(len));
memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6], value, len);
len += 6;
while(len < seg_len) {
*((char *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+len]) = 0x57;
len++;
}
*out = offset;
}
static void write_default_value(msft_typelib_t *typelib, type_t *type, expr_t *expr, int *out)
{
int vt;
if (expr->type == EXPR_STRLIT || expr->type == EXPR_WSTRLIT) {
if (get_type_vt(type) != VT_BSTR)
error("string default value applied to non-string type\n");
chat("default value '%s'\n", expr->u.sval);
write_string_value(typelib, out, expr->u.sval);
return;
}
if (type_get_type(type) == TYPE_ENUM) {
vt = VT_I4;
} else if (is_ptr(type)) {
vt = get_type_vt(type_pointer_get_ref(type));
if (vt == VT_USERDEFINED)
vt = VT_I4;
if (expr->cval)
warning("non-null pointer default value\n");
} else {
vt = get_type_vt(type);
switch(vt) { switch(vt) {
case VT_I2: case VT_I2:
case VT_I4: case VT_I4:
@ -1224,46 +1234,15 @@ static void write_value(msft_typelib_t* typelib, int *out, int vt, const void *v
case VT_INT: case VT_INT:
case VT_UINT: case VT_UINT:
case VT_HRESULT: case VT_HRESULT:
case VT_PTR: break;
case VT_UNKNOWN:
case VT_DISPATCH:
{
const unsigned int lv = get_ulong_val(*(const unsigned int *)value, vt);
if((lv & 0x3ffffff) == lv) {
*out = 0x80000000;
*out |= vt << 26;
*out |= lv;
} else {
int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, 8, 0);
*((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt;
memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2], value, 4);
*((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6]) = 0x5757;
*out = offset;
}
return;
}
case VT_BSTR:
{
const char *s = (const char *) value;
int len = strlen(s), seg_len = (len + 6 + 3) & ~0x3;
int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, seg_len, 0);
*((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt;
memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+2], &len, sizeof(len));
memcpy(&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+6], value, len);
len += 6;
while(len < seg_len) {
*((char *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset+len]) = 0x57;
len++;
}
*out = offset;
return;
}
default: default:
warning("can't write value of type %d yet\n", vt); warning("can't write value of type %d yet\n", vt);
}
return; return;
} }
}
write_int_value(typelib, out, vt, expr->cval);
}
static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid, static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid,
int vt, const void *value, int *offset) int vt, const void *value, int *offset)
@ -1280,7 +1259,10 @@ static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid,
guidentry.next_hash = -1; guidentry.next_hash = -1;
guidoffset = ctl2_alloc_guid(typelib, &guidentry); guidoffset = ctl2_alloc_guid(typelib, &guidentry);
write_value(typelib, &data_out, vt, value); if(vt == VT_BSTR)
write_string_value(typelib, &data_out, value);
else
write_int_value(typelib, &data_out, vt, *(int*)value);
custoffset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATAGUID, 12, 0); custoffset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATAGUID, 12, 0);
@ -1293,33 +1275,6 @@ static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid,
return S_OK; return S_OK;
} }
/* It's possible to have a default value for pointer arguments too.
In this case default value has a referenced type, e.g.
'LONG*' argument gets VT_I4, 'DOUBLE*' - VT_R8. IUnknown* and IDispatch*
are recognised too and stored as VT_UNKNOWN and VT_DISPATCH.
But IUnknown/IDispatch arguments can only have default value of 0
(or expression that resolves to zero) while other pointers can have
any default value. */
static int get_defaultvalue_vt(type_t *type)
{
int vt;
if (type_get_type(type) == TYPE_ENUM)
vt = VT_I4;
else
{
vt = get_type_vt(type);
if (vt == VT_PTR && is_ptr(type)) {
vt = get_type_vt(type_pointer_get_ref(type));
/* The only acceptable value for pointers to non-basic types
is NULL, it's stored as VT_I4 for both 32 and 64 bit typelibs. */
if (vt == VT_USERDEFINED)
vt = VT_I4;
}
}
return vt;
}
static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index) static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
{ {
int offset, name_offset; int offset, name_offset;
@ -1500,7 +1455,8 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
/* 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, type_function_get_rettype(func->type), func, &typedata[1], NULL, NULL, &decoded_size); encode_var(typeinfo->typelib, type_function_get_rettype(func->type), func,
&typedata[1], &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;
@ -1537,26 +1493,13 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index)
if(defaultdata) *defaultdata = -1; if(defaultdata) *defaultdata = -1;
encode_var(typeinfo->typelib, arg->type, arg, paramdata, NULL, NULL, &decoded_size); encode_var(typeinfo->typelib, arg->type, arg, paramdata, &decoded_size);
if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) { if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
switch(attr->type) { switch(attr->type) {
case ATTR_DEFAULTVALUE: case ATTR_DEFAULTVALUE:
{ {
int vt;
expr_t *expr = (expr_t *)attr->u.pval;
vt = get_defaultvalue_vt(arg->type);
paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */ paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */
if (expr->type == EXPR_STRLIT || expr->type == EXPR_WSTRLIT) write_default_value(typeinfo->typelib, arg->type, (expr_t *)attr->u.pval, defaultdata);
{
if (vt != VT_BSTR) error("string default value applied to non-string type\n");
chat("default value '%s'\n", expr->u.sval);
write_value(typeinfo->typelib, defaultdata, vt, expr->u.sval);
}
else
{
chat("default value %d\n", expr->cval);
write_value(typeinfo->typelib, defaultdata, vt, &expr->cval);
}
break; break;
} }
case ATTR_IN: case ATTR_IN:
@ -1663,8 +1606,7 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
int offset, id; int offset, id;
unsigned int typedata_size; unsigned int typedata_size;
INT *typedata; INT *typedata;
int var_datawidth; unsigned int var_datawidth, var_alignment = 0;
int var_alignment;
int var_type_size, var_kind = 0 /* VAR_PERINSTANCE */; int var_type_size, var_kind = 0 /* VAR_PERINSTANCE */;
int alignment; int alignment;
int varflags = 0; int varflags = 0;
@ -1766,8 +1708,8 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
typeinfo->var_offsets[var_num] = offset; typeinfo->var_offsets[var_num] = offset;
/* figure out type widths and whatnot */ /* figure out type widths and whatnot */
encode_var(typeinfo->typelib, var->type, var, &typedata[1], &var_datawidth, var_datawidth = type_memsize_and_alignment(var->type, &var_alignment);
&var_alignment, &var_type_size); encode_var(typeinfo->typelib, var->type, var, &typedata[1], &var_type_size);
/* pad out starting position to data width */ /* pad out starting position to data width */
typeinfo->datawidth += var_alignment - 1; typeinfo->datawidth += var_alignment - 1;
@ -1775,7 +1717,7 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
switch(typeinfo->typekind) { switch(typeinfo->typekind) {
case TKIND_ENUM: case TKIND_ENUM:
write_value(typeinfo->typelib, &typedata[4], VT_I4, &var->eval->cval); write_int_value(typeinfo->typelib, &typedata[4], VT_I4, var->eval->cval);
var_kind = 2; /* VAR_CONST */ var_kind = 2; /* VAR_CONST */
var_type_size += 16; /* sizeof(VARIANT) */ var_type_size += 16; /* sizeof(VARIANT) */
typeinfo->datawidth = var_datawidth; typeinfo->datawidth = var_datawidth;
@ -1791,7 +1733,6 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
case TKIND_DISPATCH: case TKIND_DISPATCH:
var_kind = 3; /* VAR_DISPATCH */ var_kind = 3; /* VAR_DISPATCH */
typeinfo->datawidth = pointer_size; typeinfo->datawidth = pointer_size;
var_alignment = 4;
break; break;
default: default:
error("add_var_desc: unhandled type kind %d\n", typeinfo->typekind); error("add_var_desc: unhandled type kind %d\n", typeinfo->typekind);
@ -2038,11 +1979,29 @@ static void add_dispatch(msft_typelib_t *typelib)
static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface) static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinterface)
{ {
int num_parents = 0, num_funcs = 0;
importinfo_t *importinfo = NULL;
const statement_t *stmt_func;
type_t *inherit, *ref;
int idx = 0; int idx = 0;
var_t *func; var_t *func;
var_t *var; var_t *var;
msft_typeinfo_t *msft_typeinfo; msft_typeinfo_t *msft_typeinfo;
if (-1 < dispinterface->typelib_idx)
return;
inherit = type_dispiface_get_inherit(dispinterface);
if (inherit)
{
importinfo = find_importinfo(typelib, inherit->name);
if (!importinfo && type_iface_get_inherit(inherit) && inherit->typelib_idx == -1)
add_interface_typeinfo(typelib, inherit);
}
/* check typelib_idx again, it could have been added while resolving the parent interface */
if (-1 < dispinterface->typelib_idx) if (-1 < dispinterface->typelib_idx)
return; return;
@ -2051,11 +2010,31 @@ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinte
dispinterface->attrs); dispinterface->attrs);
msft_typeinfo->typeinfo->size = pointer_size; msft_typeinfo->typeinfo->size = pointer_size;
msft_typeinfo->typeinfo->typekind |= 0x2100; msft_typeinfo->typeinfo->typekind |= pointer_size << 11 | pointer_size << 6;
msft_typeinfo->typeinfo->flags |= 0x1000; /* TYPEFLAG_FDISPATCHABLE */ msft_typeinfo->typeinfo->flags |= 0x1000; /* TYPEFLAG_FDISPATCHABLE */
add_dispatch(typelib); add_dispatch(typelib);
msft_typeinfo->typeinfo->cImplTypes = 1;
if (inherit)
{
add_impl_type(msft_typeinfo, inherit, importinfo);
msft_typeinfo->typeinfo->typekind |= 0x10;
}
/* count the number of inherited interfaces and non-local functions */
for (ref = inherit; ref; ref = type_iface_get_inherit(ref))
{
num_parents++;
STATEMENTS_FOR_EACH_FUNC( stmt_func, type_iface_get_stmts(ref) )
{
var_t *func = stmt_func->u.var;
if (!is_local(func->attrs)) num_funcs++;
}
}
msft_typeinfo->typeinfo->datatype2 = num_funcs << 16 | num_parents;
msft_typeinfo->typeinfo->cbSizeVft = num_funcs * pointer_size;
msft_typeinfo->typeinfo->cImplTypes = 1; /* IDispatch */
/* count the no of methods, as the variable indices come after the funcs */ /* count the no of methods, as the variable indices come after the funcs */
if (dispinterface->details.iface->disp_methods) if (dispinterface->details.iface->disp_methods)
@ -2120,16 +2099,13 @@ static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface)
interface->typelib_idx = typelib->typelib_header.nrtypeinfos; interface->typelib_idx = typelib->typelib_header.nrtypeinfos;
msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs); msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs);
msft_typeinfo->typeinfo->size = pointer_size; msft_typeinfo->typeinfo->size = pointer_size;
msft_typeinfo->typeinfo->typekind |= 0x2200; msft_typeinfo->typeinfo->typekind |= 0x0200;
msft_typeinfo->typeinfo->typekind |= pointer_size << 11;
for (derived = inherit; derived; derived = type_iface_get_inherit(derived)) for (derived = inherit; derived; derived = type_iface_get_inherit(derived))
if (derived->name && !strcmp(derived->name, "IDispatch")) if (derived->name && !strcmp(derived->name, "IDispatch"))
msft_typeinfo->typeinfo->flags |= 0x1000; /* TYPEFLAG_FDISPATCHABLE */ msft_typeinfo->typeinfo->flags |= 0x1000; /* TYPEFLAG_FDISPATCHABLE */
/* can't be dual if it doesn't derive from IDispatch */
if (!(msft_typeinfo->typeinfo->flags & 0x1000)) /* TYPEFLAG_FDISPATCHABLE */
msft_typeinfo->typeinfo->flags &= ~0x40; /* TYPEFLAG_FDUAL */
if(type_iface_get_inherit(interface)) if(type_iface_get_inherit(interface))
add_impl_type(msft_typeinfo, type_iface_get_inherit(interface), add_impl_type(msft_typeinfo, type_iface_get_inherit(interface),
ref_importinfo); ref_importinfo);
@ -2209,7 +2185,8 @@ static void add_union_typeinfo(msft_typelib_t *typelib, type_t *tunion)
static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef) static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef)
{ {
msft_typeinfo_t *msft_typeinfo = NULL; msft_typeinfo_t *msft_typeinfo = NULL;
int alignment, datatype1, datatype2, size, duplicate = 0; int datatype1, datatype2, duplicate = 0;
unsigned int size, alignment = 0;
type_t *type; type_t *type;
if (-1 < tdef->typelib_idx) if (-1 < tdef->typelib_idx)
@ -2225,8 +2202,8 @@ static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef)
else else
duplicate = 1; duplicate = 1;
encode_type(typelib, get_type_vt(type), type, encode_type(typelib, get_type_vt(type), type, &datatype1, &datatype2);
&datatype1, &size, &alignment, &datatype2); size = type_memsize_and_alignment(type, &alignment);
if (msft_typeinfo) if (msft_typeinfo)
{ {
@ -2367,6 +2344,7 @@ static void add_type_typeinfo(msft_typelib_t *typelib, type_t *type)
break; break;
case TYPE_BASIC: case TYPE_BASIC:
case TYPE_POINTER: case TYPE_POINTER:
case TYPE_ARRAY:
break; break;
default: default:
error("add_entry: unhandled type 0x%x for %s\n", error("add_entry: unhandled type 0x%x for %s\n",
@ -2669,7 +2647,9 @@ static void save_all_changes(msft_typelib_t *typelib)
sprintf( typelib_id, "#%d", expr->cval ); sprintf( typelib_id, "#%d", expr->cval );
add_output_to_resources( "TYPELIB", typelib_id ); add_output_to_resources( "TYPELIB", typelib_id );
output_typelib_regscript( typelib->typelib ); output_typelib_regscript( typelib->typelib );
#ifdef __REACTOS__
flush_output_resources( typelib_name ); flush_output_resources( typelib_name );
#endif
} }
else flush_output_buffer( typelib_name ); else flush_output_buffer( typelib_name );
} }
@ -2687,8 +2667,6 @@ int create_msft_typelib(typelib_t *typelib)
GUID midl_info_guid = {0xde77ba65,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}}; GUID midl_info_guid = {0xde77ba65,0x517c,0x11d1,{0xa2,0xda,0x00,0x00,0xf8,0x77,0x3c,0xe9}};
char info_string[128]; char info_string[128];
pointer_size = (typelib_kind == SYS_WIN64) ? 8 : 4;
msft = xmalloc(sizeof(*msft)); msft = xmalloc(sizeof(*msft));
memset(msft, 0, sizeof(*msft)); memset(msft, 0, sizeof(*msft));
msft->typelib = typelib; msft->typelib = typelib;
@ -2696,7 +2674,7 @@ int create_msft_typelib(typelib_t *typelib)
ctl2_init_header(msft); ctl2_init_header(msft);
ctl2_init_segdir(msft); ctl2_init_segdir(msft);
msft->typelib_header.varflags |= typelib_kind; msft->typelib_header.varflags |= (pointer_size == 8) ? SYS_WIN64 : SYS_WIN32;
/* /*
* The following two calls return an offset or -1 if out of memory. We * The following two calls return an offset or -1 if out of memory. We

View file

@ -329,7 +329,7 @@ static void init_library(struct sltg_typelib *sltg)
sltg->library.name = add_name(sltg, sltg->typelib->name); sltg->library.name = add_name(sltg, sltg->typelib->name);
sltg->library.helpstring = NULL; sltg->library.helpstring = NULL;
sltg->library.helpcontext = 0; sltg->library.helpcontext = 0;
sltg->library.syskind = typelib_kind; sltg->library.syskind = (pointer_size == 8) ? SYS_WIN64 : SYS_WIN32;
sltg->library.lcid = 0x0409; sltg->library.lcid = 0x0409;
sltg->library.libflags = 0; sltg->library.libflags = 0;
sltg->library.version = 0; sltg->library.version = 0;
@ -719,7 +719,7 @@ static int get_element_size(type_t *type)
case VT_INT: case VT_INT:
case VT_UINT: case VT_UINT:
return typelib_kind == SYS_WIN16 ? 2 : 4; return /* typelib_kind == SYS_WIN16 ? 2 : */ 4;
case VT_UI2: case VT_UI2:
case VT_I2: case VT_I2:
@ -1824,7 +1824,6 @@ static void save_all_changes(struct sltg_typelib *typelib)
sprintf(typelib_id, "#%d", expr->cval); sprintf(typelib_id, "#%d", expr->cval);
add_output_to_resources("TYPELIB", typelib_id); add_output_to_resources("TYPELIB", typelib_id);
output_typelib_regscript(typelib->typelib); output_typelib_regscript(typelib->typelib);
flush_output_resources(typelib_name);
} }
else flush_output_buffer(typelib_name); else flush_output_buffer(typelib_name);
} }
@ -1836,8 +1835,6 @@ int create_sltg_typelib(typelib_t *typelib)
void *library_block; void *library_block;
int library_block_size, library_block_index; int library_block_size, library_block_index;
pointer_size = (typelib_kind == SYS_WIN64) ? 8 : 4;
sltg.typelib = typelib; sltg.typelib = typelib;
sltg.typeinfo_count = 0; sltg.typeinfo_count = 0;
sltg.typeinfo_size = 0; sltg.typeinfo_size = 0;