widl: Remove var_t's ptr_level field and start write_pointers.
This commit is contained in:
parent
44e3200a8d
commit
ef433e2792
|
@ -114,6 +114,18 @@ s_sum_fixed_array(int a[5])
|
|||
return a[0] + a[1] + a[2] + a[3] + a[4];
|
||||
}
|
||||
|
||||
int
|
||||
s_pints_sum(pints_t *pints)
|
||||
{
|
||||
return *pints->pi + **pints->ppi + ***pints->pppi;
|
||||
}
|
||||
|
||||
double
|
||||
s_ptypes_sum(ptypes_t *pt)
|
||||
{
|
||||
return *pt->pc + *pt->ps + *pt->pl + *pt->pf + *pt->pd;
|
||||
}
|
||||
|
||||
void
|
||||
s_stop(void)
|
||||
{
|
||||
|
@ -155,9 +167,14 @@ basic_tests(void)
|
|||
static char string[] = "I am a string";
|
||||
static int f[5] = {1, 3, 0, -2, -4};
|
||||
static vector_t a = {1, 3, 7};
|
||||
pints_t pints;
|
||||
ptypes_t ptypes;
|
||||
int i1, i2, i3, *pi2, *pi3, **ppi3;
|
||||
double u, v;
|
||||
float s, t;
|
||||
long q, r;
|
||||
short h;
|
||||
char c;
|
||||
int x;
|
||||
|
||||
ok(int_return() == INT_CODE, "RPC int_return\n");
|
||||
|
@ -191,6 +208,29 @@ basic_tests(void)
|
|||
ok(q == 9, "RPC square_half_long\n");
|
||||
ok(r == 1, "RPC square_half_long\n");
|
||||
|
||||
i1 = 19;
|
||||
i2 = -3;
|
||||
i3 = -29;
|
||||
pi2 = &i2;
|
||||
pi3 = &i3;
|
||||
ppi3 = &pi3;
|
||||
pints.pi = &i1;
|
||||
pints.ppi = &pi2;
|
||||
pints.pppi = &ppi3;
|
||||
ok(pints_sum(&pints) == -13, "RPC pints_sum\n");
|
||||
|
||||
c = 10;
|
||||
h = 3;
|
||||
q = 14;
|
||||
s = -5.0f;
|
||||
u = 11.0;
|
||||
ptypes.pc = &c;
|
||||
ptypes.ps = &h;
|
||||
ptypes.pl = &q;
|
||||
ptypes.pf = &s;
|
||||
ptypes.pd = &u;
|
||||
ok(ptypes_sum(&ptypes) == 33.0, "RPC ptypes_sum\n");
|
||||
|
||||
ok(sum_fixed_array(f) == -2, "RPC sum_fixed_array\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,22 @@ typedef struct tag_vector
|
|||
]
|
||||
interface IServer
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
int *pi;
|
||||
int **ppi;
|
||||
int ***pppi;
|
||||
} pints_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *pc;
|
||||
short *ps;
|
||||
long *pl;
|
||||
float *pf;
|
||||
double *pd;
|
||||
} ptypes_t;
|
||||
|
||||
int int_return(void);
|
||||
int square(int x);
|
||||
int sum(int x, int y);
|
||||
|
@ -42,5 +58,7 @@ interface IServer
|
|||
float square_half_float(float x, [out] float *y);
|
||||
long square_half_long(long x, [out] long *y);
|
||||
int sum_fixed_array(int a[5]);
|
||||
int pints_sum(pints_t *pints);
|
||||
double ptypes_sum(ptypes_t *ptypes);
|
||||
void stop(void);
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
|
|||
}
|
||||
}
|
||||
|
||||
write_type(client, def->type, def);
|
||||
write_type(client, def->type);
|
||||
fprintf(client, " ");
|
||||
write_prefix_name(client, prefix_client, def);
|
||||
fprintf(client, "(\n");
|
||||
|
@ -133,10 +133,10 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
|
|||
indent++;
|
||||
|
||||
/* declare return value '_RetVal' */
|
||||
if (!is_void(def->type, NULL))
|
||||
if (!is_void(def->type))
|
||||
{
|
||||
print_client("");
|
||||
write_type(client, def->type, def);
|
||||
write_type(client, def->type);
|
||||
fprintf(client, " _RetVal;\n");
|
||||
}
|
||||
|
||||
|
@ -226,7 +226,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
|
|||
write_remoting_arguments(client, indent, func, type_offset, PASS_OUT, PHASE_UNMARSHAL);
|
||||
|
||||
/* unmarshal return value */
|
||||
if (!is_void(def->type, NULL))
|
||||
if (!is_void(def->type))
|
||||
print_phase_basetype(client, indent, PHASE_UNMARSHAL, PASS_RETURN, def, "_RetVal");
|
||||
|
||||
/* update proc_offset */
|
||||
|
@ -235,7 +235,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
|
|||
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
|
||||
*proc_offset += get_size_procformatstring_var(var);
|
||||
}
|
||||
if (!is_void(def->type, NULL))
|
||||
if (!is_void(def->type))
|
||||
*proc_offset += get_size_procformatstring_var(def);
|
||||
else
|
||||
*proc_offset += 2; /* FC_END and FC_PAD */
|
||||
|
@ -257,7 +257,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
|
|||
|
||||
|
||||
/* emit return code */
|
||||
if (!is_void(def->type, NULL))
|
||||
if (!is_void(def->type))
|
||||
{
|
||||
fprintf(client, "\n");
|
||||
print_client("return _RetVal;\n");
|
||||
|
|
|
@ -46,6 +46,26 @@ static void indent(FILE *h, int delta)
|
|||
if (delta > 0) indentation += delta;
|
||||
}
|
||||
|
||||
int is_ptrchain_attr(const var_t *var, enum attr_type t)
|
||||
{
|
||||
if (is_attr(var->attrs, t))
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
type_t *type = var->type;
|
||||
for (;;)
|
||||
{
|
||||
if (is_attr(type->attrs, t))
|
||||
return 1;
|
||||
else if (type->kind == TKIND_ALIAS)
|
||||
type = type->orig;
|
||||
else if (is_ptr(type))
|
||||
type = type->ref;
|
||||
else return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int is_attr(const attr_list_t *list, enum attr_type t)
|
||||
{
|
||||
const attr_t *attr;
|
||||
|
@ -70,9 +90,8 @@ unsigned long get_attrv(const attr_list_t *list, enum attr_type t)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int is_void(const type_t *t, const var_t *v)
|
||||
int is_void(const type_t *t)
|
||||
{
|
||||
if (v && v->ptr_level) return 0;
|
||||
if (!t->type && !t->ref) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -105,15 +124,6 @@ void write_guid(FILE *f, const char *guid_prefix, const char *name, const UUID *
|
|||
uuid->Data4[6], uuid->Data4[7]);
|
||||
}
|
||||
|
||||
static void write_pident(FILE *h, const var_t *v)
|
||||
{
|
||||
int c;
|
||||
for (c=0; c<v->ptr_level; c++) {
|
||||
fprintf(h, "*");
|
||||
}
|
||||
if (v->name) fprintf(h, "%s", v->name);
|
||||
}
|
||||
|
||||
void write_name(FILE *h, const var_t *v)
|
||||
{
|
||||
if (is_attr( v->attrs, ATTR_PROPGET ))
|
||||
|
@ -159,11 +169,9 @@ static void write_field(FILE *h, var_t *v)
|
|||
if (!v) return;
|
||||
if (v->type) {
|
||||
indent(h, 0);
|
||||
write_type(h, v->type, NULL);
|
||||
if (get_name(v)) {
|
||||
fprintf(h, " ");
|
||||
write_pident(h, v);
|
||||
}
|
||||
write_type(h, v->type);
|
||||
if (get_name(v))
|
||||
fprintf(h, " %s", v->name);
|
||||
else {
|
||||
/* not all C/C++ compilers support anonymous structs and unions */
|
||||
switch (v->type->type) {
|
||||
|
@ -220,10 +228,8 @@ static int needs_space_after(type_t *t)
|
|||
return t->kind == TKIND_ALIAS || ! is_ptr(t);
|
||||
}
|
||||
|
||||
void write_type(FILE *h, type_t *t, const var_t *v)
|
||||
void write_type(FILE *h, type_t *t)
|
||||
{
|
||||
int c;
|
||||
|
||||
if (t->is_const) fprintf(h, "const ");
|
||||
|
||||
if (t->kind == TKIND_ALIAS) fprintf(h, "%s", t->name);
|
||||
|
@ -278,18 +284,13 @@ void write_type(FILE *h, type_t *t, const var_t *v)
|
|||
case RPC_FC_UP:
|
||||
case RPC_FC_FP:
|
||||
case RPC_FC_OP:
|
||||
if (t->ref) write_type(h, t->ref, NULL);
|
||||
if (t->ref) write_type(h, t->ref);
|
||||
fprintf(h, "%s*", needs_space_after(t->ref) ? " " : "");
|
||||
break;
|
||||
default:
|
||||
fprintf(h, "%s", t->name);
|
||||
}
|
||||
}
|
||||
if (v) {
|
||||
for (c=0; c<v->ptr_level; c++) {
|
||||
fprintf(h, "*");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -358,7 +359,7 @@ void write_user_types(void)
|
|||
void write_typedef(type_t *type)
|
||||
{
|
||||
fprintf(header, "typedef ");
|
||||
write_type(header, type->orig, NULL);
|
||||
write_type(header, type->orig);
|
||||
fprintf(header, "%s%s;\n", needs_space_after(type->orig) ? " " : "", type->name);
|
||||
}
|
||||
|
||||
|
@ -396,13 +397,13 @@ void write_expr(FILE *h, const expr_t *e, int brackets)
|
|||
break;
|
||||
case EXPR_CAST:
|
||||
fprintf(h, "(");
|
||||
write_type(h, e->u.tref, NULL);
|
||||
write_type(h, e->u.tref);
|
||||
fprintf(h, ")");
|
||||
write_expr(h, e->ref, 1);
|
||||
break;
|
||||
case EXPR_SIZEOF:
|
||||
fprintf(h, "sizeof(");
|
||||
write_type(h, e->u.tref, NULL);
|
||||
write_type(h, e->u.tref);
|
||||
fprintf(h, ")");
|
||||
break;
|
||||
case EXPR_SHL:
|
||||
|
@ -451,11 +452,9 @@ void write_constdef(const var_t *v)
|
|||
void write_externdef(const var_t *v)
|
||||
{
|
||||
fprintf(header, "extern const ");
|
||||
write_type(header, v->type, NULL);
|
||||
if (get_name(v)) {
|
||||
fprintf(header, " ");
|
||||
write_pident(header, v);
|
||||
}
|
||||
write_type(header, v->type);
|
||||
if (get_name(v))
|
||||
fprintf(header, " %s", v->name);
|
||||
fprintf(header, ";\n\n");
|
||||
}
|
||||
|
||||
|
@ -486,7 +485,7 @@ int has_out_arg_or_return(const func_t *func)
|
|||
{
|
||||
const var_t *var;
|
||||
|
||||
if (!is_void(func->def->type, NULL))
|
||||
if (!is_void(func->def->type))
|
||||
return 1;
|
||||
|
||||
if (!func->args)
|
||||
|
@ -579,7 +578,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
|
|||
}
|
||||
else fprintf(h, ",");
|
||||
}
|
||||
write_type(h, arg->type, arg);
|
||||
write_type(h, arg->type);
|
||||
if (arg->args)
|
||||
{
|
||||
fprintf(h, " (STDMETHODCALLTYPE *");
|
||||
|
@ -612,7 +611,7 @@ static void write_cpp_method_def(const type_t *iface)
|
|||
if (!is_callas(def->attrs)) {
|
||||
indent(header, 0);
|
||||
fprintf(header, "virtual ");
|
||||
write_type(header, def->type, def);
|
||||
write_type(header, def->type);
|
||||
fprintf(header, " STDMETHODCALLTYPE ");
|
||||
write_name(header, def);
|
||||
fprintf(header, "(\n");
|
||||
|
@ -637,7 +636,7 @@ static void do_write_c_method_def(const type_t *iface, const char *name)
|
|||
const var_t *def = cur->def;
|
||||
if (!is_callas(def->attrs)) {
|
||||
indent(header, 0);
|
||||
write_type(header, def->type, def);
|
||||
write_type(header, def->type);
|
||||
fprintf(header, " (STDMETHODCALLTYPE *");
|
||||
write_name(header, def);
|
||||
fprintf(header, ")(\n");
|
||||
|
@ -670,7 +669,7 @@ static void write_method_proto(const type_t *iface)
|
|||
|
||||
if (!is_local(def->attrs)) {
|
||||
/* proxy prototype */
|
||||
write_type(header, def->type, def);
|
||||
write_type(header, def->type);
|
||||
fprintf(header, " CALLBACK %s_", iface->name);
|
||||
write_name(header, def);
|
||||
fprintf(header, "_Proxy(\n");
|
||||
|
@ -693,14 +692,14 @@ static void write_method_proto(const type_t *iface)
|
|||
if (&m->entry != iface->funcs) {
|
||||
const var_t *mdef = m->def;
|
||||
/* proxy prototype - use local prototype */
|
||||
write_type(header, mdef->type, mdef);
|
||||
write_type(header, mdef->type);
|
||||
fprintf(header, " CALLBACK %s_", iface->name);
|
||||
write_name(header, mdef);
|
||||
fprintf(header, "_Proxy(\n");
|
||||
write_args(header, m->args, iface->name, 1, TRUE);
|
||||
fprintf(header, ");\n");
|
||||
/* stub prototype - use remotable prototype */
|
||||
write_type(header, def->type, def);
|
||||
write_type(header, def->type);
|
||||
fprintf(header, " __RPC_STUB %s_", iface->name);
|
||||
write_name(header, mdef);
|
||||
fprintf(header, "_Stub(\n");
|
||||
|
@ -719,7 +718,7 @@ static void write_function_proto(const type_t *iface, const func_t *fun, const c
|
|||
var_t *def = fun->def;
|
||||
|
||||
/* FIXME: do we need to handle call_as? */
|
||||
write_type(header, def->type, def);
|
||||
write_type(header, def->type);
|
||||
fprintf(header, " ");
|
||||
write_prefix_name(header, prefix, def);
|
||||
fprintf(header, "(\n");
|
||||
|
|
|
@ -21,16 +21,19 @@
|
|||
#ifndef __WIDL_HEADER_H
|
||||
#define __WIDL_HEADER_H
|
||||
|
||||
#include "widltypes.h"
|
||||
|
||||
extern int is_ptrchain_attr(const var_t *var, enum attr_type t);
|
||||
extern int is_attr(const attr_list_t *list, enum attr_type t);
|
||||
extern void *get_attrp(const attr_list_t *list, enum attr_type t);
|
||||
extern unsigned long get_attrv(const attr_list_t *list, enum attr_type t);
|
||||
extern int is_void(const type_t *t, const var_t *v);
|
||||
extern int is_void(const type_t *t);
|
||||
extern int is_conformant_array( const array_dims_t *array );
|
||||
extern int is_non_void(const expr_list_t *list);
|
||||
extern void write_name(FILE *h, const var_t *v);
|
||||
extern void write_prefix_name(FILE *h, const char *prefix, const var_t *v);
|
||||
extern const char* get_name(const var_t *v);
|
||||
extern void write_type(FILE *h, type_t *t, const var_t *v);
|
||||
extern void write_type(FILE *h, type_t *t);
|
||||
extern int is_object(const attr_list_t *list);
|
||||
extern int is_local(const attr_list_t *list);
|
||||
extern const var_t *is_callas(const attr_list_t *list);
|
||||
|
@ -52,16 +55,21 @@ extern int has_out_arg_or_return(const func_t *func);
|
|||
extern void write_guid(FILE *f, const char *guid_prefix, const char *name,
|
||||
const UUID *uuid);
|
||||
|
||||
static inline int is_string_type(const attr_list_t *attrs, int ptr_level, const array_dims_t *array)
|
||||
static inline int last_ptr(const type_t *type)
|
||||
{
|
||||
return (is_attr(attrs, ATTR_STRING) &&
|
||||
((ptr_level == 1 && !array) || (ptr_level == 0 && array)));
|
||||
return is_ptr(type) && !is_ptr(type->ref);
|
||||
}
|
||||
|
||||
static inline int is_array_type(const attr_list_t *attrs, int ptr_level, const array_dims_t *array)
|
||||
static inline int is_string_type(const attr_list_t *attrs, const type_t *type, const array_dims_t *array)
|
||||
{
|
||||
return ((ptr_level == 1 && !array && is_attr(attrs, ATTR_SIZEIS)) ||
|
||||
(ptr_level == 0 && array));
|
||||
return (is_attr(attrs, ATTR_STRING) &&
|
||||
((last_ptr(type) && !array) || (!is_ptr(type) && array)));
|
||||
}
|
||||
|
||||
static inline int is_array_type(const attr_list_t *attrs, const type_t *type, const array_dims_t *array)
|
||||
{
|
||||
return ((last_ptr(type) && !array && is_attr(attrs, ATTR_SIZEIS)) ||
|
||||
(!is_ptr(type) && array));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -79,11 +79,13 @@ static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, exp
|
|||
static type_t *make_type(unsigned char type, type_t *ref);
|
||||
static 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 void set_type(var_t *v, type_t *type, array_dims_t *arr);
|
||||
static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr);
|
||||
static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface);
|
||||
static ifref_t *make_ifref(type_t *iface);
|
||||
static var_list_t *append_var(var_list_t *list, var_t *var);
|
||||
static var_t *make_var(char *name);
|
||||
static pident_list_t *append_pident(pident_list_t *list, pident_t *p);
|
||||
static pident_t *make_pident(var_t *var);
|
||||
static func_list_t *append_func(func_list_t *list, func_t *func);
|
||||
static func_t *make_func(var_t *def, var_list_t *args);
|
||||
static type_t *make_class(char *name);
|
||||
|
@ -127,6 +129,8 @@ static void check_arg(var_t *arg);
|
|||
type_t *type;
|
||||
var_t *var;
|
||||
var_list_t *var_list;
|
||||
pident_t *pident;
|
||||
pident_list_t *pident_list;
|
||||
func_t *func;
|
||||
func_list_t *func_list;
|
||||
ifref_t *ifref;
|
||||
|
@ -234,8 +238,10 @@ static void check_arg(var_t *arg);
|
|||
%type <ifref> coclass_int
|
||||
%type <ifref_list> gbl_statements coclass_ints
|
||||
%type <var> arg field s_field case enum constdef externdef
|
||||
%type <var_list> m_args no_args args fields cases enums enum_list pident_list dispint_props
|
||||
%type <var> m_ident t_ident ident p_ident pident
|
||||
%type <var_list> m_args no_args args fields cases enums enum_list dispint_props
|
||||
%type <var> m_ident t_ident ident
|
||||
%type <pident> p_ident pident
|
||||
%type <pident_list> pident_list
|
||||
%type <func> funcdef
|
||||
%type <func_list> int_statements dispint_meths
|
||||
%type <type> coclass coclasshdr coclassdef
|
||||
|
@ -297,12 +303,12 @@ int_statements: { $$ = NULL; }
|
|||
statement: ';' {}
|
||||
| constdef ';' { if (!parse_only && do_header) { write_constdef($1); } }
|
||||
| cppquote {}
|
||||
| enumdef ';' { if (!parse_only && do_header) { write_type(header, $1, NULL); fprintf(header, ";\n\n"); } }
|
||||
| enumdef ';' { if (!parse_only && do_header) { write_type(header, $1); fprintf(header, ";\n\n"); } }
|
||||
| externdef ';' { if (!parse_only && do_header) { write_externdef($1); } }
|
||||
| import {}
|
||||
| structdef ';' { if (!parse_only && do_header) { write_type(header, $1, NULL); fprintf(header, ";\n\n"); } }
|
||||
| structdef ';' { if (!parse_only && do_header) { write_type(header, $1); fprintf(header, ";\n\n"); } }
|
||||
| typedef ';' {}
|
||||
| uniondef ';' { if (!parse_only && do_header) { write_type(header, $1, NULL); fprintf(header, ";\n\n"); } }
|
||||
| uniondef ';' { if (!parse_only && do_header) { write_type(header, $1); fprintf(header, ";\n\n"); } }
|
||||
;
|
||||
|
||||
cppquote: tCPPQUOTE '(' aSTRING ')' { if (!parse_only && do_header) fprintf(header, "%s\n", $3); }
|
||||
|
@ -339,22 +345,24 @@ args: arg { check_arg($1); $$ = append_var( NULL, $1 ); }
|
|||
;
|
||||
|
||||
/* split into two rules to get bison to resolve a tVOID conflict */
|
||||
arg: attributes type pident array { $$ = $3;
|
||||
set_type($$, $2, $4);
|
||||
arg: attributes type pident array { $$ = $3->var;
|
||||
set_type($$, $2, $3->ptr_level, $4);
|
||||
free($3);
|
||||
$$->attrs = $1;
|
||||
}
|
||||
| type pident array { $$ = $2;
|
||||
set_type($$, $1, $3);
|
||||
| type pident array { $$ = $2->var;
|
||||
set_type($$, $1, $2->ptr_level, $3);
|
||||
free($2);
|
||||
}
|
||||
| attributes type pident '(' m_args ')' { $$ = $3;
|
||||
$$->ptr_level--;
|
||||
set_type($$, $2, NULL);
|
||||
| attributes type pident '(' m_args ')' { $$ = $3->var;
|
||||
set_type($$, $2, $3->ptr_level - 1, NULL);
|
||||
free($3);
|
||||
$$->attrs = $1;
|
||||
$$->args = $5;
|
||||
}
|
||||
| type pident '(' m_args ')' { $$ = $2;
|
||||
$$->ptr_level--;
|
||||
set_type($$, $1, NULL);
|
||||
| type pident '(' m_args ')' { $$ = $2->var;
|
||||
set_type($$, $1, $2->ptr_level - 1, NULL);
|
||||
free($2);
|
||||
$$->args = $4;
|
||||
}
|
||||
;
|
||||
|
@ -482,7 +490,7 @@ case: tCASE expr ':' field { attr_t *a = make_attrp(ATTR_CASE, $2);
|
|||
;
|
||||
|
||||
constdef: tCONST type ident '=' expr_const { $$ = reg_const($3);
|
||||
set_type($$, $2, NULL);
|
||||
set_type($$, $2, 0, NULL);
|
||||
$$->eval = $5;
|
||||
}
|
||||
;
|
||||
|
@ -574,7 +582,7 @@ expr_const: expr { $$ = $1;
|
|||
;
|
||||
|
||||
externdef: tEXTERN tCONST type ident { $$ = $4;
|
||||
set_type($$, $3, NULL);
|
||||
set_type($$, $3, 0, NULL);
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -588,15 +596,21 @@ field: s_field ';' { $$ = $1; }
|
|||
| ';' { $$ = NULL; }
|
||||
;
|
||||
|
||||
s_field: m_attributes type pident array { $$ = $3; set_type($$, $2, $4); $$->attrs = $1; }
|
||||
s_field: m_attributes type pident array { $$ = $3->var;
|
||||
set_type($$, $2, $3->ptr_level, $4);
|
||||
free($3);
|
||||
$$->attrs = $1;
|
||||
}
|
||||
;
|
||||
|
||||
funcdef:
|
||||
m_attributes type callconv pident
|
||||
'(' m_args ')' { set_type($4, $2, NULL);
|
||||
$4->attrs = $1;
|
||||
$$ = make_func($4, $6);
|
||||
if (is_attr($4->attrs, ATTR_IN)) {
|
||||
'(' m_args ')' { var_t *v = $4->var;
|
||||
set_type(v, $2, $4->ptr_level, NULL);
|
||||
free($4);
|
||||
v->attrs = $1;
|
||||
$$ = make_func(v, $6);
|
||||
if (is_attr(v->attrs, ATTR_IN)) {
|
||||
yyerror("inapplicable attribute [in] for function '%s'",$$->def->name);
|
||||
}
|
||||
}
|
||||
|
@ -792,14 +806,14 @@ p_ident: '*' pident %prec PPTR { $$ = $2; $$->ptr_level++; }
|
|||
| tCONST p_ident { $$ = $2; /* FIXME */ }
|
||||
;
|
||||
|
||||
pident: ident
|
||||
pident: ident { $$ = make_pident($1); }
|
||||
| p_ident
|
||||
| '(' pident ')' { $$ = $2; }
|
||||
;
|
||||
|
||||
pident_list:
|
||||
pident { $$ = append_var( NULL, $1 ); }
|
||||
| pident_list ',' pident { $$ = append_var( $1, $3 ); }
|
||||
pident { $$ = append_pident( NULL, $1 ); }
|
||||
| pident_list ',' pident { $$ = append_pident( $1, $3 ); }
|
||||
;
|
||||
|
||||
pointer_type:
|
||||
|
@ -1185,6 +1199,7 @@ static type_t *make_type(unsigned char type, type_t *ref)
|
|||
t->funcs = NULL;
|
||||
t->fields = NULL;
|
||||
t->ifaces = NULL;
|
||||
t->typestring_offset = 0;
|
||||
t->ignore = parse_only;
|
||||
t->is_const = FALSE;
|
||||
t->sign = 0;
|
||||
|
@ -1195,10 +1210,13 @@ static type_t *make_type(unsigned char type, type_t *ref)
|
|||
return t;
|
||||
}
|
||||
|
||||
static void set_type(var_t *v, type_t *type, array_dims_t *arr)
|
||||
static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr)
|
||||
{
|
||||
v->type = type;
|
||||
v->array = arr;
|
||||
|
||||
for ( ; 0 < ptr_level; --ptr_level)
|
||||
v->type = make_type(RPC_FC_RP, v->type);
|
||||
}
|
||||
|
||||
static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface)
|
||||
|
@ -1237,7 +1255,6 @@ static var_t *make_var(char *name)
|
|||
{
|
||||
var_t *v = xmalloc(sizeof(var_t));
|
||||
v->name = name;
|
||||
v->ptr_level = 0;
|
||||
v->type = NULL;
|
||||
v->args = NULL;
|
||||
v->attrs = NULL;
|
||||
|
@ -1246,6 +1263,25 @@ static var_t *make_var(char *name)
|
|||
return v;
|
||||
}
|
||||
|
||||
static pident_list_t *append_pident(pident_list_t *list, pident_t *p)
|
||||
{
|
||||
if (!p) return list;
|
||||
if (!list) {
|
||||
list = xmalloc(sizeof(*list));
|
||||
list_init(list);
|
||||
}
|
||||
list_add_tail(list, &p->entry);
|
||||
return list;
|
||||
}
|
||||
|
||||
static pident_t *make_pident(var_t *var)
|
||||
{
|
||||
pident_t *p = xmalloc(sizeof(*p));
|
||||
p->var = var;
|
||||
p->ptr_level = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
static func_list_t *append_func(func_list_t *list, func_t *func)
|
||||
{
|
||||
if (!func) return list;
|
||||
|
@ -1326,10 +1362,10 @@ static type_t *reg_type(type_t *type, const char *name, int t)
|
|||
return type;
|
||||
}
|
||||
|
||||
static type_t *reg_typedefs(type_t *type, var_list_t *names, attr_list_t *attrs)
|
||||
static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *attrs)
|
||||
{
|
||||
type_t *ptr = type;
|
||||
const var_t *name;
|
||||
const pident_t *pident;
|
||||
int ptrc = 0;
|
||||
int is_str = is_attr(attrs, ATTR_STRING);
|
||||
unsigned char ptr_type = get_attrv(attrs, ATTR_POINTERTYPE);
|
||||
|
@ -1345,9 +1381,9 @@ static type_t *reg_typedefs(type_t *type, var_list_t *names, attr_list_t *attrs)
|
|||
c = t->type;
|
||||
if (c != RPC_FC_CHAR && c != RPC_FC_BYTE && c != RPC_FC_WCHAR)
|
||||
{
|
||||
name = LIST_ENTRY( list_head( names ), const var_t, entry );
|
||||
pident = LIST_ENTRY( list_head( pidents ), const pident_t, entry );
|
||||
yyerror("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays",
|
||||
name->name);
|
||||
pident->var->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1363,11 +1399,13 @@ static type_t *reg_typedefs(type_t *type, var_list_t *names, attr_list_t *attrs)
|
|||
type->name = gen_name();
|
||||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY( name, names, const var_t, entry )
|
||||
LIST_FOR_EACH_ENTRY( pident, pidents, const pident_t, entry )
|
||||
{
|
||||
var_t *name = pident->var;
|
||||
|
||||
if (name->name) {
|
||||
type_t *cur = ptr;
|
||||
int cptr = name->ptr_level;
|
||||
int cptr = pident->ptr_level;
|
||||
if (cptr > ptrc) {
|
||||
while (cptr > ptrc) {
|
||||
cur = ptr = make_type(RPC_FC_RP, cur);
|
||||
|
@ -1467,20 +1505,20 @@ static int get_struct_type(var_list_t *fields)
|
|||
{
|
||||
type_t *t = field->type;
|
||||
|
||||
if (field->ptr_level > 0)
|
||||
if (is_ptr(field->type))
|
||||
{
|
||||
has_pointer = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_string_type(field->attrs, 0, field->array))
|
||||
if (is_string_type(field->attrs, field->type, field->array))
|
||||
{
|
||||
has_conformance = 1;
|
||||
has_variance = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_array_type(field->attrs, 0, field->array))
|
||||
if (is_array_type(field->attrs, field->type, field->array))
|
||||
{
|
||||
if (field->array && is_conformant_array(field->array))
|
||||
{
|
||||
|
@ -1700,21 +1738,23 @@ static char *gen_name(void)
|
|||
return name;
|
||||
}
|
||||
|
||||
static void process_typedefs(var_list_t *names)
|
||||
static void process_typedefs(pident_list_t *pidents)
|
||||
{
|
||||
var_t *name, *next;
|
||||
pident_t *pident, *next;
|
||||
|
||||
if (!names) return;
|
||||
LIST_FOR_EACH_ENTRY_SAFE( name, next, names, var_t, entry )
|
||||
if (!pidents) return;
|
||||
LIST_FOR_EACH_ENTRY_SAFE( pident, next, pidents, pident_t, entry )
|
||||
{
|
||||
type_t *type = find_type(name->name, 0);
|
||||
var_t *var = pident->var;
|
||||
type_t *type = find_type(var->name, 0);
|
||||
|
||||
if (! parse_only && do_header)
|
||||
write_typedef(type);
|
||||
if (in_typelib && type->attrs)
|
||||
add_typelib_entry(type);
|
||||
|
||||
free(name);
|
||||
free(pident);
|
||||
free(var);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@ static void clear_output_vars( const var_list_t *args )
|
|||
|
||||
int is_var_ptr(const var_t *v)
|
||||
{
|
||||
return v->ptr_level || is_ptr(v->type);
|
||||
return is_ptr(v->type);
|
||||
}
|
||||
|
||||
int cant_be_null(const var_t *v)
|
||||
|
@ -247,12 +247,17 @@ static void proxy_free_variables( var_list_t *args, unsigned int type_offset )
|
|||
if (!args) return;
|
||||
LIST_FOR_EACH_ENTRY( arg, args, const var_t, entry )
|
||||
{
|
||||
size_t start_offset;
|
||||
size_t size_type = get_size_typeformatstring_var(arg, &start_offset);
|
||||
start_offset += type_offset;
|
||||
|
||||
if (is_attr(arg->attrs, ATTR_OUT))
|
||||
{
|
||||
free_variable( arg, type_offset );
|
||||
fprintf(proxy, "\n");
|
||||
}
|
||||
type_offset += get_size_typeformatstring_var(arg);
|
||||
|
||||
type_offset += size_type;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,11 +265,11 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
|
|||
unsigned int proc_offset, unsigned int *type_offset)
|
||||
{
|
||||
var_t *def = cur->def;
|
||||
int has_ret = !is_void(def->type, def);
|
||||
int has_ret = !is_void(def->type);
|
||||
unsigned int offset;
|
||||
|
||||
indent = 0;
|
||||
write_type(proxy, def->type, def);
|
||||
write_type(proxy, def->type);
|
||||
print_proxy( " STDMETHODCALLTYPE %s_", iface->name);
|
||||
write_name(proxy, def);
|
||||
print_proxy( "_Proxy(\n");
|
||||
|
@ -275,7 +280,7 @@ static void gen_proxy(type_t *iface, const func_t *cur, int idx,
|
|||
/* local variables */
|
||||
if (has_ret) {
|
||||
print_proxy( "" );
|
||||
write_type(proxy, def->type, def);
|
||||
write_type(proxy, def->type);
|
||||
print_proxy( " _RetVal;\n");
|
||||
}
|
||||
print_proxy( "RPC_MESSAGE _RpcMessage;\n" );
|
||||
|
@ -355,7 +360,7 @@ static void gen_stub(type_t *iface, const func_t *cur, const char *cas,
|
|||
{
|
||||
var_t *def = cur->def;
|
||||
const var_t *arg;
|
||||
int has_ret = !is_void(def->type, def);
|
||||
int has_ret = !is_void(def->type);
|
||||
unsigned int offset;
|
||||
|
||||
indent = 0;
|
||||
|
|
|
@ -192,7 +192,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
|
|||
assign_stub_out_args(server, indent, func);
|
||||
|
||||
/* Call the real server function */
|
||||
if (!is_void(def->type, NULL))
|
||||
if (!is_void(def->type))
|
||||
print_server("_RetVal = ");
|
||||
else
|
||||
print_server("");
|
||||
|
@ -246,7 +246,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset, unsig
|
|||
write_remoting_arguments(server, indent, func, type_offset, PASS_OUT, PHASE_MARSHAL);
|
||||
|
||||
/* marshall the return value */
|
||||
if (!is_void(def->type, NULL))
|
||||
if (!is_void(def->type))
|
||||
print_phase_basetype(server, indent, PHASE_MARSHAL, PASS_RETURN, def, "_RetVal");
|
||||
|
||||
indent--;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -42,7 +42,7 @@ void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, enu
|
|||
void write_remoting_arguments(FILE *file, int indent, const func_t *func, unsigned int *type_offset, enum pass pass, enum remoting_phase phase);
|
||||
size_t get_size_procformatstring_var(const var_t *var);
|
||||
size_t get_size_procformatstring_func(const func_t *func);
|
||||
size_t get_size_typeformatstring_var(const var_t *var);
|
||||
size_t get_size_typeformatstring_var(const var_t *var, size_t *start_offset);
|
||||
size_t get_size_procformatstring(const ifref_list_t *ifaces, int for_objects);
|
||||
size_t get_size_typeformatstring(const ifref_list_t *ifaces, int for_objects);
|
||||
void assign_stub_out_args( FILE *file, int indent, const func_t *func );
|
||||
|
|
|
@ -39,6 +39,7 @@ typedef struct _expr_t expr_t;
|
|||
typedef struct _type_t type_t;
|
||||
typedef struct _typeref_t typeref_t;
|
||||
typedef struct _var_t var_t;
|
||||
typedef struct _pident_t pident_t;
|
||||
typedef struct _func_t func_t;
|
||||
typedef struct _ifref_t ifref_t;
|
||||
typedef struct _typelib_entry_t typelib_entry_t;
|
||||
|
@ -51,6 +52,7 @@ typedef struct list str_list_t;
|
|||
typedef struct list func_list_t;
|
||||
typedef struct list expr_list_t;
|
||||
typedef struct list var_list_t;
|
||||
typedef struct list pident_list_t;
|
||||
typedef struct list ifref_list_t;
|
||||
typedef struct list array_dims_t;
|
||||
|
||||
|
@ -205,6 +207,7 @@ struct _type_t {
|
|||
var_list_t *fields; /* interfaces, structures and enumerations */
|
||||
ifref_list_t *ifaces; /* coclasses */
|
||||
type_t *orig; /* dup'd types */
|
||||
unsigned int typestring_offset;
|
||||
int ignore, is_const, sign;
|
||||
int defined, written, user_types_registered;
|
||||
int typelib_idx;
|
||||
|
@ -212,7 +215,6 @@ struct _type_t {
|
|||
|
||||
struct _var_t {
|
||||
char *name;
|
||||
int ptr_level;
|
||||
array_dims_t *array;
|
||||
type_t *type;
|
||||
var_list_t *args; /* for function pointers */
|
||||
|
@ -223,6 +225,14 @@ struct _var_t {
|
|||
struct list entry;
|
||||
};
|
||||
|
||||
struct _pident_t {
|
||||
var_t *var;
|
||||
int ptr_level;
|
||||
|
||||
/* parser-internal */
|
||||
struct list entry;
|
||||
};
|
||||
|
||||
struct _func_t {
|
||||
var_t *def;
|
||||
var_list_t *args;
|
||||
|
|
|
@ -1049,7 +1049,8 @@ static void dump_type(type_t *t)
|
|||
|
||||
static int encode_var(
|
||||
msft_typelib_t *typelib, /* [I] The type library in which to encode the TYPEDESC. */
|
||||
var_t *var, /* [I] The type description to encode. */
|
||||
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. */
|
||||
|
@ -1061,20 +1062,18 @@ static int encode_var(
|
|||
int child_size;
|
||||
int vt;
|
||||
int scratch;
|
||||
type_t *type;
|
||||
|
||||
if (!width) width = &scratch;
|
||||
if (!alignment) alignment = &scratch;
|
||||
if (!decoded_size) decoded_size = &scratch;
|
||||
*decoded_size = 0;
|
||||
|
||||
chat("encode_var: var %p var->type %p var->type->name %s var->ptr_level %d var->type->ref %p\n",
|
||||
var, var->type, var->type->name ? var->type->name : "NULL", var->ptr_level, var->type->ref);
|
||||
if(var->ptr_level) {
|
||||
int skip_ptr;
|
||||
var->ptr_level--;
|
||||
skip_ptr = encode_var(typelib, var, &target_type, NULL, NULL, &child_size);
|
||||
var->ptr_level++;
|
||||
chat("encode_var: var %p type %p type->name %s type->ref %p\n",
|
||||
var, type, type->name ? type->name : "NULL", type->ref);
|
||||
|
||||
vt = get_type_vt(type);
|
||||
if (vt == VT_PTR) {
|
||||
int skip_ptr = encode_var(typelib, type->ref, var, &target_type, NULL, NULL, &child_size);
|
||||
|
||||
if(skip_ptr == 2) {
|
||||
chat("encode_var: skipping ptr\n");
|
||||
|
@ -1124,7 +1123,7 @@ static int encode_var(
|
|||
chat("array with %d dimensions\n", num_dims);
|
||||
array_save = var->array;
|
||||
var->array = NULL;
|
||||
encode_var(typelib, var, &target_type, width, alignment, NULL);
|
||||
encode_var(typelib, type, var, &target_type, width, alignment, NULL);
|
||||
var->array = array_save;
|
||||
arrayoffset = ctl2_alloc_segment(typelib, MSFT_SEG_ARRAYDESC, (2 + 2 * num_dims) * sizeof(long), 0);
|
||||
arraydata = (void *)&typelib->typelib_segment_data[MSFT_SEG_ARRAYDESC][arrayoffset];
|
||||
|
@ -1153,10 +1152,8 @@ static int encode_var(
|
|||
*decoded_size = 20 /*sizeof(ARRAYDESC)*/ + (num_dims - 1) * 8 /*sizeof(SAFEARRAYBOUND)*/;
|
||||
return 0;
|
||||
}
|
||||
dump_type(var->type);
|
||||
dump_type(type);
|
||||
|
||||
vt = get_type_vt(var->type);
|
||||
type = var->type;
|
||||
encode_type(typelib, vt, type, encoded_type, width, alignment, decoded_size);
|
||||
if(type->type == RPC_FC_IP) return 2;
|
||||
return 0;
|
||||
|
@ -1177,6 +1174,7 @@ static void write_value(msft_typelib_t* typelib, int *out, int vt, void *value)
|
|||
case VT_INT:
|
||||
case VT_UINT:
|
||||
case VT_HRESULT:
|
||||
case VT_PTR:
|
||||
{
|
||||
unsigned long *lv = value;
|
||||
if((*lv & 0x3ffffff) == *lv) {
|
||||
|
@ -1389,7 +1387,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int
|
|||
|
||||
/* fill out the basic type information */
|
||||
typedata[0] = typedata_size | (index << 16);
|
||||
encode_var(typeinfo->typelib, func->def, &typedata[1], NULL, NULL, &decoded_size);
|
||||
encode_var(typeinfo->typelib, func->def->type, func->def, &typedata[1], NULL, NULL, &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;
|
||||
|
@ -1427,7 +1425,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int
|
|||
|
||||
if(defaultdata) *defaultdata = -1;
|
||||
|
||||
encode_var(typeinfo->typelib, arg, paramdata, NULL, NULL, &decoded_size);
|
||||
encode_var(typeinfo->typelib, arg->type, arg, paramdata, NULL, NULL, &decoded_size);
|
||||
if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
|
||||
switch(attr->type) {
|
||||
case ATTR_DEFAULTVALUE_EXPR:
|
||||
|
@ -1629,7 +1627,7 @@ 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, &typedata[1], &var_datawidth,
|
||||
encode_var(typeinfo->typelib, var->type, var, &typedata[1], &var_datawidth,
|
||||
&var_alignment, &var_type_size);
|
||||
|
||||
/* pad out starting position to data width */
|
||||
|
|
Loading…
Reference in New Issue