Commit cdec0fe4 authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

widl: Add support for bit-fields in non-remote structures.

parent 2906af59
......@@ -380,6 +380,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
case TYPE_INTERFACE:
case TYPE_POINTER:
case TYPE_ARRAY:
case TYPE_BITFIELD:
/* nothing to do */
break;
case TYPE_ALIAS:
......
......@@ -295,6 +295,9 @@ void write_type_left(FILE *h, type_t *t, int declonly)
case TYPE_VOID:
fprintf(h, "void");
break;
case TYPE_BITFIELD:
write_type_left(h, type_bitfield_get_field(t), declonly);
break;
case TYPE_ALIAS:
case TYPE_FUNCTION:
/* handled elsewhere */
......@@ -308,15 +311,38 @@ void write_type_right(FILE *h, type_t *t, int is_field)
{
if (!h) return;
if (type_get_type(t) == TYPE_ARRAY && !type_array_is_decl_as_ptr(t)) {
if (is_conformant_array(t)) {
fprintf(h, "[%s]", is_field ? "1" : "");
t = type_array_get_element(t);
switch (type_get_type(t))
{
case TYPE_ARRAY:
if (!type_array_is_decl_as_ptr(t))
{
if (is_conformant_array(t))
{
fprintf(h, "[%s]", is_field ? "1" : "");
t = type_array_get_element(t);
}
for ( ;
type_get_type(t) == TYPE_ARRAY && !type_array_is_decl_as_ptr(t);
t = type_array_get_element(t))
fprintf(h, "[%u]", type_array_get_dim(t));
}
for ( ;
type_get_type(t) == TYPE_ARRAY && !type_array_is_decl_as_ptr(t);
t = type_array_get_element(t))
fprintf(h, "[%u]", type_array_get_dim(t));
break;
case TYPE_BITFIELD:
fprintf(h, " : %lu", type_bitfield_get_bits(t)->cval);
break;
case TYPE_VOID:
case TYPE_BASIC:
case TYPE_ENUM:
case TYPE_STRUCT:
case TYPE_ENCAPSULATED_UNION:
case TYPE_UNION:
case TYPE_ALIAS:
case TYPE_MODULE:
case TYPE_COCLASS:
case TYPE_FUNCTION:
case TYPE_INTERFACE:
case TYPE_POINTER:
break;
}
}
......
......@@ -278,7 +278,7 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s
%type <attr> attribute type_qualifier function_specifier
%type <attr_list> m_attributes attributes attrib_list m_type_qual_list
%type <str_list> str_list
%type <expr> m_expr expr expr_const expr_int_const array
%type <expr> m_expr expr expr_const expr_int_const array m_bitfield
%type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
%type <ifinfo> interfacehdr
%type <stgclass> storage_cls_spec
......@@ -294,9 +294,9 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s
%type <var> arg ne_union_field union_field s_field case enum declaration
%type <var_list> m_args args fields ne_union_fields cases enums enum_list dispint_props field
%type <var> m_ident ident
%type <declarator> declarator direct_declarator init_declarator
%type <declarator> declarator direct_declarator init_declarator struct_declarator
%type <declarator> m_any_declarator any_declarator any_declarator_no_ident any_direct_declarator
%type <declarator_list> declarator_list
%type <declarator_list> declarator_list struct_declarator_list
%type <func> funcdef
%type <type> coclass coclasshdr coclassdef
%type <num> pointer_type version
......@@ -679,7 +679,7 @@ fields: { $$ = NULL; }
| fields field { $$ = append_var_list($1, $2); }
;
field: m_attributes decl_spec declarator_list ';'
field: m_attributes decl_spec struct_declarator_list ';'
{ const char *first = LIST_ENTRY(list_head($3), declarator_t, entry)->var->name;
check_field_attrs(first, $1);
$$ = set_var_types($1, $2, $3);
......@@ -980,6 +980,22 @@ declarator_list:
| declarator_list ',' declarator { $$ = append_declarator( $1, $3 ); }
;
m_bitfield: { $$ = NULL; }
| ':' expr_const { $$ = $2; }
;
struct_declarator: any_declarator m_bitfield { $$ = $1; $$->bits = $2;
if (!$$->bits && !$$->var->name)
error_loc("unnamed fields are not allowed");
}
;
struct_declarator_list:
struct_declarator { $$ = append_declarator( NULL, $1 ); }
| struct_declarator_list ',' struct_declarator
{ $$ = append_declarator( $1, $3 ); }
;
init_declarator:
declarator { $$ = $1; }
| declarator '=' expr_const { $$ = $1; $1->var->eval = $3; }
......@@ -1529,6 +1545,9 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
error_loc("calling convention applied to non-function-pointer type\n");
}
if (decl->bits)
v->type = type_new_bitfield(v->type, decl->bits);
return v;
}
......@@ -1620,6 +1639,7 @@ static declarator_t *make_declarator(var_t *var)
d->type = NULL;
d->func_type = NULL;
d->array = NULL;
d->bits = NULL;
return d;
}
......@@ -2211,6 +2231,7 @@ static int is_allowed_conf_type(const type_t *type)
case TYPE_COCLASS:
case TYPE_FUNCTION:
case TYPE_INTERFACE:
case TYPE_BITFIELD:
return FALSE;
}
return FALSE;
......@@ -2254,24 +2275,30 @@ static void check_field_common(const type_t *container_type,
{
type_t *type = arg->type;
int more_to_do;
const char *container_type_name = NULL;
const char *container_type_name;
const char *var_type;
switch (type_get_type_detect_alias(type))
switch (type_get_type(container_type))
{
case TYPE_STRUCT:
container_type_name = "struct";
var_type = "field";
break;
case TYPE_UNION:
container_type_name = "union";
var_type = "arm";
break;
case TYPE_ENCAPSULATED_UNION:
container_type_name = "encapsulated union";
var_type = "arm";
break;
case TYPE_FUNCTION:
container_type_name = "function";
var_type = "parameter";
break;
default:
break;
/* should be no other container types */
assert(0);
}
if (is_attr(arg->attrs, ATTR_LENGTHIS) &&
......@@ -2331,24 +2358,35 @@ static void check_field_common(const type_t *container_type,
check_remoting_fields(arg, type);
break;
case TGT_INVALID:
{
const char *reason = "is invalid";
switch (type_get_type(type))
{
case TYPE_VOID:
error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot derive from void *\n",
arg->name, container_type_name, container_name);
reason = "cannot derive from void *";
break;
case TYPE_FUNCTION:
error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot be a function pointer\n",
arg->name, container_type_name, container_name);
reason = "cannot be a function pointer";
break;
case TYPE_BITFIELD:
reason = "cannot be a bit-field";
break;
case TYPE_COCLASS:
reason = "cannot be a class";
break;
case TYPE_INTERFACE:
reason = "cannot be a non-pointer to an interface";
break;
case TYPE_MODULE:
/* FIXME */
reason = "cannot be a module";
break;
default:
break;
}
error_loc_info(&arg->loc_info, "%s \'%s\' of %s \'%s\' %s\n",
var_type, arg->name, container_type_name, container_name, reason);
break;
}
case TGT_CTXT_HANDLE:
case TGT_CTXT_HANDLE_POINTER:
/* FIXME */
......@@ -2452,6 +2490,16 @@ static void check_remoting_args(const var_t *func)
check_field_common(func->type, funcname, arg);
}
if (type_get_type(type_function_get_rettype(func->type)) != TYPE_VOID)
{
var_t var;
var = *func;
var.type = type_function_get_rettype(func->type);
var.name = xstrdup("return value");
check_field_common(func->type, funcname, &var);
free(var.name);
}
}
static void add_explicit_handle_if_necessary(var_t *func)
......
......@@ -244,6 +244,7 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
case TYPE_MODULE:
case TYPE_VOID:
case TYPE_ALIAS:
case TYPE_BITFIELD:
break;
}
return TGT_INVALID;
......@@ -1294,10 +1295,11 @@ unsigned int type_memsize(const type_t *t, unsigned int *align)
case TYPE_COCLASS:
case TYPE_MODULE:
case TYPE_FUNCTION:
case TYPE_BITFIELD:
/* these types should not be encountered here due to language
* restrictions (interface, void, coclass, module), logical
* restrictions (alias - due to type_get_type call above) or
* checking restrictions (function). */
* checking restrictions (function, bitfield). */
assert(0);
}
......
......@@ -244,6 +244,10 @@ unsigned short get_type_vt(type_t *t)
case TYPE_FUNCTION:
error("get_type_vt: functions not supported\n");
break;
case TYPE_BITFIELD:
error("get_type_vt: bitfields not supported\n");
break;
}
return 0;
}
......
......@@ -302,6 +302,56 @@ type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *unio
return t;
}
static int is_valid_bitfield_type(const type_t *type)
{
switch (type_get_type(type))
{
case TYPE_ENUM:
return TRUE;
case TYPE_BASIC:
switch (type_basic_get_type(type))
{
case TYPE_BASIC_INT8:
case TYPE_BASIC_INT16:
case TYPE_BASIC_INT32:
case TYPE_BASIC_INT64:
case TYPE_BASIC_INT:
case TYPE_BASIC_INT3264:
case TYPE_BASIC_CHAR:
case TYPE_BASIC_HYPER:
case TYPE_BASIC_BYTE:
case TYPE_BASIC_WCHAR:
case TYPE_BASIC_ERROR_STATUS_T:
return TRUE;
case TYPE_BASIC_FLOAT:
case TYPE_BASIC_DOUBLE:
case TYPE_BASIC_HANDLE:
return FALSE;
}
return FALSE;
default:
return FALSE;
}
}
type_t *type_new_bitfield(type_t *field, const expr_t *bits)
{
type_t *t;
if (!is_valid_bitfield_type(field))
error_loc("bit-field has invalid type\n");
if (bits->cval < 0)
error_loc("negative width for bit-field\n");
/* FIXME: validate bits->cval <= memsize(field) * 8 */
t = make_type(TYPE_BITFIELD);
t->details.bitfield.field = field;
t->details.bitfield.bits = bits;
return t;
}
static int compute_method_indexes(type_t *iface)
{
int idx;
......
......@@ -39,6 +39,7 @@ type_t *type_new_enum(const char *name, int defined, var_list_t *enums);
type_t *type_new_struct(char *name, int defined, var_list_t *fields);
type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields);
type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases);
type_t *type_new_bitfield(type_t *field_type, const expr_t *bits);
void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts);
void type_dispinterface_define(type_t *iface, var_list_t *props, func_list_t *methods);
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface);
......@@ -190,6 +191,7 @@ static inline int type_is_complete(const type_t *type)
case TYPE_COCLASS:
case TYPE_POINTER:
case TYPE_ARRAY:
case TYPE_BITFIELD:
return TRUE;
}
return FALSE;
......@@ -283,4 +285,18 @@ static inline unsigned char type_pointer_get_default_fc(const type_t *type)
return type->details.pointer.def_fc;
}
static inline type_t *type_bitfield_get_field(const type_t *type)
{
type = type_get_real_type(type);
assert(type_get_type(type) == TYPE_BITFIELD);
return type->details.bitfield.field;
}
static inline const expr_t *type_bitfield_get_bits(const type_t *type)
{
type = type_get_real_type(type);
assert(type_get_type(type) == TYPE_BITFIELD);
return type->details.bitfield.bits;
}
#endif /* WIDL_TYPE_TREE_H */
......@@ -343,6 +343,12 @@ struct pointer_details
unsigned char def_fc;
};
struct bitfield_details
{
struct _type_t *field;
const expr_t *bits;
};
enum type_type
{
TYPE_VOID,
......@@ -358,6 +364,7 @@ enum type_type
TYPE_INTERFACE,
TYPE_POINTER,
TYPE_ARRAY,
TYPE_BITFIELD,
};
struct _type_t {
......@@ -375,6 +382,7 @@ struct _type_t {
struct coclass_details coclass;
struct basic_details basic;
struct pointer_details pointer;
struct bitfield_details bitfield;
} details;
type_t *orig; /* dup'd types */
unsigned int typestring_offset;
......@@ -408,6 +416,7 @@ struct _declarator_t {
type_t *type;
type_t *func_type;
array_dims_t *array;
expr_t *bits;
/* parser-internal */
struct list entry;
......
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