Commit f46c077d authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

widl: Support WinRT runtimeclass type parsing.

parent 79d14397
......@@ -463,6 +463,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
case TYPE_ARRAY:
case TYPE_BITFIELD:
case TYPE_APICONTRACT:
case TYPE_RUNTIMECLASS:
/* nothing to do */
break;
case TYPE_ALIAS:
......
......@@ -463,6 +463,9 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
case TYPE_COCLASS:
fprintf(h, "%s", name);
break;
case TYPE_RUNTIMECLASS:
fprintf(h, "%s", type_get_name(type_runtimeclass_get_default_iface(t), name_type));
break;
case TYPE_VOID:
fprintf(h, "void");
break;
......@@ -545,6 +548,7 @@ void write_type_right(FILE *h, type_t *t, int is_field)
case TYPE_MODULE:
case TYPE_COCLASS:
case TYPE_INTERFACE:
case TYPE_RUNTIMECLASS:
break;
case TYPE_APICONTRACT:
/* not supposed to be here */
......@@ -1031,7 +1035,8 @@ static int is_aggregate_return(const var_t *func)
{
enum type_type type = type_get_type(type_function_get_rettype(func->declspec.type));
return type == TYPE_STRUCT || type == TYPE_UNION ||
type == TYPE_COCLASS || type == TYPE_INTERFACE;
type == TYPE_COCLASS || type == TYPE_INTERFACE ||
type == TYPE_RUNTIMECLASS;
}
static char *get_vtbl_entry_name(const type_t *iface, const var_t *func)
......@@ -1689,6 +1694,39 @@ static void write_apicontract(FILE *header, type_t *apicontract)
free(name);
}
static void write_runtimeclass(FILE *header, type_t *runtimeclass)
{
expr_t *contract = get_attrp(runtimeclass->attrs, ATTR_CONTRACT);
char *name, *c_name;
name = format_namespace(runtimeclass->namespace, "", ".", runtimeclass->name, NULL);
c_name = format_namespace(runtimeclass->namespace, "", "_", runtimeclass->name, NULL);
fprintf(header, "/*\n");
fprintf(header, " * Class %s\n", name);
fprintf(header, " */\n");
if (contract) write_apicontract_guard_start(header, contract);
fprintf(header, "#ifndef RUNTIMECLASS_%s_DEFINED\n", c_name);
fprintf(header, "#define RUNTIMECLASS_%s_DEFINED\n", c_name);
fprintf(header, "#endif /* RUNTIMECLASS_%s_DEFINED */\n", c_name);
free(c_name);
free(name);
if (contract) write_apicontract_guard_end(header, contract);
fprintf(header, "\n");
}
static void write_runtimeclass_forward(FILE *header, type_t *runtimeclass)
{
fprintf(header, "#ifndef __%s_FWD_DEFINED__\n", runtimeclass->c_name);
fprintf(header, "#define __%s_FWD_DEFINED__\n", runtimeclass->c_name);
fprintf(header, "#ifdef __cplusplus\n");
write_namespace_start(header, runtimeclass->namespace);
write_line(header, 0, "class %s;", runtimeclass->name);
write_namespace_end(header, runtimeclass->namespace);
fprintf(header, "#else\n");
fprintf(header, "typedef struct %s %s;\n", runtimeclass->c_name, runtimeclass->c_name);
fprintf(header, "#endif /* defined __cplusplus */\n");
fprintf(header, "#endif /* defined __%s_FWD_DEFINED__ */\n\n", runtimeclass->c_name);
}
static void write_import(FILE *header, const char *fname)
{
char *hname, *p;
......@@ -1753,6 +1791,8 @@ static void write_forward_decls(FILE *header, const statement_list_t *stmts)
}
else if (type_get_type(stmt->u.type) == TYPE_COCLASS)
write_coclass_forward(header, stmt->u.type);
else if (type_get_type(stmt->u.type) == TYPE_RUNTIMECLASS)
write_runtimeclass_forward(header, stmt->u.type);
break;
case STMT_TYPEREF:
case STMT_IMPORTLIB:
......@@ -1809,6 +1849,8 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
write_coclass(header, stmt->u.type);
else if (type_get_type(stmt->u.type) == TYPE_APICONTRACT)
write_apicontract(header, stmt->u.type);
else if (type_get_type(stmt->u.type) == TYPE_RUNTIMECLASS)
write_runtimeclass(header, stmt->u.type);
else
{
write_type_definition(header, stmt->u.type, stmt->declonly);
......
......@@ -25,7 +25,6 @@
extern int is_ptrchain_attr(const var_t *var, enum attr_type t);
extern int is_aliaschain_attr(const type_t *var, enum attr_type t);
extern int is_attr(const attr_list_t *list, enum attr_type t);
extern void *get_attrp(const attr_list_t *list, enum attr_type t);
extern unsigned int get_attrv(const attr_list_t *list, enum attr_type t);
extern const char* get_name(const var_t *v);
......
......@@ -298,6 +298,7 @@ static const struct keyword keywords[] = {
{"pascal", tPASCAL, 0},
{"properties", tPROPERTIES, 0},
{"register", tREGISTER, 0},
{"runtimeclass", tRUNTIMECLASS, 1},
{"short", tSHORT, 0},
{"signed", tSIGNED, 0},
{"sizeof", tSIZEOF, 0},
......
......@@ -353,6 +353,7 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
return TGT_ENUM;
case TYPE_POINTER:
if (type_get_type(type_pointer_get_ref_type(type)) == TYPE_INTERFACE ||
type_get_type(type_pointer_get_ref_type(type)) == TYPE_RUNTIMECLASS ||
(type_get_type(type_pointer_get_ref_type(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS)))
return TGT_IFACE_POINTER;
else if (is_aliaschain_attr(type_pointer_get_ref_type(type), ATTR_CONTEXTHANDLE))
......@@ -373,6 +374,7 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
case TYPE_VOID:
case TYPE_ALIAS:
case TYPE_BITFIELD:
case TYPE_RUNTIMECLASS:
break;
case TYPE_APICONTRACT:
/* not supposed to be here */
......@@ -1971,6 +1973,7 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
case TYPE_FUNCTION:
case TYPE_BITFIELD:
case TYPE_APICONTRACT:
case TYPE_RUNTIMECLASS:
/* these types should not be encountered here due to language
* restrictions (interface, void, coclass, module), logical
* restrictions (alias - due to type_get_type call above) or
......@@ -2073,6 +2076,7 @@ static unsigned int type_buffer_alignment(const type_t *t)
case TYPE_FUNCTION:
case TYPE_BITFIELD:
case TYPE_APICONTRACT:
case TYPE_RUNTIMECLASS:
/* these types should not be encountered here due to language
* restrictions (interface, void, coclass, module), logical
* restrictions (alias - due to type_get_type call above) or
......
......@@ -218,6 +218,7 @@ unsigned short get_type_vt(type_t *t)
case TYPE_MODULE:
case TYPE_UNION:
case TYPE_ENCAPSULATED_UNION:
case TYPE_RUNTIMECLASS:
return VT_USERDEFINED;
case TYPE_VOID:
......
......@@ -215,6 +215,16 @@ type_t *type_new_coclass(char *name)
return type;
}
type_t *type_new_runtimeclass(char *name, struct namespace *namespace)
{
type_t *type = get_type(TYPE_RUNTIMECLASS, name, NULL, 0);
if (type->type_type != TYPE_RUNTIMECLASS || type->defined)
error_loc("%s: redefinition error; original definition was at %s:%d\n",
type->name, type->loc_info.input_name, type->loc_info.line_number);
type->name = name;
type->namespace = namespace;
return type;
}
type_t *type_new_array(const char *name, const decl_spec_t *element, int declptr,
unsigned int dim, expr_t *size_is, expr_t *length_is)
......@@ -509,6 +519,15 @@ type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces)
return coclass;
}
type_t *type_runtimeclass_define(type_t *runtimeclass, ifref_list_t *ifaces)
{
runtimeclass->details.runtimeclass.ifaces = ifaces;
runtimeclass->defined = TRUE;
if (!type_runtimeclass_get_default_iface(runtimeclass))
error_loc("missing default interface on runtimeclass %s\n", runtimeclass->name);
return runtimeclass;
}
int type_is_equal(const type_t *type1, const type_t *type2)
{
if (type_get_type_detect_alias(type1) != type_get_type_detect_alias(type2))
......
......@@ -44,14 +44,17 @@ type_t *type_new_struct(char *name, struct namespace *namespace, int defined, va
type_t *type_new_nonencapsulated_union(const char *name, int defined, var_list_t *fields);
type_t *type_new_encapsulated_union(char *name, var_t *switch_field, var_t *union_field, var_list_t *cases);
type_t *type_new_bitfield(type_t *field_type, const expr_t *bits);
type_t *type_new_runtimeclass(char *name, struct namespace *namespace);
void type_interface_define(type_t *iface, type_t *inherit, statement_list_t *stmts);
void type_dispinterface_define(type_t *iface, var_list_t *props, var_list_t *methods);
void type_dispinterface_define_from_iface(type_t *dispiface, type_t *iface);
void type_module_define(type_t *module, statement_list_t *stmts);
type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces);
type_t *type_runtimeclass_define(type_t *runtimeclass, ifref_list_t *ifaces);
int type_is_equal(const type_t *type1, const type_t *type2);
const char *type_get_name(const type_t *type, enum name_type name_type);
char *gen_name(void);
extern int is_attr(const attr_list_t *list, enum attr_type t);
/* FIXME: shouldn't need to export this */
type_t *duptype(type_t *t, int dupname);
......@@ -222,6 +225,7 @@ static inline int type_is_complete(const type_t *type)
case TYPE_POINTER:
case TYPE_ARRAY:
case TYPE_BITFIELD:
case TYPE_RUNTIMECLASS:
return TRUE;
case TYPE_APICONTRACT:
assert(0);
......@@ -322,6 +326,26 @@ static inline ifref_list_t *type_coclass_get_ifaces(const type_t *type)
return type->details.coclass.ifaces;
}
static inline ifref_list_t *type_runtimeclass_get_ifaces(const type_t *type)
{
type = type_get_real_type(type);
assert(type_get_type(type) == TYPE_RUNTIMECLASS);
return type->details.runtimeclass.ifaces;
}
static inline type_t *type_runtimeclass_get_default_iface(const type_t *type)
{
ifref_list_t *ifaces = type_runtimeclass_get_ifaces(type);
ifref_t *entry;
if (!ifaces) return NULL;
LIST_FOR_EACH_ENTRY(entry, ifaces, ifref_t, entry)
if (is_attr(entry->attrs, ATTR_DEFAULT))
return entry->iface;
return NULL;
}
static inline const decl_spec_t *type_pointer_get_ref(const type_t *type)
{
type = type_get_real_type(type);
......
......@@ -425,6 +425,11 @@ struct alias_details
struct _decl_spec_t aliasee;
};
struct runtimeclass_details
{
ifref_list_t *ifaces;
};
#define HASHMAX 64
struct namespace {
......@@ -452,6 +457,7 @@ enum type_type
TYPE_ARRAY,
TYPE_BITFIELD,
TYPE_APICONTRACT,
TYPE_RUNTIMECLASS,
};
struct _type_t {
......@@ -472,6 +478,7 @@ struct _type_t {
struct pointer_details pointer;
struct bitfield_details bitfield;
struct alias_details alias;
struct runtimeclass_details runtimeclass;
} details;
const char *c_name;
unsigned int typestring_offset;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment