Commit a43a250b authored by Huw Davies's avatar Huw Davies Committed by Alexandre Julliard

Add enum support.

Another attempt at getting the alignment bits correct.
parent a49278ac
...@@ -428,15 +428,19 @@ enum_list: enum ...@@ -428,15 +428,19 @@ enum_list: enum
enum: ident '=' expr_const { $$ = reg_const($1); enum: ident '=' expr_const { $$ = reg_const($1);
$$->eval = $3; $$->eval = $3;
$$->lval = $3->cval; $$->lval = $3->cval;
$$->type = make_type(RPC_FC_LONG, &std_int);
} }
| ident { $$ = reg_const($1); | ident { $$ = reg_const($1);
$$->lval = 0; /* default for first enum entry */ $$->lval = 0; /* default for first enum entry */
$$->type = make_type(RPC_FC_LONG, &std_int);
} }
; ;
enumdef: tENUM t_ident '{' enums '}' { $$ = get_typev(RPC_FC_ENUM16, $2, tsENUM); enumdef: tENUM t_ident '{' enums '}' { $$ = get_typev(RPC_FC_ENUM16, $2, tsENUM);
$$->fields = $4; $$->fields = $4;
$$->defined = TRUE; $$->defined = TRUE;
if(in_typelib)
add_enum($$);
} }
; ;
......
...@@ -250,3 +250,16 @@ void add_struct(type_t *structure) ...@@ -250,3 +250,16 @@ void add_struct(type_t *structure)
LINK(entry, typelib->entry); LINK(entry, typelib->entry);
typelib->entry = entry; typelib->entry = entry;
} }
void add_enum(type_t *enumeration)
{
typelib_entry_t *entry;
if (!typelib) return;
chat("add enum: %s\n", enumeration->name);
entry = xmalloc(sizeof(*entry));
entry->kind = TKIND_ENUM;
entry->u.enumeration = enumeration;
LINK(entry, typelib->entry);
typelib->entry = entry;
}
...@@ -28,6 +28,7 @@ extern void add_interface(type_t *iface); ...@@ -28,6 +28,7 @@ extern void add_interface(type_t *iface);
extern void add_coclass(class_t *cls); extern void add_coclass(class_t *cls);
extern void add_module(type_t *module); extern void add_module(type_t *module);
extern void add_struct(type_t *structure); extern void add_struct(type_t *structure);
extern void add_enum(type_t *enumeration);
/* Copied from wtypes.h. Not included directly because that would create a /* Copied from wtypes.h. Not included directly because that would create a
* circular dependency (after all, wtypes.h is generated by widl...) */ * circular dependency (after all, wtypes.h is generated by widl...) */
......
...@@ -240,6 +240,7 @@ struct _typelib_entry_t { ...@@ -240,6 +240,7 @@ struct _typelib_entry_t {
type_t *interface; type_t *interface;
type_t *module; type_t *module;
type_t *structure; type_t *structure;
type_t *enumeration;
} u; } u;
DECL_LINK(typelib_entry_t) DECL_LINK(typelib_entry_t)
}; };
......
...@@ -1353,9 +1353,9 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index) ...@@ -1353,9 +1353,9 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index)
typeinfo->names[index] = offset; typeinfo->names[index] = offset;
namedata = typeinfo->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset; namedata = typeinfo->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset;
namedata[9] &= ~0x10;
if (*((INT *)namedata) == -1) { if (*((INT *)namedata) == -1) {
*((INT *)namedata) = typeinfo->typelib->typelib_typeinfo_offsets[typeinfo->typeinfo->typekind >> 16]; *((INT *)namedata) = typeinfo->typelib->typelib_typeinfo_offsets[typeinfo->typeinfo->typekind >> 16];
namedata[9] &= ~0x10;
} }
for (arg = last_arg, i = 0; arg; arg = PREV_LINK(arg), i++) { for (arg = last_arg, i = 0; arg; arg = PREV_LINK(arg), i++) {
...@@ -1369,49 +1369,13 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index) ...@@ -1369,49 +1369,13 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index)
return S_OK; return S_OK;
} }
static void set_alignment(
msft_typeinfo_t* typeinfo,
WORD cbAlignment)
{
if (!cbAlignment) return;
if (cbAlignment > 16) return;
typeinfo->typeinfo->typekind &= ~0xf800;
/* FIXME: There's probably some way to simplify this. */
switch (typeinfo->typeinfo->typekind & 15) {
case TKIND_ALIAS:
default:
break;
case TKIND_ENUM:
case TKIND_INTERFACE:
case TKIND_DISPATCH:
case TKIND_COCLASS:
if (cbAlignment > 4) cbAlignment = 4;
break;
case TKIND_RECORD:
case TKIND_MODULE:
case TKIND_UNION:
cbAlignment = 1;
break;
}
typeinfo->typeinfo->typekind |= cbAlignment << 11;
return;
}
static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var) static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
{ {
int offset; int offset;
INT *typedata; INT *typedata;
int var_datawidth; int var_datawidth;
int var_alignment; int var_alignment;
int var_type_size; int var_type_size, var_kind = 0 /* VAR_PERINSTANCE */;
int alignment; int alignment;
int varflags = 0; int varflags = 0;
attr_t *attr; attr_t *attr;
...@@ -1460,20 +1424,26 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var) ...@@ -1460,20 +1424,26 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
/* pad out starting position to data width */ /* pad out starting position to data width */
typeinfo->datawidth += var_alignment - 1; typeinfo->datawidth += var_alignment - 1;
typeinfo->datawidth &= ~(var_alignment - 1); typeinfo->datawidth &= ~(var_alignment - 1);
typedata[4] = typeinfo->datawidth;
if((typeinfo->typeinfo->typekind & 0xf) == TKIND_ENUM) {
/* add the new variable to the total data width */ write_value(typeinfo->typelib, &typedata[4], VT_I4, &var->lval);
typeinfo->datawidth += var_datawidth; var_kind = 2; /* VAR_CONST */
var_type_size += 16; /* sizeof(VARIANT) */
typeinfo->datawidth = var_datawidth;
} else {
typedata[4] = typeinfo->datawidth;
typeinfo->datawidth += var_datawidth;
}
/* add type description size to total required allocation */ /* add type description size to total required allocation */
typedata[3] += var_type_size << 16; typedata[3] += var_type_size << 16 | var_kind;
/* fix type alignment */ /* fix type alignment */
alignment = (typeinfo->typeinfo->typekind >> 11) & 0x1f; alignment = (typeinfo->typeinfo->typekind >> 11) & 0x1f;
if (alignment < var_alignment) { if (alignment < var_alignment) {
alignment = var_alignment; alignment = var_alignment;
typeinfo->typeinfo->typekind &= ~0xf800; typeinfo->typeinfo->typekind &= ~0xffc0;
typeinfo->typeinfo->typekind |= alignment << 11; typeinfo->typeinfo->typekind |= alignment << 11 | alignment << 6;
} }
/* ??? */ /* ??? */
...@@ -1499,7 +1469,9 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var) ...@@ -1499,7 +1469,9 @@ static HRESULT add_var_desc(msft_typeinfo_t *typeinfo, UINT index, var_t* var)
if (*((INT *)namedata) == -1) { if (*((INT *)namedata) == -1) {
*((INT *)namedata) = typeinfo->typelib->typelib_typeinfo_offsets[typeinfo->typeinfo->typekind >> 16]; *((INT *)namedata) = typeinfo->typelib->typelib_typeinfo_offsets[typeinfo->typeinfo->typekind >> 16];
namedata[9] |= 0x10; namedata[9] |= 0x10;
} } else
namedata[9] &= ~0x10;
if ((typeinfo->typeinfo->typekind & 15) == TKIND_ENUM) { if ((typeinfo->typeinfo->typekind & 15) == TKIND_ENUM) {
namedata[9] |= 0x20; namedata[9] |= 0x20;
} }
...@@ -1544,8 +1516,7 @@ static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_ ...@@ -1544,8 +1516,7 @@ static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_
msft_typeinfo->typeinfo = typeinfo; msft_typeinfo->typeinfo = typeinfo;
typeinfo->typekind |= kind | 0x220; typeinfo->typekind |= kind | 0x20;
set_alignment(msft_typeinfo, 4);
for( ; attr; attr = NEXT_LINK(attr)) { for( ; attr; attr = NEXT_LINK(attr)) {
switch(attr->type) { switch(attr->type) {
...@@ -1620,6 +1591,7 @@ static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface) ...@@ -1620,6 +1591,7 @@ static void add_interface_typeinfo(msft_typelib_t *typelib, type_t *interface)
msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs, msft_typeinfo = create_msft_typeinfo(typelib, TKIND_INTERFACE, interface->name, interface->attrs,
typelib->typelib_header.nrtypeinfos); typelib->typelib_header.nrtypeinfos);
msft_typeinfo->typeinfo->size = 4; msft_typeinfo->typeinfo->size = 4;
msft_typeinfo->typeinfo->typekind |= 0x2200;
if(interface->ref) if(interface->ref)
add_impl_type(msft_typeinfo, interface->ref); add_impl_type(msft_typeinfo, interface->ref);
...@@ -1651,6 +1623,25 @@ static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure) ...@@ -1651,6 +1623,25 @@ static void add_structure_typeinfo(msft_typelib_t *typelib, type_t *structure)
} }
} }
static void add_enum_typeinfo(msft_typelib_t *typelib, type_t *enumeration)
{
int idx = 0;
var_t *cur = enumeration->fields;
msft_typeinfo_t *msft_typeinfo;
enumeration->typelib_idx = typelib->typelib_header.nrtypeinfos;
msft_typeinfo = create_msft_typeinfo(typelib, TKIND_ENUM, enumeration->name, enumeration->attrs,
typelib->typelib_header.nrtypeinfos);
msft_typeinfo->typeinfo->size = 0;
while(NEXT_LINK(cur)) cur = NEXT_LINK(cur);
while(cur) {
add_var_desc(msft_typeinfo, idx, cur);
idx++;
cur = PREV_LINK(cur);
}
}
static void add_entry(msft_typelib_t *typelib, typelib_entry_t *entry) static void add_entry(msft_typelib_t *typelib, typelib_entry_t *entry)
{ {
switch(entry->kind) { switch(entry->kind) {
...@@ -1662,13 +1653,16 @@ static void add_entry(msft_typelib_t *typelib, typelib_entry_t *entry) ...@@ -1662,13 +1653,16 @@ static void add_entry(msft_typelib_t *typelib, typelib_entry_t *entry)
add_structure_typeinfo(typelib, entry->u.structure); add_structure_typeinfo(typelib, entry->u.structure);
break; break;
case TKIND_ENUM:
add_enum_typeinfo(typelib, entry->u.enumeration);
break;
default: default:
error("add_entry: unhandled type %d\n", entry->kind); error("add_entry: unhandled type %d\n", entry->kind);
break; break;
} }
} }
static void set_name(msft_typelib_t *typelib) static void set_name(msft_typelib_t *typelib)
{ {
int offset; int 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