[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(ARCH STREQUAL "i386")
add_definitions(/D_X86_ /DWIN32 /D_WINDOWS)
add_definitions(/D_X86_ /D__i386__ /DWIN32 /D_WINDOWS)
endif()
if(MSVC_VERSION GREATER 1699)
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.
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
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");
if (handle_var)
{
if (explicit_fc == RPC_FC_BIND_GENERIC)
if (explicit_fc == FC_BIND_GENERIC)
print_client("%s %s;\n",
get_explicit_generic_handle_type(handle_var)->name, handle_var->name );
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");
if (explicit_fc == RPC_FC_BIND_GENERIC)
if (explicit_fc == FC_BIND_GENERIC)
{
fprintf(client, "\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)
{
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 );
}
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)
{
case RPC_FC_BIND_PRIMITIVE:
case FC_BIND_PRIMITIVE:
print_client("__frame->_Handle = %s;\n", handle_var->name);
fprintf(client, "\n");
break;
case RPC_FC_BIND_GENERIC:
case FC_BIND_GENERIC:
print_client("__frame->_Handle = %s_bind(%s);\n",
get_explicit_generic_handle_type(handle_var)->name, handle_var->name);
fprintf(client, "\n");
break;
case RPC_FC_BIND_CONTEXT:
case FC_BIND_CONTEXT:
{
/* if the context_handle attribute appears in the chain of types
* 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");
}
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)
{
const statement_t *stmt;
@ -296,11 +358,30 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
if (!implicit_handle)
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 )
{
const var_t *func = stmt->u.var;
write_function_stub( iface, func, method_count++, *proc_offset );
*proc_offset += get_size_procformatstring_func( iface, func );
switch (stmt->type)
{
case STMT_DECLARATION:
{
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 );
*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)
{
int has_func = 0;
int needs_stub = 0;
const statement_t *stmt2;
type_t *iface = stmt->u.type;
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");
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;
break;
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;
}
if (stmt2->type == STMT_TYPEDEF)
{
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 (has_func)
if (needs_stub)
{
write_implicithandledecl(iface);
@ -528,26 +627,6 @@ void write_client(const statement_list_t *stmts)
if (!client)
return;
if (do_win32 && do_win64)
{
fprintf(client, "#ifndef _WIN64\n\n");
pointer_size = 4;
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 );
}
write_client_routines( stmts );
fclose(client);
}

View file

@ -50,6 +50,7 @@ static int is_integer_type(const type_t *type)
case TYPE_BASIC_INT64:
case TYPE_BASIC_INT:
case TYPE_BASIC_INT3264:
case TYPE_BASIC_LONG:
case TYPE_BASIC_CHAR:
case TYPE_BASIC_HYPER:
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_INT:
case TYPE_BASIC_INT3264:
case TYPE_BASIC_LONG:
return type_basic_get_sign(type) < 0;
case TYPE_BASIC_CHAR:
return TRUE;
@ -519,11 +521,11 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
break;
case EXPR_STRLIT:
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;
case EXPR_WSTRLIT:
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;
case EXPR_CHARCONST:
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 : "");
result.is_variable = FALSE;
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;
case EXPR_PPTR:
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)));
}
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)
{
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 : "");
break;
case TYPE_POINTER:
{
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 ");
break;
}
case TYPE_ARRAY:
if (t->name && type_array_is_decl_as_ptr(t))
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);
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;
case TYPE_BASIC:
if (type_basic_get_type(t) != TYPE_BASIC_INT32 &&
type_basic_get_type(t) != TYPE_BASIC_INT64 &&
type_basic_get_type(t) != TYPE_BASIC_LONG &&
type_basic_get_type(t) != TYPE_BASIC_HYPER)
{
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_HANDLE: fprintf(h, "handle_t"); break;
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)
fprintf(h, "ULONG");
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)
{
if (!h) return;
if (type_is_alias(t)) return;
switch (type_get_type(t))
{
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))
{
fprintf(h, "[%s]", is_field ? "1" : "");
t = type_array_get_element(t);
}
for ( ;
type_get_type(t) == TYPE_ARRAY && !type_array_is_decl_as_ptr(t);
t = type_array_get_element(t))
else
fprintf(h, "[%u]", type_array_get_dim(t));
}
write_type_right(h, elem, FALSE);
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:
fprintf(h, " : %u", type_bitfield_get_bits(t)->cval);
break;
@ -450,7 +481,6 @@ void write_type_right(FILE *h, type_t *t, int is_field)
case TYPE_COCLASS:
case TYPE_FUNCTION:
case TYPE_INTERFACE:
case TYPE_POINTER:
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)
{
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 (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;
}
if (get_explicit_generic_handle_type( var ))
{
*explicit_fc = RPC_FC_BIND_GENERIC;
*explicit_fc = FC_BIND_GENERIC;
return var;
}
if (is_context_handle( var->type ))
{
*explicit_fc = RPC_FC_BIND_CONTEXT;
*explicit_fc = FC_BIND_CONTEXT;
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 &&
type_basic_get_type( var->type ) == TYPE_BASIC_HANDLE)
*implicit_fc = RPC_FC_BIND_PRIMITIVE;
*implicit_fc = FC_BIND_PRIMITIVE;
else
*implicit_fc = RPC_FC_BIND_GENERIC;
*implicit_fc = FC_BIND_GENERIC;
return var;
}
*implicit_fc = RPC_FC_AUTO_HANDLE;
*implicit_fc = FC_AUTO_HANDLE;
return NULL;
}
@ -1276,7 +1347,7 @@ static void write_locals(FILE *fp, const type_t *iface, int body)
if (cas) {
const statement_t *stmt2 = NULL;
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;
if (&stmt2->entry != type_iface_get_stmts(iface)) {
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:
if (type_get_type(stmt->u.type) == TYPE_INTERFACE)
{
if (is_object(stmt->u.type) || is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE))
write_forward(header, stmt->u.type);
type_t *iface = 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)
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)
{
type_t *iface = stmt->u.type;
type_t *async_iface = iface->details.iface->async_iface;
if (is_object(iface)) is_object_interface++;
if (is_attr(stmt->u.type->attrs, ATTR_DISPINTERFACE) || is_object(stmt->u.type))
{
write_com_interface_start(header, iface);
write_header_stmts(header, type_iface_get_stmts(iface), stmt->u.type, TRUE);
write_com_interface_end(header, iface);
if (async_iface)
{
write_com_interface_start(header, async_iface);
write_com_interface_end(header, async_iface);
}
}
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, "#ifdef _WIN32\n");
fprintf(header, "#ifndef __REQUIRED_RPCNDR_H_VERSION__\n");
fprintf(header, "#define __REQUIRED_RPCNDR_H_VERSION__ 475\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, "#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, "#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, "\n");
for_each_serializable(stmts, header, write_serialize_function_decl);
write_user_types(header);
write_generic_handle_routines(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 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_array(FILE *h, array_dims_t *v, int field);
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,
unsigned char *explicit_fc, unsigned char *implicit_fc );
extern int has_out_arg_or_return(const var_t *func);
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)
{
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 attr_token(const char *kw);
static void switch_to_acf(void);
static warning_list_t *disabled_warnings = NULL;
#define MAX_IMPORT_DEPTH 20
@ -225,9 +227,14 @@ SAFEARRAY{ws}*/\( return tSAFEARRAY;
<INITIAL,ATTR>\.\.\. return ELLIPSIS;
<INITIAL,ATTR>. return yytext[0];
<<EOF>> {
if (import_stack_ptr)
return aEOF;
else yyterminate();
if (import_stack_ptr)
return aEOF;
if (acf_name)
{
switch_to_acf();
return aACF;
}
yyterminate();
}
%%
@ -250,6 +257,7 @@ static const struct keyword keywords[] = {
{"TRUE", tTRUE},
{"__cdecl", tCDECL},
{"__fastcall", tFASTCALL},
{"__int32", tINT32},
{"__int3264", tINT3264},
{"__int64", tINT64},
{"__pascal", tPASCAL},
@ -562,6 +570,38 @@ void abort_import(void)
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)
{
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
version 2.2 of Bison. */
#ifndef YY_PARSER_E_REACTOSSYNC_GCC_HOST_TOOLS_SDK_TOOLS_WIDL_PARSER_TAB_H_INCLUDED
# define 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_MSVC_HOST_TOOLS_SDK_TOOLS_WIDL_PARSER_TAB_H_INCLUDED
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
@ -56,179 +56,181 @@ extern int parser_debug;
aSQSTRING = 266,
aUUID = 267,
aEOF = 268,
SHL = 269,
SHR = 270,
MEMBERPTR = 271,
EQUALITY = 272,
INEQUALITY = 273,
GREATEREQUAL = 274,
LESSEQUAL = 275,
LOGICALOR = 276,
LOGICALAND = 277,
ELLIPSIS = 278,
tAGGREGATABLE = 279,
tALLOCATE = 280,
tANNOTATION = 281,
tAPPOBJECT = 282,
tASYNC = 283,
tASYNCUUID = 284,
tAUTOHANDLE = 285,
tBINDABLE = 286,
tBOOLEAN = 287,
tBROADCAST = 288,
tBYTE = 289,
tBYTECOUNT = 290,
tCALLAS = 291,
tCALLBACK = 292,
tCASE = 293,
tCDECL = 294,
tCHAR = 295,
tCOCLASS = 296,
tCODE = 297,
tCOMMSTATUS = 298,
tCONST = 299,
tCONTEXTHANDLE = 300,
tCONTEXTHANDLENOSERIALIZE = 301,
tCONTEXTHANDLESERIALIZE = 302,
tCONTROL = 303,
tCPPQUOTE = 304,
tDECODE = 305,
tDEFAULT = 306,
tDEFAULTBIND = 307,
tDEFAULTCOLLELEM = 308,
tDEFAULTVALUE = 309,
tDEFAULTVTABLE = 310,
tDISABLECONSISTENCYCHECK = 311,
tDISPLAYBIND = 312,
tDISPINTERFACE = 313,
tDLLNAME = 314,
tDOUBLE = 315,
tDUAL = 316,
tENABLEALLOCATE = 317,
tENCODE = 318,
tENDPOINT = 319,
tENTRY = 320,
tENUM = 321,
tERRORSTATUST = 322,
tEXPLICITHANDLE = 323,
tEXTERN = 324,
tFALSE = 325,
tFASTCALL = 326,
tFAULTSTATUS = 327,
tFLOAT = 328,
tFORCEALLOCATE = 329,
tHANDLE = 330,
tHANDLET = 331,
tHELPCONTEXT = 332,
tHELPFILE = 333,
tHELPSTRING = 334,
tHELPSTRINGCONTEXT = 335,
tHELPSTRINGDLL = 336,
tHIDDEN = 337,
tHYPER = 338,
tID = 339,
tIDEMPOTENT = 340,
tIGNORE = 341,
tIIDIS = 342,
tIMMEDIATEBIND = 343,
tIMPLICITHANDLE = 344,
tIMPORT = 345,
tIMPORTLIB = 346,
tIN = 347,
tIN_LINE = 348,
tINLINE = 349,
tINPUTSYNC = 350,
tINT = 351,
tINT3264 = 352,
tINT64 = 353,
tINTERFACE = 354,
tLCID = 355,
tLENGTHIS = 356,
tLIBRARY = 357,
tLICENSED = 358,
tLOCAL = 359,
tLONG = 360,
tMAYBE = 361,
tMESSAGE = 362,
tMETHODS = 363,
tMODULE = 364,
tNAMESPACE = 365,
tNOCODE = 366,
tNONBROWSABLE = 367,
tNONCREATABLE = 368,
tNONEXTENSIBLE = 369,
tNOTIFY = 370,
tNOTIFYFLAG = 371,
tNULL = 372,
tOBJECT = 373,
tODL = 374,
tOLEAUTOMATION = 375,
tOPTIMIZE = 376,
tOPTIONAL = 377,
tOUT = 378,
tPARTIALIGNORE = 379,
tPASCAL = 380,
tPOINTERDEFAULT = 381,
tPRAGMA_WARNING = 382,
tPROGID = 383,
tPROPERTIES = 384,
tPROPGET = 385,
tPROPPUT = 386,
tPROPPUTREF = 387,
tPROXY = 388,
tPTR = 389,
tPUBLIC = 390,
tRANGE = 391,
tREADONLY = 392,
tREF = 393,
tREGISTER = 394,
tREPRESENTAS = 395,
tREQUESTEDIT = 396,
tRESTRICTED = 397,
tRETVAL = 398,
tSAFEARRAY = 399,
tSHORT = 400,
tSIGNED = 401,
tSIZEIS = 402,
tSIZEOF = 403,
tSMALL = 404,
tSOURCE = 405,
tSTATIC = 406,
tSTDCALL = 407,
tSTRICTCONTEXTHANDLE = 408,
tSTRING = 409,
tSTRUCT = 410,
tSWITCH = 411,
tSWITCHIS = 412,
tSWITCHTYPE = 413,
tTHREADING = 414,
tTRANSMITAS = 415,
tTRUE = 416,
tTYPEDEF = 417,
tUIDEFAULT = 418,
tUNION = 419,
tUNIQUE = 420,
tUNSIGNED = 421,
tUSESGETLASTERROR = 422,
tUSERMARSHAL = 423,
tUUID = 424,
tV1ENUM = 425,
tVARARG = 426,
tVERSION = 427,
tVIPROGID = 428,
tVOID = 429,
tWCHAR = 430,
tWIREMARSHAL = 431,
tAPARTMENT = 432,
tNEUTRAL = 433,
tSINGLE = 434,
tFREE = 435,
tBOTH = 436,
CAST = 437,
PPTR = 438,
POS = 439,
NEG = 440,
ADDRESSOF = 441
aACF = 269,
SHL = 270,
SHR = 271,
MEMBERPTR = 272,
EQUALITY = 273,
INEQUALITY = 274,
GREATEREQUAL = 275,
LESSEQUAL = 276,
LOGICALOR = 277,
LOGICALAND = 278,
ELLIPSIS = 279,
tAGGREGATABLE = 280,
tALLOCATE = 281,
tANNOTATION = 282,
tAPPOBJECT = 283,
tASYNC = 284,
tASYNCUUID = 285,
tAUTOHANDLE = 286,
tBINDABLE = 287,
tBOOLEAN = 288,
tBROADCAST = 289,
tBYTE = 290,
tBYTECOUNT = 291,
tCALLAS = 292,
tCALLBACK = 293,
tCASE = 294,
tCDECL = 295,
tCHAR = 296,
tCOCLASS = 297,
tCODE = 298,
tCOMMSTATUS = 299,
tCONST = 300,
tCONTEXTHANDLE = 301,
tCONTEXTHANDLENOSERIALIZE = 302,
tCONTEXTHANDLESERIALIZE = 303,
tCONTROL = 304,
tCPPQUOTE = 305,
tDECODE = 306,
tDEFAULT = 307,
tDEFAULTBIND = 308,
tDEFAULTCOLLELEM = 309,
tDEFAULTVALUE = 310,
tDEFAULTVTABLE = 311,
tDISABLECONSISTENCYCHECK = 312,
tDISPLAYBIND = 313,
tDISPINTERFACE = 314,
tDLLNAME = 315,
tDOUBLE = 316,
tDUAL = 317,
tENABLEALLOCATE = 318,
tENCODE = 319,
tENDPOINT = 320,
tENTRY = 321,
tENUM = 322,
tERRORSTATUST = 323,
tEXPLICITHANDLE = 324,
tEXTERN = 325,
tFALSE = 326,
tFASTCALL = 327,
tFAULTSTATUS = 328,
tFLOAT = 329,
tFORCEALLOCATE = 330,
tHANDLE = 331,
tHANDLET = 332,
tHELPCONTEXT = 333,
tHELPFILE = 334,
tHELPSTRING = 335,
tHELPSTRINGCONTEXT = 336,
tHELPSTRINGDLL = 337,
tHIDDEN = 338,
tHYPER = 339,
tID = 340,
tIDEMPOTENT = 341,
tIGNORE = 342,
tIIDIS = 343,
tIMMEDIATEBIND = 344,
tIMPLICITHANDLE = 345,
tIMPORT = 346,
tIMPORTLIB = 347,
tIN = 348,
tIN_LINE = 349,
tINLINE = 350,
tINPUTSYNC = 351,
tINT = 352,
tINT32 = 353,
tINT3264 = 354,
tINT64 = 355,
tINTERFACE = 356,
tLCID = 357,
tLENGTHIS = 358,
tLIBRARY = 359,
tLICENSED = 360,
tLOCAL = 361,
tLONG = 362,
tMAYBE = 363,
tMESSAGE = 364,
tMETHODS = 365,
tMODULE = 366,
tNAMESPACE = 367,
tNOCODE = 368,
tNONBROWSABLE = 369,
tNONCREATABLE = 370,
tNONEXTENSIBLE = 371,
tNOTIFY = 372,
tNOTIFYFLAG = 373,
tNULL = 374,
tOBJECT = 375,
tODL = 376,
tOLEAUTOMATION = 377,
tOPTIMIZE = 378,
tOPTIONAL = 379,
tOUT = 380,
tPARTIALIGNORE = 381,
tPASCAL = 382,
tPOINTERDEFAULT = 383,
tPRAGMA_WARNING = 384,
tPROGID = 385,
tPROPERTIES = 386,
tPROPGET = 387,
tPROPPUT = 388,
tPROPPUTREF = 389,
tPROXY = 390,
tPTR = 391,
tPUBLIC = 392,
tRANGE = 393,
tREADONLY = 394,
tREF = 395,
tREGISTER = 396,
tREPRESENTAS = 397,
tREQUESTEDIT = 398,
tRESTRICTED = 399,
tRETVAL = 400,
tSAFEARRAY = 401,
tSHORT = 402,
tSIGNED = 403,
tSIZEIS = 404,
tSIZEOF = 405,
tSMALL = 406,
tSOURCE = 407,
tSTATIC = 408,
tSTDCALL = 409,
tSTRICTCONTEXTHANDLE = 410,
tSTRING = 411,
tSTRUCT = 412,
tSWITCH = 413,
tSWITCHIS = 414,
tSWITCHTYPE = 415,
tTHREADING = 416,
tTRANSMITAS = 417,
tTRUE = 418,
tTYPEDEF = 419,
tUIDEFAULT = 420,
tUNION = 421,
tUNIQUE = 422,
tUNSIGNED = 423,
tUSESGETLASTERROR = 424,
tUSERMARSHAL = 425,
tUUID = 426,
tV1ENUM = 427,
tVARARG = 428,
tVERSION = 429,
tVIPROGID = 430,
tVOID = 431,
tWCHAR = 432,
tWIREMARSHAL = 433,
tAPARTMENT = 434,
tNEUTRAL = 435,
tSINGLE = 436,
tFREE = 437,
tBOTH = 438,
CAST = 439,
PPTR = 440,
POS = 441,
NEG = 442,
ADDRESSOF = 443
};
#endif
@ -237,14 +239,13 @@ extern int parser_debug;
typedef union YYSTYPE YYSTYPE;
union YYSTYPE
{
#line 138 "parser.y" /* yacc.c:1909 */
#line 144 "parser.y" /* yacc.c:1909 */
attr_t *attr;
attr_list_t *attr_list;
str_list_t *str_list;
expr_t *expr;
expr_list_t *expr_list;
array_dims_t *array_dims;
type_t *type;
var_t *var;
var_list_t *var_list;
@ -266,7 +267,7 @@ union YYSTYPE
struct _decl_spec_t *declspec;
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_DECLARED 1
@ -277,4 +278,4 @@ extern YYSTYPE parser_lval;
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 "typetree.h"
static unsigned char pointer_default = RPC_FC_UP;
static unsigned char pointer_default = FC_UP;
typedef struct list typelist_t;
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_attrp(enum attr_type type, void *val);
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_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);
@ -82,7 +82,7 @@ static declarator_list_t *append_declarator(declarator_list_t *list, declarator_
static declarator_t *make_declarator(var_t *var);
static type_t *make_safearray(type_t *type);
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 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 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_type_decl(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;
#ifndef __REACTOS__
static typelib_t *current_typelib;
#endif
%}
%union {
attr_t *attr;
@ -141,7 +147,6 @@ static struct namespace *current_namespace = &global_namespace;
str_list_t *str_list;
expr_t *expr;
expr_list_t *expr_list;
array_dims_t *array_dims;
type_t *type;
var_t *var;
var_list_t *var_list;
@ -170,7 +175,7 @@ static struct namespace *current_namespace = &global_namespace;
%token <dbl> aDOUBLE
%token <str> aSTRING aWSTRING aSQSTRING
%token <uuid> aUUID
%token aEOF
%token aEOF aACF
%token SHL SHR
%token MEMBERPTR
%token EQUALITY INEQUALITY
@ -207,7 +212,7 @@ static struct namespace *current_namespace = &global_namespace;
%token tIMPORT tIMPORTLIB
%token tIN tIN_LINE tINLINE
%token tINPUTSYNC
%token tINT tINT3264 tINT64
%token tINT tINT32 tINT3264 tINT64
%token tINTERFACE
%token tLCID
%token tLENGTHIS tLIBRARY
@ -263,8 +268,9 @@ static struct namespace *current_namespace = &global_namespace;
%token tWCHAR tWIREMARSHAL
%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> acf_attributes acf_attribute_list
%type <str_list> str_list
%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
@ -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_all_user_types($1);
write_header($1);
@ -327,11 +333,16 @@ input: gbl_statements { fix_incomplete();
write_client($1);
write_server($1);
write_regscript($1);
#ifndef __REACTOS__
write_typelib_regscript($1);
#endif
write_dlldata($1);
write_local_stubs($1);
}
;
m_acf: /* empty */ | aACF acf_statements
gbl_statements: { $$ = NULL; }
| gbl_statements namespacedef '{' { push_namespace($2); } gbl_statements '}'
{ pop_namespace($2); $$ = append_statements($1, $5); }
@ -425,21 +436,33 @@ import: import_start imp_statements aEOF { $$ = $1->name;
;
importlib: tIMPORTLIB '(' aSTRING ')'
/* ifdef __REACTOS__ */
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; }
| tLIBRARY aKNOWNTYPE { $$ = $2; }
;
library_start: attributes libraryhdr '{' { $$ = make_library($2, check_library_attrs($2, $1));
/* ifdef __REACTOS__ */
if (!parse_only) start_typelib($$);
/* else
if (!parse_only && do_typelib) current_typelib = $$;
*/
}
;
librarydef: library_start imp_statements '}'
/* ifdef __REACTOS__ */
semicolon_opt { $$ = $1;
$$->stmts = $2;
if (!parse_only) end_typelib();
}
/* else
semicolon_opt { $$ = $1; $$->stmts = $2; }
*/
;
m_args: { $$ = NULL; }
@ -468,8 +491,8 @@ arg: attributes decl_spec m_any_declarator { if ($2->stgclass != STG_NONE && $
;
array: '[' expr ']' { $$ = $2;
if (!$$->is_const)
error_loc("array dimension is not an integer constant\n");
if (!$$->is_const || $$->cval <= 0)
error_loc("array dimension is not a positive integer constant\n");
}
| '[' '*' ']' { $$ = make_expr(EXPR_VOID); }
| '[' ']' { $$ = make_expr(EXPR_VOID); }
@ -816,10 +839,11 @@ m_int:
int_std: tINT { $$ = type_new_int(TYPE_BASIC_INT, 0); }
| tSHORT m_int { $$ = type_new_int(TYPE_BASIC_INT16, 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); }
| tINT64 { $$ = type_new_int(TYPE_BASIC_INT64, 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); }
;
@ -909,6 +933,7 @@ interfacedef: interfacehdr inherit
if($$ == $2)
error_loc("Interface can't inherit from itself\n");
type_interface_define($$, $2, $4);
check_async_uuid($$);
pointer_default = $1.old_pointer_default;
}
/* MIDL is able to import the definition of a base class from inside the
@ -977,7 +1002,7 @@ decl_spec_no_type:
declarator:
'*' 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));
else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
| direct_declarator
@ -986,9 +1011,9 @@ declarator:
direct_declarator:
ident { $$ = make_declarator($1); }
| '(' 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;
$$->func_type = append_ptrchain_type($$->type, type_new_function($3));
$$->func_type = append_chain_type($$->type, type_new_function($3));
$$->type = NULL;
}
;
@ -996,7 +1021,7 @@ direct_declarator:
/* abstract declarator */
abstract_declarator:
'*' 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));
else if ($$->type) $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
| abstract_direct_declarator
@ -1005,7 +1030,7 @@ abstract_declarator:
/* abstract declarator without accepting direct declarator */
abstract_declarator_no_direct:
'*' 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));
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_declarator_no_direct ')' { $$ = $2; }
| abstract_direct_declarator array { $$ = $1; $$->array = append_array($$->array, $2); }
| array { $$ = make_declarator(NULL); $$->array = append_array($$->array, $1); }
| abstract_direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); }
| array { $$ = make_declarator(NULL); $$->type = append_array($$->type, $1); }
| '(' m_args ')'
{ $$ = 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;
}
| abstract_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;
}
;
@ -1035,7 +1060,7 @@ abstract_direct_declarator:
/* abstract or non-abstract declarator */
any_declarator:
'*' 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)); }
| any_direct_declarator
;
@ -1043,7 +1068,7 @@ any_declarator:
/* abstract or non-abstract declarator without accepting direct declarator */
any_declarator_no_direct:
'*' 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)); }
;
@ -1058,16 +1083,16 @@ m_any_declarator: { $$ = make_declarator(NULL); }
any_direct_declarator:
ident { $$ = make_declarator($1); }
| '(' any_declarator_no_direct ')' { $$ = $2; }
| any_direct_declarator array { $$ = $1; $$->array = append_array($$->array, $2); }
| array { $$ = make_declarator(NULL); $$->array = append_array($$->array, $1); }
| any_direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); }
| array { $$ = make_declarator(NULL); $$->type = append_array($$->type, $1); }
| '(' m_args ')'
{ $$ = 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;
}
| any_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;
}
;
@ -1107,9 +1132,9 @@ threading_type:
;
pointer_type:
tREF { $$ = RPC_FC_RP; }
| tUNIQUE { $$ = RPC_FC_UP; }
| tPTR { $$ = RPC_FC_FP; }
tREF { $$ = FC_RP; }
| tUNIQUE { $$ = FC_UP; }
| tPTR { $$ = FC_FP; }
;
structdef: tSTRUCT t_ident '{' fields '}' { $$ = type_new_struct($2, current_namespace, TRUE, $4); }
@ -1147,6 +1172,40 @@ version:
| 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)
@ -1236,10 +1295,13 @@ static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_lis
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;
const attr_t *attr;
attr_t *new_attr;
if (!list) return NULL;
@ -1247,7 +1309,8 @@ static attr_list_t *dupattrs(const attr_list_t *list)
list_init( new_list );
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;
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;
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->attrs = NULL;
}
@ -1341,16 +1404,19 @@ static expr_list_t *append_expr(expr_list_t *list, expr_t *expr)
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;
if (!list)
{
list = xmalloc( sizeof(*list) );
list_init( list );
}
list_add_tail( list, &expr->entry );
return list;
type_t *array;
if (!expr)
return chain;
/* An array is always a reference pointer unless explicitly marked otherwise
* (regardless of what the default pointer attribute is). */
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);
@ -1406,6 +1472,7 @@ static int is_allowed_range_type(const type_t *type)
case TYPE_BASIC_INT64:
case TYPE_BASIC_INT:
case TYPE_BASIC_INT3264:
case TYPE_BASIC_LONG:
case TYPE_BASIC_BYTE:
case TYPE_BASIC_CHAR:
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 (!ptrchain)
return type;
for (ptrchain_type = ptrchain; type_pointer_get_ref(ptrchain_type); ptrchain_type = type_pointer_get_ref(ptrchain_type))
;
assert(ptrchain_type->type_type == TYPE_POINTER);
ptrchain_type->details.pointer.ref = type;
return ptrchain;
if (is_ptr(type))
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;
for (chain_type = chain; get_array_or_ptr_ref(chain_type); chain_type = get_array_or_ptr_ref(chain_type))
;
if (is_ptr(chain_type))
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)
@ -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;
expr_list_t *sizes = get_attrp(attrs, ATTR_SIZEIS);
expr_list_t *lengs = get_attrp(attrs, ATTR_LENGTHIS);
int sizeless;
expr_t *dim;
type_t **ptype;
array_dims_t *arr = decl ? decl->array : NULL;
type_t *func_type = decl ? decl->func_type : NULL;
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 */
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->attrs = attrs;
/* check for pointer attribute being applied to non-pointer, non-array
* type */
if (!arr)
if (!is_array(v->type))
{
int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE);
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 (ptr_attr && ptr_attr != RPC_FC_UP &&
if (ptr_attr && ptr_attr != FC_UP &&
type_get_type(type_pointer_get_ref(ptr)) == TYPE_INTERFACE)
warning_loc_info(&v->loc_info,
"%s: pointer attribute applied to interface "
"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
* 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;
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",
v->name);
while (is_ptr(t))
t = type_pointer_get_ref(t);
for (;;)
{
if (is_ptr(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 &&
(get_basic_fc(t) != RPC_FC_CHAR &&
get_basic_fc(t) != RPC_FC_BYTE &&
get_basic_fc(t) != RPC_FC_WCHAR))
(get_basic_fc(t) != FC_CHAR &&
get_basic_fc(t) != FC_BYTE &&
get_basic_fc(t) != FC_WCHAR))
{
error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n",
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",
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;
if (sizes) LIST_FOR_EACH_ENTRY(dim, sizes, expr_t, entry)
{
@ -1739,6 +1797,18 @@ var_t *make_var(char *name)
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)
{
if (!d) return list;
@ -1756,7 +1826,6 @@ static declarator_t *make_declarator(var_t *var)
d->var = var ? var : make_var(NULL);
d->type = NULL;
d->func_type = NULL;
d->array = NULL;
d->bits = NULL;
return d;
}
@ -1764,7 +1833,7 @@ static declarator_t *make_declarator(var_t *var)
static type_t *make_safearray(type_t *type)
{
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)
@ -2415,6 +2484,7 @@ static int is_allowed_conf_type(const type_t *type)
case TYPE_BASIC_INT32:
case TYPE_BASIC_INT64:
case TYPE_BASIC_INT:
case TYPE_BASIC_LONG:
case TYPE_BASIC_CHAR:
case TYPE_BASIC_HYPER:
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)
{
const statement_t *stmt;

View file

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

View file

@ -317,7 +317,7 @@ extern int parser_lex (void);
#undef YY_DECL
#endif
#line 231 "parser.l"
#line 238 "parser.l"
#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_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;
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) );
break;
@ -680,7 +686,8 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
/* proxy vtable */
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");
indent++;
print_proxy( "{\n");
@ -759,7 +766,9 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
print_proxy( "},\n");
print_proxy( "{\n");
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--;
print_proxy( "}\n");
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 (need_proxy(stmt->u.type))
write_proxy(stmt->u.type, proc_offset);
type_t *iface = stmt->u.type;
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)[(*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;
char *file_id = proxy_token;
int i, count, have_baseiid = 0;
unsigned int table_version;
type_t **interfaces;
const type_t * delegate_to;
@ -950,7 +971,7 @@ static void write_proxy_routines(const statement_list_t *stmts)
write_stubdesc(expr_eval_routines);
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( "\n");
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");
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, "{\n");
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");
fprintf(proxy, " _%s_IID_Lookup,\n", file_id);
fprintf(proxy, " %d,\n", count);
fprintf(proxy, " %d,\n", get_stub_mode() == MODE_Oif ? 2 : 1);
fprintf(proxy, " 0,\n");
fprintf(proxy, " %u,\n", table_version);
fprintf(proxy, " %s,\n", table_version == 6 ? "_AsyncInterfaceTable" : "0");
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);
if(!proxy) return;
if (do_win32 && do_win64)
{
fprintf(proxy, "\n#ifndef _WIN64\n\n");
pointer_size = 4;
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 );
}
write_proxy_routines( stmts );
fclose(proxy);
}

View file

@ -34,6 +34,9 @@
#include "parser.h"
#include "header.h"
#include "typegen.h"
#ifndef __REACTOS__
#include "typelib.h"
#endif
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 )
{
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 flags = 0;
char id_part[12] = "";
#ifndef __REACTOS__
char *resname = typelib_name;
#endif
expr_t *expr;
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 );
put_str( indent++, "{\n" );
expr = get_attrp( typelib->attrs, ATTR_ID );
#ifdef __REACTOS__
if (expr)
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",
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, "}\n" );
put_str( --indent, "}\n" );
@ -319,6 +359,9 @@ void output_typelib_regscript( const typelib_t *typelib )
write_progids( typelib->stmts );
put_str( --indent, "}\n" );
#ifdef __REACTOS__
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->");
if (explicit_fc == RPC_FC_BIND_PRIMITIVE)
if (explicit_fc == FC_BIND_PRIMITIVE)
{
print_server("__frame->%s = _pRpcMessage->Handle;\n", handle_var->name);
fprintf(server, "\n");
@ -544,26 +544,6 @@ void write_server(const statement_list_t *stmts)
if (!server)
return;
if (do_win32 && do_win64)
{
fprintf(server, "#ifndef _WIN64\n\n");
pointer_size = 4;
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 );
}
write_server_routines( stmts );
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_struct_fc(const type_t *type);
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 "typetree.h"
#ifdef __REACTOS__
static typelib_t *typelib;
#endif
/* List of oleauto types that should be recognized by name.
* (most of) these seem to be intrinsic types in mktyplib.
@ -161,6 +163,7 @@ unsigned short get_type_vt(type_t *t)
else
return VT_INT;
case TYPE_BASIC_INT32:
case TYPE_BASIC_LONG:
case TYPE_BASIC_ERROR_STATUS_T:
if (type_basic_get_sign(t) > 0)
return VT_UI4;
@ -173,7 +176,7 @@ unsigned short get_type_vt(type_t *t)
else
return VT_I8;
case TYPE_BASIC_INT3264:
if (typelib_kind == SYS_WIN64)
if (pointer_size == 8)
{
if (type_basic_get_sign(t) > 0)
return VT_UI8;
@ -204,10 +207,10 @@ unsigned short get_type_vt(type_t *t)
{
if (match(type_array_get_element(t)->name, "SAFEARRAY"))
return VT_SAFEARRAY;
return VT_PTR;
}
else
error("get_type_vt: array types not supported\n");
return VT_PTR;
return VT_CARRAY;
case TYPE_INTERFACE:
if(match(t->name, "IUnknown"))
@ -243,6 +246,7 @@ unsigned short get_type_vt(type_t *t)
return 0;
}
#ifdef __REACTOS__
void start_typelib(typelib_t *typelib_type)
{
if (!do_typelib) return;
@ -253,11 +257,9 @@ void end_typelib(void)
{
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)
{
@ -383,7 +385,11 @@ static void read_importlib(importlib_t *importlib)
close(fd);
}
#ifdef __REACTOS__
void add_importlib(const char *name)
#else
void add_importlib(const char *name, typelib_t *typelib)
#endif
{
importlib_t *importlib;

View file

@ -21,9 +21,13 @@
#ifndef __WIDL_TYPELIB_H
#define __WIDL_TYPELIB_H
#ifdef __REACTOS__
extern void start_typelib(typelib_t *typelib_type);
extern void end_typelib(void);
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
* 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_INT:
case TYPE_BASIC_INT3264:
case TYPE_BASIC_LONG:
case TYPE_BASIC_CHAR:
case TYPE_BASIC_HYPER:
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->stmts = stmts;
iface->details.iface->inherit = inherit;
iface->details.iface->disp_inherit = NULL;
iface->details.iface->async_iface = NULL;
iface->defined = TRUE;
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->inherit = find_type("IDispatch", NULL, 0);
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;
compute_method_indexes(iface);
}
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface)
{
type_dispinterface_define(dispiface, iface->details.iface->disp_props,
iface->details.iface->disp_methods);
dispiface->details.iface = xmalloc(sizeof(*dispiface->details.iface));
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)

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;
}
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)
{
return type->defined;

View file

@ -43,14 +43,10 @@
#include "wine/wpp.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[] =
"Usage: widl [options...] infile.idl\n"
" or: widl [options...] --dlldata-only name1 [name2...]\n"
" --acf=file Use ACF file\n"
" -app_config Ignored, present for midl compatibility\n"
" -b arch Set the target architecture\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"
" -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"
" -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"
" --oldnames Use old naming conventions\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-server=p Prefix names of server functions with 'p'\n"
" -r Generate registration script\n"
" -robust Ignored, present for midl compatibility\n"
" --winrt Enable Windows Runtime mode\n"
" --ns_prefix Prefix namespaces with ABI namespace\n"
" -s Generate server stub\n"
@ -80,8 +77,7 @@ static const char usage[] =
" -u Generate interface identifiers file\n"
" -V Print version and exit\n"
" -W Enable pedantic warnings\n"
" --win32 Only generate 32-bit code\n"
" --win64 Only generate 64-bit code\n"
" --win32, --win64 Set the target architecture (Win32 or Win64)\n"
" --win32-align n Set win32 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"
@ -96,6 +92,20 @@ static const char usage[] =
static const char version_string[] = "Wine IDL Compiler version " PACKAGE_VERSION "\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 parser_debug, yy_flex_debug;
@ -113,8 +123,6 @@ int do_idfile = 0;
int do_dlldata = 0;
static int no_preprocess = 0;
int old_names = 0;
int do_win32 = 1;
int do_win64 = 1;
int win32_packing = 8;
int win64_packing = 8;
int winrt_mode = 0;
@ -123,6 +131,7 @@ static enum stub_mode stub_mode = MODE_Os;
char *input_name;
char *input_idl_name;
char *acf_name;
char *header_name;
char *local_stubs_name;
char *header_token;
@ -146,49 +155,53 @@ int line_number = 1;
static FILE *idfile;
unsigned int pointer_size = 0;
syskind_t typelib_kind = sizeof(void*) == 8 ? SYS_WIN64 : SYS_WIN32;
time_t now;
enum {
OLDNAMES_OPTION = CHAR_MAX + 1,
ACF_OPTION,
APP_CONFIG_OPTION,
DLLDATA_OPTION,
DLLDATA_ONLY_OPTION,
LOCAL_STUBS_OPTION,
OLD_TYPELIB_OPTION,
PREFIX_ALL_OPTION,
PREFIX_CLIENT_OPTION,
PREFIX_SERVER_OPTION,
PRINT_HELP,
RT_NS_PREFIX,
RT_OPTION,
ROBUST_OPTION,
WIN32_OPTION,
WIN64_OPTION,
WIN32_ALIGN_OPTION,
WIN64_ALIGN_OPTION,
APP_CONFIG_OPTION,
OLD_TYPELIB_OPTION
WIN64_ALIGN_OPTION
};
static const char short_options[] =
"b:cC:d:D:EhH:I:m:No:O:pP:rsS:tT:uU:VW";
static const struct option long_options[] = {
{ "acf", 1, NULL, ACF_OPTION },
{ "app_config", 0, NULL, APP_CONFIG_OPTION },
{ "dlldata", 1, NULL, DLLDATA_OPTION },
{ "dlldata-only", 0, NULL, DLLDATA_ONLY_OPTION },
{ "help", 0, NULL, PRINT_HELP },
{ "local-stubs", 1, NULL, LOCAL_STUBS_OPTION },
{ "ns_prefix", 0, NULL, RT_NS_PREFIX },
{ "oldnames", 0, NULL, OLDNAMES_OPTION },
{ "oldtlb", 0, NULL, OLD_TYPELIB_OPTION },
{ "output", 0, NULL, 'o' },
{ "prefix-all", 1, NULL, PREFIX_ALL_OPTION },
{ "prefix-client", 1, NULL, PREFIX_CLIENT_OPTION },
{ "prefix-server", 1, NULL, PREFIX_SERVER_OPTION },
{ "robust", 0, NULL, ROBUST_OPTION },
{ "target", 0, NULL, 'b' },
{ "winrt", 0, NULL, RT_OPTION },
{ "win32", 0, NULL, WIN32_OPTION },
{ "win64", 0, NULL, WIN64_OPTION },
{ "win32-align", 1, NULL, WIN32_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 }
};
@ -265,20 +278,24 @@ static void set_target( const char *target )
{
static const struct
{
const char *name;
syskind_t kind;
const char *name;
enum target_cpu cpu;
} cpu_names[] =
{
{ "i386", SYS_WIN32 },
{ "i486", SYS_WIN32 },
{ "i586", SYS_WIN32 },
{ "i686", SYS_WIN32 },
{ "i786", SYS_WIN32 },
{ "amd64", SYS_WIN64 },
{ "x86_64", SYS_WIN64 },
{ "powerpc", SYS_WIN32 },
{ "arm", SYS_WIN32 },
{ "aarch64", SYS_WIN64 }
{ "i386", CPU_x86 },
{ "i486", CPU_x86 },
{ "i586", CPU_x86 },
{ "i686", CPU_x86 },
{ "i786", CPU_x86 },
{ "amd64", CPU_x86_64 },
{ "x86_64", CPU_x86_64 },
{ "powerpc", CPU_POWERPC },
{ "arm", CPU_ARM },
{ "armv5", CPU_ARM },
{ "armv6", CPU_ARM },
{ "armv7", CPU_ARM },
{ "arm64", CPU_ARM64 },
{ "aarch64", CPU_ARM64 },
};
unsigned int i;
@ -292,7 +309,7 @@ static void set_target( const char *target )
{
if (!strcmp( cpu_names[i].name, spec ))
{
typelib_kind = cpu_names[i].kind;
target_cpu = cpu_names[i].cpu;
free( spec );
return;
}
@ -487,6 +504,11 @@ static void write_id_data_stmts(const statement_list_t *stmts)
uuid = get_attrp(type->attrs, ATTR_UUID);
write_id_guid(idfile, "IID", is_attr(type->attrs, ATTR_DISPINTERFACE) ? "DIID" : "IID",
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)
{
@ -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_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, "#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");
start_cplusplus_guard(idfile);
@ -605,12 +632,10 @@ int main(int argc,char *argv[])
use_abi_namespace = 1;
break;
case WIN32_OPTION:
do_win32 = 1;
do_win64 = 0;
pointer_size = 4;
break;
case WIN64_OPTION:
do_win32 = 0;
do_win64 = 1;
pointer_size = 8;
break;
case WIN32_ALIGN_OPTION:
win32_packing = strtol(optarg, NULL, 0);
@ -622,9 +647,15 @@ int main(int argc,char *argv[])
if(win64_packing != 2 && win64_packing != 4 && win64_packing != 8)
error("Packing must be one of 2, 4 or 8\n");
break;
case ACF_OPTION:
acf_name = xstrdup(optarg);
break;
case APP_CONFIG_OPTION:
/* widl does not distinguish between app_mode and default mode,
but we ignore this option for midl compatibility */
break;
case ROBUST_OPTION:
/* FIXME: Support robust option */
break;
case 'b':
set_target( optarg );
@ -657,8 +688,8 @@ int main(int argc,char *argv[])
wpp_add_include_path(optarg);
break;
case 'm':
if (!strcmp( optarg, "32" )) typelib_kind = SYS_WIN32;
else if (!strcmp( optarg, "64" )) typelib_kind = SYS_WIN64;
if (!strcmp( optarg, "32" )) pointer_size = 4;
else if (!strcmp( optarg, "64" )) pointer_size = 8;
break;
case 'N':
no_preprocess = 1;
@ -725,6 +756,26 @@ int main(int argc,char *argv[])
wpp_add_include_path(DEFAULT_INCLUDE_DIR);
#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 (output_name && do_everything && !do_header && !do_typelib && !do_proxies &&
!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_dlldata;
extern int old_names;
extern int do_win32;
extern int do_win64;
extern int win32_packing;
extern int win64_packing;
extern int winrt_mode;
@ -55,6 +53,7 @@ extern int use_abi_namespace;
extern char *input_name;
extern char *input_idl_name;
extern char *acf_name;
extern char *header_name;
extern char *header_token;
extern char *local_stubs_name;
@ -76,6 +75,13 @@ extern time_t now;
extern int line_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
{
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_server(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 write_local_stubs(const statement_list_t *stmts);
extern void write_dlldata(const statement_list_t *stmts);

View file

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

View file

@ -57,6 +57,7 @@
#include "hash.h"
#include "typetree.h"
#include "parser.h"
#include "typegen.h"
#ifdef __REACTOS__
#define S_OK 0
@ -791,8 +792,6 @@ static int encode_type(
int vt, /* [I] vt to encode */
type_t *type, /* [I] type */
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 default_type;
@ -805,8 +804,6 @@ static int encode_type(
chat("encode_type vt %d type %p\n", vt, type);
default_type = 0x80000000 | (vt << 16) | vt;
if (!width) width = &scratch;
if (!alignment) alignment = &scratch;
if (!decoded_size) decoded_size = &scratch;
*decoded_size = 0;
@ -815,38 +812,20 @@ static int encode_type(
case VT_I1:
case VT_UI1:
*encoded_type = default_type;
*width = 1;
*alignment = 1;
break;
case 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;
case 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;
case VT_UI2:
case VT_I2:
case VT_BOOL:
*encoded_type = default_type;
*width = 2;
*alignment = 2;
break;
case VT_I4:
@ -855,56 +834,40 @@ static int encode_type(
case VT_ERROR:
case VT_HRESULT:
*encoded_type = default_type;
*width = 4;
*alignment = 4;
break;
case VT_R8:
case VT_I8:
case VT_UI8:
*encoded_type = default_type;
*width = 8;
*alignment = 8;
break;
case VT_CY:
case VT_DATE:
*encoded_type = default_type;
*width = 8;
*alignment = 8;
break;
case VT_DECIMAL:
*encoded_type = default_type;
*width = 16;
*alignment = 8;
break;
case VT_VOID:
*encoded_type = 0x80000000 | (VT_EMPTY << 16) | vt;
*width = 0;
*alignment = 1;
break;
case VT_UNKNOWN:
case VT_DISPATCH:
case VT_BSTR:
*encoded_type = default_type;
*width = pointer_size;
*alignment = 4;
break;
case VT_VARIANT:
*encoded_type = default_type;
*width = 8 + 2 * pointer_size;
*alignment = 8;
break;
case VT_LPSTR:
case VT_LPWSTR:
*encoded_type = 0xfffe0000 | vt;
*width = pointer_size;
*alignment = 4;
break;
case VT_PTR:
@ -920,14 +883,12 @@ static int encode_type(
next_vt = VT_VOID;
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
* add another */
if(next_vt == VT_DISPATCH || next_vt == VT_UNKNOWN) {
chat("encode_type: skipping ptr\n");
*encoded_type = target_type;
*width = pointer_size;
*alignment = 4;
*decoded_size = child_size;
break;
}
@ -956,8 +917,6 @@ static int encode_type(
*encoded_type = typeoffset;
*width = pointer_size;
*alignment = 4;
*decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size;
break;
}
@ -967,7 +926,8 @@ static int encode_type(
type_t *element_type = type_alias_get_aliasee(type_array_get_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) {
typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
@ -993,26 +953,39 @@ static int encode_type(
*encoded_type = typeoffset;
*width = pointer_size;
*alignment = 4;
*decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size;
break;
}
case VT_USERDEFINED:
{
importinfo_t *importinfo;
int typeinfo_offset;
/* 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))
type = type_alias_get_aliasee(type);
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 */
while (type_is_alias(type) && !is_attr(type->attrs, ATTR_PUBLIC))
type = type_alias_get_aliasee(type);
chat("encode_type: VT_USERDEFINED - type %p name = %s real type %d idx %d\n", type,
type->name, type_get_type(type), type->typelib_idx);
chat("encode_type: VT_USERDEFINED - adding new type %s, real type %d\n",
type->name, type_get_type(type));
if(type->typelib_idx == -1) {
chat("encode_type: trying to ref not added type\n");
switch (type_get_type(type)) {
switch (type_get_type(type))
{
case TYPE_STRUCT:
add_structure_typeinfo(typelib, type);
break;
@ -1032,9 +1005,9 @@ static int encode_type(
error("encode_type: VT_USERDEFINED - unhandled type %d\n",
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) {
typedata = (void *)&typelib->typelib_segment_data[MSFT_SEG_TYPEDESC][typeoffset];
if ((typedata[0] == ((0x7fff << 16) | VT_USERDEFINED)) && (typedata[1] == typeinfo_offset)) break;
@ -1049,16 +1022,12 @@ static int encode_type(
}
*encoded_type = typeoffset;
*width = 0;
*alignment = 1;
break;
}
default:
error("encode_type: unrecognized type %d.\n", vt);
*encoded_type = default_type;
*width = 0;
*alignment = 1;
break;
}
@ -1075,8 +1044,6 @@ static int encode_var(
type_t *type, /* [I] The type description to encode. */
var_t *var, /* [I] The var to encode. */
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 typeoffset;
@ -1086,8 +1053,6 @@ static int encode_var(
int vt;
int scratch;
if (!width) width = &scratch;
if (!alignment) alignment = &scratch;
if (!decoded_size) decoded_size = &scratch;
*decoded_size = 0;
@ -1106,7 +1071,7 @@ static int encode_var(
++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);
arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];
@ -1132,7 +1097,6 @@ static int encode_var(
typedata[1] = arrayoffset;
*encoded_type = typeoffset;
*width = *width * elements;
*decoded_size = 20 /*sizeof(ARRAYDESC)*/ + (num_dims - 1) * 8 /*sizeof(SAFEARRAYBOUND)*/;
return 0;
}
@ -1141,15 +1105,12 @@ static int encode_var(
if (vt == VT_PTR) {
type_t *ref = is_ptr(type) ?
type_pointer_get_ref(type) : type_array_get_element(type);
int skip_ptr = encode_var(typelib, ref, var,
&target_type, NULL, NULL, &child_size);
int skip_ptr = encode_var(typelib, ref, var, &target_type, &child_size);
if(skip_ptr == 2) {
chat("encode_var: skipping ptr\n");
*encoded_type = target_type;
*decoded_size = child_size;
*width = pointer_size;
*alignment = 4;
return 0;
}
@ -1163,7 +1124,7 @@ static int encode_var(
if (target_type & 0x80000000) {
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));
mix_field = get_type_vt(element_type) | VT_ARRAY | VT_BYREF;
} else {
@ -1180,15 +1141,13 @@ static int encode_var(
*encoded_type = typeoffset;
*width = pointer_size;
*alignment = 4;
*decoded_size = 8 /*sizeof(TYPEDESC)*/ + child_size;
return 0;
}
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
* add another */
if(vt == VT_DISPATCH || vt == VT_UNKNOWN) return 2;
@ -1210,59 +1169,79 @@ static unsigned int get_ulong_val(unsigned int val, int vt)
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)
{
switch(vt) {
case VT_I2:
case VT_I4:
case VT_R4:
case VT_BOOL:
case VT_I1:
case VT_UI1:
case VT_UI2:
case VT_UI4:
case VT_INT:
case VT_UINT:
case VT_HRESULT:
case VT_PTR:
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);
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], &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++;
}
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;
}
default:
warning("can't write value of type %d yet\n", vt);
}
return;
}
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) {
case VT_I2:
case VT_I4:
case VT_R4:
case VT_BOOL:
case VT_I1:
case VT_UI1:
case VT_UI2:
case VT_UI4:
case VT_INT:
case VT_UINT:
case VT_HRESULT:
break;
default:
warning("can't write value of type %d yet\n", vt);
return;
}
}
write_int_value(typelib, out, vt, expr->cval);
}
static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid,
@ -1280,7 +1259,10 @@ static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid,
guidentry.next_hash = -1;
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);
@ -1293,33 +1275,6 @@ static HRESULT set_custdata(msft_typelib_t *typelib, REFGUID guid,
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)
{
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 */
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[3] = ((52 /*sizeof(FUNCDESC)*/ + decoded_size) << 16) | typeinfo->typeinfo->cbSizeVft;
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;
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 ) {
switch(attr->type) {
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 */
if (expr->type == EXPR_STRLIT || expr->type == EXPR_WSTRLIT)
{
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);
}
write_default_value(typeinfo->typelib, arg->type, (expr_t *)attr->u.pval, defaultdata);
break;
}
case ATTR_IN:
@ -1663,8 +1606,7 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
int offset, id;
unsigned int typedata_size;
INT *typedata;
int var_datawidth;
int var_alignment;
unsigned int var_datawidth, var_alignment = 0;
int var_type_size, var_kind = 0 /* VAR_PERINSTANCE */;
int alignment;
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;
/* figure out type widths and whatnot */
encode_var(typeinfo->typelib, var->type, var, &typedata[1], &var_datawidth,
&var_alignment, &var_type_size);
var_datawidth = type_memsize_and_alignment(var->type, &var_alignment);
encode_var(typeinfo->typelib, var->type, var, &typedata[1], &var_type_size);
/* pad out starting position to data width */
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) {
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_type_size += 16; /* sizeof(VARIANT) */
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:
var_kind = 3; /* VAR_DISPATCH */
typeinfo->datawidth = pointer_size;
var_alignment = 4;
break;
default:
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)
{
int num_parents = 0, num_funcs = 0;
importinfo_t *importinfo = NULL;
const statement_t *stmt_func;
type_t *inherit, *ref;
int idx = 0;
var_t *func;
var_t *var;
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)
return;
@ -2051,11 +2010,31 @@ static void add_dispinterface_typeinfo(msft_typelib_t *typelib, type_t *dispinte
dispinterface->attrs);
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 */
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 */
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;
msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs);
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))
if (derived->name && !strcmp(derived->name, "IDispatch"))
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))
add_impl_type(msft_typeinfo, type_iface_get_inherit(interface),
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)
{
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;
if (-1 < tdef->typelib_idx)
@ -2225,8 +2202,8 @@ static void add_typedef_typeinfo(msft_typelib_t *typelib, type_t *tdef)
else
duplicate = 1;
encode_type(typelib, get_type_vt(type), type,
&datatype1, &size, &alignment, &datatype2);
encode_type(typelib, get_type_vt(type), type, &datatype1, &datatype2);
size = type_memsize_and_alignment(type, &alignment);
if (msft_typeinfo)
{
@ -2367,6 +2344,7 @@ static void add_type_typeinfo(msft_typelib_t *typelib, type_t *type)
break;
case TYPE_BASIC:
case TYPE_POINTER:
case TYPE_ARRAY:
break;
default:
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 );
add_output_to_resources( "TYPELIB", typelib_id );
output_typelib_regscript( typelib->typelib );
#ifdef __REACTOS__
flush_output_resources( typelib_name );
#endif
}
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}};
char info_string[128];
pointer_size = (typelib_kind == SYS_WIN64) ? 8 : 4;
msft = xmalloc(sizeof(*msft));
memset(msft, 0, sizeof(*msft));
msft->typelib = typelib;
@ -2696,7 +2674,7 @@ int create_msft_typelib(typelib_t *typelib)
ctl2_init_header(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

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