widl: Store the "const" type qualifier inside the decl_spec_t structure.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Richard Pospesel 2019-08-17 20:07:06 -05:00 committed by Alexandre Julliard
parent df948ccc05
commit 7e4da76689
6 changed files with 86 additions and 60 deletions

View File

@ -521,11 +521,11 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
break; break;
case EXPR_STRLIT: case EXPR_STRLIT:
result.is_temporary = TRUE; result.is_temporary = TRUE;
result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_CHAR, 0), NULL); result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_CHAR, 0));
break; break;
case EXPR_WSTRLIT: case EXPR_WSTRLIT:
result.is_temporary = TRUE; result.is_temporary = TRUE;
result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0), NULL); result.type = type_new_pointer(FC_UP, type_new_int(TYPE_BASIC_WCHAR, 0));
break; break;
case EXPR_CHARCONST: case EXPR_CHARCONST:
result.is_temporary = TRUE; result.is_temporary = TRUE;
@ -575,7 +575,7 @@ static struct expression_type resolve_expression(const struct expr_loc *expr_loc
expr_loc->attr ? expr_loc->attr : ""); expr_loc->attr ? expr_loc->attr : "");
result.is_variable = FALSE; result.is_variable = FALSE;
result.is_temporary = TRUE; result.is_temporary = TRUE;
result.type = type_new_pointer(FC_UP, result.type, NULL); result.type = type_new_pointer(FC_UP, result.type);
break; break;
case EXPR_PPTR: case EXPR_PPTR:
result = resolve_expression(expr_loc, cont_type, e->ref); result = resolve_expression(expr_loc, cont_type, e->ref);

View File

@ -318,8 +318,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
name = type_get_name(t, name_type); name = type_get_name(t, name_type);
if (is_attr(t->attrs, ATTR_CONST) && if ((ds->qualifier & TYPE_QUALIFIER_CONST) && (type_is_alias(t) || !is_ptr(t)))
(type_is_alias(t) || !is_ptr(t)))
fprintf(h, "const "); fprintf(h, "const ");
if (type_is_alias(t)) fprintf(h, "%s", t->name); if (type_is_alias(t)) fprintf(h, "%s", t->name);
@ -369,7 +368,7 @@ void write_type_left(FILE *h, const decl_spec_t *ds, enum name_type name_type, i
{ {
write_type_left(h, type_pointer_get_ref(t), name_type, declonly, FALSE); write_type_left(h, type_pointer_get_ref(t), name_type, declonly, FALSE);
write_pointer_left(h, type_pointer_get_ref_type(t)); write_pointer_left(h, type_pointer_get_ref_type(t));
if (is_attr(t->attrs, ATTR_CONST)) fprintf(h, "const "); if (ds->qualifier & TYPE_QUALIFIER_CONST) fprintf(h, "const ");
break; break;
} }
case TYPE_ARRAY: case TYPE_ARRAY:
@ -813,17 +812,17 @@ static void write_typedef(FILE *header, type_t *type)
int is_const_decl(const var_t *var) int is_const_decl(const var_t *var)
{ {
const type_t *t; const decl_spec_t *t;
/* strangely, MIDL accepts a const attribute on any pointer in the /* strangely, MIDL accepts a const attribute on any pointer in the
* declaration to mean that data isn't being instantiated. this appears * declaration to mean that data isn't being instantiated. this appears
* to be a bug, but there is no benefit to being incompatible with MIDL, * to be a bug, but there is no benefit to being incompatible with MIDL,
* so we'll do the same thing */ * so we'll do the same thing */
for (t = var->declspec.type; ; ) for (t = &var->declspec; ; )
{ {
if (is_attr(t->attrs, ATTR_CONST)) if (t->qualifier & TYPE_QUALIFIER_CONST)
return TRUE; return TRUE;
else if (is_ptr(t)) else if (is_ptr(t->type))
t = type_pointer_get_ref_type(t); t = type_pointer_get_ref(t->type);
else break; else break;
} }
return FALSE; return FALSE;

View File

@ -59,13 +59,13 @@ static void fix_incomplete_types(type_t *complete_type);
static str_list_t *append_str(str_list_t *list, char *str); static str_list_t *append_str(str_list_t *list, char *str);
static attr_list_t *append_attr(attr_list_t *list, attr_t *attr); static attr_list_t *append_attr(attr_list_t *list, attr_t *attr);
static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list); static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list);
static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass); static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right,
attr_t *attr, enum storage_class stgclass, enum type_qualifier qual);
static attr_t *make_attr(enum attr_type type); static attr_t *make_attr(enum attr_type type);
static attr_t *make_attrv(enum attr_type type, unsigned int val); static attr_t *make_attrv(enum attr_type type, unsigned int 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 type_t *append_array(type_t *chain, expr_t *expr); static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_t *decl, int top);
static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl, int top);
static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls); static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls);
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);
@ -74,7 +74,8 @@ static declarator_list_t *append_declarator(declarator_list_t *list, declarator_
static declarator_t *make_declarator(var_t *var); static declarator_t *make_declarator(var_t *var);
static type_t *make_safearray(type_t *type); static type_t *make_safearray(type_t *type);
static typelib_t *make_library(const char *name, const attr_list_t *attrs); static typelib_t *make_library(const char *name, const attr_list_t *attrs);
static type_t *append_chain_type(type_t *chain, type_t *type); static void append_array(declarator_t *decl, expr_t *expr);
static void append_chain_type(declarator_t *decl, type_t *type, enum type_qualifier qual);
static void append_chain_callconv(type_t *chain, char *callconv); static void append_chain_callconv(type_t *chain, char *callconv);
static warning_list_t *append_warning(warning_list_t *, int); static warning_list_t *append_warning(warning_list_t *, int);
@ -158,6 +159,7 @@ static typelib_t *current_typelib;
struct _import_t *import; struct _import_t *import;
struct _decl_spec_t *declspec; struct _decl_spec_t *declspec;
enum storage_class stgclass; enum storage_class stgclass;
enum type_qualifier type_qualifier;
} }
%token <str> aIDENTIFIER aPRAGMA %token <str> aIDENTIFIER aPRAGMA
@ -259,14 +261,15 @@ static typelib_t *current_typelib;
%token tWCHAR tWIREMARSHAL %token tWCHAR tWIREMARSHAL
%token tAPARTMENT tNEUTRAL tSINGLE tFREE tBOTH %token tAPARTMENT tNEUTRAL tSINGLE tFREE tBOTH
%type <attr> attribute type_qualifier function_specifier acf_attribute %type <attr> attribute function_specifier acf_attribute
%type <attr_list> m_attributes attributes attrib_list m_type_qual_list %type <attr_list> m_attributes attributes attrib_list
%type <attr_list> acf_attributes acf_attribute_list %type <attr_list> acf_attributes acf_attribute_list
%type <str_list> str_list %type <str_list> str_list
%type <expr> m_expr expr expr_const expr_int_const array m_bitfield %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_list> m_exprs /* exprs expr_list */ expr_list_int_const
%type <ifinfo> interfacehdr %type <ifinfo> interfacehdr
%type <stgclass> storage_cls_spec %type <stgclass> storage_cls_spec
%type <type_qualifier> type_qualifier m_type_qual_list
%type <declspec> decl_spec decl_spec_no_type m_decl_spec_no_type %type <declspec> decl_spec decl_spec_no_type m_decl_spec_no_type
%type <type> inherit interface interfacedef interfacedec %type <type> inherit interface interfacedef interfacedec
%type <type> dispinterface dispinterfacehdr dispinterfacedef %type <type> dispinterface dispinterfacehdr dispinterfacedef
@ -951,16 +954,16 @@ function_specifier:
; ;
type_qualifier: type_qualifier:
tCONST { $$ = make_attr(ATTR_CONST); } tCONST { $$ = TYPE_QUALIFIER_CONST; }
; ;
m_type_qual_list: { $$ = NULL; } m_type_qual_list: { $$ = 0; }
| m_type_qual_list type_qualifier { $$ = append_attr($1, $2); } | m_type_qual_list type_qualifier { $$ = $1 | $2; }
; ;
decl_spec: type m_decl_spec_no_type { $$ = make_decl_spec($1, $2, NULL, NULL, STG_NONE); } decl_spec: type m_decl_spec_no_type { $$ = make_decl_spec($1, $2, NULL, NULL, STG_NONE, 0); }
| decl_spec_no_type type m_decl_spec_no_type | decl_spec_no_type type m_decl_spec_no_type
{ $$ = make_decl_spec($2, $1, $3, NULL, STG_NONE); } { $$ = make_decl_spec($2, $1, $3, NULL, STG_NONE, 0); }
; ;
m_decl_spec_no_type: { $$ = NULL; } m_decl_spec_no_type: { $$ = NULL; }
@ -968,14 +971,14 @@ m_decl_spec_no_type: { $$ = NULL; }
; ;
decl_spec_no_type: decl_spec_no_type:
type_qualifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, $1, STG_NONE); } type_qualifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, NULL, STG_NONE, $1); }
| function_specifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, $1, STG_NONE); } | function_specifier m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, $1, STG_NONE, 0); }
| storage_cls_spec m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, NULL, $1); } | storage_cls_spec m_decl_spec_no_type { $$ = make_decl_spec(NULL, $2, NULL, NULL, $1, 0); }
; ;
declarator: declarator:
'*' m_type_qual_list declarator %prec PPTR '*' m_type_qual_list declarator %prec PPTR
{ $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); } { $$ = $3; append_chain_type($$, type_new_pointer(pointer_default, NULL), $2); }
| callconv declarator { $$ = $2; append_chain_callconv($$->type, $1); } | callconv declarator { $$ = $2; append_chain_callconv($$->type, $1); }
| direct_declarator | direct_declarator
; ;
@ -983,14 +986,14 @@ declarator:
direct_declarator: direct_declarator:
ident { $$ = make_declarator($1); } ident { $$ = make_declarator($1); }
| '(' declarator ')' { $$ = $2; } | '(' declarator ')' { $$ = $2; }
| direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); } | direct_declarator array { $$ = $1; append_array($$, $2); }
| direct_declarator '(' m_args ')' { $$ = $1; $$->type = append_chain_type($$->type, type_new_function($3)); } | direct_declarator '(' m_args ')' { $$ = $1; append_chain_type($$, type_new_function($3), 0); }
; ;
/* abstract declarator */ /* abstract declarator */
abstract_declarator: abstract_declarator:
'*' m_type_qual_list m_abstract_declarator %prec PPTR '*' m_type_qual_list m_abstract_declarator %prec PPTR
{ $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); } { $$ = $3; append_chain_type($$, type_new_pointer(pointer_default, NULL), $2); }
| callconv m_abstract_declarator { $$ = $2; append_chain_callconv($$->type, $1); } | callconv m_abstract_declarator { $$ = $2; append_chain_callconv($$->type, $1); }
| abstract_direct_declarator | abstract_direct_declarator
; ;
@ -998,7 +1001,7 @@ abstract_declarator:
/* abstract declarator without accepting direct declarator */ /* abstract declarator without accepting direct declarator */
abstract_declarator_no_direct: abstract_declarator_no_direct:
'*' m_type_qual_list m_any_declarator %prec PPTR '*' m_type_qual_list m_any_declarator %prec PPTR
{ $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); } { $$ = $3; append_chain_type($$, type_new_pointer(pointer_default, NULL), $2); }
| callconv m_any_declarator { $$ = $2; append_chain_callconv($$->type, $1); } | callconv m_any_declarator { $$ = $2; append_chain_callconv($$->type, $1); }
; ;
@ -1010,22 +1013,22 @@ m_abstract_declarator: { $$ = make_declarator(NULL); }
/* abstract direct declarator */ /* abstract direct declarator */
abstract_direct_declarator: abstract_direct_declarator:
'(' abstract_declarator_no_direct ')' { $$ = $2; } '(' abstract_declarator_no_direct ')' { $$ = $2; }
| abstract_direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); } | abstract_direct_declarator array { $$ = $1; append_array($$, $2); }
| array { $$ = make_declarator(NULL); $$->type = append_array($$->type, $1); } | array { $$ = make_declarator(NULL); append_array($$, $1); }
| '(' m_args ')' | '(' m_args ')'
{ $$ = make_declarator(NULL); { $$ = make_declarator(NULL);
$$->type = append_chain_type($$->type, type_new_function($2)); append_chain_type($$, type_new_function($2), 0);
} }
| abstract_direct_declarator '(' m_args ')' | abstract_direct_declarator '(' m_args ')'
{ $$ = $1; { $$ = $1;
$$->type = append_chain_type($$->type, type_new_function($3)); append_chain_type($$, type_new_function($3), 0);
} }
; ;
/* abstract or non-abstract declarator */ /* abstract or non-abstract declarator */
any_declarator: any_declarator:
'*' m_type_qual_list m_any_declarator %prec PPTR '*' m_type_qual_list m_any_declarator %prec PPTR
{ $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); } { $$ = $3; append_chain_type($$, type_new_pointer(pointer_default, NULL), $2); }
| callconv m_any_declarator { $$ = $2; append_chain_callconv($$->type, $1); } | callconv m_any_declarator { $$ = $2; append_chain_callconv($$->type, $1); }
| any_direct_declarator | any_direct_declarator
; ;
@ -1033,7 +1036,7 @@ any_declarator:
/* abstract or non-abstract declarator without accepting direct declarator */ /* abstract or non-abstract declarator without accepting direct declarator */
any_declarator_no_direct: any_declarator_no_direct:
'*' m_type_qual_list m_any_declarator %prec PPTR '*' m_type_qual_list m_any_declarator %prec PPTR
{ $$ = $3; $$->type = append_chain_type($$->type, type_new_pointer(pointer_default, NULL, $2)); } { $$ = $3; append_chain_type($$, type_new_pointer(pointer_default, NULL), $2); }
| callconv m_any_declarator { $$ = $2; append_chain_callconv($$->type, $1); } | callconv m_any_declarator { $$ = $2; append_chain_callconv($$->type, $1); }
; ;
@ -1048,15 +1051,15 @@ m_any_declarator: { $$ = make_declarator(NULL); }
any_direct_declarator: any_direct_declarator:
ident { $$ = make_declarator($1); } ident { $$ = make_declarator($1); }
| '(' any_declarator_no_direct ')' { $$ = $2; } | '(' any_declarator_no_direct ')' { $$ = $2; }
| any_direct_declarator array { $$ = $1; $$->type = append_array($$->type, $2); } | any_direct_declarator array { $$ = $1; append_array($$, $2); }
| array { $$ = make_declarator(NULL); $$->type = append_array($$->type, $1); } | array { $$ = make_declarator(NULL); append_array($$, $1); }
| '(' m_args ')' | '(' m_args ')'
{ $$ = make_declarator(NULL); { $$ = make_declarator(NULL);
$$->type = append_chain_type($$->type, type_new_function($2)); append_chain_type($$, type_new_function($2), 0);
} }
| any_direct_declarator '(' m_args ')' | any_direct_declarator '(' m_args ')'
{ $$ = $1; { $$ = $1;
$$->type = append_chain_type($$->type, type_new_function($3)); append_chain_type($$, type_new_function($3), 0);
} }
; ;
@ -1281,7 +1284,8 @@ static attr_list_t *map_attrs(const attr_list_t *list, map_attrs_filter_t filter
return new_list; return new_list;
} }
static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right, attr_t *attr, enum storage_class stgclass) static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t *right,
attr_t *attr, enum storage_class stgclass, enum type_qualifier qual)
{ {
decl_spec_t *declspec = left ? left : right; decl_spec_t *declspec = left ? left : right;
if (!declspec) if (!declspec)
@ -1290,6 +1294,7 @@ static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t
declspec->type = NULL; declspec->type = NULL;
declspec->attrs = NULL; declspec->attrs = NULL;
declspec->stgclass = STG_NONE; declspec->stgclass = STG_NONE;
declspec->qualifier = 0;
} }
declspec->type = type; declspec->type = type;
if (left && declspec != left) if (left && declspec != left)
@ -1299,6 +1304,7 @@ static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t
declspec->stgclass = left->stgclass; declspec->stgclass = left->stgclass;
else if (left->stgclass != STG_NONE) else if (left->stgclass != STG_NONE)
error_loc("only one storage class can be specified\n"); error_loc("only one storage class can be specified\n");
declspec->qualifier |= left->qualifier;
assert(!left->type); assert(!left->type);
free(left); free(left);
} }
@ -1309,6 +1315,7 @@ static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t
declspec->stgclass = right->stgclass; declspec->stgclass = right->stgclass;
else if (right->stgclass != STG_NONE) else if (right->stgclass != STG_NONE)
error_loc("only one storage class can be specified\n"); error_loc("only one storage class can be specified\n");
declspec->qualifier |= right->qualifier;
assert(!right->type); assert(!right->type);
free(right); free(right);
} }
@ -1318,6 +1325,7 @@ static decl_spec_t *make_decl_spec(type_t *type, decl_spec_t *left, decl_spec_t
declspec->stgclass = stgclass; declspec->stgclass = stgclass;
else if (stgclass != STG_NONE) else if (stgclass != STG_NONE)
error_loc("only one storage class can be specified\n"); error_loc("only one storage class can be specified\n");
declspec->qualifier |= qual;
/* apply attributes to type */ /* apply attributes to type */
if (type && declspec->attrs) if (type && declspec->attrs)
@ -1368,19 +1376,19 @@ static expr_list_t *append_expr(expr_list_t *list, expr_t *expr)
return list; return list;
} }
static type_t *append_array(type_t *chain, expr_t *expr) static void append_array(declarator_t *decl, expr_t *expr)
{ {
type_t *array; type_t *array;
if (!expr) if (!expr)
return chain; return;
/* An array is always a reference pointer unless explicitly marked otherwise /* An array is always a reference pointer unless explicitly marked otherwise
* (regardless of what the default pointer attribute is). */ * (regardless of what the default pointer attribute is). */
array = type_new_array(NULL, NULL, FALSE, expr->is_const ? expr->cval : 0, array = type_new_array(NULL, NULL, FALSE, expr->is_const ? expr->cval : 0,
expr->is_const ? NULL : expr, NULL, FC_RP); expr->is_const ? NULL : expr, NULL, FC_RP);
return append_chain_type(chain, array); append_chain_type(decl, array, 0);
} }
static struct list type_pool = LIST_INIT(type_pool); static struct list type_pool = LIST_INIT(type_pool);
@ -1473,27 +1481,38 @@ static type_t *get_chain_end(type_t *type)
return type; return type;
} }
static type_t *append_chain_type(type_t *chain, type_t *type) static void append_chain_type(declarator_t *decl, type_t *type, enum type_qualifier qual)
{ {
type_t *chain_type; type_t *chain_type;
if (!chain) if (!decl->type)
return type; {
chain_type = get_chain_end(chain); decl->type = type;
decl->qualifier = qual;
return;
}
chain_type = get_chain_end(decl->type);
if (is_ptr(chain_type)) if (is_ptr(chain_type))
{
chain_type->details.pointer.ref.type = type; chain_type->details.pointer.ref.type = type;
chain_type->details.pointer.ref.qualifier = qual;
}
else if (is_array(chain_type)) else if (is_array(chain_type))
{
chain_type->details.array.elem.type = type; chain_type->details.array.elem.type = type;
chain_type->details.array.elem.qualifier = qual;
}
else if (is_func(chain_type)) else if (is_func(chain_type))
{
chain_type->details.function->retval->declspec.type = type; chain_type->details.function->retval->declspec.type = type;
chain_type->details.function->retval->declspec.qualifier = qual;
}
else else
assert(0); assert(0);
if (!is_func(chain_type)) if (!is_func(chain_type))
type->attrs = move_attr(type->attrs, chain_type->attrs, ATTR_CALLCONV); type->attrs = move_attr(type->attrs, chain_type->attrs, ATTR_CALLCONV);
return chain;
} }
static void append_chain_callconv(type_t *chain, char *callconv) static void append_chain_callconv(type_t *chain, char *callconv)
@ -1521,7 +1540,7 @@ static warning_list_t *append_warning(warning_list_t *list, int num)
return list; return list;
} }
static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const declarator_t *decl, static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_t *decl,
int top) int top)
{ {
var_t *v = decl->var; var_t *v = decl->var;
@ -1540,8 +1559,10 @@ static var_t *declare_var(attr_list_t *attrs, decl_spec_t *decl_spec, const decl
} }
/* add type onto the end of the pointers in pident->type */ /* add type onto the end of the pointers in pident->type */
v->declspec.type = append_chain_type(decl ? decl->type : NULL, type); append_chain_type(decl, type, decl_spec->qualifier);
v->declspec.stgclass = decl_spec->stgclass; v->declspec = *decl_spec;
v->declspec.type = decl->type;
v->declspec.qualifier = decl->qualifier;
v->attrs = attrs; v->attrs = attrs;
if (is_attr(type->attrs, ATTR_CALLCONV) && !is_func(type)) if (is_attr(type->attrs, ATTR_CALLCONV) && !is_func(type))
@ -1778,6 +1799,7 @@ static declarator_t *make_declarator(var_t *var)
declarator_t *d = xmalloc(sizeof(*d)); declarator_t *d = xmalloc(sizeof(*d));
d->var = var ? var : make_var(NULL); d->var = var ? var : make_var(NULL);
d->type = NULL; d->type = NULL;
d->qualifier = 0;
d->bits = NULL; d->bits = NULL;
return d; return d;
} }
@ -1912,7 +1934,7 @@ static void fix_incomplete_types(type_t *complete_type)
static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, attr_list_t *attrs) static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, attr_list_t *attrs)
{ {
const declarator_t *decl; declarator_t *decl;
type_t *type = decl_spec->type; type_t *type = decl_spec->type;
if (is_attr(attrs, ATTR_UUID) && !is_attr(attrs, ATTR_PUBLIC)) if (is_attr(attrs, ATTR_UUID) && !is_attr(attrs, ATTR_PUBLIC))
@ -1934,7 +1956,7 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
type->attrs = attrs; type->attrs = attrs;
} }
LIST_FOR_EACH_ENTRY( decl, decls, const declarator_t, entry ) LIST_FOR_EACH_ENTRY( decl, decls, declarator_t, entry )
{ {
if (decl->var->name) { if (decl->var->name) {
@ -2126,7 +2148,6 @@ struct allowed_attr allowed_attr[] =
/* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" }, /* ATTR_CASE */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
/* ATTR_CODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" }, /* ATTR_CODE */ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "code" },
/* ATTR_COMMSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" }, /* ATTR_COMMSTATUS */ { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, "comm_status" },
/* ATTR_CONST */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "const" },
/* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" }, /* ATTR_CONTEXTHANDLE */ { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "context_handle" },
/* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" }, /* ATTR_CONTROL */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
/* ATTR_DECODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "decode" }, /* ATTR_DECODE */ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "decode" },

View File

@ -176,12 +176,11 @@ type_t *type_new_function(var_list_t *args)
return t; return t;
} }
type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs) type_t *type_new_pointer(unsigned char pointer_default, type_t *ref)
{ {
type_t *t = make_type(TYPE_POINTER); type_t *t = make_type(TYPE_POINTER);
t->details.pointer.def_fc = pointer_default; t->details.pointer.def_fc = pointer_default;
t->details.pointer.ref.type = ref; t->details.pointer.ref.type = ref;
t->attrs = attrs;
return t; return t;
} }

View File

@ -30,7 +30,7 @@ enum name_type {
}; };
type_t *type_new_function(var_list_t *args); type_t *type_new_function(var_list_t *args);
type_t *type_new_pointer(unsigned char pointer_default, type_t *ref, attr_list_t *attrs); type_t *type_new_pointer(unsigned char pointer_default, type_t *ref);
type_t *type_new_alias(const decl_spec_t *t, const char *name); type_t *type_new_alias(const decl_spec_t *t, const char *name);
type_t *type_new_module(char *name); type_t *type_new_module(char *name);
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,

View File

@ -81,7 +81,6 @@ enum attr_type
ATTR_CASE, ATTR_CASE,
ATTR_CODE, ATTR_CODE,
ATTR_COMMSTATUS, ATTR_COMMSTATUS,
ATTR_CONST, /* const pseudo-attribute */
ATTR_CONTEXTHANDLE, ATTR_CONTEXTHANDLE,
ATTR_CONTROL, ATTR_CONTROL,
ATTR_DECODE, ATTR_DECODE,
@ -235,6 +234,11 @@ enum storage_class
STG_REGISTER, STG_REGISTER,
}; };
enum type_qualifier
{
TYPE_QUALIFIER_CONST = 1,
};
enum statement_type enum statement_type
{ {
STMT_LIBRARY, STMT_LIBRARY,
@ -299,6 +303,7 @@ struct _decl_spec_t
type_t *type; type_t *type;
attr_list_t *attrs; attr_list_t *attrs;
enum storage_class stgclass; enum storage_class stgclass;
enum type_qualifier qualifier;
}; };
struct _attr_t { struct _attr_t {
@ -478,6 +483,7 @@ struct _var_t {
struct _declarator_t { struct _declarator_t {
var_t *var; var_t *var;
type_t *type; type_t *type;
enum type_qualifier qualifier;
expr_t *bits; expr_t *bits;
/* parser-internal */ /* parser-internal */
@ -626,6 +632,7 @@ static inline decl_spec_t *init_declspec(decl_spec_t *declspec, type_t *type)
declspec->type = type; declspec->type = type;
declspec->attrs = NULL; declspec->attrs = NULL;
declspec->stgclass = STG_NONE; declspec->stgclass = STG_NONE;
declspec->qualifier = 0;
return declspec; return declspec;
} }