widl: Simplify correlation descriptor code.
This commit is contained in:
parent
b95197ac19
commit
88c8128704
|
@ -210,6 +210,21 @@ s_sum_cs(cs_t *cs)
|
|||
return s_sum_conf_array(cs->ca, cs->n);
|
||||
}
|
||||
|
||||
int
|
||||
s_sum_cps(cps_t *cps)
|
||||
{
|
||||
int sum = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < *cps->pn; ++i)
|
||||
sum += cps->ca1[i];
|
||||
|
||||
for (i = 0; i < 2 * cps->n; ++i)
|
||||
sum += cps->ca2[i];
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
void
|
||||
s_stop(void)
|
||||
{
|
||||
|
@ -393,7 +408,9 @@ array_tests(void)
|
|||
};
|
||||
static int c[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
static vector_t vs[2] = {{1, -2, 3}, {4, -5, -6}};
|
||||
cps_t cps;
|
||||
cs_t *cs;
|
||||
int n;
|
||||
|
||||
ok(sum_fixed_int_3d(m) == 4116, "RPC sum_fixed_int_3d\n");
|
||||
|
||||
|
@ -417,6 +434,13 @@ array_tests(void)
|
|||
cs->ca[4] = -4;
|
||||
ok(sum_cs(cs) == 1, "RPC sum_cs\n");
|
||||
HeapFree(GetProcessHeap(), 0, cs);
|
||||
|
||||
n = 5;
|
||||
cps.pn = &n;
|
||||
cps.ca1 = &c[2];
|
||||
cps.n = 3;
|
||||
cps.ca2 = &c[3];
|
||||
ok(sum_cps(&cps) == 53, "RPC sum_cps\n");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -119,7 +119,16 @@ interface IServer
|
|||
[size_is(n)] int ca[];
|
||||
} cs_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int *pn;
|
||||
[size_is(*pn)] int *ca1;
|
||||
[size_is(n * 2)] int *ca2;
|
||||
int n;
|
||||
} cps_t;
|
||||
|
||||
int sum_cs(cs_t *cs);
|
||||
int sum_cps(cps_t *cps);
|
||||
|
||||
void stop(void);
|
||||
}
|
||||
|
|
|
@ -1387,7 +1387,6 @@ static var_t *make_var(char *name)
|
|||
v->args = NULL;
|
||||
v->attrs = NULL;
|
||||
v->eval = NULL;
|
||||
v->corrdesc = 0;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ struct expr_eval_routine
|
|||
static size_t fields_memsize(const var_list_t *fields, unsigned int *align);
|
||||
static size_t write_struct_tfs(FILE *file, type_t *type, const char *name, unsigned int *tfsoff);
|
||||
static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
|
||||
const char *name, int level, unsigned int *tfsoff);
|
||||
const char *name, int write_ptr, unsigned int *tfsoff);
|
||||
|
||||
const char *string_of_type(unsigned char type)
|
||||
{
|
||||
|
@ -160,32 +160,6 @@ static int is_embedded_complex(const type_t *type)
|
|||
return is_struct(tc) || is_union(tc) || is_array(type);
|
||||
}
|
||||
|
||||
static long field_offset(const type_t *strct, const char *name, var_t **pfield)
|
||||
{
|
||||
long offset = 0;
|
||||
var_list_t *fields = strct->fields;
|
||||
var_t *f;
|
||||
|
||||
if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
|
||||
{
|
||||
unsigned int align = 0;
|
||||
|
||||
if (f->name != NULL && strcmp(name, f->name) == 0)
|
||||
{
|
||||
if (pfield) *pfield = f;
|
||||
return offset;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: handle possible padding */
|
||||
offset += type_memsize(f->type, &align);
|
||||
}
|
||||
}
|
||||
|
||||
if (pfield) *pfield = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int compare_expr(const expr_t *a, const expr_t *b)
|
||||
{
|
||||
int ret;
|
||||
|
@ -442,7 +416,8 @@ static int write_base_type(FILE *file, const type_t *type, unsigned int *typestr
|
|||
}
|
||||
|
||||
/* write conformance / variance descriptor */
|
||||
static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const type_t *structure, const expr_t *expr)
|
||||
static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const type_t *structure,
|
||||
unsigned int baseoff, const expr_t *expr)
|
||||
{
|
||||
unsigned char operator_type = 0;
|
||||
const char *operator_string = "no operators";
|
||||
|
@ -526,18 +501,19 @@ static size_t write_conf_or_var_desc(FILE *file, const func_t *func, const type_
|
|||
if (structure->fields) LIST_FOR_EACH_ENTRY( var, structure->fields, const var_t, entry )
|
||||
{
|
||||
unsigned int align = 0;
|
||||
offset -= type_memsize(var->type, &align);
|
||||
/* FIXME: take alignment into account */
|
||||
if (!strcmp(var->name, subexpr->u.sval))
|
||||
{
|
||||
correlation_variable = var->type;
|
||||
break;
|
||||
}
|
||||
offset += type_memsize(var->type, &align);
|
||||
}
|
||||
if (!correlation_variable)
|
||||
error("write_conf_or_var_desc: couldn't find variable %s in structure\n",
|
||||
subexpr->u.sval);
|
||||
|
||||
offset -= baseoff;
|
||||
correlation_type = RPC_FC_NORMAL_CONFORMANCE;
|
||||
}
|
||||
else
|
||||
|
@ -819,7 +795,7 @@ static int processed(const type_t *type)
|
|||
}
|
||||
|
||||
static void write_member_type(FILE *file, type_t *type, const var_t *field,
|
||||
unsigned int *tfsoff)
|
||||
unsigned int *corroff, unsigned int *tfsoff)
|
||||
{
|
||||
if (is_ptr(type))
|
||||
{
|
||||
|
@ -828,10 +804,19 @@ static void write_member_type(FILE *file, type_t *type, const var_t *field,
|
|||
}
|
||||
else if (is_embedded_complex(type))
|
||||
{
|
||||
size_t absoff = (field && field->corrdesc
|
||||
? field->corrdesc
|
||||
: type->typestring_offset);
|
||||
short reloff = absoff - (*tfsoff + 2);
|
||||
size_t absoff;
|
||||
short reloff;
|
||||
|
||||
if (is_union(type->type) && is_attr(field->attrs, ATTR_SWITCHIS))
|
||||
{
|
||||
absoff = *corroff;
|
||||
*corroff += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
absoff = type->typestring_offset;
|
||||
}
|
||||
reloff = absoff - (*tfsoff + 2);
|
||||
|
||||
print_file(file, 2, "0x4c,\t/* FC_EMBEDDED_COMPLEX */\n");
|
||||
/* FIXME: actually compute necessary padding */
|
||||
|
@ -855,6 +840,35 @@ static void write_end(FILE *file, unsigned int *tfsoff)
|
|||
*tfsoff += 1;
|
||||
}
|
||||
|
||||
static void write_descriptors(FILE *file, type_t *type, unsigned int *tfsoff)
|
||||
{
|
||||
unsigned int offset = 0;
|
||||
var_list_t *fs = type->fields;
|
||||
var_t *f;
|
||||
|
||||
if (fs) LIST_FOR_EACH_ENTRY(f, fs, var_t, entry)
|
||||
{
|
||||
unsigned int align = 0;
|
||||
type_t *ft = f->type;
|
||||
if (is_union(ft->type) && is_attr(f->attrs, ATTR_SWITCHIS))
|
||||
{
|
||||
unsigned int absoff = ft->typestring_offset;
|
||||
short reloff = absoff - (*tfsoff + 6);
|
||||
print_file(file, 0, "/* %d */\n", *tfsoff);
|
||||
print_file(file, 2, "0x%x,\t/* %s */\n", ft->type, string_of_type(ft->type));
|
||||
print_file(file, 2, "0x%x,\t/* FIXME: always FC_LONG */\n", RPC_FC_LONG);
|
||||
write_conf_or_var_desc(file, current_func, current_structure, offset,
|
||||
get_attrp(f->attrs, ATTR_SWITCHIS));
|
||||
print_file(file, 2, "NdrFcShort(%hd),\t/* Offset= %hd (%u) */\n",
|
||||
reloff, reloff, absoff);
|
||||
*tfsoff += 8;
|
||||
}
|
||||
|
||||
/* FIXME: take alignment into account */
|
||||
offset += type_memsize(ft, &align);
|
||||
}
|
||||
}
|
||||
|
||||
static size_t write_pointer_description(FILE *file, type_t *type, size_t mem_offset,
|
||||
int level, unsigned int *typestring_offset)
|
||||
{
|
||||
|
@ -959,6 +973,8 @@ static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
|
|||
}
|
||||
else if (type->size_is)
|
||||
{
|
||||
unsigned int align = 0;
|
||||
|
||||
if (rtype == RPC_FC_CHAR)
|
||||
WRITE_FCTYPE(file, FC_C_CSTRING, *typestring_offset);
|
||||
else
|
||||
|
@ -966,7 +982,12 @@ static size_t write_string_tfs(FILE *file, const attr_list_t *attrs,
|
|||
print_file(file, 2, "0x%x, /* FC_STRING_SIZED */\n", RPC_FC_STRING_SIZED);
|
||||
*typestring_offset += 2;
|
||||
|
||||
*typestring_offset += write_conf_or_var_desc(file, current_func, NULL, type->size_is);
|
||||
*typestring_offset += write_conf_or_var_desc(
|
||||
file, current_func, current_structure,
|
||||
(type->declarray && current_structure
|
||||
? type_memsize(current_structure, &align)
|
||||
: 0),
|
||||
type->size_is);
|
||||
|
||||
return start_offset;
|
||||
}
|
||||
|
@ -997,7 +1018,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type
|
|||
pointer_type = RPC_FC_RP;
|
||||
|
||||
has_pointer = FALSE;
|
||||
if (write_embedded_types(file, attrs, type, name, 0, typestring_offset))
|
||||
if (write_embedded_types(file, attrs, type->ref, name, FALSE, typestring_offset))
|
||||
has_pointer = TRUE;
|
||||
|
||||
size = type_memsize(type, &align);
|
||||
|
@ -1011,9 +1032,14 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type
|
|||
print_file(file, 2, "0x%x,\t/* %d */\n", align - 1, align - 1);
|
||||
*typestring_offset += 2;
|
||||
|
||||
align = 0;
|
||||
if (type->type != RPC_FC_BOGUS_ARRAY)
|
||||
{
|
||||
unsigned char tc = type->type;
|
||||
unsigned int baseoff
|
||||
= type->declarray && current_structure
|
||||
? type_memsize(current_structure, &align)
|
||||
: 0;
|
||||
|
||||
if (tc == RPC_FC_LGFARRAY || tc == RPC_FC_LGVARRAY)
|
||||
{
|
||||
|
@ -1028,8 +1054,8 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type
|
|||
|
||||
if (is_conformant_array(type))
|
||||
*typestring_offset
|
||||
+= write_conf_or_var_desc(file, current_func,
|
||||
current_structure, size_is);
|
||||
+= write_conf_or_var_desc(file, current_func, current_structure,
|
||||
baseoff, size_is);
|
||||
|
||||
if (type->type == RPC_FC_SMVARRAY || type->type == RPC_FC_LGVARRAY)
|
||||
{
|
||||
|
@ -1053,8 +1079,8 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type
|
|||
|
||||
if (length_is)
|
||||
*typestring_offset
|
||||
+= write_conf_or_var_desc(file, current_func,
|
||||
current_structure, length_is);
|
||||
+= write_conf_or_var_desc(file, current_func, current_structure,
|
||||
baseoff, length_is);
|
||||
|
||||
if (has_pointer)
|
||||
{
|
||||
|
@ -1066,7 +1092,7 @@ static size_t write_array_tfs(FILE *file, const attr_list_t *attrs, type_t *type
|
|||
*typestring_offset += 1;
|
||||
}
|
||||
|
||||
write_member_type(file, type->ref, NULL, typestring_offset);
|
||||
write_member_type(file, type->ref, NULL, NULL, typestring_offset);
|
||||
write_end(file, typestring_offset);
|
||||
}
|
||||
else
|
||||
|
@ -1089,7 +1115,8 @@ static const var_t *find_array_or_string_in_struct(const type_t *type)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void write_struct_members(FILE *file, const type_t *type, unsigned int *typestring_offset)
|
||||
static void write_struct_members(FILE *file, const type_t *type,
|
||||
unsigned int *corroff, unsigned int *typestring_offset)
|
||||
{
|
||||
const var_t *field;
|
||||
|
||||
|
@ -1097,7 +1124,7 @@ static void write_struct_members(FILE *file, const type_t *type, unsigned int *t
|
|||
{
|
||||
type_t *ft = field->type;
|
||||
if (!ft->declarray || !is_conformant_array(ft))
|
||||
write_member_type(file, ft, field, typestring_offset);
|
||||
write_member_type(file, ft, field, corroff, typestring_offset);
|
||||
}
|
||||
|
||||
write_end(file, typestring_offset);
|
||||
|
@ -1106,32 +1133,37 @@ static void write_struct_members(FILE *file, const type_t *type, unsigned int *t
|
|||
static size_t write_struct_tfs(FILE *file, type_t *type,
|
||||
const char *name, unsigned int *tfsoff)
|
||||
{
|
||||
const type_t *save_current_structure = current_structure;
|
||||
unsigned int total_size;
|
||||
const var_t *array;
|
||||
size_t start_offset;
|
||||
size_t array_offset;
|
||||
int has_pointers;
|
||||
int has_pointers = 0;
|
||||
unsigned int align = 0;
|
||||
unsigned int corroff;
|
||||
var_t *f;
|
||||
|
||||
guard_rec(type);
|
||||
current_structure = type;
|
||||
|
||||
total_size = type_memsize(type, &align);
|
||||
if (total_size > USHRT_MAX)
|
||||
error("structure size for %s exceeds %d bytes by %d bytes\n",
|
||||
name, USHRT_MAX, total_size - USHRT_MAX);
|
||||
|
||||
has_pointers = write_embedded_types(file, NULL, type, name, 0, tfsoff);
|
||||
if (type->fields) LIST_FOR_EACH_ENTRY(f, type->fields, var_t, entry)
|
||||
has_pointers |= write_embedded_types(file, f->attrs, f->type, f->name,
|
||||
FALSE, tfsoff);
|
||||
|
||||
array = find_array_or_string_in_struct(type);
|
||||
if (array && !processed(array->type))
|
||||
{
|
||||
current_structure = type;
|
||||
array_offset
|
||||
= is_attr(array->attrs, ATTR_STRING)
|
||||
? write_string_tfs(file, array->attrs, array->type, array->name, tfsoff)
|
||||
: write_array_tfs(file, array->attrs, array->type, array->name, tfsoff);
|
||||
current_structure = NULL;
|
||||
}
|
||||
|
||||
corroff = *tfsoff;
|
||||
write_descriptors(file, type, tfsoff);
|
||||
|
||||
start_offset = *tfsoff;
|
||||
update_tfsoff(type, start_offset, file);
|
||||
|
@ -1171,10 +1203,9 @@ static size_t write_struct_tfs(FILE *file, type_t *type,
|
|||
*tfsoff += 1;
|
||||
}
|
||||
|
||||
current_structure = type;
|
||||
write_struct_members(file, type, tfsoff);
|
||||
current_structure = NULL;
|
||||
write_struct_members(file, type, &corroff, tfsoff);
|
||||
|
||||
current_structure = save_current_structure;
|
||||
return start_offset;
|
||||
}
|
||||
|
||||
|
@ -1230,8 +1261,7 @@ static void write_branch_type(FILE *file, const type_t *t, unsigned int *tfsoff)
|
|||
*tfsoff += 2;
|
||||
}
|
||||
|
||||
static size_t write_union_tfs(FILE *file, type_t *type, const char *name,
|
||||
unsigned int *tfsoff)
|
||||
static size_t write_union_tfs(FILE *file, type_t *type, unsigned int *tfsoff)
|
||||
{
|
||||
unsigned int align = 0;
|
||||
unsigned int start_offset;
|
||||
|
@ -1244,14 +1274,13 @@ static size_t write_union_tfs(FILE *file, type_t *type, const char *name,
|
|||
|
||||
guard_rec(type);
|
||||
|
||||
/* use a level of 1 so pointers always get written */
|
||||
write_embedded_types(file, NULL, type, name, 1, tfsoff);
|
||||
|
||||
if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
|
||||
{
|
||||
expr_list_t *cases = get_attrp(f->attrs, ATTR_CASE);
|
||||
if (cases)
|
||||
nbranch += list_count(cases);
|
||||
if (f->type)
|
||||
write_embedded_types(file, f->attrs, f->type, f->name, TRUE, tfsoff);
|
||||
}
|
||||
|
||||
start_offset = *tfsoff;
|
||||
|
@ -1321,7 +1350,7 @@ static size_t write_ip_tfs(FILE *file, const func_t *func, const type_t *type, c
|
|||
expr.is_const = FALSE;
|
||||
print_file(file, 2, "0x2f, /* FC_IP */\n");
|
||||
print_file(file, 2, "0x5c, /* FC_PAD */\n");
|
||||
*typeformat_offset += write_conf_or_var_desc(file, func, NULL, &expr) + 2;
|
||||
*typeformat_offset += write_conf_or_var_desc(file, func, NULL, 0, &expr) + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1404,7 +1433,7 @@ static size_t write_typeformatstring_var(FILE *file, int indent, const func_t *f
|
|||
return write_struct_tfs(file, type, var->name, typeformat_offset);
|
||||
case RPC_FC_ENCAPSULATED_UNION:
|
||||
case RPC_FC_NON_ENCAPSULATED_UNION:
|
||||
return write_union_tfs(file, type, var->name, typeformat_offset);
|
||||
return write_union_tfs(file, type, typeformat_offset);
|
||||
case RPC_FC_IGNORE:
|
||||
case RPC_FC_BIND_PRIMITIVE:
|
||||
/* nothing to do */
|
||||
|
@ -1475,92 +1504,19 @@ static void set_tfswrite(type_t *type, int val)
|
|||
}
|
||||
|
||||
static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *type,
|
||||
const char *name, int level, unsigned int *tfsoff)
|
||||
const char *name, int write_ptr, unsigned int *tfsoff)
|
||||
{
|
||||
var_list_t *fields = type->fields;
|
||||
int retmask = 0;
|
||||
size_t offset = 0;
|
||||
var_t *f;
|
||||
|
||||
if (fields) LIST_FOR_EACH_ENTRY(f, fields, var_t, entry)
|
||||
{
|
||||
unsigned int align = 0;
|
||||
type_t *ft = f->type;
|
||||
|
||||
if (!ft) continue;
|
||||
else if (ft->type == RPC_FC_NON_ENCAPSULATED_UNION)
|
||||
{
|
||||
expr_t *swexp = get_attrp(f->attrs, ATTR_SWITCHIS);
|
||||
const char *swname;
|
||||
var_t *swvar;
|
||||
size_t corroff;
|
||||
unsigned char corrdesc, op = 0;
|
||||
short creloff, ureloff;
|
||||
|
||||
if (swexp == NULL)
|
||||
error("union %s needs a switch_is attribute\n", f->name);
|
||||
if (swexp->type != EXPR_IDENTIFIER)
|
||||
error("%s: only identifiers are supported for switch_is at this time\n",
|
||||
f->name);
|
||||
|
||||
if (!processed(ft))
|
||||
write_union_tfs(file, ft, f->name, tfsoff);
|
||||
|
||||
swname = swexp->u.sval;
|
||||
corroff = field_offset(type, swname, &swvar);
|
||||
corrdesc = swvar->type->type;
|
||||
creloff = corroff - offset;
|
||||
|
||||
f->corrdesc = *tfsoff;
|
||||
ureloff = ft->typestring_offset - (f->corrdesc + 6);
|
||||
print_file(file, 0, "/* %d */\n", f->corrdesc);
|
||||
print_file(file, 2, "0x%x,\t/* %s */\n", ft->type, string_of_type(ft->type));
|
||||
print_file(file, 2, "0x8,\t/* FIXME: support other switch types */\n");
|
||||
print_file(file, 2, "0x%x,\t/* Corr desc: %s */\n",
|
||||
corrdesc, string_of_type(corrdesc & 0xf));
|
||||
print_file(file, 2, "0x%x,\n", op);
|
||||
print_file(file, 2, "NdrFcShort(0x%hx),\t/* %hd */\n", creloff, creloff);
|
||||
print_file(file, 2, "NdrFcShort(0x%hx),\t/* Offset= %hd (%lu) */\n",
|
||||
ureloff, ureloff, ft->typestring_offset);
|
||||
*tfsoff += 8;
|
||||
}
|
||||
else
|
||||
retmask |= write_embedded_types(file, attrs, ft, f->name,
|
||||
level + 1, tfsoff);
|
||||
|
||||
/* FIXME: this doesn't take alignment/padding into account */
|
||||
offset += type_memsize(ft, &align);
|
||||
}
|
||||
/* don't generate a pointer for first-level arrays since we want to
|
||||
descend into them to write their pointers, not stop here */
|
||||
else if (level == 0 && is_array(type))
|
||||
{
|
||||
return write_embedded_types(file, NULL, type->ref, name, level + 1, tfsoff);
|
||||
}
|
||||
else if (is_ptr(type))
|
||||
if (is_ptr(type))
|
||||
{
|
||||
type_t *ref = type->ref;
|
||||
|
||||
if (!processed(ref) && !is_base_type(ref->type))
|
||||
{
|
||||
if (is_ptr(ref))
|
||||
{
|
||||
retmask |= write_embedded_types(file, attrs, ref, name,
|
||||
level + 1, tfsoff);
|
||||
}
|
||||
else if (is_struct(ref->type))
|
||||
{
|
||||
write_struct_tfs(file, ref, name, tfsoff);
|
||||
}
|
||||
else
|
||||
{
|
||||
error("write_embedded_types: type format string unknown for %s (0x%x)\n",
|
||||
name, ref->type);
|
||||
}
|
||||
}
|
||||
retmask |= write_embedded_types(file, NULL, ref, name, TRUE, tfsoff);
|
||||
|
||||
/* top-level pointers are handled inline */
|
||||
if (1 < level)
|
||||
/* top-level pointers are handled inline for structures */
|
||||
if (write_ptr)
|
||||
write_pointer_tfs(file, type, tfsoff);
|
||||
|
||||
retmask |= 1;
|
||||
|
@ -1571,6 +1527,16 @@ static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *ty
|
|||
{
|
||||
write_array_tfs(file, attrs, type, name, tfsoff);
|
||||
}
|
||||
else if (is_struct(type->type))
|
||||
{
|
||||
if (!processed(type))
|
||||
write_struct_tfs(file, type, name, tfsoff);
|
||||
}
|
||||
else if (is_union(type->type))
|
||||
{
|
||||
if (!processed(type))
|
||||
write_union_tfs(file, type, tfsoff);
|
||||
}
|
||||
else if (!is_base_type(type->type))
|
||||
error("write_embedded_types: unknown embedded type for %s (0x%x)\n",
|
||||
name, type->type);
|
||||
|
|
|
@ -227,7 +227,6 @@ struct _var_t {
|
|||
var_list_t *args; /* for function pointers */
|
||||
attr_list_t *attrs;
|
||||
expr_t *eval;
|
||||
size_t corrdesc; /* offset to correlation descriptor (e.g., for unions) */
|
||||
|
||||
/* parser-internal */
|
||||
struct list entry;
|
||||
|
|
Loading…
Reference in New Issue