widl: Support WinRT contract attribute.
Signed-off-by: Rémi Bernon <rbernon@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
ee490ee26c
commit
54035a2101
|
@ -28,7 +28,7 @@ import "windowscontracts.idl";
|
|||
|
||||
namespace Windows {
|
||||
namespace Foundation {
|
||||
[version(0x06020000)]
|
||||
[contract(Windows.Foundation.FoundationContract, 1.0)]
|
||||
enum PropertyType {
|
||||
Empty = 0,
|
||||
UInt8 = 1,
|
||||
|
@ -73,19 +73,19 @@ namespace Windows {
|
|||
OtherTypeArray = 1044
|
||||
};
|
||||
|
||||
[version(0x06020000)]
|
||||
[contract(Windows.Foundation.FoundationContract, 1.0)]
|
||||
struct Point {
|
||||
FLOAT X;
|
||||
FLOAT Y;
|
||||
};
|
||||
|
||||
[version(0x06020000)]
|
||||
[contract(Windows.Foundation.FoundationContract, 1.0)]
|
||||
struct Size {
|
||||
FLOAT Width;
|
||||
FLOAT Height;
|
||||
};
|
||||
|
||||
[version(0x06020000)]
|
||||
[contract(Windows.Foundation.FoundationContract, 1.0)]
|
||||
struct Rect {
|
||||
FLOAT X;
|
||||
FLOAT Y;
|
||||
|
@ -93,18 +93,18 @@ namespace Windows {
|
|||
FLOAT Height;
|
||||
};
|
||||
|
||||
[version(0x06020000)]
|
||||
[contract(Windows.Foundation.FoundationContract, 1.0)]
|
||||
struct DateTime {
|
||||
INT64 UniversalTime;
|
||||
};
|
||||
|
||||
[version(0x06020000)]
|
||||
[contract(Windows.Foundation.FoundationContract, 1.0)]
|
||||
struct TimeSpan {
|
||||
INT64 Duration;
|
||||
};
|
||||
|
||||
[
|
||||
version(0x06030000),
|
||||
contract(Windows.Foundation.FoundationContract, 1.0),
|
||||
uuid(96369f54-8eb6-48f0-abce-c1b211e627c3)
|
||||
]
|
||||
interface IStringable : IInspectable
|
||||
|
|
|
@ -45,6 +45,11 @@ generic_handle_list_t generic_handle_list = LIST_INIT(generic_handle_list);
|
|||
|
||||
static void write_type_v(FILE *f, const decl_spec_t *t, int is_field, int declonly, const char *name, enum name_type name_type);
|
||||
|
||||
static void write_winrt_type_comments(FILE *header, const type_t *type);
|
||||
|
||||
static void write_apicontract_guard_start(FILE *header, const expr_t *expr);
|
||||
static void write_apicontract_guard_end(FILE *header, const expr_t *expr);
|
||||
|
||||
static void indent(FILE *h, int delta)
|
||||
{
|
||||
int c;
|
||||
|
@ -218,7 +223,9 @@ static void write_fields(FILE *h, var_list_t *fields, enum name_type name_type)
|
|||
}
|
||||
|
||||
LIST_FOR_EACH_ENTRY( v, fields, var_t, entry ) {
|
||||
expr_t *contract = get_attrp(v->attrs, ATTR_CONTRACT);
|
||||
if (!v || !v->declspec.type) continue;
|
||||
if (contract) write_apicontract_guard_start(h, contract);
|
||||
|
||||
indent(h, 0);
|
||||
name = v->name;
|
||||
|
@ -252,6 +259,7 @@ static void write_fields(FILE *h, var_list_t *fields, enum name_type name_type)
|
|||
}
|
||||
write_type_v(h, &v->declspec, TRUE, v->declonly, name, name_type);
|
||||
fprintf(h, ";\n");
|
||||
if (contract) write_apicontract_guard_end(h, contract);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,6 +269,8 @@ static void write_enums(FILE *h, var_list_t *enums, const char *enum_name)
|
|||
if (!enums) return;
|
||||
LIST_FOR_EACH_ENTRY( v, enums, var_t, entry )
|
||||
{
|
||||
expr_t *contract = get_attrp(v->attrs, ATTR_CONTRACT);
|
||||
if (contract) write_apicontract_guard_start(h, contract);
|
||||
if (v->name) {
|
||||
indent(h, 0);
|
||||
if(!enum_name)
|
||||
|
@ -273,8 +283,9 @@ static void write_enums(FILE *h, var_list_t *enums, const char *enum_name)
|
|||
}
|
||||
}
|
||||
if (list_next( enums, &v->entry )) fprintf(h, ",\n");
|
||||
else fprintf(h, "\n");
|
||||
if (contract) write_apicontract_guard_end(h, contract);
|
||||
}
|
||||
fprintf(h, "\n");
|
||||
}
|
||||
|
||||
int needs_space_after(type_t *t)
|
||||
|
@ -563,7 +574,9 @@ static void write_type_definition(FILE *f, type_t *t, int declonly)
|
|||
int in_namespace = t->namespace && !is_global_namespace(t->namespace);
|
||||
int save_written = t->written;
|
||||
decl_spec_t ds = {.type = t};
|
||||
expr_t *contract = get_attrp(t->attrs, ATTR_CONTRACT);
|
||||
|
||||
if (contract) write_apicontract_guard_start(f, contract);
|
||||
if(in_namespace) {
|
||||
fprintf(f, "#ifdef __cplusplus\n");
|
||||
fprintf(f, "} /* extern \"C\" */\n");
|
||||
|
@ -581,6 +594,7 @@ static void write_type_definition(FILE *f, type_t *t, int declonly)
|
|||
fprintf(f, ";\n");
|
||||
fprintf(f, "#endif\n\n");
|
||||
}
|
||||
if (contract) write_apicontract_guard_end(f, contract);
|
||||
}
|
||||
|
||||
void write_type_decl(FILE *f, const decl_spec_t *t, const char *name)
|
||||
|
@ -1468,12 +1482,55 @@ static char *format_apicontract_macro(const type_t *type)
|
|||
return name;
|
||||
}
|
||||
|
||||
static void write_winrt_type_comments(FILE *header, const type_t *type)
|
||||
{
|
||||
expr_t *contract = get_attrp(type->attrs, ATTR_CONTRACT);
|
||||
fprintf(header, " *\n");
|
||||
if (contract)
|
||||
{
|
||||
const type_t *type = contract->u.tref.type;
|
||||
char *name = format_namespace(type->namespace, "", ".", type->name, NULL);
|
||||
int ver = contract->ref->u.lval;
|
||||
fprintf(header, " * Introduced to %s in version %d.%d\n *\n", name, (ver >> 16) & 0xffff, ver & 0xffff);
|
||||
free(name);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_apicontract_guard_start(FILE *header, const expr_t *expr)
|
||||
{
|
||||
const type_t *type;
|
||||
char *name;
|
||||
int ver;
|
||||
if (!winrt_mode) return;
|
||||
type = expr->u.tref.type;
|
||||
ver = expr->ref->u.lval;
|
||||
name = format_apicontract_macro(type);
|
||||
fprintf(header, "#if %s_VERSION >= %#x\n", name, ver);
|
||||
free(name);
|
||||
}
|
||||
|
||||
static void write_apicontract_guard_end(FILE *header, const expr_t *expr)
|
||||
{
|
||||
const type_t *type;
|
||||
char *name;
|
||||
int ver;
|
||||
if (!winrt_mode) return;
|
||||
type = expr->u.tref.type;
|
||||
ver = expr->ref->u.lval;
|
||||
name = format_apicontract_macro(type);
|
||||
fprintf(header, "#endif /* %s_VERSION >= %#x */\n", name, ver);
|
||||
free(name);
|
||||
}
|
||||
|
||||
static void write_com_interface_start(FILE *header, const type_t *iface)
|
||||
{
|
||||
int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE);
|
||||
expr_t *contract = get_attrp(iface->attrs, ATTR_CONTRACT);
|
||||
fprintf(header, "/*****************************************************************************\n");
|
||||
fprintf(header, " * %s %sinterface\n", iface->name, dispinterface ? "disp" : "");
|
||||
if (winrt_mode) write_winrt_type_comments(header, iface);
|
||||
fprintf(header, " */\n");
|
||||
if (contract) write_apicontract_guard_start(header, contract);
|
||||
fprintf(header,"#ifndef __%s_%sINTERFACE_DEFINED__\n", iface->c_name, dispinterface ? "DISP" : "");
|
||||
fprintf(header,"#define __%s_%sINTERFACE_DEFINED__\n\n", iface->c_name, dispinterface ? "DISP" : "");
|
||||
}
|
||||
|
@ -1482,6 +1539,7 @@ static void write_com_interface_end(FILE *header, type_t *iface)
|
|||
{
|
||||
int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE);
|
||||
const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
|
||||
expr_t *contract = get_attrp(iface->attrs, ATTR_CONTRACT);
|
||||
type_t *type;
|
||||
|
||||
if (uuid)
|
||||
|
@ -1559,17 +1617,22 @@ static void write_com_interface_end(FILE *header, type_t *iface)
|
|||
write_locals(header, iface, FALSE);
|
||||
fprintf(header, "\n");
|
||||
}
|
||||
fprintf(header,"#endif /* __%s_%sINTERFACE_DEFINED__ */\n\n", iface->c_name, dispinterface ? "DISP" : "");
|
||||
fprintf(header, "#endif /* __%s_%sINTERFACE_DEFINED__ */\n", iface->c_name, dispinterface ? "DISP" : "");
|
||||
if (contract) write_apicontract_guard_end(header, contract);
|
||||
fprintf(header, "\n");
|
||||
}
|
||||
|
||||
static void write_rpc_interface_start(FILE *header, const type_t *iface)
|
||||
{
|
||||
unsigned int ver = get_attrv(iface->attrs, ATTR_VERSION);
|
||||
const var_t *var = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
|
||||
expr_t *contract = get_attrp(iface->attrs, ATTR_CONTRACT);
|
||||
|
||||
fprintf(header, "/*****************************************************************************\n");
|
||||
fprintf(header, " * %s interface (v%d.%d)\n", iface->name, MAJORVERSION(ver), MINORVERSION(ver));
|
||||
if (winrt_mode) write_winrt_type_comments(header, iface);
|
||||
fprintf(header, " */\n");
|
||||
if (contract) write_apicontract_guard_start(header, contract);
|
||||
fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name);
|
||||
fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name);
|
||||
if (var)
|
||||
|
@ -1594,7 +1657,10 @@ static void write_rpc_interface_start(FILE *header, const type_t *iface)
|
|||
|
||||
static void write_rpc_interface_end(FILE *header, const type_t *iface)
|
||||
{
|
||||
fprintf(header,"\n#endif /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name);
|
||||
expr_t *contract = get_attrp(iface->attrs, ATTR_CONTRACT);
|
||||
fprintf(header, "\n#endif /* __%s_INTERFACE_DEFINED__ */\n", iface->name);
|
||||
if (contract) write_apicontract_guard_end(header, contract);
|
||||
fprintf(header, "\n");
|
||||
}
|
||||
|
||||
static void write_coclass(FILE *header, type_t *cocl)
|
||||
|
|
|
@ -339,6 +339,7 @@ static const struct keyword attr_keywords[] =
|
|||
{"context_handle", tCONTEXTHANDLE, 0},
|
||||
{"context_handle_noserialize", tCONTEXTHANDLENOSERIALIZE, 0},
|
||||
{"context_handle_serialize", tCONTEXTHANDLENOSERIALIZE, 0},
|
||||
{"contract", tCONTRACT, 1},
|
||||
{"contractversion", tCONTRACTVERSION, 1},
|
||||
{"control", tCONTROL, 0},
|
||||
{"custom", tCUSTOM, 0},
|
||||
|
|
|
@ -181,6 +181,7 @@ static typelib_t *current_typelib;
|
|||
%token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS
|
||||
%token tCONST tCONTEXTHANDLE tCONTEXTHANDLENOSERIALIZE
|
||||
%token tCONTEXTHANDLESERIALIZE
|
||||
%token tCONTRACT
|
||||
%token tCONTRACTVERSION
|
||||
%token tCONTROL tCPPQUOTE
|
||||
%token tCUSTOM
|
||||
|
@ -271,6 +272,7 @@ static typelib_t *current_typelib;
|
|||
%type <str_list> str_list
|
||||
%type <expr> m_expr expr expr_const expr_int_const array m_bitfield
|
||||
%type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
|
||||
%type <expr> contract_req
|
||||
%type <type> interfacehdr
|
||||
%type <stgclass> storage_cls_spec
|
||||
%type <type_qualifier> type_qualifier m_type_qual_list
|
||||
|
@ -508,6 +510,12 @@ contract_ver:
|
|||
| aNUM '.' aNUM { $$ = MAKEVERSION($3, $1); }
|
||||
;
|
||||
|
||||
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), $$);
|
||||
}
|
||||
|
||||
attribute: { $$ = NULL; }
|
||||
| tAGGREGATABLE { $$ = make_attr(ATTR_AGGREGATABLE); }
|
||||
| tANNOTATION '(' aSTRING ')' { $$ = make_attrp(ATTR_ANNOTATION, $3); }
|
||||
|
@ -523,6 +531,7 @@ attribute: { $$ = NULL; }
|
|||
| tCONTEXTHANDLE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); }
|
||||
| tCONTEXTHANDLENOSERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ }
|
||||
| tCONTEXTHANDLESERIALIZE { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ }
|
||||
| tCONTRACT '(' contract_req ')' { $$ = make_attrp(ATTR_CONTRACT, $3); }
|
||||
| tCONTRACTVERSION '(' contract_ver ')' { $$ = make_attrv(ATTR_CONTRACTVERSION, $3); }
|
||||
| tCONTROL { $$ = make_attr(ATTR_CONTROL); }
|
||||
| tCUSTOM '(' uuid_string ',' expr_const ')' { $$ = make_custom_attr($3, $5); }
|
||||
|
@ -2180,6 +2189,7 @@ struct allowed_attr allowed_attr[] =
|
|||
/* ATTR_CODE */ { 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
|
||||
/* ATTR_COMMSTATUS */ { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
|
||||
/* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
|
||||
/* ATTR_CONTRACT */ { 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, "contract" },
|
||||
/* ATTR_CONTRACTVERSION */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "contractversion" },
|
||||
/* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, "control" },
|
||||
/* ATTR_CUSTOM */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, "custom" },
|
||||
|
|
|
@ -84,6 +84,7 @@ enum attr_type
|
|||
ATTR_CODE,
|
||||
ATTR_COMMSTATUS,
|
||||
ATTR_CONTEXTHANDLE,
|
||||
ATTR_CONTRACT,
|
||||
ATTR_CONTRACTVERSION,
|
||||
ATTR_CONTROL,
|
||||
ATTR_CUSTOM,
|
||||
|
|
Loading…
Reference in New Issue