Add enum support.
Another attempt at getting the alignment bits correct.
This commit is contained in:
parent
a49278acc2
commit
a43a250bd1
|
@ -428,15 +428,19 @@ enum_list: enum
|
|||
enum: ident '=' expr_const { $$ = reg_const($1);
|
||||
$$->eval = $3;
|
||||
$$->lval = $3->cval;
|
||||
$$->type = make_type(RPC_FC_LONG, &std_int);
|
||||
}
|
||||
| ident { $$ = reg_const($1);
|
||||
$$->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);
|
||||
$$->fields = $4;
|
||||
$$->defined = TRUE;
|
||||
if(in_typelib)
|
||||
add_enum($$);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -250,3 +250,16 @@ void add_struct(type_t *structure)
|
|||
LINK(entry, typelib->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);
|
|||
extern void add_coclass(class_t *cls);
|
||||
extern void add_module(type_t *module);
|
||||
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
|
||||
* circular dependency (after all, wtypes.h is generated by widl...) */
|
||||
|
|
|
@ -240,6 +240,7 @@ struct _typelib_entry_t {
|
|||
type_t *interface;
|
||||
type_t *module;
|
||||
type_t *structure;
|
||||
type_t *enumeration;
|
||||
} u;
|
||||
DECL_LINK(typelib_entry_t)
|
||||
};
|
||||
|
|
|
@ -1353,9 +1353,9 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index)
|
|||
typeinfo->names[index] = offset;
|
||||
|
||||
namedata = typeinfo->typelib->typelib_segment_data[MSFT_SEG_NAME] + offset;
|
||||
namedata[9] &= ~0x10;
|
||||
if (*((INT *)namedata) == -1) {
|
||||
*((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++) {
|
||||
|
@ -1369,49 +1369,13 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, func_t *func, int index)
|
|||
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)
|
||||
{
|
||||
int offset;
|
||||
INT *typedata;
|
||||
int var_datawidth;
|
||||
int var_alignment;
|
||||
int var_type_size;
|
||||
int var_type_size, var_kind = 0 /* VAR_PERINSTANCE */;
|
||||
int alignment;
|
||||
int varflags = 0;
|
||||
attr_t *attr;
|
||||
|
@ -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 */
|
||||
typeinfo->datawidth += var_alignment - 1;
|
||||
typeinfo->datawidth &= ~(var_alignment - 1);
|
||||
typedata[4] = typeinfo->datawidth;
|
||||
|
||||
/* add the new variable to the total data width */
|
||||
if((typeinfo->typeinfo->typekind & 0xf) == TKIND_ENUM) {
|
||||
write_value(typeinfo->typelib, &typedata[4], VT_I4, &var->lval);
|
||||
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 */
|
||||
typedata[3] += var_type_size << 16;
|
||||
typedata[3] += var_type_size << 16 | var_kind;
|
||||
|
||||
/* fix type alignment */
|
||||
alignment = (typeinfo->typeinfo->typekind >> 11) & 0x1f;
|
||||
if (alignment < var_alignment) {
|
||||
alignment = var_alignment;
|
||||
typeinfo->typeinfo->typekind &= ~0xf800;
|
||||
typeinfo->typeinfo->typekind |= alignment << 11;
|
||||
typeinfo->typeinfo->typekind &= ~0xffc0;
|
||||
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)
|
|||
if (*((INT *)namedata) == -1) {
|
||||
*((INT *)namedata) = typeinfo->typelib->typelib_typeinfo_offsets[typeinfo->typeinfo->typekind >> 16];
|
||||
namedata[9] |= 0x10;
|
||||
}
|
||||
} else
|
||||
namedata[9] &= ~0x10;
|
||||
|
||||
if ((typeinfo->typeinfo->typekind & 15) == TKIND_ENUM) {
|
||||
namedata[9] |= 0x20;
|
||||
}
|
||||
|
@ -1544,8 +1516,7 @@ static msft_typeinfo_t *create_msft_typeinfo(msft_typelib_t *typelib, enum type_
|
|||
|
||||
msft_typeinfo->typeinfo = typeinfo;
|
||||
|
||||
typeinfo->typekind |= kind | 0x220;
|
||||
set_alignment(msft_typeinfo, 4);
|
||||
typeinfo->typekind |= kind | 0x20;
|
||||
|
||||
for( ; attr; attr = NEXT_LINK(attr)) {
|
||||
switch(attr->type) {
|
||||
|
@ -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,
|
||||
typelib->typelib_header.nrtypeinfos);
|
||||
msft_typeinfo->typeinfo->size = 4;
|
||||
msft_typeinfo->typeinfo->typekind |= 0x2200;
|
||||
|
||||
if(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)
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
switch(entry->kind) {
|
||||
|
@ -1662,13 +1653,16 @@ static void add_entry(msft_typelib_t *typelib, typelib_entry_t *entry)
|
|||
add_structure_typeinfo(typelib, entry->u.structure);
|
||||
break;
|
||||
|
||||
case TKIND_ENUM:
|
||||
add_enum_typeinfo(typelib, entry->u.enumeration);
|
||||
break;
|
||||
|
||||
default:
|
||||
error("add_entry: unhandled type %d\n", entry->kind);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void set_name(msft_typelib_t *typelib)
|
||||
{
|
||||
int offset;
|
||||
|
|
Loading…
Reference in New Issue