widl: Rename pident to declarator and parse the array declarations as part of declarators.

This allows arrays to be used in typedefs and const statements.
This commit is contained in:
Rob Shearman 2008-04-25 10:58:24 +01:00 committed by Alexandre Julliard
parent 2f381f30a6
commit 21cd6865c8
2 changed files with 68 additions and 68 deletions

View File

@ -90,13 +90,13 @@ static attr_t *make_attrv(enum attr_type type, unsigned long val);
static attr_t *make_attrp(enum attr_type type, void *val); static attr_t *make_attrp(enum attr_type type, void *val);
static expr_list_t *append_expr(expr_list_t *list, expr_t *expr); static expr_list_t *append_expr(expr_list_t *list, expr_t *expr);
static array_dims_t *append_array(array_dims_t *list, expr_t *expr); static array_dims_t *append_array(array_dims_t *list, expr_t *expr);
static void set_type(var_t *v, type_t *type, const pident_t *pident, array_dims_t *arr, int top); static void set_type(var_t *v, type_t *type, const declarator_t *decl, int top);
static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface); static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface);
static ifref_t *make_ifref(type_t *iface); static ifref_t *make_ifref(type_t *iface);
static var_list_t *append_var(var_list_t *list, var_t *var); static var_list_t *append_var(var_list_t *list, var_t *var);
static var_t *make_var(char *name); static var_t *make_var(char *name);
static pident_list_t *append_pident(pident_list_t *list, pident_t *p); static declarator_list_t *append_declarator(declarator_list_t *list, declarator_t *p);
static pident_t *make_pident(var_t *var); static declarator_t *make_declarator(var_t *var);
static func_list_t *append_func(func_list_t *list, func_t *func); static func_list_t *append_func(func_list_t *list, func_t *func);
static func_t *make_func(var_t *def); static func_t *make_func(var_t *def);
static type_t *make_class(char *name); static type_t *make_class(char *name);
@ -165,8 +165,8 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s
type_t *type; type_t *type;
var_t *var; var_t *var;
var_list_t *var_list; var_list_t *var_list;
pident_t *pident; declarator_t *declarator;
pident_list_t *pident_list; declarator_list_t *declarator_list;
func_t *func; func_t *func;
func_list_t *func_list; func_list_t *func_list;
statement_t *statement; statement_t *statement;
@ -276,9 +276,8 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s
%type <attr> attribute %type <attr> attribute
%type <attr_list> m_attributes attributes attrib_list %type <attr_list> m_attributes attributes attrib_list
%type <str_list> str_list %type <str_list> str_list
%type <expr> m_expr expr expr_const %type <expr> m_expr expr expr_const array
%type <expr_list> m_exprs /* exprs expr_list */ expr_list_const %type <expr_list> m_exprs /* exprs expr_list */ expr_list_const
%type <array_dims> array array_list
%type <ifinfo> interfacehdr %type <ifinfo> interfacehdr
%type <type> inherit interface interfacedef interfacedec %type <type> inherit interface interfacedef interfacedec
%type <type> dispinterface dispinterfacehdr dispinterfacedef %type <type> dispinterface dispinterfacehdr dispinterfacedef
@ -291,8 +290,8 @@ static statement_list_t *append_statement(statement_list_t *list, statement_t *s
%type <var> arg field s_field case enum constdef externdef %type <var> arg field s_field case enum constdef externdef
%type <var_list> m_args no_args args fields cases enums enum_list dispint_props %type <var_list> m_args no_args args fields cases enums enum_list dispint_props
%type <var> m_ident t_ident ident %type <var> m_ident t_ident ident
%type <pident> pident func_ident direct_ident %type <declarator> declarator func_declarator direct_declarator
%type <pident_list> pident_list %type <declarator_list> declarator_list
%type <func> funcdef %type <func> funcdef
%type <func_list> int_statements dispint_meths %type <func_list> int_statements dispint_meths
%type <type> coclass coclasshdr coclassdef %type <type> coclass coclasshdr coclassdef
@ -448,25 +447,19 @@ args: arg { check_arg($1); $$ = append_var( NULL, $1 ); }
; ;
/* split into two rules to get bison to resolve a tVOID conflict */ /* split into two rules to get bison to resolve a tVOID conflict */
arg: attributes type pident array { $$ = $3->var; arg: attributes type declarator { $$ = $3->var;
$$->attrs = $1; $$->attrs = $1;
set_type($$, $2, $3, $4, TRUE); set_type($$, $2, $3, TRUE);
free($3); free($3);
} }
| type pident array { $$ = $2->var; | type declarator { $$ = $2->var;
set_type($$, $1, $2, $3, TRUE); set_type($$, $1, $2, TRUE);
free($2); free($2);
} }
; ;
array: { $$ = NULL; } array: '[' m_expr ']' { $$ = $2; }
| '[' array_list ']' { $$ = $2; } | '[' '*' ']' { $$ = make_expr(EXPR_VOID); }
| '[' '*' ']' { $$ = append_array( NULL, make_expr(EXPR_VOID) ); }
;
array_list: m_expr /* size of first dimension is optional */ { $$ = append_array( NULL, $1 ); }
| array_list ',' expr { $$ = append_array( $1, $3 ); }
| array_list ']' '[' expr { $$ = append_array( $1, $4 ); }
; ;
m_attributes: { $$ = NULL; } m_attributes: { $$ = NULL; }
@ -594,7 +587,7 @@ case: tCASE expr_const ':' field { attr_t *a = make_attrp(ATTR_CASE, append_e
; ;
constdef: tCONST type ident '=' expr_const { $$ = reg_const($3); constdef: tCONST type ident '=' expr_const { $$ = reg_const($3);
set_type($$, $2, NULL, NULL, FALSE); set_type($$, $2, NULL, FALSE);
$$->eval = $5; $$->eval = $5;
} }
; ;
@ -704,7 +697,7 @@ expr_const: expr { $$ = $1;
; ;
externdef: tEXTERN tCONST type ident { $$ = $4; externdef: tEXTERN tCONST type ident { $$ = $4;
set_type($$, $3, NULL, NULL, FALSE); set_type($$, $3, NULL, FALSE);
} }
; ;
@ -718,17 +711,17 @@ field: s_field ';' { $$ = $1; }
| ';' { $$ = NULL; } | ';' { $$ = NULL; }
; ;
s_field: m_attributes type pident array { $$ = $3->var; s_field: m_attributes type declarator { $$ = $3->var;
$$->attrs = check_field_attrs($$->name, $1); $$->attrs = check_field_attrs($$->name, $1);
set_type($$, $2, $3, $4, FALSE); set_type($$, $2, $3, FALSE);
free($3); free($3);
} }
; ;
funcdef: funcdef:
m_attributes type pident { var_t *v = $3->var; m_attributes type declarator { var_t *v = $3->var;
v->attrs = check_function_attrs(v->name, $1); v->attrs = check_function_attrs(v->name, $1);
set_type(v, $2, $3, NULL, FALSE); set_type(v, $2, $3, FALSE);
free($3); free($3);
$$ = make_func(v); $$ = make_func(v);
} }
@ -933,29 +926,32 @@ moduledef: modulehdr '{' int_statements '}'
} }
; ;
pident: '*' pident %prec PPTR { $$ = $2; $$->type = make_type(pointer_default, $$->type); } declarator:
| tCONST pident { $$ = $2; /* FIXME */ } '*' declarator %prec PPTR { $$ = $2; $$->type = make_type(pointer_default, $$->type); }
| callconv pident { $$ = $2; type_set_function_callconv($$->func_type, $1); } | tCONST declarator { $$ = $2; /* FIXME */ }
| direct_ident | callconv declarator { $$ = $2; type_set_function_callconv($$->func_type, $1); }
| direct_declarator
; ;
func_ident: direct_ident '(' m_args ')' func_declarator: direct_declarator '(' m_args ')'
{ $$ = $1; { $$ = $1;
$$->type = append_ptrchain_type($$->type, make_func_type($3)); $$->type = append_ptrchain_type($$->type, make_func_type($3));
} }
; ;
direct_ident: ident { $$ = make_pident($1); } direct_declarator:
| '(' pident ')' { $$ = $2; } ident { $$ = make_declarator($1); }
| func_ident { $$ = $1; | '(' declarator ')' { $$ = $2; }
| direct_declarator array { $$ = $1; $$->array = append_array($$->array, $2); }
| func_declarator { $$ = $1;
$$->func_type = $$->type; $$->func_type = $$->type;
$$->type = NULL; $$->type = NULL;
} }
; ;
pident_list: declarator_list:
pident { $$ = append_pident( NULL, $1 ); } declarator { $$ = append_declarator( NULL, $1 ); }
| pident_list ',' pident { $$ = append_pident( $1, $3 ); } | declarator_list ',' declarator { $$ = append_declarator( $1, $3 ); }
; ;
pointer_type: pointer_type:
@ -988,7 +984,8 @@ type: tVOID { $$ = duptype(find_type("void", 0), 1); }
| tSAFEARRAY '(' type ')' { $$ = make_safearray($3); } | tSAFEARRAY '(' type ')' { $$ = make_safearray($3); }
; ;
typedef: tTYPEDEF m_attributes type pident_list { reg_typedefs($3, $4, check_typedef_attrs($2)); typedef: tTYPEDEF m_attributes type declarator_list
{ reg_typedefs($3, $4, check_typedef_attrs($2));
$$ = process_typedefs($4); $$ = process_typedefs($4);
} }
; ;
@ -1230,7 +1227,7 @@ static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type)
return ptrchain; return ptrchain;
} }
static void set_type(var_t *v, type_t *type, const pident_t *pident, array_dims_t *arr, static void set_type(var_t *v, type_t *type, const declarator_t *decl,
int top) int top)
{ {
expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS); expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS);
@ -1239,9 +1236,10 @@ static void set_type(var_t *v, type_t *type, const pident_t *pident, array_dims_
int sizeless, has_varconf; int sizeless, has_varconf;
expr_t *dim; expr_t *dim;
type_t *atype, **ptype; type_t *atype, **ptype;
array_dims_t *arr = decl ? decl->array : NULL;
/* add type onto the end of the pointers in pident->type */ /* add type onto the end of the pointers in pident->type */
v->type = append_ptrchain_type(pident ? pident->type : NULL, type); v->type = append_ptrchain_type(decl ? decl->type : NULL, type);
/* the highest level of pointer specified should default to the var's ptr attr /* the highest level of pointer specified should default to the var's ptr attr
* or (RPC_FC_RP if not specified and it's a top level ptr), not * or (RPC_FC_RP if not specified and it's a top level ptr), not
@ -1386,11 +1384,11 @@ static void set_type(var_t *v, type_t *type, const pident_t *pident, array_dims_
/* v->type is currently pointing the the type on the left-side of the /* v->type is currently pointing the the type on the left-side of the
* declaration, so we need to fix this up so that it is the return type of the * declaration, so we need to fix this up so that it is the return type of the
* function and make v->type point to the function side of the declaration */ * function and make v->type point to the function side of the declaration */
if (pident && pident->func_type) if (decl && decl->func_type)
{ {
type_t *t; type_t *t;
type_t *return_type = v->type; type_t *return_type = v->type;
v->type = pident->func_type; v->type = decl->func_type;
for (t = v->type; is_ptr(t); t = t->ref) for (t = v->type; is_ptr(t); t = t->ref)
; ;
assert(t->type == RPC_FC_FUNCTION); assert(t->type == RPC_FC_FUNCTION);
@ -1449,24 +1447,25 @@ static var_t *make_var(char *name)
return v; return v;
} }
static pident_list_t *append_pident(pident_list_t *list, pident_t *p) static declarator_list_t *append_declarator(declarator_list_t *list, declarator_t *d)
{ {
if (!p) return list; if (!d) return list;
if (!list) { if (!list) {
list = xmalloc(sizeof(*list)); list = xmalloc(sizeof(*list));
list_init(list); list_init(list);
} }
list_add_tail(list, &p->entry); list_add_tail(list, &d->entry);
return list; return list;
} }
static pident_t *make_pident(var_t *var) static declarator_t *make_declarator(var_t *var)
{ {
pident_t *p = xmalloc(sizeof(*p)); declarator_t *d = xmalloc(sizeof(*d));
p->var = var; d->var = var;
p->type = NULL; d->type = NULL;
p->func_type = NULL; d->func_type = NULL;
return p; d->array = NULL;
return d;
} }
static func_list_t *append_func(func_list_t *list, func_t *func) static func_list_t *append_func(func_list_t *list, func_t *func)
@ -1592,9 +1591,9 @@ static void fix_incomplete(void)
} }
} }
static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *attrs) static type_t *reg_typedefs(type_t *type, declarator_list_t *decls, attr_list_t *attrs)
{ {
const pident_t *pident; const declarator_t *decl;
int is_str = is_attr(attrs, ATTR_STRING); int is_str = is_attr(attrs, ATTR_STRING);
if (is_str) if (is_str)
@ -1608,9 +1607,9 @@ static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *a
c = t->type; c = t->type;
if (c != RPC_FC_CHAR && c != RPC_FC_BYTE && c != RPC_FC_WCHAR) if (c != RPC_FC_CHAR && c != RPC_FC_BYTE && c != RPC_FC_WCHAR)
{ {
pident = LIST_ENTRY( list_head( pidents ), const pident_t, entry ); decl = LIST_ENTRY( list_head( decls ), const declarator_t, entry );
error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n", error_loc("'%s': [string] attribute is only valid on 'char', 'byte', or 'wchar_t' pointers and arrays\n",
pident->var->name); decl->var->name);
} }
} }
@ -1626,16 +1625,16 @@ static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *a
type->name = gen_name(); type->name = gen_name();
} }
LIST_FOR_EACH_ENTRY( pident, pidents, const pident_t, entry ) LIST_FOR_EACH_ENTRY( decl, decls, const declarator_t, entry )
{ {
var_t *name = pident->var; var_t *name = decl->var;
if (name->name) { if (name->name) {
type_t *cur; type_t *cur;
/* set the attributes to allow set_type to do some checks on them */ /* set the attributes to allow set_type to do some checks on them */
name->attrs = attrs; name->attrs = attrs;
set_type(name, type, pident, NULL, 0); set_type(name, type, decl, 0);
cur = alias(name->type, name->name); cur = alias(name->type, name->name);
cur->attrs = attrs; cur->attrs = attrs;
@ -2563,21 +2562,21 @@ static statement_t *make_statement_module(type_t *type)
return stmt; return stmt;
} }
static statement_t *process_typedefs(pident_list_t *pidents) static statement_t *process_typedefs(declarator_list_t *decls)
{ {
pident_t *pident, *next; declarator_t *decl, *next;
statement_t *stmt; statement_t *stmt;
type_list_t **type_list; type_list_t **type_list;
if (!pidents) return NULL; if (!decls) return NULL;
stmt = make_statement(STMT_TYPEDEF); stmt = make_statement(STMT_TYPEDEF);
stmt->u.type_list = NULL; stmt->u.type_list = NULL;
type_list = &stmt->u.type_list; type_list = &stmt->u.type_list;
LIST_FOR_EACH_ENTRY_SAFE( pident, next, pidents, pident_t, entry ) LIST_FOR_EACH_ENTRY_SAFE( decl, next, decls, declarator_t, entry )
{ {
var_t *var = pident->var; var_t *var = decl->var;
type_t *type = find_type(var->name, 0); type_t *type = find_type(var->name, 0);
*type_list = xmalloc(sizeof(type_list_t)); *type_list = xmalloc(sizeof(type_list_t));
(*type_list)->type = type; (*type_list)->type = type;
@ -2589,7 +2588,7 @@ static statement_t *process_typedefs(pident_list_t *pidents)
add_typelib_entry(type); add_typelib_entry(type);
type_list = &(*type_list)->next; type_list = &(*type_list)->next;
free(pident); free(decl);
free(var); free(var);
} }

View File

@ -43,7 +43,7 @@ typedef struct _expr_t expr_t;
typedef struct _type_t type_t; typedef struct _type_t type_t;
typedef struct _typeref_t typeref_t; typedef struct _typeref_t typeref_t;
typedef struct _var_t var_t; typedef struct _var_t var_t;
typedef struct _pident_t pident_t; typedef struct _declarator_t declarator_t;
typedef struct _func_t func_t; typedef struct _func_t func_t;
typedef struct _ifref_t ifref_t; typedef struct _ifref_t ifref_t;
typedef struct _typelib_entry_t typelib_entry_t; typedef struct _typelib_entry_t typelib_entry_t;
@ -60,7 +60,7 @@ typedef struct list str_list_t;
typedef struct list func_list_t; typedef struct list func_list_t;
typedef struct list expr_list_t; typedef struct list expr_list_t;
typedef struct list var_list_t; typedef struct list var_list_t;
typedef struct list pident_list_t; typedef struct list declarator_list_t;
typedef struct list ifref_list_t; typedef struct list ifref_list_t;
typedef struct list array_dims_t; typedef struct list array_dims_t;
typedef struct list user_type_list_t; typedef struct list user_type_list_t;
@ -288,10 +288,11 @@ struct _var_t {
struct list entry; struct list entry;
}; };
struct _pident_t { struct _declarator_t {
var_t *var; var_t *var;
type_t *type; type_t *type;
type_t *func_type; type_t *func_type;
array_dims_t *array;
/* parser-internal */ /* parser-internal */
struct list entry; struct list entry;