Revert 37416 because it does not build on all machines.
[reactos.git] / reactos / tools / widl / parser.y
index d044c07..3c0a5fe 100644 (file)
@@ -128,8 +128,7 @@ 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);
 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);
@@ -157,7 +156,6 @@ 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);
-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);
@@ -311,7 +309,7 @@ static func_list_t *append_func_from_statement(func_list_t *list, statement_t *s
 %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
@@ -401,7 +399,7 @@ semicolon_opt:
 
 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");
@@ -411,13 +409,19 @@ statement:
                                                  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); }
@@ -819,7 +823,7 @@ base_type: tBYTE                            { $$ = make_builtin($<str>1); }
                                                }
        | 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); }
@@ -841,15 +845,12 @@ int_std:  tINT                                    { $$ = 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($$);
@@ -881,7 +882,7 @@ dispinterfacehdr: attributes dispinterface  { attr_t *attrs;
                                                  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);
@@ -920,7 +921,7 @@ dispinterfacedef: dispinterfacehdr '{'
        ;
 
 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; }
@@ -933,7 +934,7 @@ interfacehdr: attributes interface          { $$.interface = $2;
                                                    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);
@@ -957,7 +958,7 @@ interfacedef: interfacehdr inherit
        | 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($$);
@@ -1059,7 +1060,6 @@ pointer_type:
 
 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;
@@ -1069,15 +1069,15 @@ structdef: tSTRUCT t_ident '{' fields '}'       { $$ = get_typev(RPC_FC_STRUCT, $2, ts
                                                 }
        ;
 
-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); }
        ;
 
@@ -1089,7 +1089,6 @@ typedef: tTYPEDEF m_attributes decl_spec declarator_list
 
 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;
@@ -1098,7 +1097,6 @@ uniondef: tUNION t_ident '{' ne_union_fields '}'
          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);
@@ -1128,14 +1126,14 @@ static void decl_builtin(const char *name, unsigned char type)
 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)
@@ -1392,7 +1390,6 @@ type_t *make_type(unsigned char type, type_t *ref)
   t->tfswrite = FALSE;
   t->checked = FALSE;
   t->typelib_idx = -1;
-  init_loc_info(&t->loc_info);
   return t;
 }
 
@@ -1704,7 +1701,9 @@ static var_t *make_var(char *name)
   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;
 }
 
@@ -1761,7 +1760,7 @@ static type_t *make_class(char *name)
 
 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);
 }
@@ -1895,12 +1894,6 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
     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);
@@ -1915,7 +1908,7 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at
   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)))
@@ -1923,9 +1916,9 @@ type_t *find_type(const char *name, int t)
   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;
@@ -1933,23 +1926,23 @@ static type_t *find_type_or_error(const char *name, int t)
   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;
@@ -2618,12 +2611,7 @@ static void check_remoting_fields(const var_t *var, type_t *type)
     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)
@@ -2705,7 +2693,7 @@ static void add_explicit_handle_if_necessary(func_t *func)
                  * 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) );
@@ -2860,7 +2848,7 @@ static statement_t *process_typedefs(declarator_list_t *decls)
     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;
@@ -2903,17 +2891,3 @@ static func_list_t *append_func_from_statement(func_list_t *list, statement_t *s
     }
     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);
-}