From 22929dd8af7bbe9cf4f5f6c75adf2d2e511f3184 Mon Sep 17 00:00:00 2001 From: Elizabeth Figura Date: Fri, 21 Jun 2024 18:28:36 -0500 Subject: [PATCH] widl: Store the hexadecimal flag inside of the expr_t union. --- tools/widl/expr.c | 35 +++++++++++--------------- tools/widl/expr.h | 2 +- tools/widl/header.c | 4 +-- tools/widl/parser.y | 56 +++++++++++++++++++++++++---------------- tools/widl/widltypes.h | 9 +++++-- tools/widl/write_msft.c | 7 +++--- tools/widl/write_sltg.c | 2 +- 7 files changed, 63 insertions(+), 52 deletions(-) diff --git a/tools/widl/expr.c b/tools/widl/expr.c index e0c56b81089..e51ed6c94c4 100644 --- a/tools/widl/expr.c +++ b/tools/widl/expr.c @@ -112,28 +112,24 @@ static int is_float_type(const type_t *type) expr_t *make_expr(enum expr_type type) { expr_t *e = xmalloc(sizeof(expr_t)); + memset(e, 0, sizeof(*e)); e->type = type; - e->ref = NULL; - e->u.lval = 0; - e->is_const = FALSE; - e->cval = 0; return e; } -expr_t *make_exprl(enum expr_type type, int val) +expr_t *make_exprl(enum expr_type type, const struct integer *integer) { expr_t *e = xmalloc(sizeof(expr_t)); + memset(e, 0, sizeof(*e)); e->type = type; - e->ref = NULL; - e->u.lval = val; - e->is_const = FALSE; + e->u.integer = *integer; /* check for numeric constant */ - if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE) + if (type == EXPR_NUM || type == EXPR_TRUEFALSE) { /* make sure true/false value is valid */ - assert(type != EXPR_TRUEFALSE || val == 0 || val == 1); + assert(type != EXPR_TRUEFALSE || integer->value == 0 || integer->value == 1); e->is_const = TRUE; - e->cval = val; + e->cval = integer->value; } return e; } @@ -252,10 +248,9 @@ expr_t *make_expr1(enum expr_type type, expr_t *expr) { expr_t *e; e = xmalloc(sizeof(expr_t)); + memset(e, 0, sizeof(*e)); e->type = type; e->ref = expr; - e->u.lval = 0; - e->is_const = FALSE; /* check for compile-time optimization */ if (expr->is_const) { @@ -514,7 +509,6 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc { case EXPR_VOID: break; - case EXPR_HEXNUM: case EXPR_NUM: case EXPR_TRUEFALSE: result.is_temporary = FALSE; @@ -692,16 +686,16 @@ void write_expr(FILE *h, const expr_t *e, int brackets, case EXPR_VOID: break; case EXPR_NUM: - fprintf(h, "%u", e->u.lval); - break; - case EXPR_HEXNUM: - fprintf(h, "0x%x", e->u.lval); + if (e->u.integer.is_hex) + fprintf(h, "0x%x", e->u.integer.value); + else + fprintf(h, "%u", e->u.integer.value); break; case EXPR_DOUBLE: fprintf(h, "%#.15g", e->u.dval); break; case EXPR_TRUEFALSE: - if (e->u.lval == 0) + if (e->u.integer.value == 0) fprintf(h, "FALSE"); else fprintf(h, "TRUE"); @@ -869,9 +863,8 @@ int compare_expr(const expr_t *a, const expr_t *b) switch (a->type) { case EXPR_NUM: - case EXPR_HEXNUM: case EXPR_TRUEFALSE: - return a->u.lval - b->u.lval; + return a->u.integer.value - b->u.integer.value; case EXPR_DOUBLE: return a->u.dval - b->u.dval; case EXPR_IDENTIFIER: diff --git a/tools/widl/expr.h b/tools/widl/expr.h index 7b0e1b2c7ba..89c0acf5491 100644 --- a/tools/widl/expr.h +++ b/tools/widl/expr.h @@ -26,7 +26,7 @@ struct expr_loc }; extern expr_t *make_expr(enum expr_type type); -extern expr_t *make_exprl(enum expr_type type, int val); +extern expr_t *make_exprl(enum expr_type type, const struct integer *integer); extern expr_t *make_exprd(enum expr_type type, double val); extern expr_t *make_exprs(enum expr_type type, char *val); extern expr_t *make_exprt(enum expr_type type, var_t *var, expr_t *expr); diff --git a/tools/widl/header.c b/tools/widl/header.c index bb30156b8a3..413354d5b56 100644 --- a/tools/widl/header.c +++ b/tools/widl/header.c @@ -1583,7 +1583,7 @@ static void write_apicontract_guard_start(FILE *header, const expr_t *expr) int ver; if (!winrt_mode) return; type = expr->u.tref.type; - ver = expr->ref->u.lval; + ver = expr->ref->u.integer.value; name = format_apicontract_macro(type); fprintf(header, "#if %s_VERSION >= %#x\n", name, ver); free(name); @@ -1596,7 +1596,7 @@ static void write_apicontract_guard_end(FILE *header, const expr_t *expr) int ver; if (!winrt_mode) return; type = expr->u.tref.type; - ver = expr->ref->u.lval; + ver = expr->ref->u.integer.value; name = format_apicontract_macro(type); fprintf(header, "#endif /* %s_VERSION >= %#x */\n", name, ver); free(name); diff --git a/tools/widl/parser.y b/tools/widl/parser.y index f5b82f29db3..3d64587d526 100644 --- a/tools/widl/parser.y +++ b/tools/widl/parser.y @@ -596,12 +596,14 @@ contract_ver: ; contract_req - : decl_spec ',' contract_ver { if ($1->type->type_type != TYPE_APICONTRACT) - error_loc("type %s is not an apicontract\n", $1->type->name); - $$ = make_exprl(EXPR_NUM, $3); - $$ = make_exprt(EXPR_GTREQL, declare_var(NULL, $1, make_declarator(NULL), 0), $$); - } - ; + : decl_spec ',' contract_ver { + struct integer integer = {.value = $3}; + if ($1->type->type_type != TYPE_APICONTRACT) + error_loc("type %s is not an apicontract\n", $1->type->name); + $$ = make_exprl(EXPR_NUM, &integer); + $$ = make_exprt(EXPR_GTREQL, declare_var(NULL, $1, make_declarator(NULL), 0), $$); + } + ; static_attr : decl_spec ',' contract_req { if ($1->type->type_type != TYPE_INTERFACE) @@ -793,21 +795,28 @@ enums | enum_list ; -enum_list: enum { if (!$1->eval) - $1->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */); +enum_list: enum { + struct integer integer = {.value = 0}; + if (!$1->eval) + $1->eval = make_exprl(EXPR_NUM, &integer); $$ = append_var( NULL, $1 ); - } - | enum_list ',' enum { if (!$3->eval) + } + | enum_list ',' enum { + if (!$3->eval) { var_t *last = LIST_ENTRY( list_tail($$), var_t, entry ); - enum expr_type type = EXPR_NUM; - if (last->eval->type == EXPR_HEXNUM) type = EXPR_HEXNUM; - if (last->eval->cval + 1 < 0) type = EXPR_HEXNUM; - $3->eval = make_exprl(type, last->eval->cval + 1); + struct integer integer; + + if (last->eval->type == EXPR_NUM) + integer.is_hex = last->eval->u.integer.is_hex; + integer.value = last->eval->cval + 1; + if (integer.value < 0) + integer.is_hex = TRUE; + $3->eval = make_exprl(EXPR_NUM, &integer); } $$ = append_var( $1, $3 ); - } - ; + } + ; enum_member: m_attributes ident { $$ = $2; $$->attrs = check_enum_member_attrs($1); @@ -835,12 +844,17 @@ m_expr | expr ; -expr: aNUM { $$ = make_exprl(EXPR_NUM, $1); } - | aHEXNUM { $$ = make_exprl(EXPR_HEXNUM, $1); } +expr: aNUM { struct integer integer = {.value = $1}; + $$ = make_exprl(EXPR_NUM, &integer); } + | aHEXNUM { struct integer integer = {.value = $1, .is_hex = TRUE}; + $$ = make_exprl(EXPR_NUM, &integer); } | aDOUBLE { $$ = make_exprd(EXPR_DOUBLE, $1); } - | tFALSE { $$ = make_exprl(EXPR_TRUEFALSE, 0); } - | tNULL { $$ = make_exprl(EXPR_NUM, 0); } - | tTRUE { $$ = make_exprl(EXPR_TRUEFALSE, 1); } + | tFALSE { struct integer integer = {.value = 0}; + $$ = make_exprl(EXPR_TRUEFALSE, &integer); } + | tNULL { struct integer integer = {.value = 0}; + $$ = make_exprl(EXPR_NUM, &integer); } + | tTRUE { struct integer integer = {.value = 1}; + $$ = make_exprl(EXPR_TRUEFALSE, &integer); } | aSTRING { $$ = make_exprs(EXPR_STRLIT, $1); } | aWSTRING { $$ = make_exprs(EXPR_WSTRLIT, $1); } | aSQSTRING { $$ = make_exprs(EXPR_CHARCONST, $1); } diff --git a/tools/widl/widltypes.h b/tools/widl/widltypes.h index 7bc24fad0d3..44559e9f2ef 100644 --- a/tools/widl/widltypes.h +++ b/tools/widl/widltypes.h @@ -191,7 +191,6 @@ enum expr_type { EXPR_VOID, EXPR_NUM, - EXPR_HEXNUM, EXPR_DOUBLE, EXPR_IDENTIFIER, EXPR_NEG, @@ -349,11 +348,17 @@ struct _attr_t { struct location where; }; +struct integer +{ + int value; + int is_hex; +}; + struct _expr_t { enum expr_type type; const expr_t *ref; union { - int lval; + struct integer integer; double dval; const char *sval; const expr_t *ext; diff --git a/tools/widl/write_msft.c b/tools/widl/write_msft.c index b9a3d6664f2..66401fd09ed 100644 --- a/tools/widl/write_msft.c +++ b/tools/widl/write_msft.c @@ -1299,9 +1299,8 @@ static void set_custdata_attr(msft_typelib_t *typelib, attr_custdata_t *custdata case EXPR_WSTRLIT: set_custdata(typelib, &custdata->id, VT_BSTR, custdata->pval->u.sval, offset); break; - case EXPR_HEXNUM: case EXPR_NUM: - set_custdata(typelib, &custdata->id, VT_I4, &custdata->pval->u.lval, offset); + set_custdata(typelib, &custdata->id, VT_I4, &custdata->pval->u.integer.value, offset); break; default: error("custom() attribute with unknown type\n"); @@ -1395,7 +1394,7 @@ static int add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index) break; case ATTR_HELPCONTEXT: extra_attr = max(extra_attr, 1); - help_context = expr->u.lval; + help_context = expr->u.integer.value; break; case ATTR_HELPSTRING: extra_attr = max(extra_attr, 2); @@ -1403,7 +1402,7 @@ static int add_func_desc(msft_typeinfo_t* typeinfo, var_t *func, int index) break; case ATTR_HELPSTRINGCONTEXT: extra_attr = max(extra_attr, 6); - help_string_context = expr->u.lval; + help_string_context = expr->u.integer.value; break; case ATTR_HIDDEN: funcflags |= 0x40; /* FUNCFLAG_FHIDDEN */ diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c index d09fdb37c5c..5429b60c607 100644 --- a/tools/widl/write_sltg.c +++ b/tools/widl/write_sltg.c @@ -1060,7 +1060,7 @@ static int get_func_flags(const var_t *func, int *dispid, int *invokekind, int * flags |= 0x10; /* FUNCFLAG_FDISPLAYBIND */ break; case ATTR_HELPCONTEXT: - *helpcontext = expr->u.lval; + *helpcontext = expr->u.integer.value; break; case ATTR_HELPSTRING: *helpstring = attr->u.pval;