SySync to wine-1.1.1 (Patch 5 of 10):
[reactos.git] / reactos / tools / widl / parser.y
index c337aa6..2c43dfe 100644 (file)
@@ -309,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
+%type <type> enumdef structdef uniondef typedecl
 %type <type> type
 %type <ifref> coclass_int
 %type <ifref_list> coclass_ints
@@ -399,7 +399,7 @@ semicolon_opt:
 
 statement:
          cppquote                              { $$ = make_statement_cppquote($1); }
-       | enumdef ';'                           { $$ = make_statement_type_decl($1);
+       | typedecl ';'                          { $$ = make_statement_type_decl($1);
                                                  if (!parse_only && do_header) {
                                                    write_type_def_or_decl(header, $1, FALSE, NULL);
                                                    fprintf(header, ";\n\n");
@@ -409,19 +409,13 @@ 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; }
-       | uniondef ';'                          { $$ = make_statement_type_decl($1);
-                                                 if (!parse_only && do_header) {
-                                                   write_type_def_or_decl(header, $1, FALSE, NULL);
-                                                   fprintf(header, ";\n\n");
-                                                 }
-                                               }
+       ;
+
+typedecl:
+         enumdef
+       | structdef
+       | uniondef
        ;
 
 cppquote: tCPPQUOTE '(' aSTRING ')'            { $$ = $3; if (!parse_only && do_header) fprintf(header, "%s\n", $3); }
@@ -874,8 +868,8 @@ coclass_int:
          m_attributes interfacedec             { $$ = make_ifref($2); $$->attrs = $1; }
        ;
 
-dispinterface: tDISPINTERFACE aIDENTIFIER      { $$ = get_type(0, $2, 0); $$->kind = TKIND_DISPATCH; }
-       |      tDISPINTERFACE aKNOWNTYPE        { $$ = get_type(0, $2, 0); $$->kind = TKIND_DISPATCH; }
+dispinterface: tDISPINTERFACE aIDENTIFIER      { $$ = get_type(RPC_FC_IP, $2, 0); $$->kind = TKIND_DISPATCH; }
+       |      tDISPINTERFACE aKNOWNTYPE        { $$ = get_type(RPC_FC_IP, $2, 0); $$->kind = TKIND_DISPATCH; }
        ;
 
 dispinterfacehdr: attributes dispinterface     { attr_t *attrs;
@@ -1479,6 +1473,14 @@ static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
     error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n",
               v->name);
 
+  if (is_attr(v->attrs, ATTR_V1ENUM))
+  {
+    if (v->type->type == RPC_FC_ENUM16)
+      v->type->type = RPC_FC_ENUM32;
+    else
+      error_loc("'%s': [v1_enum] attribute applied to non-enum type\n", v->name);
+  }
+
   sizeless = FALSE;
   if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry)
   {
@@ -1900,16 +1902,22 @@ 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)))
     cur = cur->next;
-  if (!cur) {
+  return cur ? cur->type : NULL;
+}
+
+type_t *find_type(const char *name, int t)
+{
+  type_t *type = find_type_helper(name, t);
+  if (!type) {
     error_loc("type '%s' not found\n", name);
     return NULL;
   }
-  return cur->type;
+  return type;
 }
 
 static type_t *find_type2(char *name, int t)
@@ -1921,25 +1929,18 @@ static type_t *find_type2(char *name, int t)
 
 int is_type(const char *name)
 {
-  struct rtype *cur = type_hash[hash_ident(name)];
-  while (cur && (cur->t || strcmp(cur->name, name)))
-    cur = cur->next;
-  if (cur) return TRUE;
-  return FALSE;
+  return find_type_helper(name, 0) != NULL;
 }
 
 static type_t *get_type(unsigned char type, char *name, int t)
 {
-  struct rtype *cur = NULL;
   type_t *tp;
   if (name) {
-    cur = type_hash[hash_ident(name)];
-    while (cur && (cur->t != t || strcmp(cur->name, name)))
-      cur = cur->next;
-  }
-  if (cur) {
-    free(name);
-    return cur->type;
+    tp = find_type_helper(name, t);
+    if (tp) {
+      free(name);
+      return tp;
+    }
   }
   tp = make_type(type, NULL);
   tp->name = name;
@@ -2604,7 +2605,12 @@ static void check_remoting_fields(const var_t *var, type_t *type)
     type->checked = TRUE;
 
     if (is_struct(type->type))
-        fields = type->fields_or_args;
+    {
+        if (type->defined)
+            fields = type->fields_or_args;
+        else
+            error_loc_info(&var->loc_info, "undefined type declaration %s\n", type->name);
+    }
     else if (is_union(type->type))
     {
         if (type->type == RPC_FC_ENCAPSULATED_UNION)
@@ -2616,7 +2622,7 @@ static void check_remoting_fields(const var_t *var, type_t *type)
             fields = type->fields_or_args;
     }
 
-    if (fields) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
+    if (fields) LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
         if (field->type) check_field_common(type, type->name, field);
 }