forked from Mirrors/wine-wine
widl: Add support for "inline" on function definitions.
Fix applying calling convention to function type.oldstable
parent
146ef11b77
commit
4f8f89e6bb
|
@ -312,6 +312,7 @@ void write_type_v(FILE *h, type_t *t, int is_field, int declonly,
|
|||
int i;
|
||||
const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
|
||||
if (!callconv) callconv = "";
|
||||
if (is_attr(pt->attrs, ATTR_INLINE)) fprintf(h, "inline ");
|
||||
write_type_left(h, pt->ref, declonly);
|
||||
fputc(' ', h);
|
||||
if (ptr_level) fputc('(', h);
|
||||
|
|
|
@ -233,7 +233,8 @@ static const struct keyword keywords[] = {
|
|||
{"hyper", tHYPER},
|
||||
{"import", tIMPORT},
|
||||
{"importlib", tIMPORTLIB},
|
||||
{"in_line", tINLINE},
|
||||
{"in_line", tIN_LINE},
|
||||
{"inline", tINLINE},
|
||||
{"int", tINT},
|
||||
{"interface", tINTERFACE},
|
||||
{"library", tLIBRARY},
|
||||
|
|
|
@ -116,7 +116,6 @@ static type_t *make_int(int sign);
|
|||
static typelib_t *make_library(const char *name, const attr_list_t *attrs);
|
||||
static type_t *make_func_type(var_list_t *args);
|
||||
static type_t *make_pointer_type(type_t *ref, attr_list_t *attrs);
|
||||
static void type_set_function_callconv(type_t *type, char *callconv);
|
||||
static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type);
|
||||
|
||||
static type_t *reg_type(type_t *type, const char *name, int t);
|
||||
|
@ -139,14 +138,14 @@ static statement_t *process_typedefs(var_list_t *names);
|
|||
static void check_arg(var_t *arg);
|
||||
static void check_functions(const type_t *iface);
|
||||
static void check_all_user_types(const statement_list_t *stmts);
|
||||
static const attr_list_t *check_iface_attrs(const char *name, const attr_list_t *attrs);
|
||||
static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs);
|
||||
static attr_list_t *check_function_attrs(const char *name, attr_list_t *attrs);
|
||||
static attr_list_t *check_typedef_attrs(attr_list_t *attrs);
|
||||
static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs);
|
||||
static const attr_list_t *check_library_attrs(const char *name, const attr_list_t *attrs);
|
||||
static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs);
|
||||
static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs);
|
||||
static const attr_list_t *check_module_attrs(const char *name, const attr_list_t *attrs);
|
||||
static const attr_list_t *check_coclass_attrs(const char *name, const attr_list_t *attrs);
|
||||
static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs);
|
||||
static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs);
|
||||
const char *get_attr_display_name(enum attr_type type);
|
||||
static void add_explicit_handle_if_necessary(func_t *func);
|
||||
|
||||
|
@ -234,7 +233,7 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s
|
|||
%token tIMMEDIATEBIND
|
||||
%token tIMPLICITHANDLE
|
||||
%token tIMPORT tIMPORTLIB
|
||||
%token tIN tINLINE
|
||||
%token tIN tIN_LINE tINLINE
|
||||
%token tINPUTSYNC
|
||||
%token tINT tINT64
|
||||
%token tINTERFACE
|
||||
|
@ -286,7 +285,7 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s
|
|||
%token tVOID
|
||||
%token tWCHAR tWIREMARSHAL
|
||||
|
||||
%type <attr> attribute type_qualifier
|
||||
%type <attr> attribute type_qualifier function_specifier
|
||||
%type <attr_list> m_attributes attributes attrib_list m_type_qual_list decl_spec_no_type m_decl_spec_no_type
|
||||
%type <str_list> str_list
|
||||
%type <expr> m_expr expr expr_const expr_int_const array
|
||||
|
@ -968,6 +967,10 @@ moduledef: modulehdr '{' int_statements '}'
|
|||
}
|
||||
;
|
||||
|
||||
function_specifier:
|
||||
tINLINE { $$ = make_attr(ATTR_INLINE); }
|
||||
;
|
||||
|
||||
type_qualifier:
|
||||
tCONST { $$ = make_attr(ATTR_CONST); }
|
||||
;
|
||||
|
@ -987,12 +990,13 @@ m_decl_spec_no_type: { $$ = NULL; }
|
|||
|
||||
decl_spec_no_type:
|
||||
type_qualifier m_decl_spec_no_type { $$ = append_attr($2, $1); }
|
||||
| function_specifier m_decl_spec_no_type { $$ = append_attr($2, $1); }
|
||||
;
|
||||
|
||||
declarator:
|
||||
'*' m_type_qual_list declarator %prec PPTR
|
||||
{ $$ = $3; $$->type = append_ptrchain_type($$->type, make_pointer_type(NULL, $2)); }
|
||||
| callconv declarator { $$ = $2; type_set_function_callconv($$->func_type, $1); }
|
||||
| callconv declarator { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
|
||||
| direct_declarator
|
||||
;
|
||||
|
||||
|
@ -1157,6 +1161,19 @@ static attr_list_t *append_attr(attr_list_t *list, attr_t *attr)
|
|||
return list;
|
||||
}
|
||||
|
||||
static attr_list_t *move_attr(attr_list_t *dst, attr_list_t *src, enum attr_type type)
|
||||
{
|
||||
attr_t *attr;
|
||||
if (!src) return dst;
|
||||
LIST_FOR_EACH_ENTRY(attr, src, attr_t, entry)
|
||||
if (attr->type == type)
|
||||
{
|
||||
list_remove(&attr->entry);
|
||||
return append_attr(dst, attr);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list)
|
||||
{
|
||||
struct list *entry;
|
||||
|
@ -1309,16 +1326,6 @@ static type_t *make_func_type(var_list_t *args)
|
|||
return t;
|
||||
}
|
||||
|
||||
static void type_set_function_callconv(type_t *type, char *callconv)
|
||||
{
|
||||
if (!type)
|
||||
error_loc("calling convention applied to non-function-pointer type\n");
|
||||
for (; is_ptr(type); type = type->ref)
|
||||
;
|
||||
assert(type->type == RPC_FC_FUNCTION);
|
||||
type->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, callconv));
|
||||
}
|
||||
|
||||
static type_t *make_pointer_type(type_t *ref, attr_list_t *attrs)
|
||||
{
|
||||
type_t *t = make_type(pointer_default, ref);
|
||||
|
@ -1348,6 +1355,20 @@ static void set_type(var_t *v, type_t *type, const declarator_t *decl,
|
|||
type_t *atype, **ptype;
|
||||
array_dims_t *arr = decl ? decl->array : NULL;
|
||||
|
||||
if (is_attr(type->attrs, ATTR_INLINE))
|
||||
{
|
||||
if (!decl || !decl->func_type)
|
||||
error_loc("inline attribute applied to non-function type\n");
|
||||
else
|
||||
{
|
||||
type_t *t;
|
||||
/* move inline attribute from return type node to function node */
|
||||
for (t = decl->func_type; is_ptr(t); t = t->ref)
|
||||
;
|
||||
t->attrs = move_attr(t->attrs, type->attrs, ATTR_INLINE);
|
||||
}
|
||||
}
|
||||
|
||||
/* add type onto the end of the pointers in pident->type */
|
||||
v->type = append_ptrchain_type(decl ? decl->type : NULL, type);
|
||||
|
||||
|
@ -1496,20 +1517,31 @@ static void set_type(var_t *v, type_t *type, const declarator_t *decl,
|
|||
* function and make v->type point to the function side of the declaration */
|
||||
if (decl && decl->func_type)
|
||||
{
|
||||
type_t *t;
|
||||
type_t *ft, *t;
|
||||
type_t *return_type = v->type;
|
||||
v->type = decl->func_type;
|
||||
for (t = v->type; is_ptr(t); t = t->ref)
|
||||
for (ft = v->type; is_ptr(ft); ft = ft->ref)
|
||||
;
|
||||
assert(t->type == RPC_FC_FUNCTION);
|
||||
t->ref = return_type;
|
||||
if (is_object_interface && !is_attr(t->attrs, ATTR_CALLCONV))
|
||||
assert(ft->type == RPC_FC_FUNCTION);
|
||||
ft->ref = return_type;
|
||||
/* move calling convention attribute, if present, from pointer nodes to
|
||||
* function node */
|
||||
for (t = v->type; is_ptr(t); t = t->ref)
|
||||
ft->attrs = move_attr(ft->attrs, t->attrs, ATTR_CALLCONV);
|
||||
if (is_object_interface && !is_attr(ft->attrs, ATTR_CALLCONV))
|
||||
{
|
||||
static char *stdmethodcalltype;
|
||||
if (!stdmethodcalltype) stdmethodcalltype = strdup("STDMETHODCALLTYPE");
|
||||
t->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, stdmethodcalltype));
|
||||
ft->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, stdmethodcalltype));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
type_t *t;
|
||||
for (t = v->type; is_ptr(t); t = t->ref)
|
||||
if (is_attr(t->attrs, ATTR_CALLCONV))
|
||||
error_loc("calling convention applied to non-function-pointer type\n");
|
||||
}
|
||||
}
|
||||
|
||||
static var_list_t *set_var_types(attr_list_t *attrs, type_t *type, declarator_list_t *decls)
|
||||
|
@ -2163,6 +2195,7 @@ struct allowed_attr allowed_attr[] =
|
|||
/* ATTR_IMMEDIATEBIND */ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
|
||||
/* ATTR_IMPLICIT_HANDLE */ { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
|
||||
/* ATTR_IN */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "in" },
|
||||
/* ATTR_INLINE */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inline" },
|
||||
/* ATTR_INPUTSYNC */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
|
||||
/* ATTR_LENGTHIS */ { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, "length_is" },
|
||||
/* ATTR_LIBLCID */ { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" },
|
||||
|
@ -2205,7 +2238,7 @@ const char *get_attr_display_name(enum attr_type type)
|
|||
return allowed_attr[type].display_name;
|
||||
}
|
||||
|
||||
static const attr_list_t *check_iface_attrs(const char *name, const attr_list_t *attrs)
|
||||
static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
|
@ -2276,7 +2309,7 @@ static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs)
|
|||
return attrs;
|
||||
}
|
||||
|
||||
static const attr_list_t *check_library_attrs(const char *name, const attr_list_t *attrs)
|
||||
static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
|
@ -2302,7 +2335,7 @@ static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs)
|
|||
return attrs;
|
||||
}
|
||||
|
||||
static const attr_list_t *check_module_attrs(const char *name, const attr_list_t *attrs)
|
||||
static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
|
@ -2315,7 +2348,7 @@ static const attr_list_t *check_module_attrs(const char *name, const attr_list_t
|
|||
return attrs;
|
||||
}
|
||||
|
||||
static const attr_list_t *check_coclass_attrs(const char *name, const attr_list_t *attrs)
|
||||
static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs)
|
||||
{
|
||||
const attr_t *attr;
|
||||
if (!attrs) return attrs;
|
||||
|
|
|
@ -105,6 +105,7 @@ enum attr_type
|
|||
ATTR_IMMEDIATEBIND,
|
||||
ATTR_IMPLICIT_HANDLE,
|
||||
ATTR_IN,
|
||||
ATTR_INLINE,
|
||||
ATTR_INPUTSYNC,
|
||||
ATTR_LENGTHIS,
|
||||
ATTR_LIBLCID,
|
||||
|
@ -256,7 +257,7 @@ struct _type_t {
|
|||
enum type_kind kind;
|
||||
unsigned char type;
|
||||
struct _type_t *ref;
|
||||
const attr_list_t *attrs;
|
||||
attr_list_t *attrs;
|
||||
func_list_t *funcs; /* interfaces and modules */
|
||||
var_list_t *fields_or_args; /* interfaces, structures, enumerations and functions (for args) */
|
||||
ifref_list_t *ifaces; /* coclasses */
|
||||
|
|
Loading…
Reference in New Issue