Commit 23673ca3 authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

widl: Determine pointer fc at generation time instead of at parse time.

Avoid changing the details of a pointer once created. Properly determine the pointer type for arrays.
parent f8e36ab4
......@@ -439,12 +439,12 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
case EXPR_STRLIT:
result.is_variable = FALSE;
result.is_temporary = TRUE;
result.type = type_new_pointer(type_new_int(TYPE_BASIC_CHAR, 0), NULL);
result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL);
break;
case EXPR_WSTRLIT:
result.is_variable = FALSE;
result.is_temporary = TRUE;
result.type = type_new_pointer(type_new_int(TYPE_BASIC_WCHAR, 0), NULL);
result.type = type_new_pointer(RPC_FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL);
break;
case EXPR_DOUBLE:
result.is_variable = FALSE;
......@@ -491,7 +491,7 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
expr_loc->attr ? expr_loc->attr : "");
result.is_variable = FALSE;
result.is_temporary = TRUE;
result.type = type_new_pointer(result.type, NULL);
result.type = type_new_pointer(RPC_FC_UP, result.type, NULL);
break;
case EXPR_PPTR:
result = resolve_expression(expr_loc, cont_type, e->ref);
......
......@@ -65,7 +65,7 @@
#define YYERROR_VERBOSE
unsigned char pointer_default = RPC_FC_UP;
static unsigned char pointer_default = RPC_FC_UP;
static int is_object_interface = FALSE;
typedef struct list typelist_t;
......@@ -928,7 +928,7 @@ decl_spec_no_type:
declarator:
'*' m_type_qual_list declarator %prec PPTR
{ $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(NULL, $2)); }
{ $$ = $3; $$->type = append_ptrchain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); }
| callconv declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
| direct_declarator
;
......@@ -1278,9 +1278,8 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
v->type = append_ptrchain_type(decl ? decl->type : NULL, type);
v->stgclass = decl_spec->stgclass;
/* the highest level of pointer specified should default to the var's ptr attr
* or (RPC_FC_RP if not specified and it's a top level ptr), not
* pointer_default so we need to fix that up here */
/* check for pointer attribute being applied to non-pointer, non-array
* type */
if (!arr)
{
int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE);
......@@ -1296,25 +1295,20 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
else
break;
}
if (ptr && is_ptr(ptr) && (ptr_attr || top))
if (is_ptr(ptr))
{
if (ptr_attr && ptr_attr != RPC_FC_UP &&
type_get_type(type_pointer_get_ref(ptr)) == TYPE_INTERFACE)
warning_loc_info(&v->loc_info,
"%s: pointer attribute applied to interface "
"pointer type has no effect\n", v->name);
if (top && !ptr_attr)
ptr_attr = RPC_FC_RP;
if (ptr_attr != (*pt)->details.pointer.fc)
if (!ptr_attr && top && (*pt)->details.pointer.def_fc != RPC_FC_RP)
{
/* create new type to avoid changing original type */
/* FIXME: this is a horrible hack - we might be changing the pointer
* type of an alias here, so we also need corresponding hacks in
* get_pointer_fc to handle this. The type of pointer that the type
* ends up having is context sensitive and so we shouldn't be
* setting it here, but rather determining it when it is used. */
/* FIXME: this is a horrible hack to cope with the issue that we
* store an offset to the typeformat string in the type object, but
* two typeformat strings may be written depending on whether the
* pointer is a toplevel parameter or not */
*pt = duptype(*pt, 1);
(*pt)->details.pointer.fc = ptr_attr;
}
}
else if (ptr_attr)
......@@ -1358,7 +1352,8 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
*ptype = type_new_array(NULL, *ptype, FALSE,
dim->is_const ? dim->cval : 0,
dim->is_const ? NULL : dim, NULL);
dim->is_const ? NULL : dim, NULL,
pointer_default);
}
ptype = &v->type;
......@@ -1373,11 +1368,11 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
else
*ptype = type_new_array((*ptype)->name,
type_array_get_element(*ptype), FALSE,
0, dim, NULL);
0, dim, NULL, 0);
}
else if (is_ptr(*ptype))
*ptype = type_new_array((*ptype)->name, type_pointer_get_ref(*ptype), TRUE,
0, dim, NULL);
0, dim, NULL, pointer_default);
else
error_loc("%s: size_is attribute applied to illegal type\n", v->name);
}
......@@ -1402,7 +1397,7 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
type_array_is_decl_as_ptr(*ptype),
type_array_get_dim(*ptype),
type_array_get_conformance(*ptype),
dim);
dim, type_array_get_ptr_default_fc(*ptype));
}
else
error_loc("%s: length_is attribute applied to illegal type\n", v->name);
......@@ -1563,7 +1558,8 @@ static func_t *make_func(var_t *def)
static type_t *make_safearray(type_t *type)
{
return type_new_array(NULL, type_new_alias(type, "SAFEARRAY"), TRUE, 0, NULL, NULL);
return type_new_array(NULL, type_new_alias(type, "SAFEARRAY"), TRUE, 0,
NULL, NULL, RPC_FC_RP);
}
static typelib_t *make_library(const char *name, const attr_list_t *attrs)
......
......@@ -156,10 +156,8 @@ int cant_be_null(const var_t *v)
switch (typegen_detect_type(v->type, v->attrs, TDT_IGNORE_STRINGS))
{
case TGT_ARRAY:
/* FIXME: work out pointer type */
return 0;
case TGT_POINTER:
return (get_pointer_fc(v->type) == RPC_FC_RP);
return (get_pointer_fc(v->type, v->attrs, TRUE) == RPC_FC_RP);
case TGT_CTXT_HANDLE_POINTER:
return TRUE;
default:
......@@ -248,7 +246,7 @@ static void free_variable( const var_t *arg, const char *local_var_prefix )
}
/* fall through */
case TGT_POINTER:
if (get_pointer_fc(type) == RPC_FC_FP)
if (get_pointer_fc(type, arg->attrs, TRUE) == RPC_FC_FP)
{
print_proxy( "NdrClearOutParameters( &__frame->_StubMsg, ");
fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset );
......
......@@ -88,6 +88,6 @@ expr_t *get_size_is_expr(const type_t *t, const char *name);
int is_full_pointer_function(const var_t *func);
void write_full_pointer_init(FILE *file, int indent, const var_t *func, int is_server);
void write_full_pointer_free(FILE *file, int indent, const var_t *func);
unsigned char get_pointer_fc(const type_t *type);
unsigned char get_pointer_fc(const type_t *type, const attr_list_t *attrs, int toplevel_param);
unsigned char get_struct_fc(const type_t *type);
enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *attrs, unsigned int flags);
......@@ -72,10 +72,10 @@ type_t *type_new_function(var_list_t *args)
return t;
}
type_t *type_new_pointer(type_t *ref, attr_list_t *attrs)
type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs)
{
type_t *t = make_type(TYPE_POINTER);
t->details.pointer.fc = pointer_default;
t->details.pointer.def_fc = pointer_default;
t->details.pointer.ref = ref;
t->attrs = attrs;
return t;
......@@ -118,7 +118,8 @@ type_t *type_new_coclass(char *name)
type_t *type_new_array(const char *name, type_t *element, int declptr,
unsigned int dim, expr_t *size_is, expr_t *length_is)
unsigned int dim, expr_t *size_is, expr_t *length_is,
unsigned char ptr_default_fc)
{
type_t *t = make_type(TYPE_ARRAY);
if (name) t->name = xstrdup(name);
......@@ -129,6 +130,7 @@ type_t *type_new_array(const char *name, type_t *element, int declptr,
else
t->details.array.dim = dim;
t->details.array.elem = element;
t->details.array.ptr_def_fc = ptr_default_fc;
return t;
}
......
......@@ -25,11 +25,12 @@
#define WIDL_TYPE_TREE_H
type_t *type_new_function(var_list_t *args);
type_t *type_new_pointer(type_t *ref, attr_list_t *attrs);
type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs);
type_t *type_new_alias(type_t *t, const char *name);
type_t *type_new_module(char *name);
type_t *type_new_array(const char *name, type_t *element, int declptr,
unsigned int dim, expr_t *size_is, expr_t *length_is);
unsigned int dim, expr_t *size_is, expr_t *length_is,
unsigned char ptr_default_fc);
type_t *type_new_basic(enum type_basic_type basic_type);
type_t *type_new_int(enum type_basic_type basic_type, int sign);
type_t *type_new_void(void);
......@@ -268,6 +269,13 @@ static inline int type_array_is_decl_as_ptr(const type_t *type)
return type->details.array.declptr;
}
static inline unsigned char type_array_get_ptr_default_fc(const type_t *type)
{
type = type_get_real_type(type);
assert(type_get_type(type) == TYPE_ARRAY);
return type->details.array.ptr_def_fc;
}
static inline int type_is_alias(const type_t *type)
{
return type->is_alias;
......@@ -293,4 +301,11 @@ static inline type_t *type_pointer_get_ref(const type_t *type)
return type->details.pointer.ref;
}
static inline unsigned char type_pointer_get_default_fc(const type_t *type)
{
type = type_get_real_type(type);
assert(type_get_type(type) == TYPE_POINTER);
return type->details.pointer.def_fc;
}
#endif /* WIDL_TYPE_TREE_H */
......@@ -319,7 +319,8 @@ struct array_details
expr_t *length_is;
struct _type_t *elem;
unsigned int dim;
unsigned int declptr; /* if declared as a pointer */
unsigned char ptr_def_fc;
unsigned char declptr; /* if declared as a pointer */
};
struct coclass_details
......@@ -336,7 +337,7 @@ struct basic_details
struct pointer_details
{
struct _type_t *ref;
unsigned char fc;
unsigned char def_fc;
};
enum type_type
......@@ -486,8 +487,6 @@ struct _statement_t {
} u;
};
extern unsigned char pointer_default;
extern user_type_list_t user_type_list;
void check_for_additional_prototype_types(const var_list_t *list);
......
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