widl: Use type_get_type to determine the types of types during parsing and checking.
This commit is contained in:
parent
d854f32283
commit
0f7f7922ba
|
@ -813,7 +813,7 @@ int_std: tINT { $$ = make_builtin($<str>1); }
|
||||||
|
|
||||||
coclass: tCOCLASS aIDENTIFIER { $$ = make_class($2); }
|
coclass: tCOCLASS aIDENTIFIER { $$ = make_class($2); }
|
||||||
| tCOCLASS aKNOWNTYPE { $$ = find_type($2, 0);
|
| tCOCLASS aKNOWNTYPE { $$ = find_type($2, 0);
|
||||||
if ($$->type != RPC_FC_COCLASS)
|
if (type_get_type_detect_alias($$) != TYPE_COCLASS)
|
||||||
error_loc("%s was not declared a coclass at %s:%d\n",
|
error_loc("%s was not declared a coclass at %s:%d\n",
|
||||||
$2, $$->loc_info.input_name,
|
$2, $$->loc_info.input_name,
|
||||||
$$->loc_info.line_number);
|
$$->loc_info.line_number);
|
||||||
|
@ -1470,7 +1470,7 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
|
||||||
|
|
||||||
if (is_attr(v->attrs, ATTR_V1ENUM))
|
if (is_attr(v->attrs, ATTR_V1ENUM))
|
||||||
{
|
{
|
||||||
if (v->type->type == RPC_FC_ENUM16)
|
if (type_get_type_detect_alias(v->type) == TYPE_ENUM)
|
||||||
v->type->type = RPC_FC_ENUM32;
|
v->type->type = RPC_FC_ENUM32;
|
||||||
else
|
else
|
||||||
error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name);
|
error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name);
|
||||||
|
@ -1565,7 +1565,7 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
|
||||||
v->type = func_type;
|
v->type = func_type;
|
||||||
for (ft = v->type; is_ptr(ft); ft = type_pointer_get_ref(ft))
|
for (ft = v->type; is_ptr(ft); ft = type_pointer_get_ref(ft))
|
||||||
;
|
;
|
||||||
assert(ft->type == RPC_FC_FUNCTION);
|
assert(type_get_type_detect_alias(ft) == TYPE_FUNCTION);
|
||||||
ft->ref = return_type;
|
ft->ref = return_type;
|
||||||
/* move calling convention attribute, if present, from pointer nodes to
|
/* move calling convention attribute, if present, from pointer nodes to
|
||||||
* function node */
|
* function node */
|
||||||
|
@ -1771,7 +1771,10 @@ static type_t *reg_type(type_t *type, const char *name, int t)
|
||||||
|
|
||||||
static int is_incomplete(const type_t *t)
|
static int is_incomplete(const type_t *t)
|
||||||
{
|
{
|
||||||
return !t->defined && (is_struct(t->type) || is_union(t->type));
|
return !t->defined &&
|
||||||
|
(type_get_type_detect_alias(t) == TYPE_STRUCT ||
|
||||||
|
type_get_type_detect_alias(t) == TYPE_UNION ||
|
||||||
|
type_get_type_detect_alias(t) == TYPE_ENCAPSULATED_UNION);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_incomplete(type_t *t)
|
static void add_incomplete(type_t *t)
|
||||||
|
@ -1786,7 +1789,9 @@ static void fix_type(type_t *t)
|
||||||
if (type_is_alias(t) && is_incomplete(t)) {
|
if (type_is_alias(t) && is_incomplete(t)) {
|
||||||
type_t *ot = type_alias_get_aliasee(t);
|
type_t *ot = type_alias_get_aliasee(t);
|
||||||
fix_type(ot);
|
fix_type(ot);
|
||||||
if (is_struct(ot->type) || is_union(ot->type))
|
if (type_get_type_detect_alias(ot) == TYPE_STRUCT ||
|
||||||
|
type_get_type_detect_alias(ot) == TYPE_UNION ||
|
||||||
|
type_get_type_detect_alias(ot) == TYPE_ENCAPSULATED_UNION)
|
||||||
t->details.structure = ot->details.structure;
|
t->details.structure = ot->details.structure;
|
||||||
t->defined = ot->defined;
|
t->defined = ot->defined;
|
||||||
}
|
}
|
||||||
|
@ -1809,12 +1814,9 @@ static void fix_incomplete_types(type_t *complete_type)
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY_SAFE(tn, next, &incomplete_types, struct typenode, entry)
|
LIST_FOR_EACH_ENTRY_SAFE(tn, next, &incomplete_types, struct typenode, entry)
|
||||||
{
|
{
|
||||||
if (((is_struct(complete_type->type) && is_struct(tn->type->type)) ||
|
if (type_is_equal(complete_type, tn->type))
|
||||||
(is_union(complete_type->type) && is_union(tn->type->type))) &&
|
|
||||||
!strcmp(complete_type->name, tn->type->name))
|
|
||||||
{
|
{
|
||||||
tn->type->details.structure = complete_type->details.structure;
|
tn->type->details.structure = complete_type->details.structure;
|
||||||
tn->type->type = complete_type->type;
|
|
||||||
list_remove(&tn->entry);
|
list_remove(&tn->entry);
|
||||||
free(tn);
|
free(tn);
|
||||||
}
|
}
|
||||||
|
@ -1830,13 +1832,14 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
|
||||||
if (is_str)
|
if (is_str)
|
||||||
{
|
{
|
||||||
type_t *t = decl_spec->type;
|
type_t *t = decl_spec->type;
|
||||||
unsigned char c;
|
|
||||||
|
|
||||||
while (is_ptr(t))
|
while (is_ptr(t))
|
||||||
t = type_pointer_get_ref(t);
|
t = type_pointer_get_ref(t);
|
||||||
|
|
||||||
c = t->type;
|
if (type_get_type(t) != TYPE_BASIC &&
|
||||||
if (c != RPC_FC_CHAR && c != RPC_FC_BYTE && c != RPC_FC_WCHAR)
|
(type_basic_get_fc(t) != RPC_FC_CHAR &&
|
||||||
|
type_basic_get_fc(t) != RPC_FC_BYTE &&
|
||||||
|
type_basic_get_fc(t) != RPC_FC_WCHAR))
|
||||||
{
|
{
|
||||||
decl = LIST_ENTRY( list_head( decls ), const declarator_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",
|
||||||
|
@ -1847,8 +1850,10 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
|
||||||
/* We must generate names for tagless enum, struct or union.
|
/* We must generate names for tagless enum, struct or union.
|
||||||
Typedef-ing a tagless enum, struct or union means we want the typedef
|
Typedef-ing a tagless enum, struct or union means we want the typedef
|
||||||
to be included in a library hence the public attribute. */
|
to be included in a library hence the public attribute. */
|
||||||
if ((type->type == RPC_FC_ENUM16 || type->type == RPC_FC_ENUM32 ||
|
if ((type_get_type_detect_alias(type) == TYPE_ENUM ||
|
||||||
is_struct(type->type) || is_union(type->type)) &&
|
type_get_type_detect_alias(type) == TYPE_STRUCT ||
|
||||||
|
type_get_type_detect_alias(type) == TYPE_UNION ||
|
||||||
|
type_get_type_detect_alias(type) == TYPE_ENCAPSULATED_UNION) &&
|
||||||
!type->name && !parse_only)
|
!type->name && !parse_only)
|
||||||
{
|
{
|
||||||
if (! is_attr(attrs, ATTR_PUBLIC))
|
if (! is_attr(attrs, ATTR_PUBLIC))
|
||||||
|
@ -2127,7 +2132,7 @@ static void check_arg(var_t *arg)
|
||||||
const type_t *t = arg->type;
|
const type_t *t = arg->type;
|
||||||
const attr_t *attr;
|
const attr_t *attr;
|
||||||
|
|
||||||
if (t->type == 0 && ! is_var_ptr(arg))
|
if (type_get_type(t) == TYPE_VOID)
|
||||||
error_loc("argument '%s' has void type\n", arg->name);
|
error_loc("argument '%s' has void type\n", arg->name);
|
||||||
|
|
||||||
if (arg->attrs)
|
if (arg->attrs)
|
||||||
|
@ -2260,23 +2265,44 @@ static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs)
|
||||||
|
|
||||||
static int is_allowed_conf_type(const type_t *type)
|
static int is_allowed_conf_type(const type_t *type)
|
||||||
{
|
{
|
||||||
switch (type->type)
|
switch (type_get_type(type))
|
||||||
{
|
{
|
||||||
case RPC_FC_CHAR:
|
case TYPE_ENUM:
|
||||||
case RPC_FC_SMALL:
|
|
||||||
case RPC_FC_BYTE:
|
|
||||||
case RPC_FC_USMALL:
|
|
||||||
case RPC_FC_WCHAR:
|
|
||||||
case RPC_FC_SHORT:
|
|
||||||
case RPC_FC_ENUM16:
|
|
||||||
case RPC_FC_USHORT:
|
|
||||||
case RPC_FC_LONG:
|
|
||||||
case RPC_FC_ENUM32:
|
|
||||||
case RPC_FC_ULONG:
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
default:
|
case TYPE_BASIC:
|
||||||
|
switch (type_basic_get_fc(type))
|
||||||
|
{
|
||||||
|
case RPC_FC_CHAR:
|
||||||
|
case RPC_FC_SMALL:
|
||||||
|
case RPC_FC_BYTE:
|
||||||
|
case RPC_FC_USMALL:
|
||||||
|
case RPC_FC_WCHAR:
|
||||||
|
case RPC_FC_SHORT:
|
||||||
|
case RPC_FC_USHORT:
|
||||||
|
case RPC_FC_LONG:
|
||||||
|
case RPC_FC_ULONG:
|
||||||
|
case RPC_FC_ERROR_STATUS_T:
|
||||||
|
return TRUE;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
case TYPE_ALIAS:
|
||||||
|
/* shouldn't get here because of type_get_type call above */
|
||||||
|
assert(0);
|
||||||
|
/* fall through */
|
||||||
|
case TYPE_STRUCT:
|
||||||
|
case TYPE_UNION:
|
||||||
|
case TYPE_ENCAPSULATED_UNION:
|
||||||
|
case TYPE_ARRAY:
|
||||||
|
case TYPE_POINTER:
|
||||||
|
case TYPE_VOID:
|
||||||
|
case TYPE_MODULE:
|
||||||
|
case TYPE_COCLASS:
|
||||||
|
case TYPE_FUNCTION:
|
||||||
|
case TYPE_INTERFACE:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int is_ptr_guid_type(const type_t *type)
|
static int is_ptr_guid_type(const type_t *type)
|
||||||
|
@ -2320,12 +2346,23 @@ static void check_field_common(const type_t *container_type,
|
||||||
int is_context_handle = 0;
|
int is_context_handle = 0;
|
||||||
const char *container_type_name = NULL;
|
const char *container_type_name = NULL;
|
||||||
|
|
||||||
if (is_struct(container_type->type))
|
switch (type_get_type_detect_alias(type))
|
||||||
|
{
|
||||||
|
case TYPE_STRUCT:
|
||||||
container_type_name = "struct";
|
container_type_name = "struct";
|
||||||
else if (is_union(container_type->type))
|
break;
|
||||||
|
case TYPE_UNION:
|
||||||
container_type_name = "union";
|
container_type_name = "union";
|
||||||
else if (container_type->type == RPC_FC_FUNCTION)
|
break;
|
||||||
|
case TYPE_ENCAPSULATED_UNION:
|
||||||
|
container_type_name = "encapsulated union";
|
||||||
|
break;
|
||||||
|
case TYPE_FUNCTION:
|
||||||
container_type_name = "function";
|
container_type_name = "function";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (is_attr(arg->attrs, ATTR_LENGTHIS) &&
|
if (is_attr(arg->attrs, ATTR_LENGTHIS) &&
|
||||||
(is_attr(arg->attrs, ATTR_STRING) || is_aliaschain_attr(arg->type, ATTR_STRING)))
|
(is_attr(arg->attrs, ATTR_STRING) || is_aliaschain_attr(arg->type, ATTR_STRING)))
|
||||||
|
@ -2396,11 +2433,11 @@ static void check_field_common(const type_t *container_type,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type->type == 0 && !is_attr(arg->attrs, ATTR_IIDIS) && !is_wire_marshal && !is_context_handle)
|
if (type_get_type(type) == TYPE_VOID && !is_attr(arg->attrs, ATTR_IIDIS) && !is_wire_marshal && !is_context_handle)
|
||||||
error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot derive from void *\n", arg->name, container_type_name, container_name);
|
error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot derive from void *\n", arg->name, container_type_name, container_name);
|
||||||
else if (type->type == RPC_FC_FUNCTION)
|
else if (type_get_type(type) == TYPE_FUNCTION)
|
||||||
error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot be a function pointer\n", arg->name, container_type_name, container_name);
|
error_loc_info(&arg->loc_info, "parameter \'%s\' of %s \'%s\' cannot be a function pointer\n", arg->name, container_type_name, container_name);
|
||||||
else if (!is_wire_marshal && (is_struct(type->type) || is_union(type->type)))
|
else if (!is_wire_marshal && (type_get_type(type) == TYPE_STRUCT || type_get_type(type) == TYPE_UNION || type_get_type(type) == TYPE_ENCAPSULATED_UNION))
|
||||||
check_remoting_fields(arg, type);
|
check_remoting_fields(arg, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2416,14 +2453,14 @@ static void check_remoting_fields(const var_t *var, type_t *type)
|
||||||
|
|
||||||
type->checked = TRUE;
|
type->checked = TRUE;
|
||||||
|
|
||||||
if (is_struct(type->type))
|
if (type_get_type(type) == TYPE_STRUCT)
|
||||||
{
|
{
|
||||||
if (type_is_complete(type))
|
if (type_is_complete(type))
|
||||||
fields = type_struct_get_fields(type);
|
fields = type_struct_get_fields(type);
|
||||||
else
|
else
|
||||||
error_loc_info(&var->loc_info, "undefined type declaration %s\n", type->name);
|
error_loc_info(&var->loc_info, "undefined type declaration %s\n", type->name);
|
||||||
}
|
}
|
||||||
else if (is_union(type->type))
|
else if (type_get_type(type) == TYPE_UNION || type_get_type(type) == TYPE_ENCAPSULATED_UNION)
|
||||||
fields = type_union_get_cases(type);
|
fields = type_union_get_cases(type);
|
||||||
|
|
||||||
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
|
if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
|
||||||
|
@ -2466,7 +2503,7 @@ static void check_remoting_args(const var_t *func)
|
||||||
{
|
{
|
||||||
if (!ptr_level)
|
if (!ptr_level)
|
||||||
error_loc_info(&arg->loc_info, "out parameter \'%s\' of function \'%s\' is not a pointer\n", arg->name, funcname);
|
error_loc_info(&arg->loc_info, "out parameter \'%s\' of function \'%s\' is not a pointer\n", arg->name, funcname);
|
||||||
if (type->type == RPC_FC_IP && ptr_level == 1)
|
if (type_get_type(type) == TYPE_INTERFACE && ptr_level == 1)
|
||||||
error_loc_info(&arg->loc_info, "out interface pointer \'%s\' of function \'%s\' is not a double pointer\n", arg->name, funcname);
|
error_loc_info(&arg->loc_info, "out interface pointer \'%s\' of function \'%s\' is not a double pointer\n", arg->name, funcname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2608,7 +2645,7 @@ static statement_t *make_statement_declaration(var_t *var)
|
||||||
reg_const(var);
|
reg_const(var);
|
||||||
}
|
}
|
||||||
else if ((var->stgclass == STG_NONE || var->stgclass == STG_REGISTER) &&
|
else if ((var->stgclass == STG_NONE || var->stgclass == STG_REGISTER) &&
|
||||||
var->type->type != RPC_FC_FUNCTION)
|
type_get_type(var->type) != TYPE_FUNCTION)
|
||||||
error_loc("instantiation of data is illegal\n");
|
error_loc("instantiation of data is illegal\n");
|
||||||
return stmt;
|
return stmt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "widl.h"
|
#include "widl.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
@ -158,3 +159,18 @@ type_t *type_coclass_define(type_t *coclass, ifref_list_t *ifaces)
|
||||||
coclass->defined = TRUE;
|
coclass->defined = TRUE;
|
||||||
return coclass;
|
return coclass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (type1->name && type2->name)
|
||||||
|
return !strcmp(type1->name, type2->name);
|
||||||
|
else if ((!type1->name && type2->name) || (type1->name && !type2->name))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* FIXME: do deep inspection of types to determine if they are equal */
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ void type_dispinterface_define(type_t *iface, var_list_t *props, func_list_t *me
|
||||||
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);
|
||||||
|
int type_is_equal(const type_t *type1, const type_t *type2);
|
||||||
|
|
||||||
/* 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);
|
||||||
|
|
Loading…
Reference in New Issue