From e213ac9aca129c944d50dcc5158c778c9b96ecc6 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 1 Jul 2008 12:25:44 +0200 Subject: [PATCH] widl: Add some support for unencapsulated unions that need a conformance descriptor. --- dlls/rpcrt4/tests/server.c | 19 +++++++++++++++++++ dlls/rpcrt4/tests/server.idl | 7 +++++++ tools/widl/typegen.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/dlls/rpcrt4/tests/server.c b/dlls/rpcrt4/tests/server.c index 69b9ba40db3..0bf84d58225 100644 --- a/dlls/rpcrt4/tests/server.c +++ b/dlls/rpcrt4/tests/server.c @@ -333,6 +333,18 @@ s_square_encu(encu_t *eu) } } +double +s_square_unencu(int t, unencu_t *eu) +{ + switch (t) + { + case ENCU_I: return eu->i * eu->i; + case ENCU_F: return eu->f * eu->f; + default: + return 0.0; + } +} + void s_check_se2(se_t *s) { @@ -844,6 +856,7 @@ union_tests(void) { encue_t eue; encu_t eu; + unencu_t uneu; sun_t su; int i; @@ -872,6 +885,12 @@ union_tests(void) eu.tagged_union.f = 3.0; ok(square_encu(&eu) == 9.0, "RPC square_encu\n"); + uneu.i = 4; + ok(square_unencu(ENCU_I, &uneu) == 16.0, "RPC square_unencu\n"); + + uneu.f = 5.0; + ok(square_unencu(ENCU_F, &uneu) == 25.0, "RPC square_unencu\n"); + eue.t = E1; eue.tagged_union.i1 = 8; ok(square_encue(&eue) == 64.0, "RPC square_encue\n"); diff --git a/dlls/rpcrt4/tests/server.idl b/dlls/rpcrt4/tests/server.idl index 378b205d80a..26d337304f9 100644 --- a/dlls/rpcrt4/tests/server.idl +++ b/dlls/rpcrt4/tests/server.idl @@ -195,6 +195,12 @@ cpp_quote("#endif") case ENCU_F: float f; } encu_t; + typedef [switch_type(int)] union unencu + { + [case (ENCU_I)] int i; + [case (ENCU_F)] float f; + } unencu_t; + typedef enum { E1 = 23, @@ -215,6 +221,7 @@ cpp_quote("#endif") } se_t; double square_encu(encu_t *eu); + double square_unencu(int t, [switch_is(t)] unencu_t *eu); int sum_parr(int *a[3]); int sum_pcarr([size_is(n)] int *a[], int n); int enum_ord(e_t e); diff --git a/tools/widl/typegen.c b/tools/widl/typegen.c index f89f13fb9b8..f7a189a7b2f 100644 --- a/tools/widl/typegen.c +++ b/tools/widl/typegen.c @@ -2032,6 +2032,34 @@ static size_t write_union_tfs(FILE *file, type_t *type, unsigned int *tfsoff) error("union switch type must be an integer, char, or enum\n"); } } + else if (is_attr(type->attrs, ATTR_SWITCHTYPE)) + { + static const expr_t dummy_expr; /* FIXME */ + const type_t *st = get_attrp(type->attrs, ATTR_SWITCHTYPE); + + switch (st->type) + { + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_USMALL: + case RPC_FC_SHORT: + case RPC_FC_USHORT: + case RPC_FC_LONG: + case RPC_FC_ULONG: + case RPC_FC_ENUM16: + case RPC_FC_ENUM32: + print_file(file, 2, "0x%x,\t/* %s */\n", type->type, string_of_type(type->type)); + print_file(file, 2, "0x%x,\t/* Switch type= %s */\n", + st->type, string_of_type(st->type)); + *tfsoff += 2; + break; + default: + error("union switch type must be an integer, char, or enum\n"); + } + + *tfsoff += write_conf_or_var_desc(file, NULL, *tfsoff, st, &dummy_expr ); + } + print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", size, size); print_file(file, 2, "NdrFcShort(0x%x),\t/* %d */\n", nbranch, nbranch); *tfsoff += 4; -- 2.11.4.GIT