Commit ef433e27 authored by Dan Hipschman's avatar Dan Hipschman Committed by Alexandre Julliard

widl: Remove var_t's ptr_level field and start write_pointers.

parent 44e3200a
......@@ -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_ptr(type) && !is_ptr(type->ref);
}
static inline int is_string_type(const attr_list_t *attrs, const type_t *type, const array_dims_t *array)
{
return (is_attr(attrs, ATTR_STRING) &&
((ptr_level == 1 && !array) || (ptr_level == 0 && array)));
((last_ptr(type) && !array) || (!is_ptr(type) && array)));
}
static inline int is_array_type(const attr_list_t *attrs, int ptr_level, const array_dims_t *array)
static inline int is_array_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 ((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--;
......
......@@ -59,7 +59,7 @@ struct expr_eval_routine
const expr_t *expr;
};
static size_t type_memsize(const type_t *t, int ptr_level, const array_dims_t *array, unsigned int *align);
static size_t type_memsize(const type_t *t, const array_dims_t *array, unsigned int *align);
static size_t fields_memsize(const var_list_t *fields, unsigned int *align);
const char *string_of_type(unsigned char type)
......@@ -235,7 +235,6 @@ static size_t write_procformatstring_var(FILE *file, int indent,
const var_t *var, int is_return, unsigned int *type_offset)
{
size_t size;
int ptr_level = var->ptr_level;
const type_t *type = var->type;
int is_in = is_attr(var->attrs, ATTR_IN);
......@@ -243,7 +242,7 @@ static size_t write_procformatstring_var(FILE *file, int indent,
if (!is_in && !is_out) is_in = TRUE;
if (ptr_level == 0 && !var->array && is_base_type(type->type))
if (!var->array && is_base_type(type->type))
{
if (is_return)
print_file(file, indent, "0x53, /* FC_RETURN_PARAM_BASETYPE */\n");
......@@ -281,7 +280,7 @@ static size_t write_procformatstring_var(FILE *file, int indent,
print_file(file, indent, "NdrFcShort(0x%x),\n", *type_offset);
size = 4; /* includes param type prefix */
}
*type_offset += get_size_typeformatstring_var(var);
*type_offset += get_size_typeformatstring_var(var, NULL);
return size;
}
......@@ -319,7 +318,7 @@ void write_procformatstring(FILE *file, const ifref_list_t *ifaces, int for_obje
/* emit return value data */
var = func->def;
if (is_void(var->type, NULL))
if (is_void(var->type))
{
print_file(file, indent, "0x5b, /* FC_END */\n");
print_file(file, indent, "0x5c, /* FC_PAD */\n");
......@@ -347,6 +346,7 @@ static int write_base_type(FILE *file, const type_t *type, unsigned int *typestr
*typestring_offset += 1;
return 1;
}
return 0;
}
......@@ -439,7 +439,7 @@ static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const type_
if (structure->fields) LIST_FOR_EACH_ENTRY( var, structure->fields, const var_t, entry )
{
unsigned int align = 0;
offset -= type_memsize(var->type, var->ptr_level, var->array, &align);
offset -= type_memsize(var->type, var->array, &align);
/* FIXME: take alignment into account */
if (!strcmp(var->name, subexpr->u.sval))
{
......@@ -593,7 +593,7 @@ static size_t fields_memsize(const var_list_t *fields, unsigned int *align)
if (!fields) return 0;
LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry )
size += type_memsize(v->type, v->ptr_level, v->array, align);
size += type_memsize(v->type, v->array, align);
return size;
}
......@@ -614,11 +614,11 @@ static size_t get_array_size( const array_dims_t *array )
return size;
}
static size_t type_memsize(const type_t *t, int ptr_level, const array_dims_t *array, unsigned int *align)
static size_t type_memsize(const type_t *t, const array_dims_t *array, unsigned int *align)
{
size_t size = 0;
if (ptr_level)
if (is_ptr(t))
{
size = sizeof(void *);
if (size > *align) *align = size;
......@@ -671,8 +671,29 @@ static size_t type_memsize(const type_t *t, int ptr_level, const array_dims_t *a
return size;
}
static size_t write_nonsimple_pointer(FILE *file, const type_t *type, size_t offset)
{
short absoff = type->ref->typestring_offset;
short reloff = absoff - (offset + 2);
print_file(file, 2, "0x%02x, 0x10,\t/* %s */\n",
type->type, string_of_type(type->type));
print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%hd) */\n",
reloff, reloff, absoff);
return 4;
}
static size_t write_simple_pointer(FILE *file, const type_t *type)
{
print_file(file, 2, "0x%02x, 0x8,\t/* %s [simple_pointer] */\n",
type->type, string_of_type(type->type));
print_file(file, 2, "0x%02x,\t/* %s */\n", type->ref->type,
string_of_type(type->ref->type));
print_file(file, 2, "0x5c,\t/* FC_PAD */\n");
return 4;
}
static int write_pointers(FILE *file, const attr_list_t *attrs,
const type_t *type, int ptr_level,
type_t *type,
const array_dims_t *array, int level,
unsigned int *typestring_offset)
{
......@@ -681,15 +702,43 @@ static int write_pointers(FILE *file, const attr_list_t *attrs,
/* don't generate a pointer for first-level arrays since we want to
* descend into them to write their pointers, not stop here */
if ((level == 0 || ptr_level == 0) && is_array_type(attrs, ptr_level, array))
if ((level == 0 || !is_ptr(type)) && is_array_type(attrs, type, array))
{
return write_pointers(file, NULL, type, 0, NULL, level + 1, typestring_offset);
return write_pointers(file, NULL, type, NULL, level + 1, typestring_offset);
}
if (ptr_level != 0)
if (is_ptr(type))
{
/* FIXME: only general algorithm implemented, not the actual writing */
error("write_pointers: Writing type format string for pointer is unimplemented\n");
if (!is_ptr(type->ref) && 1 < level)
{
print_file(file, 0, "/* %d */\n", *typestring_offset);
if (type->ref->typestring_offset)
{
type->typestring_offset = *typestring_offset;
*typestring_offset += write_nonsimple_pointer(file, type, *typestring_offset);
}
else if (is_base_type(type->ref->type))
{
type->typestring_offset = *typestring_offset;
*typestring_offset += write_simple_pointer(file, type);
}
else
error("write_pointers: pointer doesn't point to anything recognizable (0x%02x)\n",
type->ref->type);
}
else
{
pointers_written = write_pointers(file, attrs, type->ref, array,
level + 1, typestring_offset);
if (1 < level)
{
print_file(file, 0, "/* %d */\n", *typestring_offset);
type->typestring_offset = *typestring_offset;
*typestring_offset += write_nonsimple_pointer(file, type, *typestring_offset);
}
}
return 1;
}
......@@ -705,7 +754,7 @@ static int write_pointers(FILE *file, const attr_list_t *attrs,
if (!type->fields) break;
LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry )
pointers_written += write_pointers(file, v->attrs, v->type,
v->ptr_level, v->array,
v->array,
level + 1,
typestring_offset);
......@@ -720,34 +769,45 @@ static int write_pointers(FILE *file, const attr_list_t *attrs,
}
static size_t write_pointer_description(FILE *file, const attr_list_t *attrs,
const type_t *type, int ptr_level,
const type_t *type, size_t mem_offset,
const array_dims_t *array, int level,
size_t typestring_offset)
size_t *typestring_offset)
{
size_t size = 0;
const var_t *v;
unsigned int align = 0;
/* don't generate a pointer for first-level arrays since we want to
* descend into them to write their pointers, not stop here */
if ((level == 0 || ptr_level == 0) && is_array_type(attrs, ptr_level, array))
if ((level == 0 || !is_ptr(type)) && is_array_type(attrs, type, array))
{
return write_pointer_description(file, NULL, type, 0, NULL,
level + 1, typestring_offset);
write_pointer_description(file, NULL, type, mem_offset, NULL,
level + 1, typestring_offset);
}
if (ptr_level != 0)
else if (is_ptr(type))
{
/* FIXME: only general algorithm implemented, not the actual writing */
error("write_pointer_description: Writing pointer description is unimplemented\n");
return 0;
}
/* FIXME: search through all refs for pointers too */
print_file(file, 2, "0x46,\t/* FC_NO_REPEAT */\n");
print_file(file, 2, "0x5c,\t/* FC_PAD */\n");
print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", mem_offset, mem_offset);
print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", mem_offset, mem_offset);
switch (type->type)
if (type->ref->typestring_offset)
{
*typestring_offset
+= 6 + write_nonsimple_pointer(file, type, 6 + *typestring_offset);
}
else if (is_base_type(type->ref->type))
{
*typestring_offset += 6 + write_simple_pointer(file, type);
}
else
error("write_pointer_description: unimplemented\n");
}
else
{
/* note: don't descend into complex structures or unions since these
* will always be generated as a separate type */
switch (type->type)
{
/* note: don't descend into complex structures or unions since these
* will always be generated as a separate type */
case RPC_FC_STRUCT:
case RPC_FC_CVSTRUCT:
case RPC_FC_CPSTRUCT:
......@@ -755,19 +815,21 @@ static size_t write_pointer_description(FILE *file, const attr_list_t *attrs,
case RPC_FC_PSTRUCT:
if (!type->fields) break;
LIST_FOR_EACH_ENTRY( v, type->fields, const var_t, entry )
size += write_pointer_description(file, v->attrs, v->type,
v->ptr_level, v->array,
level + 1,
typestring_offset);
{
mem_offset
+= write_pointer_description(file, v->attrs, v->type,
mem_offset, v->array,
level + 1,
typestring_offset);
}
break;
default:
/* nothing to do */
break;
}
}
return size;
return type_memsize(type, array, &align);
}
static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
......@@ -805,7 +867,7 @@ static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
print_file(file, 2,"0x%x, 0x%x, /* %s%s */\n",
pointer_type, flags,
string_of_type(pointer_type),
pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"),
(flags & RPC_FC_P_SIMPLEPOINTER) ? " [simple_pointer]" : "");
*typestring_offset += 2;
......@@ -862,7 +924,7 @@ static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
}
static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
const type_t *type, const array_dims_t *array,
type_t *type, const array_dims_t *array,
const char *name, unsigned int *typestring_offset)
{
const expr_list_t *length_is = get_attrp(attrs, ATTR_LENGTHIS);
......@@ -876,7 +938,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
print_file(file, 2, "0x%x, 0x00, /* %s */\n",
pointer_type,
string_of_type(pointer_type));
pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"));
print_file(file, 2, "NdrFcShort(0x2),\n");
*typestring_offset += 4;
......@@ -888,10 +950,9 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
else
{
const expr_t *dim = array ? LIST_ENTRY( list_head( array ), expr_t, entry ) : NULL;
size_t pointer_start_offset = *typestring_offset;
int has_pointer = 0;
if (write_pointers(file, attrs, type, 0, array, 0, typestring_offset) > 0)
if (write_pointers(file, attrs, type, array, 0, typestring_offset) > 0)
has_pointer = 1;
start_offset = *typestring_offset;
......@@ -900,7 +961,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
{
/* fixed array */
unsigned int align = 0;
size_t size = type_memsize(type, 0, array, &align);
size_t size = type_memsize(type, array, &align);
if (size < USHRT_MAX)
{
WRITE_FCTYPE(file, FC_SMFARRAY, *typestring_offset);
......@@ -925,8 +986,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
*typestring_offset += 2;
*typestring_offset = write_pointer_description(file, attrs,
type, 0, array, 0, pointer_start_offset);
write_pointer_description(file, attrs, type, 0, array, 0, typestring_offset);
print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
*typestring_offset += 1;
}
......@@ -945,7 +1005,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
{
/* varying array */
unsigned int align = 0;
size_t element_size = type_memsize(type, 0, NULL, &align);
size_t element_size = type_memsize(type, NULL, &align);
size_t elements = dim->cval;
size_t total_size = element_size * elements;
......@@ -984,8 +1044,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
*typestring_offset += 2;
*typestring_offset += write_pointer_description(file, attrs,
type, 0, array, 0, pointer_start_offset);
write_pointer_description(file, attrs, type, 0, array, 0, typestring_offset);
print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
*typestring_offset += 1;
}
......@@ -1004,7 +1063,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
{
/* conformant array */
unsigned int align = 0;
size_t element_size = type_memsize(type, 0, NULL, &align);
size_t element_size = type_memsize(type, NULL, &align);
WRITE_FCTYPE(file, FC_CARRAY, *typestring_offset);
/* alignment */
......@@ -1022,8 +1081,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
*typestring_offset += 2;
*typestring_offset += write_pointer_description(file, attrs,
type, 0, array, 0, pointer_start_offset);
write_pointer_description(file, attrs, type, 0, array, 0, typestring_offset);
print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
*typestring_offset += 1;
}
......@@ -1042,7 +1100,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
{
/* conformant varying array */
unsigned int align = 0;
size_t element_size = type_memsize(type, 0, NULL, &align);
size_t element_size = type_memsize(type, NULL, &align);
WRITE_FCTYPE(file, FC_CVARRAY, *typestring_offset);
/* alignment */
......@@ -1063,8 +1121,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs,
print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
*typestring_offset += 2;
*typestring_offset += write_pointer_description(file, attrs,
type, 0, array, 0, pointer_start_offset);
write_pointer_description(file, attrs, type, 0, array, 0, typestring_offset);
print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
*typestring_offset += 1;
}
......@@ -1086,7 +1143,7 @@ static const var_t *find_array_or_string_in_struct(const type_t *type)
{
const var_t *last_field = LIST_ENTRY( list_tail(type->fields), const var_t, entry );
if (is_array_type(last_field->attrs, last_field->ptr_level, last_field->array))
if (is_array_type(last_field->attrs, last_field->type, last_field->array))
return last_field;
assert((last_field->type->type == RPC_FC_CSTRUCT) ||
......@@ -1107,6 +1164,12 @@ static void write_struct_members(FILE *file, const type_t *type, unsigned int *t
if (field->array)
write_array_tfs( file, field->attrs, field->type, field->array,
field->name, typestring_offset );
else if (is_ptr( field->type ))
{
/* pointers are handled in detail earlier, here just treat them like longs */
print_file( file, 2, "0x8,\t/* FC_LONG */\n" );
*typestring_offset += 1;
}
else if (!write_base_type( file, field->type, typestring_offset ))
error("Unsupported member type 0x%x\n", rtype);
}
......@@ -1121,32 +1184,28 @@ static void write_struct_members(FILE *file, const type_t *type, unsigned int *t
*typestring_offset += 1;
}
static size_t write_struct_tfs(FILE *file, const type_t *type,
static size_t write_struct_tfs(FILE *file, type_t *type,
const char *name, unsigned int *typestring_offset)
{
unsigned int total_size;
const var_t *array;
size_t start_offset;
size_t array_offset;
size_t pointer_offset;
int has_pointers;
unsigned int align = 0;
switch (type->type)
{
case RPC_FC_STRUCT:
case RPC_FC_PSTRUCT:
total_size = type_memsize(type, 0, NULL, &align);
total_size = type_memsize(type, NULL, &align);
if (total_size > USHRT_MAX)
error("structure size for parameter %s exceeds %d bytes by %d bytes\n",
name, USHRT_MAX, total_size - USHRT_MAX);
if (type->type == RPC_FC_PSTRUCT)
{
pointer_offset = *typestring_offset;
write_pointers(file, NULL, type, 0, NULL, 0, typestring_offset);
}
else pointer_offset = 0; /* silence warning */
write_pointers(file, NULL, type, NULL, 0, typestring_offset);
start_offset = *typestring_offset;
if (type->type == RPC_FC_STRUCT)
......@@ -1164,8 +1223,7 @@ static size_t write_struct_tfs(FILE *file, const type_t *type,
print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
*typestring_offset += 2;
*typestring_offset += write_pointer_description(file, NULL,
type, 0, NULL, 0, pointer_offset);
write_pointer_description(file, NULL, type, 0, NULL, 0, typestring_offset);
print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
*typestring_offset += 1;
}
......@@ -1175,7 +1233,7 @@ static size_t write_struct_tfs(FILE *file, const type_t *type,
return start_offset;
case RPC_FC_CSTRUCT:
case RPC_FC_CPSTRUCT:
total_size = type_memsize(type, 0, NULL, &align);
total_size = type_memsize(type, NULL, &align);
if (total_size > USHRT_MAX)
error("structure size for parameter %s exceeds %d bytes by %d bytes\n",
......@@ -1189,11 +1247,7 @@ static size_t write_struct_tfs(FILE *file, const type_t *type,
current_structure = NULL;
if (type->type == RPC_FC_CPSTRUCT)
{
pointer_offset = *typestring_offset;
write_pointers(file, NULL, type, 0, NULL, 0, typestring_offset);
}
else pointer_offset = 0; /* silence warning */
write_pointers(file, NULL, type, NULL, 0, typestring_offset);
start_offset = *typestring_offset;
if (type->type == RPC_FC_CSTRUCT)
......@@ -1216,8 +1270,7 @@ static size_t write_struct_tfs(FILE *file, const type_t *type,
print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
*typestring_offset += 2;
*typestring_offset += write_pointer_description(file, NULL,
type, 0, NULL, 0, pointer_offset);
write_pointer_description(file, NULL, type, 0, NULL, 0, typestring_offset);
print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
*typestring_offset += 1;
}
......@@ -1227,7 +1280,7 @@ static size_t write_struct_tfs(FILE *file, const type_t *type,
return start_offset;
case RPC_FC_CVSTRUCT:
total_size = type_memsize(type, 0, NULL, &align);
total_size = type_memsize(type, NULL, &align);
if (total_size > USHRT_MAX)
error("structure size for parameter %s exceeds %d bytes by %d bytes\n",
......@@ -1245,9 +1298,7 @@ static size_t write_struct_tfs(FILE *file, const type_t *type,
typestring_offset);
current_structure = NULL;
pointer_offset = *typestring_offset;
if (!write_pointers(file, NULL, type, 0, NULL, 0, typestring_offset))
pointer_offset = 0;
has_pointers = write_pointers(file, NULL, type, NULL, 0, typestring_offset);
start_offset = *typestring_offset;
WRITE_FCTYPE(file, FC_CVSTRUCT, *typestring_offset);
......@@ -1262,13 +1313,12 @@ static size_t write_struct_tfs(FILE *file, const type_t *type,
array_offset);
*typestring_offset += 2;
if (pointer_offset != 0)
if (has_pointers)
{
print_file(file, 2, "0x%x, /* FC_PP */\n", RPC_FC_PP);
print_file(file, 2, "0x%x, /* FC_PAD */\n", RPC_FC_PAD);
*typestring_offset += 2;
*typestring_offset += write_pointer_description(file, NULL,
type, 0, NULL, 0, pointer_offset);
write_pointer_description(file, NULL, type, 0, NULL, 0, typestring_offset);
print_file(file, 2, "0x%x, /* FC_END */\n", RPC_FC_END);
*typestring_offset += 1;
}
......@@ -1283,10 +1333,12 @@ static size_t write_struct_tfs(FILE *file, const type_t *type,
}
}
static void write_pointer_only_tfs(FILE *file, const attr_list_t *attrs, int pointer_type,
unsigned char flags, size_t offset,
unsigned int *typeformat_offset)
static size_t write_pointer_only_tfs(FILE *file, const attr_list_t *attrs, int pointer_type,
unsigned char flags, size_t offset,
unsigned int *typeformat_offset)
{
size_t start_offset = *typeformat_offset;
short reloff = offset - (*typeformat_offset + 2);
int in_attr, out_attr;
in_attr = is_attr(attrs, ATTR_IN);
out_attr = is_attr(attrs, ATTR_OUT);
......@@ -1298,7 +1350,7 @@ static void write_pointer_only_tfs(FILE *file, const attr_list_t *attrs, int poi
print_file(file, 2, "0x%x, 0x%x,\t\t/* %s",
pointer_type,
flags,
string_of_type(pointer_type));
pointer_type == RPC_FC_FP ? "FC_FP" : (pointer_type == RPC_FC_UP ? "FC_UP" : "FC_RP"));
if (file)
{
if (flags & 0x04)
......@@ -1308,8 +1360,10 @@ static void write_pointer_only_tfs(FILE *file, const attr_list_t *attrs, int poi
fprintf(file, " */\n");
}
print_file(file, 2, "NdrFcShort(0x%x), /* %d */\n", offset, offset);
print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", reloff, offset);
*typeformat_offset += 4;
return start_offset;
}
static size_t write_union_tfs(FILE *file, const attr_list_t *attrs,
......@@ -1320,7 +1374,7 @@ static size_t write_union_tfs(FILE *file, const attr_list_t *attrs,
return *typeformat_offset;
}
static size_t write_ip_tfs(FILE *file, const func_t *func, const var_t *var,
static size_t write_ip_tfs(FILE *file, const func_t *func, const type_t *type, const var_t *var,
unsigned int *typeformat_offset)
{
size_t i;
......@@ -1344,7 +1398,7 @@ static size_t write_ip_tfs(FILE *file, const func_t *func, const var_t *var,
}
else
{
const type_t *base = is_ptr(var->type) ? var->type->ref : var->type;
const type_t *base = is_ptr(type) ? type->ref : type;
const UUID *uuid = get_attrp(base->attrs, ATTR_UUID);
if (! uuid)
......@@ -1380,129 +1434,96 @@ static int get_ptr_attr(const type_t *t, int def_type)
}
static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *func,
const var_t *var, unsigned int *typeformat_offset)
type_t *type, const var_t *var,
unsigned int *typeformat_offset)
{
const type_t *type = var->type;
int var_ptrs = var->ptr_level, type_ptrs = 0;
int is_str = is_attr(var->attrs, ATTR_STRING);
chat("write_typeformatstring_var: %s\n", var->name);
int pointer_type;
size_t offset;
while (TRUE)
if (type == var->type) /* top-level pointers */
{
is_str = is_str || is_attr(type->attrs, ATTR_STRING);
if (type->kind == TKIND_ALIAS)
type = type->orig;
else if (is_ptr(type))
{
++type_ptrs;
type = type->ref;
}
else
{
type = var->type;
break;
}
}
int pointer_attr = get_attrv(var->attrs, ATTR_POINTERTYPE);
if (pointer_attr != 0 && !is_ptr(type))
error("'%s': pointer attribute applied to non-pointer type\n", var->name);
while (TRUE)
{
int ptr_level = var_ptrs + type_ptrs;
int pointer_type = 0;
if (pointer_attr == 0)
pointer_attr = get_ptr_attr(type, RPC_FC_RP);
chat("write_typeformatstring: type->type = 0x%x, type->name = %s, ptr_level = %d\n", type->type, type->name, ptr_level);
pointer_type = pointer_attr;
}
else
pointer_type = get_ptr_attr(type, RPC_FC_UP);
/* var attrs only effect the rightmost pointer */
if ((0 < var->ptr_level && var_ptrs == var->ptr_level)
|| (var->ptr_level == 0 && type == var->type))
{
int pointer_attr = get_attrv(var->attrs, ATTR_POINTERTYPE);
if (pointer_attr)
{
if (! ptr_level)
error("'%s': pointer attribute applied to non-pointer type\n", var->name);
pointer_type = pointer_attr;
}
else
pointer_type = RPC_FC_RP;
}
else /* pointers below other pointers default to unique */
pointer_type = var_ptrs ? RPC_FC_UP : get_ptr_attr(type, RPC_FC_UP);
if (((last_ptr(type) && var->array == NULL)
|| (!is_ptr(type) && var->array != NULL))
&& is_ptrchain_attr(var, ATTR_STRING))
{
return write_string_tfs(file, var->attrs, type, var->array, var->name, typeformat_offset);
}
if (is_str && ptr_level + (var->array != NULL) == 1)
return write_string_tfs(file, var->attrs, type, var->array, var->name, typeformat_offset);
if (is_array_type(var->attrs, type, var->array))
return write_array_tfs(file, var->attrs, type, var->array, var->name, typeformat_offset);
if (is_array_type(var->attrs, ptr_level, var->array))
return write_array_tfs(file, var->attrs, type, var->array, var->name, typeformat_offset);
if (!is_ptr(type))
{
/* basic types don't need a type format string */
if (is_base_type(type->type))
return 0;
if (ptr_level == 0)
switch (type->type)
{
/* basic types don't need a type format string */
if (is_base_type(type->type))
return 0;
switch (type->type)
{
case RPC_FC_STRUCT:
case RPC_FC_PSTRUCT:
case RPC_FC_CSTRUCT:
case RPC_FC_CPSTRUCT:
case RPC_FC_CVSTRUCT:
case RPC_FC_BOGUS_STRUCT:
return write_struct_tfs(file, type, var->name, typeformat_offset);
case RPC_FC_ENCAPSULATED_UNION:
case RPC_FC_NON_ENCAPSULATED_UNION:
return write_union_tfs(file, var->attrs, type, var->name, typeformat_offset);
case RPC_FC_IGNORE:
case RPC_FC_BIND_PRIMITIVE:
/* nothing to do */
return 0;
default:
error("write_typeformatstring_var: Unsupported type 0x%x for variable %s\n", type->type, var->name);
}
case RPC_FC_STRUCT:
case RPC_FC_PSTRUCT:
case RPC_FC_CSTRUCT:
case RPC_FC_CPSTRUCT:
case RPC_FC_CVSTRUCT:
case RPC_FC_BOGUS_STRUCT:
return write_struct_tfs(file, type, var->name, typeformat_offset);
case RPC_FC_ENCAPSULATED_UNION:
case RPC_FC_NON_ENCAPSULATED_UNION:
return write_union_tfs(file, var->attrs, type, var->name, typeformat_offset);
case RPC_FC_IGNORE:
case RPC_FC_BIND_PRIMITIVE:
/* nothing to do */
return 0;
default:
error("write_typeformatstring_var: Unsupported type 0x%x for variable %s\n", type->type, var->name);
}
else if (ptr_level == 1)
{
size_t start_offset = *typeformat_offset;
int in_attr = is_attr(var->attrs, ATTR_IN);
int out_attr = is_attr(var->attrs, ATTR_OUT);
const type_t *base = is_ptr(type) ? type->ref : type;
if (base->type == RPC_FC_IP)
{
return write_ip_tfs(file, func, var, typeformat_offset);
}
}
else if (last_ptr(type))
{
size_t start_offset = *typeformat_offset;
int in_attr = is_attr(var->attrs, ATTR_IN);
int out_attr = is_attr(var->attrs, ATTR_OUT);
const type_t *base = type->ref;
/* special case for pointers to base types */
if (is_base_type(base->type))
{
print_file(file, indent, "0x%x, 0x%x, /* %s %s[simple_pointer] */\n",
pointer_type, (!in_attr && out_attr) ? 0x0C : 0x08,
string_of_type(pointer_type),
(!in_attr && out_attr) ? "[allocated_on_stack] " : "");
print_file(file, indent, "0x%02x, /* %s */\n", base->type, string_of_type(base->type));
print_file(file, indent, "0x5c, /* FC_PAD */\n");
*typeformat_offset += 4;
return start_offset;
}
if (base->type == RPC_FC_IP)
{
return write_ip_tfs(file, func, type, var, typeformat_offset);
}
assert(ptr_level > 0);
if (file)
fprintf(file, "/* %2u */\n", *typeformat_offset);
write_pointer_only_tfs(file, var->attrs, pointer_type,
1 < ptr_level ? 0x10 : 0,
2, typeformat_offset);
if (var_ptrs)
--var_ptrs;
else
/* special case for pointers to base types */
if (is_base_type(base->type))
{
--type_ptrs;
type = type->ref;
print_file(file, indent, "0x%x, 0x%x, /* %s %s[simple_pointer] */\n",
pointer_type, (!in_attr && out_attr) ? 0x0C : 0x08,
string_of_type(pointer_type),
(!in_attr && out_attr) ? "[allocated_on_stack] " : "");
print_file(file, indent, "0x%02x, /* %s */\n", base->type, string_of_type(base->type));
print_file(file, indent, "0x5c, /* FC_PAD */\n");
*typeformat_offset += 4;
return start_offset;
}
}
assert(is_ptr(type));
offset = write_typeformatstring_var(file, indent, func, type->ref, var, typeformat_offset);
if (file)
fprintf(file, "/* %2u */\n", *typeformat_offset);
return write_pointer_only_tfs(file, var->attrs, pointer_type,
!last_ptr(type) ? 0x10 : 0,
offset, typeformat_offset);
}
......@@ -1536,7 +1557,7 @@ void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, int for_obje
current_func = func;
if (func->args)
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
write_typeformatstring_var(file, indent, func, var,
write_typeformatstring_var(file, indent, func, var->type, var,
&typeformat_offset);
}
}
......@@ -1551,13 +1572,13 @@ void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, int for_obje
}
static unsigned int get_required_buffer_size_type(
const type_t *type, int ptr_level, const array_dims_t *array,
const type_t *type, const array_dims_t *array,
const char *name, unsigned int *alignment)
{
size_t size = 0;
*alignment = 0;
if (ptr_level == 0)
if (!is_ptr(type))
{
switch (type->type)
{
......@@ -1595,6 +1616,7 @@ static unsigned int get_required_buffer_size_type(
return 0;
case RPC_FC_STRUCT:
case RPC_FC_PSTRUCT:
{
const var_t *field;
if (!type->fields) return 0;
......@@ -1602,7 +1624,7 @@ static unsigned int get_required_buffer_size_type(
{
unsigned int alignment;
size += get_required_buffer_size_type(
field->type, field->ptr_level, field->array, field->name,
field->type, field->array, field->name,
&alignment);
}
break;
......@@ -1610,7 +1632,7 @@ static unsigned int get_required_buffer_size_type(
case RPC_FC_RP:
if (is_base_type( type->ref->type ) || type->ref->type == RPC_FC_STRUCT)
size = get_required_buffer_size_type( type->ref, 0, NULL, name, alignment );
size = get_required_buffer_size_type( type->ref, NULL, name, alignment );
break;
default:
......@@ -1636,7 +1658,7 @@ static unsigned int get_required_buffer_size(const var_t *var, unsigned int *ali
if (pass == PASS_OUT)
{
if (out_attr && var->ptr_level > 0)
if (out_attr && is_ptr(var->type))
{
type_t *type = var->type;
......@@ -1650,7 +1672,7 @@ static unsigned int get_required_buffer_size(const var_t *var, unsigned int *ali
{
unsigned int align;
size += get_required_buffer_size_type(
field->type, field->ptr_level, field->array, field->name,
field->type, field->array, field->name,
&align);
}
return size;
......@@ -1662,7 +1684,7 @@ static unsigned int get_required_buffer_size(const var_t *var, unsigned int *ali
{
if ((!out_attr || in_attr) && !has_size && !is_attr(var->attrs, ATTR_STRING) && !var->array)
{
if (var->ptr_level > 0)
if (is_ptr(var->type))
{
type_t *type = var->type;
......@@ -1680,7 +1702,7 @@ static unsigned int get_required_buffer_size(const var_t *var, unsigned int *ali
{
unsigned int align;
size += get_required_buffer_size_type(
field->type, field->ptr_level, field->array, field->name,
field->type, field->array, field->name,
&align);
}
return size;
......@@ -1688,7 +1710,7 @@ static unsigned int get_required_buffer_size(const var_t *var, unsigned int *ali
}
}
return get_required_buffer_size_type(var->type, var->ptr_level, var->array, var->name, alignment);
return get_required_buffer_size_type(var->type, var->array, var->name, alignment);
}
}
......@@ -1706,7 +1728,7 @@ static unsigned int get_function_buffer_size( const func_t *func, enum pass pass
}
}
if (pass == PASS_OUT && !is_void(func->def->type, NULL))
if (pass == PASS_OUT && !is_void(func->def->type))
{
total_size += get_required_buffer_size(func->def, &alignment, PASS_RETURN);
total_size += alignment;
......@@ -1755,7 +1777,7 @@ void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase,
enum pass pass, const var_t *var,
const char *varname)
{
const type_t *type = var->type;
type_t *type = var->type;
unsigned int size;
unsigned int alignment = 0;
unsigned char rtype;
......@@ -1764,7 +1786,7 @@ void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase,
if (phase != PHASE_MARSHAL && phase != PHASE_UNMARSHAL)
return;
rtype = type->type;
rtype = is_ptr(type) ? type->ref->type : type->type;
switch (rtype)
{
......@@ -1813,8 +1835,8 @@ void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase,
if (phase == PHASE_MARSHAL)
{
print_file(file, indent, "*(");
write_type(file, var->type, NULL);
if (var->ptr_level)
write_type(file, is_ptr(type) ? type->ref : type);
if (is_ptr(type))
fprintf(file, " *)_StubMsg.Buffer = *");
else
fprintf(file, " *)_StubMsg.Buffer = ");
......@@ -1828,16 +1850,16 @@ void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase,
else
print_file(file, indent, "*");
fprintf(file, varname);
if (pass == PASS_IN && var->ptr_level)
if (pass == PASS_IN && is_ptr(type))
fprintf(file, " = (");
else
fprintf(file, " = *(");
write_type(file, var->type, NULL);
write_type(file, is_ptr(type) ? type->ref : type);
fprintf(file, " *)_StubMsg.Buffer;\n");
}
print_file(file, indent, "_StubMsg.Buffer += sizeof(");
write_type(file, var->type, NULL);
write_type(file, var->type);
fprintf(file, ");\n");
}
......@@ -1870,6 +1892,9 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
{
const type_t *type = var->type;
unsigned char rtype;
size_t start_offset;
size_t size_type = get_size_typeformatstring_var(var, &start_offset);
start_offset += *type_offset;
length_is = get_attrp(var->attrs, ATTR_LENGTHIS);
size_is = get_attrp(var->attrs, ATTR_SIZEIS);
......@@ -1901,12 +1926,12 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
if (is_user_derived( var ))
{
print_phase_function(file, indent, "UserMarshal", phase, var->name, *type_offset);
print_phase_function(file, indent, "UserMarshal", phase, var->name, start_offset);
}
else if (is_string_type(var->attrs, var->ptr_level, var->array))
else if (is_string_type(var->attrs, var->type, var->array))
{
if (var->array && !is_conformant_array(var->array))
print_phase_function(file, indent, "NonConformantString", phase, var->name, *type_offset);
print_phase_function(file, indent, "NonConformantString", phase, var->name, start_offset);
else
{
if (size_is && is_size_needed_for_phase(phase))
......@@ -1918,13 +1943,13 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
}
if ((phase == PHASE_FREE) || (pointer_type == RPC_FC_UP))
print_phase_function(file, indent, "Pointer", phase, var->name, *type_offset);
print_phase_function(file, indent, "Pointer", phase, var->name, start_offset);
else
print_phase_function(file, indent, "ConformantString", phase, var->name,
*type_offset + (has_size ? 4 : 2));
start_offset + (has_size ? 4 : 2));
}
}
else if (is_array_type(var->attrs, var->ptr_level, var->array))
else if (is_array_type(var->attrs, var->type, var->array))
{
const char *array_type;
......@@ -1986,31 +2011,32 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
else if (phase != PHASE_FREE)
{
if (pointer_type == RPC_FC_UP)
print_phase_function(file, indent, "Pointer", phase, var->name, *type_offset);
print_phase_function(file, indent, "Pointer", phase, var->name, start_offset);
else
print_phase_function(file, indent, array_type, phase, var->name, *type_offset + 4);
print_phase_function(file, indent, array_type, phase, var->name, start_offset);
}
}
else if (var->ptr_level == 0 && is_base_type(rtype))
else if (!is_ptr(var->type) && is_base_type(rtype))
{
print_phase_basetype(file, indent, phase, pass, var, var->name);
}
else if (var->ptr_level == 0)
else if (!is_ptr(var->type))
{
switch (rtype)
{
case RPC_FC_STRUCT:
print_phase_function(file, indent, "SimpleStruct", phase, var->name, *type_offset);
case RPC_FC_PSTRUCT:
print_phase_function(file, indent, "SimpleStruct", phase, var->name, start_offset);
break;
case RPC_FC_CSTRUCT:
case RPC_FC_CPSTRUCT:
print_phase_function(file, indent, "ConformantStruct", phase, var->name, *type_offset);
print_phase_function(file, indent, "ConformantStruct", phase, var->name, start_offset);
break;
case RPC_FC_CVSTRUCT:
print_phase_function(file, indent, "ConformantVaryingStruct", phase, var->name, *type_offset);
print_phase_function(file, indent, "ConformantVaryingStruct", phase, var->name, start_offset);
break;
case RPC_FC_BOGUS_STRUCT:
print_phase_function(file, indent, "ComplexStruct", phase, var->name, *type_offset);
print_phase_function(file, indent, "ComplexStruct", phase, var->name, start_offset);
break;
case RPC_FC_RP:
if (is_base_type( var->type->ref->type ))
......@@ -2020,43 +2046,42 @@ void write_remoting_arguments(FILE *file, int indent, const func_t *func,
else if (var->type->ref->type == RPC_FC_STRUCT)
{
if (phase != PHASE_BUFFERSIZE && phase != PHASE_FREE)
print_phase_function(file, indent, "SimpleStruct", phase, var->name, *type_offset + 4);
print_phase_function(file, indent, "SimpleStruct", phase, var->name, start_offset + 4);
}
else
{
const var_t *iid;
if ((iid = get_attrp( var->attrs, ATTR_IIDIS )))
print_file( file, indent, "_StubMsg.MaxCount = (unsigned long)%s;\n", iid->name );
print_phase_function(file, indent, "Pointer", phase, var->name, *type_offset);
print_phase_function(file, indent, "Pointer", phase, var->name, start_offset);
}
break;
default:
error("write_remoting_arguments: Unsupported type: %s (0x%02x, ptr_level: %d)\n",
var->name, rtype, var->ptr_level);
error("write_remoting_arguments: Unsupported type: %s (0x%02x)\n", var->name, rtype);
}
}
else
{
if ((var->ptr_level == 1) && (pointer_type == RPC_FC_RP) && is_base_type(rtype))
if (last_ptr(var->type) && (pointer_type == RPC_FC_RP) && is_base_type(rtype))
{
print_phase_basetype(file, indent, phase, pass, var, var->name);
}
else if ((var->ptr_level == 1) && (pointer_type == RPC_FC_RP) && (rtype == RPC_FC_STRUCT))
else if (last_ptr(var->type) && (pointer_type == RPC_FC_RP) && (rtype == RPC_FC_STRUCT))
{
if (phase != PHASE_BUFFERSIZE && phase != PHASE_FREE)
print_phase_function(file, indent, "SimpleStruct", phase, var->name, *type_offset + 4);
print_phase_function(file, indent, "SimpleStruct", phase, var->name, start_offset + 4);
}
else
{
const var_t *iid;
if ((iid = get_attrp( var->attrs, ATTR_IIDIS )))
print_file( file, indent, "_StubMsg.MaxCount = (unsigned long)%s;\n", iid->name );
print_phase_function(file, indent, "Pointer", phase, var->name, *type_offset);
print_phase_function(file, indent, "Pointer", phase, var->name, start_offset);
}
}
fprintf(file, "\n");
next:
*type_offset += get_size_typeformatstring_var(var);
*type_offset += size_type;
}
}
......@@ -2079,7 +2104,7 @@ size_t get_size_procformatstring_func(const func_t *func)
size += get_size_procformatstring_var(var);
/* return value size */
if (is_void(func->def->type, NULL))
if (is_void(func->def->type))
size += 2; /* FC_END and FC_PAD */
else
size += get_size_procformatstring_var(func->def);
......@@ -2087,11 +2112,15 @@ size_t get_size_procformatstring_func(const func_t *func)
return size;
}
size_t get_size_typeformatstring_var(const var_t *var)
size_t get_size_typeformatstring_var(const var_t *var, size_t *pstart_offset)
{
unsigned int type_offset = 0;
write_typeformatstring_var(NULL, 0, NULL, var, &type_offset);
return type_offset;
unsigned int type_offset = 2; /* 0 is used as an invalid offset */
size_t start_offset = write_typeformatstring_var(NULL, 0, NULL, var->type,
var, &type_offset);
if (pstart_offset)
*pstart_offset = start_offset - 2;
return type_offset - 2;
}
size_t get_size_procformatstring(const ifref_list_t *ifaces, int for_objects)
......@@ -2133,7 +2162,7 @@ size_t get_size_typeformatstring(const ifref_list_t *ifaces, int for_objects)
/* argument list size */
if (func->args)
LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
size += get_size_typeformatstring_var(var);
size += get_size_typeformatstring_var(var, NULL);
}
}
}
......@@ -2185,13 +2214,13 @@ static void write_struct_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_struct_expr(h, e->ref, 1, fields, structvar);
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:
......@@ -2239,10 +2268,10 @@ void declare_stub_args( FILE *file, int indent, const func_t *func )
const var_t *var;
/* declare return value '_RetVal' */
if (!is_void(def->type, NULL))
if (!is_void(def->type))
{
print_file(file, indent, "");
write_type(file, def->type, def);
write_type(file, def->type);
fprintf(file, " _RetVal;\n");
}
......@@ -2262,16 +2291,13 @@ void declare_stub_args( FILE *file, int indent, const func_t *func )
if (!in_attr && !has_size && !is_string)
{
int indirection;
print_file(file, indent, "");
write_type(file, var->type, NULL);
for (indirection = 0; indirection < var->ptr_level - 1; indirection++)
fprintf(file, "*");
write_type(file, var->type->ref);
fprintf(file, " _W%u;\n", i++);
}
print_file(file, indent, "");
write_type(file, var->type, var);
write_type(file, var->type);
fprintf(file, " ");
if (var->array) {
fprintf(file, "( *");
......@@ -2324,13 +2350,13 @@ void assign_stub_out_args( FILE *file, int indent, const func_t *func )
write_expr( file, expr, 1 );
fprintf(file, " * ");
}
size = type_memsize(type, 0, NULL, &align);
size = type_memsize(type, NULL, &align);
fprintf(file, "%u);\n", size);
}
else if (!is_string)
{
fprintf(file, " = &_W%u;\n", i);
if (var->ptr_level > 1)
if (is_ptr(var->type) && !last_ptr(var->type))
print_file(file, indent, "_W%u = 0;\n", i);
i++;
}
......
......@@ -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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment