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, ...@@ -463,6 +463,7 @@ static type_t *find_identifier(const char *identifier, const type_t *cont_type,
case TYPE_ARRAY: case TYPE_ARRAY:
case TYPE_BITFIELD: case TYPE_BITFIELD:
case TYPE_APICONTRACT: case TYPE_APICONTRACT:
case TYPE_RUNTIMECLASS:
/* nothing to do */ /* nothing to do */
break; break;
case TYPE_ALIAS: case TYPE_ALIAS:
......
...@@ -463,6 +463,9 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i ...@@ -463,6 +463,9 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
case TYPE_COCLASS: case TYPE_COCLASS:
fprintf(h, "%s", name); fprintf(h, "%s", name);
break; break;
case TYPE_RUNTIMECLASS:
fprintf(h, "%s", type_get_name(type_runtimeclass_get_default_iface(t), name_type));
break;
case TYPE_VOID: case TYPE_VOID:
fprintf(h, "void"); fprintf(h, "void");
break; break;
...@@ -545,6 +548,7 @@ void write_type_right(FILE *h, type_t *t, int is_field) ...@@ -545,6 +548,7 @@ void write_type_right(FILE *h, type_t *t, int is_field)
case TYPE_MODULE: case TYPE_MODULE:
case TYPE_COCLASS: case TYPE_COCLASS:
case TYPE_INTERFACE: case TYPE_INTERFACE:
case TYPE_RUNTIMECLASS:
break; break;
case TYPE_APICONTRACT: case TYPE_APICONTRACT:
/* not supposed to be here */ /* not supposed to be here */
...@@ -1031,7 +1035,8 @@ static int is_aggregate_return(const var_t *func) ...@@ -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)); enum type_type type = type_get_type(type_function_get_rettype(func->declspec.type));
return type == TYPE_STRUCT || type == TYPE_UNION || 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) 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) ...@@ -1689,6 +1694,39 @@ static void write_apicontract(FILE *header, type_t *apicontract)
free(name); 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) static void write_import(FILE *header, const char *fname)
{ {
char *hname, *p; char *hname, *p;
...@@ -1753,6 +1791,8 @@ static void write_forward_decls(FILE *header, const statement_list_t *stmts) ...@@ -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) else if (type_get_type(stmt->u.type) == TYPE_COCLASS)
write_coclass_forward(header, stmt->u.type); 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; break;
case STMT_TYPEREF: case STMT_TYPEREF:
case STMT_IMPORTLIB: case STMT_IMPORTLIB:
...@@ -1809,6 +1849,8 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons ...@@ -1809,6 +1849,8 @@ static void write_header_stmts(FILE *header, const statement_list_t *stmts, cons
write_coclass(header, stmt->u.type); write_coclass(header, stmt->u.type);
else if (type_get_type(stmt->u.type) == TYPE_APICONTRACT) else if (type_get_type(stmt->u.type) == TYPE_APICONTRACT)
write_apicontract(header, stmt->u.type); write_apicontract(header, stmt->u.type);
else if (type_get_type(stmt->u.type) == TYPE_RUNTIMECLASS)
write_runtimeclass(header, stmt->u.type);
else else
{ {
write_type_definition(header, stmt->u.type, stmt->declonly); write_type_definition(header, stmt->u.type, stmt->declonly);
......
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
extern int is_ptrchain_attr(const var_t *var, enum attr_type t); 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_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 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 unsigned int get_attrv(const attr_list_t *list, enum attr_type t);
extern const char* get_name(const var_t *v); extern const char* get_name(const var_t *v);
......
...@@ -298,6 +298,7 @@ static const struct keyword keywords[] = { ...@@ -298,6 +298,7 @@ static const struct keyword keywords[] = {
{"pascal", tPASCAL, 0}, {"pascal", tPASCAL, 0},
{"properties", tPROPERTIES, 0}, {"properties", tPROPERTIES, 0},
{"register", tREGISTER, 0}, {"register", tREGISTER, 0},
{"runtimeclass", tRUNTIMECLASS, 1},
{"short", tSHORT, 0}, {"short", tSHORT, 0},
{"signed", tSIGNED, 0}, {"signed", tSIGNED, 0},
{"sizeof", tSIZEOF, 0}, {"sizeof", tSIZEOF, 0},
......
...@@ -353,6 +353,7 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att ...@@ -353,6 +353,7 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
return TGT_ENUM; return TGT_ENUM;
case TYPE_POINTER: case TYPE_POINTER:
if (type_get_type(type_pointer_get_ref_type(type)) == TYPE_INTERFACE || 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))) (type_get_type(type_pointer_get_ref_type(type)) == TYPE_VOID && is_attr(attrs, ATTR_IIDIS)))
return TGT_IFACE_POINTER; return TGT_IFACE_POINTER;
else if (is_aliaschain_attr(type_pointer_get_ref_type(type), ATTR_CONTEXTHANDLE)) 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 ...@@ -373,6 +374,7 @@ enum typegen_type typegen_detect_type(const type_t *type, const attr_list_t *att
case TYPE_VOID: case TYPE_VOID:
case TYPE_ALIAS: case TYPE_ALIAS:
case TYPE_BITFIELD: case TYPE_BITFIELD:
case TYPE_RUNTIMECLASS:
break; break;
case TYPE_APICONTRACT: case TYPE_APICONTRACT:
/* not supposed to be here */ /* not supposed to be here */
...@@ -1971,6 +1973,7 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align) ...@@ -1971,6 +1973,7 @@ unsigned int type_memsize_and_alignment(const type_t *t, unsigned int *align)
case TYPE_FUNCTION: case TYPE_FUNCTION:
case TYPE_BITFIELD: case TYPE_BITFIELD:
case TYPE_APICONTRACT: case TYPE_APICONTRACT:
case TYPE_RUNTIMECLASS:
/* these types should not be encountered here due to language /* these types should not be encountered here due to language
* restrictions (interface, void, coclass, module), logical * restrictions (interface, void, coclass, module), logical
* restrictions (alias - due to type_get_type call above) or * restrictions (alias - due to type_get_type call above) or
...@@ -2073,6 +2076,7 @@ static unsigned int type_buffer_alignment(const type_t *t) ...@@ -2073,6 +2076,7 @@ static unsigned int type_buffer_alignment(const type_t *t)
case TYPE_FUNCTION: case TYPE_FUNCTION:
case TYPE_BITFIELD: case TYPE_BITFIELD:
case TYPE_APICONTRACT: case TYPE_APICONTRACT:
case TYPE_RUNTIMECLASS:
/* these types should not be encountered here due to language /* these types should not be encountered here due to language
* restrictions (interface, void, coclass, module), logical * restrictions (interface, void, coclass, module), logical
* restrictions (alias - due to type_get_type call above) or * restrictions (alias - due to type_get_type call above) or
......
...@@ -218,6 +218,7 @@ unsigned short get_type_vt(type_t *t) ...@@ -218,6 +218,7 @@ unsigned short get_type_vt(type_t *t)
case TYPE_MODULE: case TYPE_MODULE:
case TYPE_UNION: case TYPE_UNION:
case TYPE_ENCAPSULATED_UNION: case TYPE_ENCAPSULATED_UNION:
case TYPE_RUNTIMECLASS:
return VT_USERDEFINED; return VT_USERDEFINED;
case TYPE_VOID: case TYPE_VOID:
......
...@@ -215,6 +215,16 @@ type_t *type_new_coclass(char *name) ...@@ -215,6 +215,16 @@ type_t *type_new_coclass(char *name)
return type; 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, 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) 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) ...@@ -509,6 +519,15 @@ type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces)
return coclass; 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) 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)) 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 ...@@ -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_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_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_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_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(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_dispinterface_define_from_iface(type_t *dispiface, type_t *iface);
void type_module_define(type_t *module, statement_list_t *stmts); 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_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); 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); const char *type_get_name(const type_t *type, enum name_type name_type);
char *gen_name(void); char *gen_name(void);
extern int is_attr(const attr_list_t *list, enum attr_type t);
/* FIXME: shouldn't need to export this */ /* FIXME: shouldn't need to export this */
type_t *duptype(type_t *t, int dupname); type_t *duptype(type_t *t, int dupname);
...@@ -222,6 +225,7 @@ static inline int type_is_complete(const type_t *type) ...@@ -222,6 +225,7 @@ static inline int type_is_complete(const type_t *type)
case TYPE_POINTER: case TYPE_POINTER:
case TYPE_ARRAY: case TYPE_ARRAY:
case TYPE_BITFIELD: case TYPE_BITFIELD:
case TYPE_RUNTIMECLASS:
return TRUE; return TRUE;
case TYPE_APICONTRACT: case TYPE_APICONTRACT:
assert(0); assert(0);
...@@ -322,6 +326,26 @@ static inline ifref_list_t *type_coclass_get_ifaces(const type_t *type) ...@@ -322,6 +326,26 @@ static inline ifref_list_t *type_coclass_get_ifaces(const type_t *type)
return type->details.coclass.ifaces; 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) static inline const decl_spec_t *type_pointer_get_ref(const type_t *type)
{ {
type = type_get_real_type(type); type = type_get_real_type(type);
......
...@@ -425,6 +425,11 @@ struct alias_details ...@@ -425,6 +425,11 @@ struct alias_details
struct _decl_spec_t aliasee; struct _decl_spec_t aliasee;
}; };
struct runtimeclass_details
{
ifref_list_t *ifaces;
};
#define HASHMAX 64 #define HASHMAX 64
struct namespace { struct namespace {
...@@ -452,6 +457,7 @@ enum type_type ...@@ -452,6 +457,7 @@ enum type_type
TYPE_ARRAY, TYPE_ARRAY,
TYPE_BITFIELD, TYPE_BITFIELD,
TYPE_APICONTRACT, TYPE_APICONTRACT,
TYPE_RUNTIMECLASS,
}; };
struct _type_t { struct _type_t {
...@@ -472,6 +478,7 @@ struct _type_t { ...@@ -472,6 +478,7 @@ struct _type_t {
struct pointer_details pointer; struct pointer_details pointer;
struct bitfield_details bitfield; struct bitfield_details bitfield;
struct alias_details alias; struct alias_details alias;
struct runtimeclass_details runtimeclass;
} details; } details;
const char *c_name; const char *c_name;
unsigned int typestring_offset; 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