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;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double
|
||||||
|
s_sum_aligns(aligns_t *a)
|
||||||
|
{
|
||||||
|
return a->c + a->i + a->s + a->d;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
s_stop(void)
|
s_stop(void)
|
||||||
{
|
{
|
||||||
|
@ -374,6 +380,7 @@ basic_tests(void)
|
||||||
static pvectors_t pvecs = {&vec1, &pvec2};
|
static pvectors_t pvecs = {&vec1, &pvec2};
|
||||||
static sp_inner_t spi = {42};
|
static sp_inner_t spi = {42};
|
||||||
static sp_t sp = {-13, &spi};
|
static sp_t sp = {-13, &spi};
|
||||||
|
static aligns_t aligns = {3, 4, 5, 6.0};
|
||||||
pints_t pints;
|
pints_t pints;
|
||||||
ptypes_t ptypes;
|
ptypes_t ptypes;
|
||||||
int i1, i2, i3, *pi2, *pi3, **ppi3;
|
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(E2) == 2, "RPC enum_ord\n");
|
||||||
ok(enum_ord(E3) == 3, "RPC enum_ord\n");
|
ok(enum_ord(E3) == 3, "RPC enum_ord\n");
|
||||||
ok(enum_ord(E4) == 4, "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
|
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_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);
|
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);
|
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_CARRAY: return "FC_CARRAY";
|
||||||
case RPC_FC_CVARRAY: return "FC_CVARRAY";
|
case RPC_FC_CVARRAY: return "FC_CVARRAY";
|
||||||
case RPC_FC_BOGUS_ARRAY: return "FC_BOGUS_ARRAY";
|
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:
|
default:
|
||||||
error("string_of_type: unknown type 0x%02x\n", type);
|
error("string_of_type: unknown type 0x%02x\n", type);
|
||||||
return NULL;
|
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)
|
static size_t fields_memsize(const var_list_t *fields, unsigned int *align)
|
||||||
{
|
{
|
||||||
|
int have_align = FALSE;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
const var_t *v;
|
const var_t *v;
|
||||||
|
|
||||||
if (!fields) return 0;
|
if (!fields) return 0;
|
||||||
LIST_FOR_EACH_ENTRY( v, fields, const var_t, entry )
|
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;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1508,12 +1522,36 @@ static void write_struct_members(FILE *file, const type_t *type,
|
||||||
unsigned int *corroff, unsigned int *typestring_offset)
|
unsigned int *corroff, unsigned int *typestring_offset)
|
||||||
{
|
{
|
||||||
const var_t *field;
|
const var_t *field;
|
||||||
|
unsigned short offset = 0;
|
||||||
|
|
||||||
if (type->fields) LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry )
|
if (type->fields) LIST_FOR_EACH_ENTRY( field, type->fields, const var_t, entry )
|
||||||
{
|
{
|
||||||
type_t *ft = field->type;
|
type_t *ft = field->type;
|
||||||
if (!ft->declarray || !is_conformant_array(ft))
|
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);
|
write_member_type(file, ft, field, corroff, typestring_offset);
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
write_end(file, typestring_offset);
|
write_end(file, typestring_offset);
|
||||||
|
|
Loading…
Reference in New Issue