widl: Implement NDR for struct field alignment.
This commit is contained in:
parent
3d036da6d3
commit
62fb623e14
|
@ -329,6 +329,12 @@ s_sum_toplev_conf_cond(int *x, int a, int b, int c)
|
|||
return sum;
|
||||
}
|
||||
|
||||
double
|
||||
s_sum_aligns(aligns_t *a)
|
||||
{
|
||||
return a->c + a->i + a->s + a->d;
|
||||
}
|
||||
|
||||
void
|
||||
s_stop(void)
|
||||
{
|
||||
|
@ -374,6 +380,7 @@ basic_tests(void)
|
|||
static pvectors_t pvecs = {&vec1, &pvec2};
|
||||
static sp_inner_t spi = {42};
|
||||
static sp_t sp = {-13, &spi};
|
||||
static aligns_t aligns = {3, 4, 5, 6.0};
|
||||
pints_t pints;
|
||||
ptypes_t ptypes;
|
||||
int i1, i2, i3, *pi2, *pi3, **ppi3;
|
||||
|
@ -447,6 +454,8 @@ basic_tests(void)
|
|||
ok(enum_ord(E2) == 2, "RPC enum_ord\n");
|
||||
ok(enum_ord(E3) == 3, "RPC enum_ord\n");
|
||||
ok(enum_ord(E4) == 4, "RPC enum_ord\n");
|
||||
|
||||
ok(sum_aligns(&aligns) == 18.0, "RPC sum_aligns\n");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -189,5 +189,15 @@ interface IServer
|
|||
int sum_toplev_conf_2n([size_is(n * 2)] int *x, int n);
|
||||
int sum_toplev_conf_cond([size_is(c ? a : b)] int *x, int a, int b, int c);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char c;
|
||||
int i;
|
||||
short s;
|
||||
double d;
|
||||
} aligns_t;
|
||||
|
||||
double sum_aligns(aligns_t *a);
|
||||
|
||||
void stop(void);
|
||||
}
|
||||
|
|
|
@ -98,6 +98,8 @@ const char *string_of_type(unsigned char type)
|
|||
case RPC_FC_CARRAY: return "FC_CARRAY";
|
||||
case RPC_FC_CVARRAY: return "FC_CVARRAY";
|
||||
case RPC_FC_BOGUS_ARRAY: return "FC_BOGUS_ARRAY";
|
||||
case RPC_FC_ALIGNM4: return "RPC_FC_ALIGNM4";
|
||||
case RPC_FC_ALIGNM8: return "RPC_FC_ALIGNM8";
|
||||
default:
|
||||
error("string_of_type: unknown type 0x%02x\n", type);
|
||||
return NULL;
|
||||
|
@ -682,13 +684,25 @@ static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const type_
|
|||
|
||||
static size_t fields_memsize(const var_list_t *fields, unsigned int *align)
|
||||
{
|
||||
int have_align = FALSE;
|
||||
size_t size = 0;
|
||||
const var_t *v;
|
||||
|
||||
if (!fields) return 0;
|
||||
LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry )
|
||||
size += type_memsize(v->type, align);
|
||||
{
|
||||
unsigned int falign = 0;
|
||||
size_t fsize = type_memsize(v->type, &falign);
|
||||
if (!have_align)
|
||||
{
|
||||
*align = falign;
|
||||
have_align = TRUE;
|
||||
}
|
||||
size = (size + (falign - 1)) & ~(falign - 1);
|
||||
size += fsize;
|
||||
}
|
||||
|
||||
size = (size + (*align - 1)) & ~(*align - 1);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
@ -1508,12 +1522,36 @@ static void write_struct_members(FILE *file, const type_t *type,
|
|||
unsigned int *corroff, unsigned int *typestring_offset)
|
||||
{
|
||||
const var_t *field;
|
||||
unsigned short offset = 0;
|
||||
|
||||
if (type->fields) LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry )
|
||||
{
|
||||
type_t *ft = field->type;
|
||||
if (!ft->declarray || !is_conformant_array(ft))
|
||||
{
|
||||
unsigned int align = 0;
|
||||
size_t size = type_memsize(ft, &align);
|
||||
if ((align - 1) & offset)
|
||||
{
|
||||
unsigned char fc = 0;
|
||||
switch (align)
|
||||
{
|
||||
case 4:
|
||||
fc = RPC_FC_ALIGNM4;
|
||||
break;
|
||||
case 8:
|
||||
fc = RPC_FC_ALIGNM8;
|
||||
break;
|
||||
default:
|
||||
error("write_struct_members: cannot align type %d", ft->type);
|
||||
}
|
||||
print_file(file, 2, "0x%x,\t/* %s */\n", fc, string_of_type(fc));
|
||||
offset = (offset + (align - 1)) & ~(align - 1);
|
||||
*typestring_offset += 1;
|
||||
}
|
||||
write_member_type(file, ft, field, corroff, typestring_offset);
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
|
||||
write_end(file, typestring_offset);
|
||||
|
|
Loading…
Reference in New Issue