static type_t *reg_type(type_t *type, const char *name, int t);
static type_t *reg_typedefs(decl_spec_t *decl_spec, var_list_t *names, attr_list_t *attrs);
-static type_t *find_type_or_error(const char *name, int t);
-static type_t *find_type_or_error2(char *name, int t);
+static type_t *find_type2(char *name, int t);
static type_t *get_type(unsigned char type, char *name, int t);
static type_t *get_typev(unsigned char type, var_t *name, int t);
static int get_struct_type(var_list_t *fields);
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);
-static void check_def(const type_t *t);
static statement_t *make_statement(enum statement_type type);
static statement_t *make_statement_type_decl(type_t *type);
%type <type> dispinterface dispinterfacehdr dispinterfacedef
%type <type> module modulehdr moduledef
%type <type> base_type int_std
-%type <type> enumdef structdef uniondef typedecl
+%type <type> enumdef structdef uniondef
%type <type> type
%type <ifref> coclass_int
%type <ifref_list> coclass_ints
statement:
cppquote { $$ = make_statement_cppquote($1); }
- | typedecl ';' { $$ = make_statement_type_decl($1);
+ | enumdef ';' { $$ = make_statement_type_decl($1);
if (!parse_only && do_header) {
write_type_def_or_decl(header, $1, FALSE, NULL);
fprintf(header, ";\n\n");
if (!parse_only && do_header) write_declaration($1, is_in_interface);
}
| import { $$ = make_statement_import($1); }
+ | structdef ';' { $$ = make_statement_type_decl($1);
+ if (!parse_only && do_header) {
+ write_type_def_or_decl(header, $1, FALSE, NULL);
+ fprintf(header, ";\n\n");
+ }
+ }
| typedef ';' { $$ = $1; }
- ;
-
-typedecl:
- enumdef
- | structdef
- | uniondef
+ | uniondef ';' { $$ = make_statement_type_decl($1);
+ if (!parse_only && do_header) {
+ write_type_def_or_decl(header, $1, FALSE, NULL);
+ fprintf(header, ";\n\n");
+ }
+ }
;
cppquote: tCPPQUOTE '(' aSTRING ')' { $$ = $3; if (!parse_only && do_header) fprintf(header, "%s\n", $3); }
}
| tUNSIGNED { $$ = make_int(-1); }
| tFLOAT { $$ = make_builtin($<str>1); }
- | tSINGLE { $$ = find_type("float", 0); }
+ | tSINGLE { $$ = duptype(find_type("float", 0), 1); }
| tDOUBLE { $$ = make_builtin($<str>1); }
| tBOOLEAN { $$ = make_builtin($<str>1); }
| tERRORSTATUST { $$ = make_builtin($<str>1); }
coclass: tCOCLASS aIDENTIFIER { $$ = make_class($2); }
| tCOCLASS aKNOWNTYPE { $$ = find_type($2, 0);
- if ($$->kind != TKIND_COCLASS)
- error_loc("%s was not declared a coclass at %s:%d\n",
- $2, $$->loc_info.input_name,
- $$->loc_info.line_number);
+ if ($$->defined) error_loc("multiple definition error\n");
+ if ($$->kind != TKIND_COCLASS) error_loc("%s was not declared a coclass\n", $2);
}
;
coclasshdr: attributes coclass { $$ = $2;
- check_def($$);
$$->attrs = check_coclass_attrs($2->name, $1);
if (!parse_only && do_header)
write_coclass($$);
is_in_interface = TRUE;
is_object_interface = TRUE;
$$ = $2;
- check_def($$);
+ if ($$->defined) error_loc("multiple definition error\n");
attrs = make_attr(ATTR_DISPINTERFACE);
$$->attrs = append_attr( check_dispiface_attrs($2->name, $1), attrs );
$$->ref = find_type("IDispatch", 0);
;
inherit: { $$ = NULL; }
- | ':' aKNOWNTYPE { $$ = find_type_or_error2($2, 0); }
+ | ':' aKNOWNTYPE { $$ = find_type2($2, 0); }
;
interface: tINTERFACE aIDENTIFIER { $$ = get_type(RPC_FC_IP, $2, 0); $$->kind = TKIND_INTERFACE; }
pointer_default = get_attrv($1, ATTR_POINTERDEFAULT);
is_object_interface = is_object($1);
is_in_interface = TRUE;
- check_def($2);
+ if ($2->defined) error_loc("multiple definition error\n");
$2->attrs = check_iface_attrs($2->name, $1);
$2->defined = TRUE;
if (!parse_only && do_header) write_forward($2);
| interfacehdr ':' aIDENTIFIER
'{' import int_statements '}'
semicolon_opt { $$ = $1.interface;
- $$->ref = find_type_or_error2($3, 0);
+ $$->ref = find_type2($3, 0);
if (!$$->ref) error_loc("base class '%s' not found in import\n", $3);
$$->funcs = $6;
compute_method_indexes($$);
structdef: tSTRUCT t_ident '{' fields '}' { $$ = get_typev(RPC_FC_STRUCT, $2, tsSTRUCT);
/* overwrite RPC_FC_STRUCT with a more exact type */
- check_def($$);
$$->type = get_struct_type( $4 );
$$->kind = TKIND_RECORD;
$$->fields_or_args = $4;
}
;
-type: tVOID { $$ = find_type_or_error("void", 0); }
- | aKNOWNTYPE { $$ = find_type_or_error($1, 0); }
+type: tVOID { $$ = duptype(find_type("void", 0), 1); }
+ | aKNOWNTYPE { $$ = find_type($1, 0); }
| base_type { $$ = $1; }
| enumdef { $$ = $1; }
- | tENUM aIDENTIFIER { $$ = find_type_or_error2($2, tsENUM); }
+ | tENUM aIDENTIFIER { $$ = find_type2($2, tsENUM); }
| structdef { $$ = $1; }
| tSTRUCT aIDENTIFIER { $$ = get_type(RPC_FC_STRUCT, $2, tsSTRUCT); }
| uniondef { $$ = $1; }
- | tUNION aIDENTIFIER { $$ = find_type_or_error2($2, tsUNION); }
+ | tUNION aIDENTIFIER { $$ = find_type2($2, tsUNION); }
| tSAFEARRAY '(' type ')' { $$ = make_safearray($3); }
;
uniondef: tUNION t_ident '{' ne_union_fields '}'
{ $$ = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, $2, tsUNION);
- check_def($$);
$$->kind = TKIND_UNION;
$$->fields_or_args = $4;
$$->defined = TRUE;
tSWITCH '(' s_field ')'
m_ident '{' cases '}' { var_t *u = $7;
$$ = get_typev(RPC_FC_ENCAPSULATED_UNION, $2, tsUNION);
- check_def($$);
$$->kind = TKIND_UNION;
if (!u) u = make_var( xstrdup("tagged_union") );
u->type = make_type(RPC_FC_NON_ENCAPSULATED_UNION, NULL);
static type_t *make_builtin(char *name)
{
/* NAME is strdup'd in the lexer */
- type_t *t = duptype(find_type_or_error(name, 0), 0);
+ type_t *t = duptype(find_type(name, 0), 0);
t->name = name;
return t;
}
static type_t *make_int(int sign)
{
- type_t *t = duptype(find_type_or_error("int", 0), 1);
+ type_t *t = duptype(find_type("int", 0), 1);
t->sign = sign;
if (sign < 0)
t->tfswrite = FALSE;
t->checked = FALSE;
t->typelib_idx = -1;
- init_loc_info(&t->loc_info);
return t;
}
v->attrs = NULL;
v->eval = NULL;
v->stgclass = STG_NONE;
- init_loc_info(&v->loc_info);
+ v->loc_info.input_name = input_name ? input_name : "stdin";
+ v->loc_info.line_number = line_number;
+ v->loc_info.near_text = parser_text;
return v;
}
static type_t *make_safearray(type_t *type)
{
- type_t *sa = find_type_or_error("SAFEARRAY", 0);
+ type_t *sa = duptype(find_type("SAFEARRAY", 0), 1);
sa->ref = type;
return make_type(pointer_default, sa);
}
if (name->name) {
type_t *cur;
- cur = find_type(name->name, 0);
- if (cur)
- error_loc("%s: redefinition error; original definition was at %s:%d\n",
- cur->name, cur->loc_info.input_name,
- cur->loc_info.line_number);
-
/* set the attributes to allow set_type to do some checks on them */
name->attrs = attrs;
set_type(name, decl_spec, decl, 0);
return type;
}
-type_t *find_type(const char *name, int t)
+static type_t *find_type_helper(const char *name, int t)
{
struct rtype *cur = type_hash[hash_ident(name)];
while (cur && (cur->t != t || strcmp(cur->name, name)))
return cur ? cur->type : NULL;
}
-static type_t *find_type_or_error(const char *name, int t)
+type_t *find_type(const char *name, int t)
{
- type_t *type = find_type(name, t);
+ type_t *type = find_type_helper(name, t);
if (!type) {
error_loc("type '%s' not found\n", name);
return NULL;
return type;
}
-static type_t *find_type_or_error2(char *name, int t)
+static type_t *find_type2(char *name, int t)
{
- type_t *tp = find_type_or_error(name, t);
+ type_t *tp = find_type(name, t);
free(name);
return tp;
}
int is_type(const char *name)
{
- return find_type(name, 0) != NULL;
+ return find_type_helper(name, 0) != NULL;
}
static type_t *get_type(unsigned char type, char *name, int t)
{
type_t *tp;
if (name) {
- tp = find_type(name, t);
+ tp = find_type_helper(name, t);
if (tp) {
free(name);
return tp;
type->checked = TRUE;
if (is_struct(type->type))
- {
- if (type->defined)
- fields = type->fields_or_args;
- else
- error_loc_info(&var->loc_info, "undefined type declaration %s\n", type->name);
- }
+ fields = type->fields_or_args;
else if (is_union(type->type))
{
if (type->type == RPC_FC_ENCAPSULATED_UNION)
* function */
var_t *idl_handle = make_var(xstrdup("IDL_handle"));
idl_handle->attrs = append_attr(NULL, make_attr(ATTR_IN));
- idl_handle->type = find_type_or_error("handle_t", 0);
+ idl_handle->type = find_type("handle_t", 0);
if (!func->def->type->fields_or_args)
{
func->def->type->fields_or_args = xmalloc( sizeof(*func->def->type->fields_or_args) );
LIST_FOR_EACH_ENTRY_SAFE( decl, next, decls, declarator_t, entry )
{
var_t *var = decl->var;
- type_t *type = find_type_or_error(var->name, 0);
+ type_t *type = find_type(var->name, 0);
*type_list = xmalloc(sizeof(type_list_t));
(*type_list)->type = type;
(*type_list)->next = NULL;
}
return list;
}
-
-void init_loc_info(loc_info_t *i)
-{
- i->input_name = input_name ? input_name : "stdin";
- i->line_number = line_number;
- i->near_text = parser_text;
-}
-
-static void check_def(const type_t *t)
-{
- if (t->defined)
- error_loc("%s: redefinition error; original definition was at %s:%d\n",
- t->name, t->loc_info.input_name, t->loc_info.line_number);
-}