Commit 9650cf9b authored by Dan Hipschman's avatar Dan Hipschman Committed by Alexandre Julliard

widl: Correct default pointers.

parent 304852f9
......@@ -65,6 +65,8 @@
# endif
#endif
unsigned char pointer_default = RPC_FC_UP;
typedef struct list typelist_t;
struct typenode {
type_t *type;
......@@ -92,7 +94,7 @@ static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, exp
static type_t *make_type(unsigned char type, type_t *ref);
static 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, int ptr_level, array_dims_t *arr);
static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr, int top);
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);
......@@ -380,21 +382,21 @@ 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->var;
$$->attrs = $1;
set_type($$, $2, $3->ptr_level, $4);
set_type($$, $2, $3->ptr_level, $4, TRUE);
free($3);
}
| type pident array { $$ = $2->var;
set_type($$, $1, $2->ptr_level, $3);
set_type($$, $1, $2->ptr_level, $3, TRUE);
free($2);
}
| attributes type pident '(' m_args ')' { $$ = $3->var;
$$->attrs = $1;
set_type($$, $2, $3->ptr_level - 1, NULL);
set_type($$, $2, $3->ptr_level - 1, NULL, TRUE);
free($3);
$$->args = $5;
}
| type pident '(' m_args ')' { $$ = $2->var;
set_type($$, $1, $2->ptr_level - 1, NULL);
set_type($$, $1, $2->ptr_level - 1, NULL, TRUE);
free($2);
$$->args = $4;
}
......@@ -523,7 +525,7 @@ case: tCASE expr ':' field { attr_t *a = make_attrp(ATTR_CASE, append_expr(
;
constdef: tCONST type ident '=' expr_const { $$ = reg_const($3);
set_type($$, $2, 0, NULL);
set_type($$, $2, 0, NULL, FALSE);
$$->eval = $5;
}
;
......@@ -616,7 +618,7 @@ expr_const: expr { $$ = $1;
;
externdef: tEXTERN tCONST type ident { $$ = $4;
set_type($$, $3, 0, NULL);
set_type($$, $3, 0, NULL, FALSE);
}
;
......@@ -632,7 +634,7 @@ field: s_field ';' { $$ = $1; }
s_field: m_attributes type pident array { $$ = $3->var;
$$->attrs = $1;
set_type($$, $2, $3->ptr_level, $4);
set_type($$, $2, $3->ptr_level, $4, FALSE);
free($3);
}
;
......@@ -641,7 +643,7 @@ funcdef:
m_attributes type callconv pident
'(' m_args ')' { var_t *v = $4->var;
v->attrs = $1;
set_type(v, $2, $4->ptr_level, NULL);
set_type(v, $2, $4->ptr_level, NULL, FALSE);
free($4);
$$ = make_func(v, $6);
if (is_attr(v->attrs, ATTR_IN)) {
......@@ -1262,20 +1264,25 @@ static type_t *make_type(unsigned char type, type_t *ref)
return t;
}
static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr)
static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr,
int top)
{
expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS);
expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS);
int ptr_type = get_attrv(v->attrs, ATTR_POINTERTYPE);
int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE);
int ptr_type = ptr_attr;
int sizeless, has_varconf;
expr_t *dim;
type_t *atype, **ptype;
v->type = type;
if (!ptr_type && top)
ptr_type = RPC_FC_RP;
for ( ; 0 < ptr_level; --ptr_level)
{
v->type = make_type(RPC_FC_RP, v->type);
v->type = make_type(pointer_default, v->type);
if (ptr_level == 1 && ptr_type && !arr)
{
v->type->type = ptr_type;
......@@ -1287,10 +1294,13 @@ static void set_type(var_t *v, type_t *type, int ptr_level, array_dims_t *arr)
{
if (is_ptr(v->type))
{
v->type = duptype(v->type, 1);
v->type->type = ptr_type;
if (v->type->type != ptr_type)
{
v->type = duptype(v->type, 1);
v->type->type = ptr_type;
}
}
else if (!arr)
else if (!arr && ptr_attr)
error("%s: pointer attribute applied to non-pointer type\n", v->name);
}
......@@ -1504,7 +1514,7 @@ static type_t *make_safearray(type_t *type)
{
type_t *sa = duptype(find_type("SAFEARRAY", 0), 1);
sa->ref = type;
return make_type(RPC_FC_FP, sa);
return make_type(pointer_default, sa);
}
#define HASHMAX 64
......@@ -1628,7 +1638,7 @@ static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *a
int cptr = pident->ptr_level;
if (cptr > ptrc) {
while (cptr > ptrc) {
cur = ptr = make_type(RPC_FC_RP, cur);
cur = ptr = make_type(pointer_default, cur);
ptrc++;
}
} else {
......
......@@ -1994,24 +1994,10 @@ static size_t write_contexthandle_tfs(FILE *file, const type_t *type,
return start_offset;
}
static int get_ptr_attr(const type_t *t, int def_type)
{
while (TRUE)
{
int ptr_attr = get_attrv(t->attrs, ATTR_POINTERTYPE);
if (ptr_attr)
return ptr_attr;
if (t->kind != TKIND_ALIAS)
return def_type;
t = t->orig;
}
}
static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *func,
type_t *type, const var_t *var,
unsigned int *typeformat_offset)
{
int pointer_type;
size_t offset;
if (is_context_handle(type))
......@@ -2023,35 +2009,23 @@ static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *f
return type->typestring_offset;
}
if (type == var->type) /* top-level pointers */
{
int pointer_attr = get_attrv(var->attrs, ATTR_POINTERTYPE);
if (pointer_attr != 0 && !is_ptr(type) && !is_array(type))
error("'%s': pointer attribute applied to non-pointer type\n", var->name);
if (pointer_attr == 0)
pointer_attr = get_ptr_attr(type, RPC_FC_RP);
pointer_type = pointer_attr;
}
else
pointer_type = get_ptr_attr(type, RPC_FC_UP);
if ((last_ptr(type) || last_array(type)) && is_ptrchain_attr(var, ATTR_STRING))
return write_string_tfs(file, var->attrs, type, var->name, typeformat_offset);
if (is_array(type))
{
int ptr_type;
size_t off;
off = write_array_tfs(file, var->attrs, type, var->name, typeformat_offset);
if (pointer_type != RPC_FC_RP)
ptr_type = get_attrv(var->attrs, ATTR_POINTERTYPE);
if (ptr_type && ptr_type != RPC_FC_RP)
{
unsigned int absoff = type->typestring_offset;
short reloff = absoff - (*typeformat_offset + 2);
off = *typeformat_offset;
print_file(file, 0, "/* %d */\n", off);
print_file(file, 2, "0x%x, 0x0,\t/* %s */\n", pointer_type,
string_of_type(pointer_type));
print_file(file, 2, "0x%x, 0x0,\t/* %s */\n", ptr_type,
string_of_type(ptr_type));
print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%u) */\n",
reloff, reloff, absoff);
*typeformat_offset += 4;
......@@ -2101,8 +2075,8 @@ static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *f
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),
type->type, (!in_attr && out_attr) ? 0x0C : 0x08,
string_of_type(type->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");
......@@ -2116,7 +2090,7 @@ static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *f
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,
return write_pointer_only_tfs(file, var->attrs, type->type,
!last_ptr(type) ? 0x10 : 0,
offset, typeformat_offset);
}
......
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