Sync to wine-0.9.61:
authorEric Kohl <eric.kohl@reactos.org>
Wed, 12 Nov 2008 19:26:25 +0000 (19:26 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Wed, 12 Nov 2008 19:26:25 +0000 (19:26 +0000)
- Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008
widl: Stop looping in check_remoting_args when a context_handle or wire_marshal type is found as they are in effect fundamental types.

- Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008
widl: Check that fields in structures and unions referenced by non-local functions can be marshalled and that their attributes are consistent.

-Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008
widl: The implicit_handle attribute is allowed with a handle explicitly specified in the function parameters. In that case, that handle is used instead of the implicit handle. Fix the check for the explicit_handle attribute being specified without a handle being specified in the function parameters, even though issuing an error is wrong. (Thanks to Marcus Meissner & Coverity for spotting that the check didn't do what it was supposed to do.)

- Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008
widl: Automatically add "handle_t IDL_handle" parameter to functions with no explicit handle specified whose containing interface has the explicit_handle attribute.

- Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008
widl: Issue an error instead of crashing for dividing by zero in a constant expression.

- Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008
widl: Add support for "->" and "." operators in expressions.

- Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008
widl: Add support for arrays in expressions.

- Rob Shearman <rob@codeweavers.com> Sun, 20 Apr 2008
widl: Add support for '%' operator in expressions.

- Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008
widl: Fix operator precedence in expressions.

- Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008
widl: Require a constant expression for case statements.

- Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008
widl: Add support for comparison, exclusive or, logical not and positive operators in expressions.

- Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008
widl: Remove EXPR_MEMBERPTR and implement it using EXPR_PPTR and EXPR_MEMBER instead.

- Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008
widl: Don't free input_name in pop_import as we keep pointers to it in the var_t type now.

- Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008
widl: Pass the actual type into check_remoting_fields and check_field_common instead of the type name.

- Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008
widl: Check that expressions resolve so that expressions in generated code will compile. Also check that expressions return the correct type for the attribute.

- Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008
widl: Move expression functions to a new file, expr.c.

- Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008
widl: Use expr_resolve_type to get the type of the identifier in write_conf_or_var_desc. Remove the conversion of pointer types into base types as this was only needed due to lack of proper type resolving.

- Rob Shearman <rob@codeweavers.com> Tue, 22 Apr 2008
widl: Remove duplicated code in the form of the write_struct_expr function by enhancing write_expr to allow toplevel identifiers to be prefixed by a string, if specified.

- Rob Shearman <rob@codeweavers.com> Thu, 24 Apr 2008
widl: Implement lcid property on library declarations.

- Rob Shearman <rob@codeweavers.com> Thu, 24 Apr 2008
widl: Construct the pointer chain while parsing pointers, rather than storing a ptr_level. This method is more flexible and somewhat simpler.

- Rob Shearman <rob@codeweavers.com> Thu, 24 Apr 2008
widl: Allow NULL to be used in expressions.

- Rob Shearman <rob@codeweavers.com> Thu, 24 Apr 2008
widl: Create a list of statements in the whole IDL file, instead of just a list of interfaces.

- Rob Shearman <rob@codeweavers.com> Thu, 24 Apr 2008
widl: Add typedef statements to the statement lists.

- Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008
widl: Consolidate most of the inner loop of reg_typedefs into set_type.

- Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008
widl: Rename pident to declarator and parse the array declarations as part of declarators. This allows arrays to be used in typedefs and const statements.

- Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008
widl: Make the rules for parsing fields in structures, encapsulated unions and non-encapsulated unions more strict. Move the rules in fields that handle empty union cases into separate union rules so that they can't erroneously be accepted for structures or other types of unions.

- Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008
widl: Add support for declaring multiple fields of a structure in one statement.

- Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008
widl: Add support for string literals and wide-string literals in expressions.

- Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008
widl: Create a statement object for import statements. Move the writing of include directives into the generated header into header.c.

- Rob Shearman <rob@codeweavers.com> Fri, 25 Apr 2008
widl: Move the func_declarator rule entirely into direct_declarator.

- Rob Shearman <rob@codeweavers.com> Sat, 26 Apr 2008
widl: Add typedefs to typelibs which have the public or uuid attributes, not any other attribute.

- Rob Shearman <rob@codeweavers.com> Sat, 26 Apr 2008
widl: Support hex digits that use an uppercase 0X prefix.

- Rob Shearman <rob@codeweavers.com> Sun, 27 Apr 2008
widl: Accept integer constant suffixes in the lexer.

- Rob Shearman <rob@codeweavers.com> Tue, 29 Apr 2008
widl: Keep const attributes applied to pointers when writing out the type. Use an attribute to store the const qualifier for the pointer and type. Allow multiple type-qualifiers to be applied to a type by adding a declaration-specifier rule that encompasses type-qualifiers and types.

- Rob Shearman <rob@codeweavers.com> Tue, 29 Apr 2008
widl: Add support for "inline" on function definitions. Fix applying calling convention to function type.

- Rob Shearman <rob@codeweavers.com> Tue, 29 Apr 2008
widl: Make constdef and externdef take a declarator instead of an ident so that functions and arrays can be defined using the statements.

- Rob Shearman <rob@codeweavers.com> Tue, 29 Apr 2008
widl: Allow pointer attributes to be applied to function pointers.

- Rob Shearman <rob@codeweavers.com> Tue, 29 Apr 2008
widl: callback, code, comm_status and in_line are attribute names, not keywords.

- Rob Shearman <rob@codeweavers.com> Wed, 30 Apr 2008
widl: Prepare for supporting storage classes in declaration statements. Return a decl_spec_t structure from decl_spec rules so that the storage
class and type qualifiers can both be returned.

- Rob Shearman <rob@codeweavers.com> Wed, 30 Apr 2008
widl: Add the parsing of storage classes into declaration-specifiers. Support the static and register keywords. This consolidates externdef and constdef rules into one declaration rule.

- Rob Shearman <rob@codeweavers.com> Thu, 1 May 2008
widl: Consolidate writing of COM and dispatch interfaces into one function to remove duplicated code. Split up the writing into start and end to eventually support the style MIDL uses where it writes declared types, etc. between the start and end of the interface. Make internal header functions take the file pointer to print to. Don't write interface IDs for non-object interfaces and always write handle declarations even if the interface has no methods, like MIDL does.

- Gerald Pfeifer <gerald@pfeifer.com> Fri, 2 May 2008
widl: Fix syntax to also work with older versions of bison.

svn path=/trunk/; revision=37313

20 files changed:
reactos/media/doc/README.WINE
reactos/tools/widl/client.c
reactos/tools/widl/header.c
reactos/tools/widl/header.h
reactos/tools/widl/parser.l
reactos/tools/widl/parser.tab.c
reactos/tools/widl/parser.tab.h
reactos/tools/widl/parser.y
reactos/tools/widl/parser.yy.c
reactos/tools/widl/proxy.c
reactos/tools/widl/server.c
reactos/tools/widl/typegen.c
reactos/tools/widl/typegen.h
reactos/tools/widl/typelib.c
reactos/tools/widl/typelib.h
reactos/tools/widl/widl.c
reactos/tools/widl/widl.h
reactos/tools/widl/widl.rbuild
reactos/tools/widl/widltypes.h
reactos/tools/widl/write_msft.c

index 4d9ebfa..bc7f4f9 100644 (file)
@@ -26,7 +26,7 @@ reactos/tools/wpp                 # Synced to Wine-20081105 (~Wine-1.1.7)
 reactos/tools/winebuild           # Synced to Wine-20081105 (~Wine-1.1.7)
 reactos/tools/wmc                 # Synced to Wine-20081105 (~Wine-1.1.7)
 reactos/tools/wrc                 # Synced to Wine-20081105 (~Wine-1.1.7)
 reactos/tools/winebuild           # Synced to Wine-20081105 (~Wine-1.1.7)
 reactos/tools/wmc                 # Synced to Wine-20081105 (~Wine-1.1.7)
 reactos/tools/wrc                 # Synced to Wine-20081105 (~Wine-1.1.7)
-reactos/tools/widl                # Synced to Wine-0_9_60
+reactos/tools/widl                # Synced to Wine-0_9_61
 
 The following libraries are shared with Wine.
 
 
 The following libraries are shared with Wine.
 
index 51dfa10..c4d200a 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "widltypes.h"
 #include "typegen.h"
 
 #include "widltypes.h"
 #include "typegen.h"
+#include "expr.h"
 
 static FILE* client;
 static int indent = 0;
 
 static FILE* client;
 static int indent = 0;
@@ -70,25 +71,10 @@ static void check_pointers(const func_t *func)
     }
 }
 
     }
 }
 
-const var_t* get_context_handle_var(const func_t* func)
-{
-    const var_t* var;
-
-    if (!func->args)
-        return NULL;
-
-    LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
-        if (is_attr(var->attrs, ATTR_IN) && is_context_handle(var->type))
-            return var;
-
-    return NULL;
-}
-
 static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
 {
     const func_t *func;
     const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
 static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
 {
     const func_t *func;
     const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
-    int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE);
     const var_t *var;
     int method_count = 0;
 
     const var_t *var;
     int method_count = 0;
 
@@ -112,22 +98,6 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
             if (!explicit_generic_handle_var)
                 context_handle_var = get_context_handle_var(func);
         }
             if (!explicit_generic_handle_var)
                 context_handle_var = get_context_handle_var(func);
         }
-        if (explicit_handle)
-        {
-            if (!explicit_handle_var && !explicit_generic_handle_var && !context_handle_var)
-            {
-                error("%s() does not define an explicit binding handle!\n", def->name);
-                return;
-            }
-        }
-        else if (implicit_handle)
-        {
-            if (explicit_handle_var)
-            {
-                error("%s() must not define a binding handle!\n", def->name);
-                return;
-            }
-        }
 
         write_type_decl_left(client, get_func_return_type(func));
         if (needs_space_after(get_func_return_type(func)))
 
         write_type_decl_left(client, get_func_return_type(func));
         if (needs_space_after(get_func_return_type(func)))
@@ -196,12 +166,7 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
             fprintf(client, ");\n\n");
         }
 
             fprintf(client, ");\n\n");
         }
 
-        if (implicit_handle)
-        {
-            print_client("_Handle = %s;\n", implicit_handle);
-            fprintf(client, "\n");
-        }
-        else if (explicit_handle_var)
+        if (explicit_handle_var)
         {
             print_client("_Handle = %s;\n", explicit_handle_var->name);
             fprintf(client, "\n");
         {
             print_client("_Handle = %s;\n", explicit_handle_var->name);
             fprintf(client, "\n");
@@ -225,6 +190,11 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
             indent--;
             fprintf(client, "\n");
         }
             indent--;
             fprintf(client, "\n");
         }
+        else if (implicit_handle)
+        {
+            print_client("_Handle = %s;\n", implicit_handle);
+            fprintf(client, "\n");
+        }
 
         write_remoting_arguments(client, indent, func, PASS_IN, PHASE_BUFFERSIZE);
 
 
         write_remoting_arguments(client, indent, func, PASS_IN, PHASE_BUFFERSIZE);
 
@@ -460,59 +430,69 @@ static void init_client(void)
     fprintf(client, "\n");
 }
 
     fprintf(client, "\n");
 }
 
+static void write_client_ifaces(const statement_list_t *stmts, int expr_eval_routines, unsigned int *proc_offset)
+{
+    const statement_t *stmt;
+    if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
+    {
+        if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
+        {
+            type_t *iface = stmt->u.type;
+            if (!need_stub(iface))
+                return;
+
+            fprintf(client, "/*****************************************************************************\n");
+            fprintf(client, " * %s interface\n", iface->name);
+            fprintf(client, " */\n");
+            fprintf(client, "\n");
+
+            if (iface->funcs)
+            {
+                write_implicithandledecl(iface);
+
+                write_clientinterfacedecl(iface);
+                write_stubdescdecl(iface);
+                write_function_stubs(iface, proc_offset);
+
+                print_client("#if !defined(__RPC_WIN32__)\n");
+                print_client("#error  Invalid build platform for this stub.\n");
+                print_client("#endif\n");
+
+                fprintf(client, "\n");
+                write_stubdescriptor(iface, expr_eval_routines);
+            }
+        }
+        else if (stmt->type == STMT_LIBRARY)
+            write_client_ifaces(stmt->u.lib->stmts, expr_eval_routines, proc_offset);
+    }
+}
 
 
-void write_client(ifref_list_t *ifaces)
+void write_client(const statement_list_t *stmts)
 {
     unsigned int proc_offset = 0;
     int expr_eval_routines;
 {
     unsigned int proc_offset = 0;
     int expr_eval_routines;
-    ifref_t *iface;
 
     if (!do_client)
         return;
 
     if (!do_client)
         return;
-    if (do_everything && !need_stub_files(ifaces))
+    if (do_everything && !need_stub_files(stmts))
         return;
 
     init_client();
     if (!client)
         return;
 
         return;
 
     init_client();
     if (!client)
         return;
 
-    write_formatstringsdecl(client, indent, ifaces, need_stub);
+    write_formatstringsdecl(client, indent, stmts, need_stub);
     expr_eval_routines = write_expr_eval_routines(client, client_token);
     if (expr_eval_routines)
         write_expr_eval_routine_list(client, client_token);
     write_user_quad_list(client);
 
     expr_eval_routines = write_expr_eval_routines(client, client_token);
     if (expr_eval_routines)
         write_expr_eval_routine_list(client, client_token);
     write_user_quad_list(client);
 
-    if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, ifref_t, entry )
-    {
-        if (!need_stub(iface->iface))
-            continue;
-
-        fprintf(client, "/*****************************************************************************\n");
-        fprintf(client, " * %s interface\n", iface->iface->name);
-        fprintf(client, " */\n");
-        fprintf(client, "\n");
-
-        if (iface->iface->funcs)
-        {
-            write_implicithandledecl(iface->iface);
-    
-            write_clientinterfacedecl(iface->iface);
-            write_stubdescdecl(iface->iface);
-            write_function_stubs(iface->iface, &proc_offset);
-
-            print_client("#if !defined(__RPC_WIN32__)\n");
-            print_client("#error  Invalid build platform for this stub.\n");
-            print_client("#endif\n");
-
-            fprintf(client, "\n");
-            write_stubdescriptor(iface->iface, expr_eval_routines);
-        }
-    }
+    write_client_ifaces(stmts, expr_eval_routines, &proc_offset);
 
     fprintf(client, "\n");
 
 
     fprintf(client, "\n");
 
-    write_procformatstring(client, ifaces, need_stub);
-    write_typeformatstring(client, ifaces, need_stub);
+    write_procformatstring(client, stmts, need_stub);
+    write_typeformatstring(client, stmts, need_stub);
 
     fclose(client);
 }
 
     fclose(client);
 }
index 612572d..3e1b2d0 100644 (file)
@@ -33,6 +33,7 @@
 #include "utils.h"
 #include "parser.h"
 #include "header.h"
 #include "utils.h"
 #include "parser.h"
 #include "header.h"
+#include "expr.h"
 
 typedef struct _user_type_t generic_handle_t;
 
 
 typedef struct _user_type_t generic_handle_t;
 
@@ -194,7 +195,7 @@ static void write_enums(FILE *h, var_list_t *enums)
       write_name(h, v);
       if (v->eval) {
         fprintf(h, " = ");
       write_name(h, v);
       if (v->eval) {
         fprintf(h, " = ");
-        write_expr(h, v->eval, 0);
+        write_expr(h, v->eval, 0, 1, NULL, NULL);
       }
     }
     if (list_next( enums, &v->entry )) fprintf(h, ",\n");
       }
     }
     if (list_next( enums, &v->entry )) fprintf(h, ",\n");
@@ -212,7 +213,9 @@ void write_type_left(FILE *h, type_t *t, int declonly)
 {
   if (!h) return;
 
 {
   if (!h) return;
 
-  if (t->is_const) fprintf(h, "const ");
+  if (is_attr(t->attrs, ATTR_CONST) &&
+      (t->kind == TKIND_ALIAS || t->declarray || !is_ptr(t)))
+    fprintf(h, "const ");
 
   if (t->kind == TKIND_ALIAS) fprintf(h, "%s", t->name);
   else if (t->declarray) write_type_left(h, t->ref, declonly);
 
   if (t->kind == TKIND_ALIAS) fprintf(h, "%s", t->name);
   else if (t->declarray) write_type_left(h, t->ref, declonly);
@@ -272,6 +275,7 @@ void write_type_left(FILE *h, type_t *t, int declonly)
       case RPC_FC_BOGUS_ARRAY:
         write_type_left(h, t->ref, declonly);
         fprintf(h, "%s*", needs_space_after(t->ref) ? " " : "");
       case RPC_FC_BOGUS_ARRAY:
         write_type_left(h, t->ref, declonly);
         fprintf(h, "%s*", needs_space_after(t->ref) ? " " : "");
+        if (is_ptr(t) && is_attr(t->attrs, ATTR_CONST)) fprintf(h, "const ");
         break;
       default:
         fprintf(h, "%s", t->name);
         break;
       default:
         fprintf(h, "%s", t->name);
@@ -308,6 +312,7 @@ void write_type_v(FILE *h, type_t *t, int is_field, int declonly,
     int i;
     const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
     if (!callconv) callconv = "";
     int i;
     const char *callconv = get_attrp(pt->attrs, ATTR_CALLCONV);
     if (!callconv) callconv = "";
+    if (is_attr(pt->attrs, ATTR_INLINE)) fprintf(h, "inline ");
     write_type_left(h, pt->ref, declonly);
     fputc(' ', h);
     if (ptr_level) fputc('(', h);
     write_type_left(h, pt->ref, declonly);
     fputc(' ', h);
     if (ptr_level) fputc('(', h);
@@ -472,111 +477,56 @@ void write_typedef(type_t *type)
   fprintf(header, ";\n");
 }
 
   fprintf(header, ";\n");
 }
 
-void write_expr(FILE *h, const expr_t *e, int brackets)
+int is_const_decl(const var_t *var)
 {
 {
-  switch (e->type) {
-  case EXPR_VOID:
-    break;
-  case EXPR_NUM:
-    fprintf(h, "%lu", e->u.lval);
-    break;
-  case EXPR_HEXNUM:
-    fprintf(h, "0x%lx", e->u.lval);
-    break;
-  case EXPR_DOUBLE:
-    fprintf(h, "%#.15g", e->u.dval);
-    break;
-  case EXPR_TRUEFALSE:
-    if (e->u.lval == 0)
-      fprintf(h, "FALSE");
-    else
-      fprintf(h, "TRUE");
-    break;
-  case EXPR_IDENTIFIER:
-    fprintf(h, "%s", e->u.sval);
-    break;
-  case EXPR_NEG:
-    fprintf(h, "-");
-    write_expr(h, e->ref, 1);
-    break;
-  case EXPR_NOT:
-    fprintf(h, "~");
-    write_expr(h, e->ref, 1);
-    break;
-  case EXPR_PPTR:
-    fprintf(h, "*");
-    write_expr(h, e->ref, 1);
-    break;
-  case EXPR_CAST:
-    fprintf(h, "(");
-    write_type_decl(h, e->u.tref, NULL);
-    fprintf(h, ")");
-    write_expr(h, e->ref, 1);
-    break;
-  case EXPR_SIZEOF:
-    fprintf(h, "sizeof(");
-    write_type_decl(h, e->u.tref, NULL);
-    fprintf(h, ")");
-    break;
-  case EXPR_SHL:
-  case EXPR_SHR:
-  case EXPR_MUL:
-  case EXPR_DIV:
-  case EXPR_ADD:
-  case EXPR_SUB:
-  case EXPR_AND:
-  case EXPR_OR:
-    if (brackets) fprintf(h, "(");
-    write_expr(h, e->ref, 1);
-    switch (e->type) {
-    case EXPR_SHL: fprintf(h, " << "); break;
-    case EXPR_SHR: fprintf(h, " >> "); break;
-    case EXPR_MUL: fprintf(h, " * "); break;
-    case EXPR_DIV: fprintf(h, " / "); break;
-    case EXPR_ADD: fprintf(h, " + "); break;
-    case EXPR_SUB: fprintf(h, " - "); break;
-    case EXPR_AND: fprintf(h, " & "); break;
-    case EXPR_OR:  fprintf(h, " | "); break;
-    default: break;
-    }
-    write_expr(h, e->u.ext, 1);
-    if (brackets) fprintf(h, ")");
-    break;
-  case EXPR_COND:
-    if (brackets) fprintf(h, "(");
-    write_expr(h, e->ref, 1);
-    fprintf(h, " ? ");
-    write_expr(h, e->u.ext, 1);
-    fprintf(h, " : ");
-    write_expr(h, e->ext2, 1);
-    if (brackets) fprintf(h, ")");
-    break;
-  case EXPR_ADDRESSOF:
-    fprintf(h, "&");
-    write_expr(h, e->ref, 1);
-    break;
+  const type_t *t;
+  /* strangely, MIDL accepts a const attribute on any pointer in the
+  * 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,
+  * so we'll do the same thing */
+  for (t = var->type; ; )
+  {
+    if (is_attr(t->attrs, ATTR_CONST))
+      return TRUE;
+    else if (is_ptr(t))
+      t = t->ref;
+    else break;
   }
   }
+  return FALSE;
 }
 
 }
 
-void write_constdef(const var_t *v)
-{
-  fprintf(header, "#define %s (", v->name);
-  write_expr(header, v->eval, 0);
-  fprintf(header, ")\n\n");
-}
-
-void write_externdef(const var_t *v)
+void write_declaration(const var_t *v, int is_in_interface)
 {
 {
-  fprintf(header, "extern const ");
-  write_type_def_or_decl(header, v->type, FALSE, "%s", v->name);
-  fprintf(header, ";\n\n");
+  if (is_const_decl(v) && v->eval)
+  {
+    fprintf(header, "#define %s (", v->name);
+    write_expr(header, v->eval, 0, 1, NULL, NULL);
+    fprintf(header, ")\n\n");
+  }
+  else if (v->type->type != RPC_FC_FUNCTION || !is_in_interface)
+  {
+    switch (v->stgclass)
+    {
+      case STG_NONE:
+      case STG_REGISTER: /* ignored */
+        break;
+      case STG_STATIC:
+        fprintf(header, "static ");
+        break;
+      case STG_EXTERN:
+        fprintf(header, "extern ");
+        break;
+    }
+    write_type_def_or_decl(header, v->type, FALSE, "%s", v->name);
+    fprintf(header, ";\n\n");
+  }
 }
 
 }
 
-void write_library(const char *name, const attr_list_t *attr)
+void write_library(const typelib_t *typelib)
 {
 {
-  const UUID *uuid = get_attrp(attr, ATTR_UUID);
+  const UUID *uuid = get_attrp(typelib->attrs, ATTR_UUID);
   fprintf(header, "\n");
   fprintf(header, "\n");
-  write_guid(header, "LIBID", name, uuid);
+  write_guid(header, "LIBID", typelib->name, uuid);
   fprintf(header, "\n");
 }
 
   fprintf(header, "\n");
 }
 
@@ -626,6 +576,20 @@ const var_t* get_explicit_generic_handle_var(const func_t* func)
     return NULL;
 }
 
     return NULL;
 }
 
+const var_t* get_context_handle_var(const func_t* func)
+{
+    const var_t* var;
+
+    if (!func->args)
+        return NULL;
+
+    LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
+        if (is_attr(var->attrs, ATTR_IN) && is_context_handle(var->type))
+            return var;
+
+    return NULL;
+}
+
 int has_out_arg_or_return(const func_t *func)
 {
     const var_t *var;
 int has_out_arg_or_return(const func_t *func)
 {
     const var_t *var;
@@ -664,11 +628,11 @@ const var_t *is_callas(const attr_list_t *a)
   return get_attrp(a, ATTR_CALLAS);
 }
 
   return get_attrp(a, ATTR_CALLAS);
 }
 
-static void write_method_macro(const type_t *iface, const char *name)
+static void write_method_macro(FILE *header, const type_t *iface, const char *name)
 {
   const func_t *cur;
 
 {
   const func_t *cur;
 
-  if (iface->ref) write_method_macro(iface->ref, name);
+  if (iface->ref) write_method_macro(header, iface->ref, name);
 
   if (!iface->funcs) return;
 
 
   if (!iface->funcs) return;
 
@@ -727,7 +691,7 @@ void write_args(FILE *h, const var_list_t *args, const char *name, int method, i
   if (do_indent) indentation--;
 }
 
   if (do_indent) indentation--;
 }
 
-static void write_cpp_method_def(const type_t *iface)
+static void write_cpp_method_def(FILE *header, const type_t *iface)
 {
   const func_t *cur;
 
 {
   const func_t *cur;
 
@@ -752,11 +716,11 @@ static void write_cpp_method_def(const type_t *iface)
   }
 }
 
   }
 }
 
-static void do_write_c_method_def(const type_t *iface, const char *name)
+static void do_write_c_method_def(FILE *header, const type_t *iface, const char *name)
 {
   const func_t *cur;
 
 {
   const func_t *cur;
 
-  if (iface->ref) do_write_c_method_def(iface->ref, name);
+  if (iface->ref) do_write_c_method_def(header, iface->ref, name);
 
   if (!iface->funcs) return;
   indent(header, 0);
 
   if (!iface->funcs) return;
   indent(header, 0);
@@ -779,17 +743,17 @@ static void do_write_c_method_def(const type_t *iface, const char *name)
   }
 }
 
   }
 }
 
-static void write_c_method_def(const type_t *iface)
+static void write_c_method_def(FILE *header, const type_t *iface)
 {
 {
-  do_write_c_method_def(iface, iface->name);
+  do_write_c_method_def(header, iface, iface->name);
 }
 
 }
 
-static void write_c_disp_method_def(const type_t *iface)
+static void write_c_disp_method_def(FILE *header, const type_t *iface)
 {
 {
-  do_write_c_method_def(iface->ref, iface->name);
+  do_write_c_method_def(header, iface->ref, iface->name);
 }
 
 }
 
-static void write_method_proto(const type_t *iface)
+static void write_method_proto(FILE *header, const type_t *iface)
 {
   const func_t *cur;
 
 {
   const func_t *cur;
 
@@ -884,7 +848,7 @@ void write_locals(FILE *fp, const type_t *iface, int body)
   }
 }
 
   }
 }
 
-static void write_function_proto(const type_t *iface, const func_t *fun, const char *prefix)
+static void write_function_proto(FILE *header, const type_t *iface, const func_t *fun, const char *prefix)
 {
   var_t *def = fun->def;
   const char *callconv = get_attrp(def->type->attrs, ATTR_CALLCONV);
 {
   var_t *def = fun->def;
   const char *callconv = get_attrp(def->type->attrs, ATTR_CALLCONV);
@@ -902,47 +866,20 @@ static void write_function_proto(const type_t *iface, const func_t *fun, const c
   fprintf(header, ");\n\n");
 }
 
   fprintf(header, ");\n\n");
 }
 
-static void write_function_protos(const type_t *iface)
+static void write_function_protos(FILE *header, const type_t *iface)
 {
 {
-  const char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
-  int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE);
-  const var_t* explicit_handle_var;
-  const var_t* explicit_generic_handle_var = NULL;
-  const var_t* context_handle_var = NULL;
   const func_t *cur;
   int prefixes_differ = strcmp(prefix_client, prefix_server);
 
   if (!iface->funcs) return;
   LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry )
   {
   const func_t *cur;
   int prefixes_differ = strcmp(prefix_client, prefix_server);
 
   if (!iface->funcs) return;
   LIST_FOR_EACH_ENTRY( cur, iface->funcs, const func_t, entry )
   {
-    var_t *def = cur->def;
-
-    /* check for a defined binding handle */
-    explicit_handle_var = get_explicit_handle_var(cur);
-    if (!explicit_handle_var)
-    {
-      explicit_generic_handle_var = get_explicit_generic_handle_var(cur);
-      if (!explicit_generic_handle_var)
-        context_handle_var = get_context_handle_var(cur);
-    }
-    if (explicit_handle) {
-      if (!explicit_handle_var && !explicit_generic_handle_var && !context_handle_var) {
-        error("%s() does not define an explicit binding handle!\n", def->name);
-        return;
-      }
-    } else if (implicit_handle) {
-      if (explicit_handle_var) {
-        error("%s() must not define a binding handle!\n", def->name);
-        return;
-      }
-    }
-
     if (prefixes_differ) {
       fprintf(header, "/* client prototype */\n");
     if (prefixes_differ) {
       fprintf(header, "/* client prototype */\n");
-      write_function_proto(iface, cur, prefix_client);
+      write_function_proto(header, iface, cur, prefix_client);
       fprintf(header, "/* server prototype */\n");
     }
       fprintf(header, "/* server prototype */\n");
     }
-    write_function_proto(iface, cur, prefix_server);
+    write_function_proto(header, iface, cur, prefix_server);
   }
 }
 
   }
 }
 
@@ -963,68 +900,76 @@ void write_forward(type_t *iface)
   }
 }
 
   }
 }
 
-static void write_iface_guid(const type_t *iface)
+static void write_iface_guid(FILE *header, const type_t *iface)
 {
   const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
   write_guid(header, "IID", iface->name, uuid);
 } 
 
 {
   const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
   write_guid(header, "IID", iface->name, uuid);
 } 
 
-static void write_dispiface_guid(const type_t *iface)
+static void write_dispiface_guid(FILE *header, const type_t *iface)
 {
   const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
   write_guid(header, "DIID", iface->name, uuid);
 }
 
 {
   const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
   write_guid(header, "DIID", iface->name, uuid);
 }
 
-static void write_coclass_guid(type_t *cocl)
+static void write_coclass_guid(FILE *header, const type_t *cocl)
 {
   const UUID *uuid = get_attrp(cocl->attrs, ATTR_UUID);
   write_guid(header, "CLSID", cocl->name, uuid);
 }
 
 {
   const UUID *uuid = get_attrp(cocl->attrs, ATTR_UUID);
   write_guid(header, "CLSID", cocl->name, uuid);
 }
 
-static void write_com_interface(type_t *iface)
+static void write_com_interface_start(FILE *header, const type_t *iface)
 {
 {
-  if (!iface->funcs && !iface->ref) {
-    parser_warning("%s has no methods\n", iface->name);
-    return;
-  }
-
+  int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE);
   fprintf(header, "/*****************************************************************************\n");
   fprintf(header, "/*****************************************************************************\n");
-  fprintf(header, " * %s interface\n", iface->name);
+  fprintf(header, " * %s %sinterface\n", iface->name, dispinterface ? "disp" : "");
   fprintf(header, " */\n");
   fprintf(header, " */\n");
-  fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name);
-  fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name);
-  write_iface_guid(iface);
-  write_forward(iface);
+  fprintf(header,"#ifndef __%s_%sINTERFACE_DEFINED__\n", iface->name, dispinterface ? "DISP" : "");
+  fprintf(header,"#define __%s_%sINTERFACE_DEFINED__\n\n", iface->name, dispinterface ? "DISP" : "");
+}
+
+static void write_com_interface_end(FILE *header, type_t *iface)
+{
+  int dispinterface = is_attr(iface->attrs, ATTR_DISPINTERFACE);
+  if (dispinterface)
+    write_dispiface_guid(header, iface);
+  else
+    write_iface_guid(header, iface);
   /* C++ interface */
   fprintf(header, "#if defined(__cplusplus) && !defined(CINTERFACE)\n");
   if (iface->ref)
   {
   /* C++ interface */
   fprintf(header, "#if defined(__cplusplus) && !defined(CINTERFACE)\n");
   if (iface->ref)
   {
-      fprintf(header, "interface %s : public %s\n", iface->name, iface->ref->name);
-      fprintf(header, "{\n");
-      indentation++;
-      write_cpp_method_def(iface);
-      indentation--;
-      fprintf(header, "};\n");
+    fprintf(header, "interface %s : public %s\n", iface->name, iface->ref->name);
+    fprintf(header, "{\n");
   }
   else
   {
   }
   else
   {
-      fprintf(header, "interface %s\n", iface->name);
-      fprintf(header, "{\n");
-      fprintf(header, "    BEGIN_INTERFACE\n");
-      fprintf(header, "\n");
-      indentation++;
-      write_cpp_method_def(iface);
-      indentation--;
-      fprintf(header, "    END_INTERFACE\n");
-      fprintf(header, "};\n");
+    fprintf(header, "interface %s\n", iface->name);
+    fprintf(header, "{\n");
+    fprintf(header, "    BEGIN_INTERFACE\n");
+    fprintf(header, "\n");
   }
   }
+  /* dispinterfaces don't have real functions, so don't write C++ functions for
+   * them */
+  if (!dispinterface)
+  {
+    indentation++;
+    write_cpp_method_def(header, iface);
+    indentation--;
+  }
+  if (!iface->ref)
+    fprintf(header, "    END_INTERFACE\n");
+  fprintf(header, "};\n");
   fprintf(header, "#else\n");
   /* C interface */
   fprintf(header, "typedef struct %sVtbl {\n", iface->name);
   indentation++;
   fprintf(header, "    BEGIN_INTERFACE\n");
   fprintf(header, "\n");
   fprintf(header, "#else\n");
   /* C interface */
   fprintf(header, "typedef struct %sVtbl {\n", iface->name);
   indentation++;
   fprintf(header, "    BEGIN_INTERFACE\n");
   fprintf(header, "\n");
-  write_c_method_def(iface);
+  if (dispinterface)
+    write_c_disp_method_def(header, iface);
+  else
+    write_c_method_def(header, iface);
   indentation--;
   fprintf(header, "    END_INTERFACE\n");
   fprintf(header, "} %sVtbl;\n", iface->name);
   indentation--;
   fprintf(header, "    END_INTERFACE\n");
   fprintf(header, "} %sVtbl;\n", iface->name);
@@ -1033,17 +978,25 @@ static void write_com_interface(type_t *iface)
   fprintf(header, "};\n");
   fprintf(header, "\n");
   fprintf(header, "#ifdef COBJMACROS\n");
   fprintf(header, "};\n");
   fprintf(header, "\n");
   fprintf(header, "#ifdef COBJMACROS\n");
-  write_method_macro(iface, iface->name);
+  /* dispinterfaces don't have real functions, so don't write macros for them,
+   * only for the interface this interface inherits from, i.e. IDispatch */
+  write_method_macro(header, dispinterface ? iface->ref : iface, iface->name);
   fprintf(header, "#endif\n");
   fprintf(header, "\n");
   fprintf(header, "#endif\n");
   fprintf(header, "\n");
   fprintf(header, "#endif\n");
   fprintf(header, "\n");
   fprintf(header, "#endif\n");
   fprintf(header, "\n");
-  write_method_proto(iface);
-  write_locals(header, iface, FALSE);
-  fprintf(header,"\n#endif  /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name);
+  /* dispinterfaces don't have real functions, so don't write prototypes for
+   * them */
+  if (!dispinterface)
+  {
+    write_method_proto(header, iface);
+    write_locals(header, iface, FALSE);
+    fprintf(header, "\n");
+  }
+  fprintf(header,"#endif  /* __%s_%sINTERFACE_DEFINED__ */\n\n", iface->name, dispinterface ? "DISP" : "");
 }
 
 }
 
-static void write_rpc_interface(const type_t *iface)
+static void write_rpc_interface_start(FILE *header, const type_t *iface)
 {
   unsigned int ver = get_attrv(iface->attrs, ATTR_VERSION);
   const char *var = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
 {
   unsigned int ver = get_attrv(iface->attrs, ATTR_VERSION);
   const char *var = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
@@ -1061,72 +1014,39 @@ static void write_rpc_interface(const type_t *iface)
   fprintf(header, " */\n");
   fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name);
   fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name);
   fprintf(header, " */\n");
   fprintf(header,"#ifndef __%s_INTERFACE_DEFINED__\n", iface->name);
   fprintf(header,"#define __%s_INTERFACE_DEFINED__\n\n", iface->name);
-  if (iface->funcs)
+  if (var) fprintf(header, "extern handle_t %s;\n", var);
+  if (old_names)
   {
   {
-    write_iface_guid(iface);
-    if (var) fprintf(header, "extern handle_t %s;\n", var);
-    if (old_names)
-    {
-        fprintf(header, "extern RPC_IF_HANDLE %s%s_ClientIfHandle;\n", prefix_client, iface->name);
-        fprintf(header, "extern RPC_IF_HANDLE %s%s_ServerIfHandle;\n", prefix_server, iface->name);
-    }
-    else
-    {
-        fprintf(header, "extern RPC_IF_HANDLE %s%s_v%d_%d_c_ifspec;\n",
-                prefix_client, iface->name, MAJORVERSION(ver), MINORVERSION(ver));
-        fprintf(header, "extern RPC_IF_HANDLE %s%s_v%d_%d_s_ifspec;\n",
-                prefix_server, iface->name, MAJORVERSION(ver), MINORVERSION(ver));
-    }
-    write_function_protos(iface);
+      fprintf(header, "extern RPC_IF_HANDLE %s%s_ClientIfHandle;\n", prefix_client, iface->name);
+      fprintf(header, "extern RPC_IF_HANDLE %s%s_ServerIfHandle;\n", prefix_server, iface->name);
+  }
+  else
+  {
+      fprintf(header, "extern RPC_IF_HANDLE %s%s_v%d_%d_c_ifspec;\n",
+              prefix_client, iface->name, MAJORVERSION(ver), MINORVERSION(ver));
+      fprintf(header, "extern RPC_IF_HANDLE %s%s_v%d_%d_s_ifspec;\n",
+              prefix_server, iface->name, MAJORVERSION(ver), MINORVERSION(ver));
   }
   }
-  fprintf(header,"\n#endif  /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name);
-
-  /* FIXME: server/client code */
 }
 
 }
 
-void write_interface(type_t *iface)
+static void write_rpc_interface_end(FILE *header, const type_t *iface)
 {
 {
-  if (is_object(iface->attrs))
-    write_com_interface(iface);
-  else
-    write_rpc_interface(iface);
+  fprintf(header,"\n#endif  /* __%s_INTERFACE_DEFINED__ */\n\n", iface->name);
 }
 
 }
 
-void write_dispinterface(type_t *iface)
+void write_interface(type_t *iface)
 {
 {
-  fprintf(header, "/*****************************************************************************\n");
-  fprintf(header, " * %s dispinterface\n", iface->name);
-  fprintf(header, " */\n");
-  fprintf(header,"#ifndef __%s_DISPINTERFACE_DEFINED__\n", iface->name);
-  fprintf(header,"#define __%s_DISPINTERFACE_DEFINED__\n\n", iface->name);
-  write_dispiface_guid(iface);
-  write_forward(iface);
-  /* C++ interface */
-  fprintf(header, "#if defined(__cplusplus) && !defined(CINTERFACE)\n");
-  fprintf(header, "interface %s : public %s\n", iface->name, iface->ref->name);
-  fprintf(header, "{\n");
-  fprintf(header, "};\n");
-  fprintf(header, "#else\n");
-  /* C interface */
-  fprintf(header, "typedef struct %sVtbl {\n", iface->name);
-  indentation++;
-  fprintf(header, "    BEGIN_INTERFACE\n");
-  fprintf(header, "\n");
-  write_c_disp_method_def(iface);
-  indentation--;
-  fprintf(header, "    END_INTERFACE\n");
-  fprintf(header, "} %sVtbl;\n", iface->name);
-  fprintf(header, "interface %s {\n", iface->name);
-  fprintf(header, "    CONST_VTBL %sVtbl* lpVtbl;\n", iface->name);
-  fprintf(header, "};\n");
-  fprintf(header, "\n");
-  fprintf(header, "#ifdef COBJMACROS\n");
-  write_method_macro(iface->ref, iface->name);
-  fprintf(header, "#endif\n");
-  fprintf(header, "\n");
-  fprintf(header, "#endif\n");
-  fprintf(header, "\n");
-  fprintf(header,"#endif  /* __%s_DISPINTERFACE_DEFINED__ */\n\n", iface->name);
+  if (is_attr(iface->attrs, ATTR_DISPINTERFACE) || is_object(iface->attrs))
+  {
+    write_com_interface_start(header, iface);
+    write_com_interface_end(header, iface);
+  }
+  else
+  {
+    write_rpc_interface_start(header, iface);
+    write_function_protos(header, iface);
+    write_rpc_interface_end(header, iface);
+  }
 }
 
 void write_coclass(type_t *cocl)
 }
 
 void write_coclass(type_t *cocl)
@@ -1134,7 +1054,7 @@ void write_coclass(type_t *cocl)
   fprintf(header, "/*****************************************************************************\n");
   fprintf(header, " * %s coclass\n", cocl->name);
   fprintf(header, " */\n\n");
   fprintf(header, "/*****************************************************************************\n");
   fprintf(header, " * %s coclass\n", cocl->name);
   fprintf(header, " */\n\n");
-  write_coclass_guid(cocl);
+  write_coclass_guid(header, cocl);
   fprintf(header, "\n");
 }
 
   fprintf(header, "\n");
 }
 
@@ -1145,3 +1065,15 @@ void write_coclass_forward(type_t *cocl)
   fprintf(header, "typedef struct %s %s;\n", cocl->name, cocl->name);
   fprintf(header, "#endif /* defined __%s_FWD_DEFINED__ */\n\n", cocl->name );
 }
   fprintf(header, "typedef struct %s %s;\n", cocl->name, cocl->name);
   fprintf(header, "#endif /* defined __%s_FWD_DEFINED__ */\n\n", cocl->name );
 }
+
+void write_import(const char *fname)
+{
+  char *hname, *p;
+
+  hname = dup_basename(fname, ".idl");
+  p = hname + strlen(hname) - 2;
+  if (p <= hname || strcmp( p, ".h" )) strcat(hname, ".h");
+
+  fprintf(header, "#include <%s>\n", hname);
+  free(hname);
+}
index e74a95f..3344c80 100644 (file)
@@ -44,22 +44,20 @@ extern int is_object(const attr_list_t *list);
 extern int is_local(const attr_list_t *list);
 extern int need_stub(const type_t *iface);
 extern int need_proxy(const type_t *iface);
 extern int is_local(const attr_list_t *list);
 extern int need_stub(const type_t *iface);
 extern int need_proxy(const type_t *iface);
-extern int need_stub_files(const ifref_list_t *ifaces);
-extern int need_proxy_file(const ifref_list_t *ifaces);
+extern int need_stub_files(const statement_list_t *stmts);
+extern int need_proxy_file(const statement_list_t *stmts);
 extern const var_t *is_callas(const attr_list_t *list);
 extern void write_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent);
 extern void write_array(FILE *h, array_dims_t *v, int field);
 extern const var_t *is_callas(const attr_list_t *list);
 extern void write_args(FILE *h, const var_list_t *arg, const char *name, int obj, int do_indent);
 extern void write_array(FILE *h, array_dims_t *v, int field);
+extern void write_import(const char *fname);
 extern void write_forward(type_t *iface);
 extern void write_interface(type_t *iface);
 extern void write_forward(type_t *iface);
 extern void write_interface(type_t *iface);
-extern void write_dispinterface(type_t *iface);
 extern void write_locals(FILE *fp, const type_t *iface, int body);
 extern void write_coclass(type_t *cocl);
 extern void write_coclass_forward(type_t *cocl);
 extern void write_typedef(type_t *type);
 extern void write_locals(FILE *fp, const type_t *iface, int body);
 extern void write_coclass(type_t *cocl);
 extern void write_coclass_forward(type_t *cocl);
 extern void write_typedef(type_t *type);
-extern void write_expr(FILE *h, const expr_t *e, int brackets);
-extern void write_constdef(const var_t *v);
-extern void write_externdef(const var_t *v);
-extern void write_library(const char *name, const attr_list_t *attr);
+extern void write_declaration(const var_t *v, int is_in_interface);
+extern void write_library(const typelib_t *typelib);
 extern void write_user_types(void);
 extern void write_context_handle_rundowns(void);
 extern void write_generic_handle_routines(void);
 extern void write_user_types(void);
 extern void write_context_handle_rundowns(void);
 extern void write_generic_handle_routines(void);
@@ -70,6 +68,7 @@ extern const var_t* get_context_handle_var(const func_t* func);
 extern int has_out_arg_or_return(const func_t *func);
 extern void write_guid(FILE *f, const char *guid_prefix, const char *name,
                        const UUID *uuid);
 extern int has_out_arg_or_return(const func_t *func);
 extern void write_guid(FILE *f, const char *guid_prefix, const char *name,
                        const UUID *uuid);
+extern int is_const_decl(const var_t *var);
 
 static inline int last_ptr(const type_t *type)
 {
 
 static inline int last_ptr(const type_t *type)
 {
index 5b24b26..c085d4f 100644 (file)
 nl     \r?\n
 ws     [ \f\t\r]
 cident [a-zA-Z_][0-9a-zA-Z_]*
 nl     \r?\n
 ws     [ \f\t\r]
 cident [a-zA-Z_][0-9a-zA-Z_]*
-int    [0-9]+
+u_suffix       (u|U)
+l_suffix       (l|L)
+int    [0-9]+({l_suffix}?{u_suffix}?|{u_suffix}?{l_suffix}?)?
 hexd   [0-9a-fA-F]
 hexd   [0-9a-fA-F]
-hex    0x{hexd}+
+hex    0(x|X){hexd}+({l_suffix}?{u_suffix}?|{u_suffix}?{l_suffix}?)?
 uuid   {hexd}{8}-{hexd}{4}-{hexd}{4}-{hexd}{4}-{hexd}{12}
 double [0-9]+\.[0-9]+([eE][+-]?[0-9]+)*
 
 %x QUOTE
 uuid   {hexd}{8}-{hexd}{4}-{hexd}{4}-{hexd}{4}-{hexd}{12}
 double [0-9]+\.[0-9]+([eE][+-]?[0-9]+)*
 
 %x QUOTE
+%x WSTRQUOTE
 %x ATTR
 %x PP_LINE
 
 %x ATTR
 %x PP_LINE
 
@@ -133,10 +136,16 @@ UUID *parse_uuid(const char *u)
                                parser_lval.str = get_buffered_cstring();
                                return aSTRING;
                        }
                                parser_lval.str = get_buffered_cstring();
                                return aSTRING;
                        }
-<QUOTE>\\\\            |
-<QUOTE>\\\"            addcchar(yytext[1]);
-<QUOTE>\\.             addcchar('\\'); addcchar(yytext[1]);
-<QUOTE>.               addcchar(yytext[0]);
+<INITIAL,ATTR>L\"      yy_push_state(WSTRQUOTE);
+<WSTRQUOTE>\"          {
+                               yy_pop_state();
+                               parser_lval.str = get_buffered_cstring();
+                               return aWSTRING;
+                       }
+<QUOTE,WSTRQUOTE>\\\\  |
+<QUOTE,WSTRQUOTE>\\\"  addcchar(yytext[1]);
+<QUOTE,WSTRQUOTE>\\.   addcchar('\\'); addcchar(yytext[1]);
+<QUOTE,WSTRQUOTE>.     addcchar(yytext[0]);
 <INITIAL,ATTR>\[       yy_push_state(ATTR); return '[';
 <ATTR>\]               yy_pop_state(); return ']';
 <ATTR>{cident}         return attr_token(yytext);
 <INITIAL,ATTR>\[       yy_push_state(ATTR); return '[';
 <ATTR>\]               yy_pop_state(); return ']';
 <ATTR>{cident}         return attr_token(yytext);
@@ -162,6 +171,13 @@ SAFEARRAY{ws}*/\(  return tSAFEARRAY;
 <INITIAL,ATTR>{ws}
 <INITIAL,ATTR>\<\<     return SHL;
 <INITIAL,ATTR>\>\>     return SHR;
 <INITIAL,ATTR>{ws}
 <INITIAL,ATTR>\<\<     return SHL;
 <INITIAL,ATTR>\>\>     return SHR;
+<INITIAL,ATTR>\-\>     return MEMBERPTR;
+<INITIAL,ATTR>==       return EQUALITY;
+<INITIAL,ATTR>!=       return INEQUALITY;
+<INITIAL,ATTR>\>=      return GREATEREQUAL;
+<INITIAL,ATTR>\<=      return LESSEQUAL;
+<INITIAL,ATTR>\|\|     return LOGICALOR;
+<INITIAL,ATTR>&&       return LOGICALAND;
 <INITIAL,ATTR>.                return yytext[0];
 <<EOF>>                        {
                                if (import_stack_ptr)
 <INITIAL,ATTR>.                return yytext[0];
 <<EOF>>                        {
                                if (import_stack_ptr)
@@ -184,6 +200,7 @@ struct keyword {
 
 static const struct keyword keywords[] = {
        {"FALSE",                       tFALSE},
 
 static const struct keyword keywords[] = {
        {"FALSE",                       tFALSE},
+       {"NULL",                        tNULL},
        {"TRUE",                        tTRUE},
        {"__cdecl",                     tCDECL},
        {"__fastcall",                  tFASTCALL},
        {"TRUE",                        tTRUE},
        {"__cdecl",                     tCDECL},
        {"__fastcall",                  tFASTCALL},
@@ -196,13 +213,10 @@ static const struct keyword keywords[] = {
        {"_stdcall",                    tSTDCALL},
        {"boolean",                     tBOOLEAN},
        {"byte",                        tBYTE},
        {"_stdcall",                    tSTDCALL},
        {"boolean",                     tBOOLEAN},
        {"byte",                        tBYTE},
-       {"callback",                    tCALLBACK},
        {"case",                        tCASE},
        {"cdecl",                       tCDECL},
        {"char",                        tCHAR},
        {"coclass",                     tCOCLASS},
        {"case",                        tCASE},
        {"cdecl",                       tCDECL},
        {"char",                        tCHAR},
        {"coclass",                     tCOCLASS},
-       {"code",                        tCODE},
-       {"comm_status",                 tCOMMSTATUS},
        {"const",                       tCONST},
        {"cpp_quote",                   tCPPQUOTE},
        {"default",                     tDEFAULT},
        {"const",                       tCONST},
        {"cpp_quote",                   tCPPQUOTE},
        {"default",                     tDEFAULT},
@@ -216,7 +230,7 @@ static const struct keyword keywords[] = {
        {"hyper",                       tHYPER},
        {"import",                      tIMPORT},
        {"importlib",                   tIMPORTLIB},
        {"hyper",                       tHYPER},
        {"import",                      tIMPORT},
        {"importlib",                   tIMPORTLIB},
-       {"in_line",                     tINLINE},
+       {"inline",                      tINLINE},
        {"int",                         tINT},
        {"interface",                   tINTERFACE},
        {"library",                     tLIBRARY},
        {"int",                         tINT},
        {"interface",                   tINTERFACE},
        {"library",                     tLIBRARY},
@@ -225,10 +239,12 @@ static const struct keyword keywords[] = {
        {"module",                      tMODULE},
        {"pascal",                      tPASCAL},
        {"properties",                  tPROPERTIES},
        {"module",                      tMODULE},
        {"pascal",                      tPASCAL},
        {"properties",                  tPROPERTIES},
+       {"register",                    tREGISTER},
        {"short",                       tSHORT},
        {"signed",                      tSIGNED},
        {"sizeof",                      tSIZEOF},
        {"short",                       tSHORT},
        {"signed",                      tSIGNED},
        {"sizeof",                      tSIZEOF},
-        {"small",                      tSMALL},
+       {"small",                       tSMALL},
+       {"static",                      tSTATIC},
        {"stdcall",                     tSTDCALL},
        {"struct",                      tSTRUCT},
        {"switch",                      tSWITCH},
        {"stdcall",                     tSTDCALL},
        {"struct",                      tSTRUCT},
        {"switch",                      tSWITCH},
@@ -253,6 +269,9 @@ static const struct keyword attr_keywords[] =
         {"broadcast",                   tBROADCAST},
         {"byte_count",                  tBYTECOUNT},
         {"call_as",                     tCALLAS},
         {"broadcast",                   tBROADCAST},
         {"byte_count",                  tBYTECOUNT},
         {"call_as",                     tCALLAS},
+        {"callback",                    tCALLBACK},
+        {"code",                        tCODE},
+        {"comm_status",                 tCOMMSTATUS},
         {"context_handle",              tCONTEXTHANDLE},
         {"context_handle_noserialize",  tCONTEXTHANDLENOSERIALIZE},
         {"context_handle_serialize",    tCONTEXTHANDLENOSERIALIZE},
         {"context_handle",              tCONTEXTHANDLE},
         {"context_handle_noserialize",  tCONTEXTHANDLENOSERIALIZE},
         {"context_handle_serialize",    tCONTEXTHANDLENOSERIALIZE},
@@ -279,6 +298,7 @@ static const struct keyword attr_keywords[] =
         {"immediatebind",               tIMMEDIATEBIND},
         {"implicit_handle",             tIMPLICITHANDLE},
         {"in",                          tIN},
         {"immediatebind",               tIMMEDIATEBIND},
         {"implicit_handle",             tIMPLICITHANDLE},
         {"in",                          tIN},
+        {"in_line",                     tIN_LINE},
         {"input_sync",                  tINPUTSYNC},
         {"lcid",                        tLCID},
         {"length_is",                   tLENGTHIS},
         {"input_sync",                  tINPUTSYNC},
         {"lcid",                        tLCID},
         {"length_is",                   tLENGTHIS},
@@ -383,7 +403,6 @@ void pop_import(void)
                free(temp_name);
        }
        temp_name = import_stack[ptr].temp_name;
                free(temp_name);
        }
        temp_name = import_stack[ptr].temp_name;
-       free( input_name );
        input_name = import_stack[ptr].input_name;
        line_number = import_stack[ptr].line_number;
        import_stack_ptr--;
        input_name = import_stack[ptr].input_name;
        line_number = import_stack[ptr].line_number;
        import_stack_ptr--;
@@ -397,20 +416,11 @@ struct imports {
 int do_import(char *fname)
 {
        FILE *f;
 int do_import(char *fname)
 {
        FILE *f;
-       char *hname, *path, *p;
+       char *path;
        struct imports *import;
        int ptr = import_stack_ptr;
        int ret;
 
        struct imports *import;
        int ptr = import_stack_ptr;
        int ret;
 
-       if (!parse_only && do_header) {
-               hname = dup_basename(fname, ".idl");
-                p = hname + strlen(hname) - 2;
-                if (p <= hname || strcmp( p, ".h" )) strcat(hname, ".h");
-
-               fprintf(header, "#include <%s>\n", hname);
-               free(hname);
-       }
-
        import = first_import;
        while (import && strcmp(import->name, fname))
                import = import->next;
        import = first_import;
        while (import && strcmp(import->name, fname))
                import = import->next;
index 20b4648..3cc926d 100644 (file)
      aHEXNUM = 261,
      aDOUBLE = 262,
      aSTRING = 263,
      aHEXNUM = 261,
      aDOUBLE = 262,
      aSTRING = 263,
-     aUUID = 264,
-     aEOF = 265,
-     SHL = 266,
-     SHR = 267,
-     tAGGREGATABLE = 268,
-     tALLOCATE = 269,
-     tAPPOBJECT = 270,
-     tASYNC = 271,
-     tASYNCUUID = 272,
-     tAUTOHANDLE = 273,
-     tBINDABLE = 274,
-     tBOOLEAN = 275,
-     tBROADCAST = 276,
-     tBYTE = 277,
-     tBYTECOUNT = 278,
-     tCALLAS = 279,
-     tCALLBACK = 280,
-     tCASE = 281,
-     tCDECL = 282,
-     tCHAR = 283,
-     tCOCLASS = 284,
-     tCODE = 285,
-     tCOMMSTATUS = 286,
-     tCONST = 287,
-     tCONTEXTHANDLE = 288,
-     tCONTEXTHANDLENOSERIALIZE = 289,
-     tCONTEXTHANDLESERIALIZE = 290,
-     tCONTROL = 291,
-     tCPPQUOTE = 292,
-     tDEFAULT = 293,
-     tDEFAULTCOLLELEM = 294,
-     tDEFAULTVALUE = 295,
-     tDEFAULTVTABLE = 296,
-     tDISPLAYBIND = 297,
-     tDISPINTERFACE = 298,
-     tDLLNAME = 299,
-     tDOUBLE = 300,
-     tDUAL = 301,
-     tENDPOINT = 302,
-     tENTRY = 303,
-     tENUM = 304,
-     tERRORSTATUST = 305,
-     tEXPLICITHANDLE = 306,
-     tEXTERN = 307,
-     tFALSE = 308,
-     tFASTCALL = 309,
-     tFLOAT = 310,
-     tHANDLE = 311,
-     tHANDLET = 312,
-     tHELPCONTEXT = 313,
-     tHELPFILE = 314,
-     tHELPSTRING = 315,
-     tHELPSTRINGCONTEXT = 316,
-     tHELPSTRINGDLL = 317,
-     tHIDDEN = 318,
-     tHYPER = 319,
-     tID = 320,
-     tIDEMPOTENT = 321,
-     tIIDIS = 322,
-     tIMMEDIATEBIND = 323,
-     tIMPLICITHANDLE = 324,
-     tIMPORT = 325,
-     tIMPORTLIB = 326,
-     tIN = 327,
-     tINLINE = 328,
-     tINPUTSYNC = 329,
-     tINT = 330,
-     tINT64 = 331,
-     tINTERFACE = 332,
-     tLCID = 333,
-     tLENGTHIS = 334,
-     tLIBRARY = 335,
-     tLOCAL = 336,
-     tLONG = 337,
-     tMETHODS = 338,
-     tMODULE = 339,
-     tNONBROWSABLE = 340,
-     tNONCREATABLE = 341,
-     tNONEXTENSIBLE = 342,
-     tOBJECT = 343,
-     tODL = 344,
-     tOLEAUTOMATION = 345,
-     tOPTIONAL = 346,
-     tOUT = 347,
-     tPASCAL = 348,
-     tPOINTERDEFAULT = 349,
-     tPROPERTIES = 350,
-     tPROPGET = 351,
-     tPROPPUT = 352,
-     tPROPPUTREF = 353,
-     tPTR = 354,
-     tPUBLIC = 355,
-     tRANGE = 356,
-     tREADONLY = 357,
-     tREF = 358,
-     tREQUESTEDIT = 359,
-     tRESTRICTED = 360,
-     tRETVAL = 361,
-     tSAFEARRAY = 362,
-     tSHORT = 363,
-     tSIGNED = 364,
-     tSINGLE = 365,
-     tSIZEIS = 366,
-     tSIZEOF = 367,
-     tSMALL = 368,
-     tSOURCE = 369,
-     tSTDCALL = 370,
-     tSTRICTCONTEXTHANDLE = 371,
-     tSTRING = 372,
-     tSTRUCT = 373,
-     tSWITCH = 374,
-     tSWITCHIS = 375,
-     tSWITCHTYPE = 376,
-     tTRANSMITAS = 377,
-     tTRUE = 378,
-     tTYPEDEF = 379,
-     tUNION = 380,
-     tUNIQUE = 381,
-     tUNSIGNED = 382,
-     tUUID = 383,
-     tV1ENUM = 384,
-     tVARARG = 385,
-     tVERSION = 386,
-     tVOID = 387,
-     tWCHAR = 388,
-     tWIREMARSHAL = 389,
-     CAST = 390,
-     PPTR = 391,
-     NEG = 392,
-     ADDRESSOF = 393
+     aWSTRING = 264,
+     aUUID = 265,
+     aEOF = 266,
+     SHL = 267,
+     SHR = 268,
+     MEMBERPTR = 269,
+     EQUALITY = 270,
+     INEQUALITY = 271,
+     GREATEREQUAL = 272,
+     LESSEQUAL = 273,
+     LOGICALOR = 274,
+     LOGICALAND = 275,
+     tAGGREGATABLE = 276,
+     tALLOCATE = 277,
+     tAPPOBJECT = 278,
+     tASYNC = 279,
+     tASYNCUUID = 280,
+     tAUTOHANDLE = 281,
+     tBINDABLE = 282,
+     tBOOLEAN = 283,
+     tBROADCAST = 284,
+     tBYTE = 285,
+     tBYTECOUNT = 286,
+     tCALLAS = 287,
+     tCALLBACK = 288,
+     tCASE = 289,
+     tCDECL = 290,
+     tCHAR = 291,
+     tCOCLASS = 292,
+     tCODE = 293,
+     tCOMMSTATUS = 294,
+     tCONST = 295,
+     tCONTEXTHANDLE = 296,
+     tCONTEXTHANDLENOSERIALIZE = 297,
+     tCONTEXTHANDLESERIALIZE = 298,
+     tCONTROL = 299,
+     tCPPQUOTE = 300,
+     tDEFAULT = 301,
+     tDEFAULTCOLLELEM = 302,
+     tDEFAULTVALUE = 303,
+     tDEFAULTVTABLE = 304,
+     tDISPLAYBIND = 305,
+     tDISPINTERFACE = 306,
+     tDLLNAME = 307,
+     tDOUBLE = 308,
+     tDUAL = 309,
+     tENDPOINT = 310,
+     tENTRY = 311,
+     tENUM = 312,
+     tERRORSTATUST = 313,
+     tEXPLICITHANDLE = 314,
+     tEXTERN = 315,
+     tFALSE = 316,
+     tFASTCALL = 317,
+     tFLOAT = 318,
+     tHANDLE = 319,
+     tHANDLET = 320,
+     tHELPCONTEXT = 321,
+     tHELPFILE = 322,
+     tHELPSTRING = 323,
+     tHELPSTRINGCONTEXT = 324,
+     tHELPSTRINGDLL = 325,
+     tHIDDEN = 326,
+     tHYPER = 327,
+     tID = 328,
+     tIDEMPOTENT = 329,
+     tIIDIS = 330,
+     tIMMEDIATEBIND = 331,
+     tIMPLICITHANDLE = 332,
+     tIMPORT = 333,
+     tIMPORTLIB = 334,
+     tIN = 335,
+     tIN_LINE = 336,
+     tINLINE = 337,
+     tINPUTSYNC = 338,
+     tINT = 339,
+     tINT64 = 340,
+     tINTERFACE = 341,
+     tLCID = 342,
+     tLENGTHIS = 343,
+     tLIBRARY = 344,
+     tLOCAL = 345,
+     tLONG = 346,
+     tMETHODS = 347,
+     tMODULE = 348,
+     tNONBROWSABLE = 349,
+     tNONCREATABLE = 350,
+     tNONEXTENSIBLE = 351,
+     tNULL = 352,
+     tOBJECT = 353,
+     tODL = 354,
+     tOLEAUTOMATION = 355,
+     tOPTIONAL = 356,
+     tOUT = 357,
+     tPASCAL = 358,
+     tPOINTERDEFAULT = 359,
+     tPROPERTIES = 360,
+     tPROPGET = 361,
+     tPROPPUT = 362,
+     tPROPPUTREF = 363,
+     tPTR = 364,
+     tPUBLIC = 365,
+     tRANGE = 366,
+     tREADONLY = 367,
+     tREF = 368,
+     tREGISTER = 369,
+     tREQUESTEDIT = 370,
+     tRESTRICTED = 371,
+     tRETVAL = 372,
+     tSAFEARRAY = 373,
+     tSHORT = 374,
+     tSIGNED = 375,
+     tSINGLE = 376,
+     tSIZEIS = 377,
+     tSIZEOF = 378,
+     tSMALL = 379,
+     tSOURCE = 380,
+     tSTATIC = 381,
+     tSTDCALL = 382,
+     tSTRICTCONTEXTHANDLE = 383,
+     tSTRING = 384,
+     tSTRUCT = 385,
+     tSWITCH = 386,
+     tSWITCHIS = 387,
+     tSWITCHTYPE = 388,
+     tTRANSMITAS = 389,
+     tTRUE = 390,
+     tTYPEDEF = 391,
+     tUNION = 392,
+     tUNIQUE = 393,
+     tUNSIGNED = 394,
+     tUUID = 395,
+     tV1ENUM = 396,
+     tVARARG = 397,
+     tVERSION = 398,
+     tVOID = 399,
+     tWCHAR = 400,
+     tWIREMARSHAL = 401,
+     ADDRESSOF = 402,
+     NEG = 403,
+     POS = 404,
+     PPTR = 405,
+     CAST = 406
    };
 #endif
 /* Tokens.  */
    };
 #endif
 /* Tokens.  */
 #define aHEXNUM 261
 #define aDOUBLE 262
 #define aSTRING 263
 #define aHEXNUM 261
 #define aDOUBLE 262
 #define aSTRING 263
-#define aUUID 264
-#define aEOF 265
-#define SHL 266
-#define SHR 267
-#define tAGGREGATABLE 268
-#define tALLOCATE 269
-#define tAPPOBJECT 270
-#define tASYNC 271
-#define tASYNCUUID 272
-#define tAUTOHANDLE 273
-#define tBINDABLE 274
-#define tBOOLEAN 275
-#define tBROADCAST 276
-#define tBYTE 277
-#define tBYTECOUNT 278
-#define tCALLAS 279
-#define tCALLBACK 280
-#define tCASE 281
-#define tCDECL 282
-#define tCHAR 283
-#define tCOCLASS 284
-#define tCODE 285
-#define tCOMMSTATUS 286
-#define tCONST 287
-#define tCONTEXTHANDLE 288
-#define tCONTEXTHANDLENOSERIALIZE 289
-#define tCONTEXTHANDLESERIALIZE 290
-#define tCONTROL 291
-#define tCPPQUOTE 292
-#define tDEFAULT 293
-#define tDEFAULTCOLLELEM 294
-#define tDEFAULTVALUE 295
-#define tDEFAULTVTABLE 296
-#define tDISPLAYBIND 297
-#define tDISPINTERFACE 298
-#define tDLLNAME 299
-#define tDOUBLE 300
-#define tDUAL 301
-#define tENDPOINT 302
-#define tENTRY 303
-#define tENUM 304
-#define tERRORSTATUST 305
-#define tEXPLICITHANDLE 306
-#define tEXTERN 307
-#define tFALSE 308
-#define tFASTCALL 309
-#define tFLOAT 310
-#define tHANDLE 311
-#define tHANDLET 312
-#define tHELPCONTEXT 313
-#define tHELPFILE 314
-#define tHELPSTRING 315
-#define tHELPSTRINGCONTEXT 316
-#define tHELPSTRINGDLL 317
-#define tHIDDEN 318
-#define tHYPER 319
-#define tID 320
-#define tIDEMPOTENT 321
-#define tIIDIS 322
-#define tIMMEDIATEBIND 323
-#define tIMPLICITHANDLE 324
-#define tIMPORT 325
-#define tIMPORTLIB 326
-#define tIN 327
-#define tINLINE 328
-#define tINPUTSYNC 329
-#define tINT 330
-#define tINT64 331
-#define tINTERFACE 332
-#define tLCID 333
-#define tLENGTHIS 334
-#define tLIBRARY 335
-#define tLOCAL 336
-#define tLONG 337
-#define tMETHODS 338
-#define tMODULE 339
-#define tNONBROWSABLE 340
-#define tNONCREATABLE 341
-#define tNONEXTENSIBLE 342
-#define tOBJECT 343
-#define tODL 344
-#define tOLEAUTOMATION 345
-#define tOPTIONAL 346
-#define tOUT 347
-#define tPASCAL 348
-#define tPOINTERDEFAULT 349
-#define tPROPERTIES 350
-#define tPROPGET 351
-#define tPROPPUT 352
-#define tPROPPUTREF 353
-#define tPTR 354
-#define tPUBLIC 355
-#define tRANGE 356
-#define tREADONLY 357
-#define tREF 358
-#define tREQUESTEDIT 359
-#define tRESTRICTED 360
-#define tRETVAL 361
-#define tSAFEARRAY 362
-#define tSHORT 363
-#define tSIGNED 364
-#define tSINGLE 365
-#define tSIZEIS 366
-#define tSIZEOF 367
-#define tSMALL 368
-#define tSOURCE 369
-#define tSTDCALL 370
-#define tSTRICTCONTEXTHANDLE 371
-#define tSTRING 372
-#define tSTRUCT 373
-#define tSWITCH 374
-#define tSWITCHIS 375
-#define tSWITCHTYPE 376
-#define tTRANSMITAS 377
-#define tTRUE 378
-#define tTYPEDEF 379
-#define tUNION 380
-#define tUNIQUE 381
-#define tUNSIGNED 382
-#define tUUID 383
-#define tV1ENUM 384
-#define tVARARG 385
-#define tVERSION 386
-#define tVOID 387
-#define tWCHAR 388
-#define tWIREMARSHAL 389
-#define CAST 390
-#define PPTR 391
-#define NEG 392
-#define ADDRESSOF 393
+#define aWSTRING 264
+#define aUUID 265
+#define aEOF 266
+#define SHL 267
+#define SHR 268
+#define MEMBERPTR 269
+#define EQUALITY 270
+#define INEQUALITY 271
+#define GREATEREQUAL 272
+#define LESSEQUAL 273
+#define LOGICALOR 274
+#define LOGICALAND 275
+#define tAGGREGATABLE 276
+#define tALLOCATE 277
+#define tAPPOBJECT 278
+#define tASYNC 279
+#define tASYNCUUID 280
+#define tAUTOHANDLE 281
+#define tBINDABLE 282
+#define tBOOLEAN 283
+#define tBROADCAST 284
+#define tBYTE 285
+#define tBYTECOUNT 286
+#define tCALLAS 287
+#define tCALLBACK 288
+#define tCASE 289
+#define tCDECL 290
+#define tCHAR 291
+#define tCOCLASS 292
+#define tCODE 293
+#define tCOMMSTATUS 294
+#define tCONST 295
+#define tCONTEXTHANDLE 296
+#define tCONTEXTHANDLENOSERIALIZE 297
+#define tCONTEXTHANDLESERIALIZE 298
+#define tCONTROL 299
+#define tCPPQUOTE 300
+#define tDEFAULT 301
+#define tDEFAULTCOLLELEM 302
+#define tDEFAULTVALUE 303
+#define tDEFAULTVTABLE 304
+#define tDISPLAYBIND 305
+#define tDISPINTERFACE 306
+#define tDLLNAME 307
+#define tDOUBLE 308
+#define tDUAL 309
+#define tENDPOINT 310
+#define tENTRY 311
+#define tENUM 312
+#define tERRORSTATUST 313
+#define tEXPLICITHANDLE 314
+#define tEXTERN 315
+#define tFALSE 316
+#define tFASTCALL 317
+#define tFLOAT 318
+#define tHANDLE 319
+#define tHANDLET 320
+#define tHELPCONTEXT 321
+#define tHELPFILE 322
+#define tHELPSTRING 323
+#define tHELPSTRINGCONTEXT 324
+#define tHELPSTRINGDLL 325
+#define tHIDDEN 326
+#define tHYPER 327
+#define tID 328
+#define tIDEMPOTENT 329
+#define tIIDIS 330
+#define tIMMEDIATEBIND 331
+#define tIMPLICITHANDLE 332
+#define tIMPORT 333
+#define tIMPORTLIB 334
+#define tIN 335
+#define tIN_LINE 336
+#define tINLINE 337
+#define tINPUTSYNC 338
+#define tINT 339
+#define tINT64 340
+#define tINTERFACE 341
+#define tLCID 342
+#define tLENGTHIS 343
+#define tLIBRARY 344
+#define tLOCAL 345
+#define tLONG 346
+#define tMETHODS 347
+#define tMODULE 348
+#define tNONBROWSABLE 349
+#define tNONCREATABLE 350
+#define tNONEXTENSIBLE 351
+#define tNULL 352
+#define tOBJECT 353
+#define tODL 354
+#define tOLEAUTOMATION 355
+#define tOPTIONAL 356
+#define tOUT 357
+#define tPASCAL 358
+#define tPOINTERDEFAULT 359
+#define tPROPERTIES 360
+#define tPROPGET 361
+#define tPROPPUT 362
+#define tPROPPUTREF 363
+#define tPTR 364
+#define tPUBLIC 365
+#define tRANGE 366
+#define tREADONLY 367
+#define tREF 368
+#define tREGISTER 369
+#define tREQUESTEDIT 370
+#define tRESTRICTED 371
+#define tRETVAL 372
+#define tSAFEARRAY 373
+#define tSHORT 374
+#define tSIGNED 375
+#define tSINGLE 376
+#define tSIZEIS 377
+#define tSIZEOF 378
+#define tSMALL 379
+#define tSOURCE 380
+#define tSTATIC 381
+#define tSTDCALL 382
+#define tSTRICTCONTEXTHANDLE 383
+#define tSTRING 384
+#define tSTRUCT 385
+#define tSWITCH 386
+#define tSWITCHIS 387
+#define tSWITCHTYPE 388
+#define tTRANSMITAS 389
+#define tTRUE 390
+#define tTYPEDEF 391
+#define tUNION 392
+#define tUNIQUE 393
+#define tUNSIGNED 394
+#define tUUID 395
+#define tV1ENUM 396
+#define tVARARG 397
+#define tVERSION 398
+#define tVOID 399
+#define tWCHAR 400
+#define tWIREMARSHAL 401
+#define ADDRESSOF 402
+#define NEG 403
+#define POS 404
+#define PPTR 405
+#define CAST 406
 
 
 
 
 
 
  * IDL Compiler
  *
  * Copyright 2002 Ove Kaaven
  * IDL Compiler
  *
  * Copyright 2002 Ove Kaaven
+ * Copyright 2006-2008 Robert Shearman
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
 #include "header.h"
 #include "typelib.h"
 #include "typegen.h"
 #include "header.h"
 #include "typelib.h"
 #include "typegen.h"
+#include "expr.h"
 
 #if defined(YYBYACC)
        /* Berkeley yacc (byacc) doesn't seem to know about these */
 
 #if defined(YYBYACC)
        /* Berkeley yacc (byacc) doesn't seem to know about these */
 #define YYERROR_VERBOSE
 
 unsigned char pointer_default = RPC_FC_UP;
 #define YYERROR_VERBOSE
 
 unsigned char pointer_default = RPC_FC_UP;
+static int is_in_interface = FALSE;
 static int is_object_interface = FALSE;
 /* are we inside a library block? */
 static int is_inside_library = FALSE;
 static int is_object_interface = FALSE;
 /* are we inside a library block? */
 static int is_inside_library = FALSE;
@@ -423,6 +452,19 @@ struct typenode {
   struct list entry;
 };
 
   struct list entry;
 };
 
+struct _import_t
+{
+  char *name;
+  int import_performed;
+};
+
+typedef struct _decl_spec_t
+{
+  type_t *type;
+  attr_list_t *attrs;
+  enum storage_class stgclass;
+} decl_spec_t;
+
 typelist_t incomplete_types = LIST_INIT(incomplete_types);
 
 static void add_incomplete(type_t *t);
 typelist_t incomplete_types = LIST_INIT(incomplete_types);
 
 static void add_incomplete(type_t *t);
@@ -430,65 +472,75 @@ static void fix_incomplete(void);
 
 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 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_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 attr_t *make_attr(enum attr_type type);
 static attr_t *make_attrv(enum attr_type type, unsigned long val);
 static attr_t *make_attrp(enum attr_type type, void *val);
 static attr_t *make_attr(enum attr_type type);
 static attr_t *make_attrv(enum attr_type type, unsigned long val);
 static attr_t *make_attrp(enum attr_type type, void *val);
-static expr_t *make_expr(enum expr_type type);
-static expr_t *make_exprl(enum expr_type type, long val);
-static expr_t *make_exprd(enum expr_type type, double val);
-static expr_t *make_exprs(enum expr_type type, char *val);
-static expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr);
-static expr_t *make_expr1(enum expr_type type, expr_t *expr);
-static expr_t *make_expr2(enum expr_type type, expr_t *exp1, expr_t *exp2);
-static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3);
-static type_t *make_type(unsigned char type, type_t *ref);
 static expr_list_t *append_expr(expr_list_t *list, expr_t *expr);
 static array_dims_t *append_array(array_dims_t *list, expr_t *expr);
 static expr_list_t *append_expr(expr_list_t *list, expr_t *expr);
 static array_dims_t *append_array(array_dims_t *list, expr_t *expr);
-static void set_type(var_t *v, type_t *type, const pident_t *pident, array_dims_t *arr, int top);
+static void set_type(var_t *v, 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 ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface);
 static ifref_t *make_ifref(type_t *iface);
 static var_list_t *append_var(var_list_t *list, var_t *var);
 static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface);
 static ifref_t *make_ifref(type_t *iface);
 static var_list_t *append_var(var_list_t *list, var_t *var);
+static var_list_t *append_var_list(var_list_t *list, var_list_t *vars);
 static var_t *make_var(char *name);
 static var_t *make_var(char *name);
-static pident_list_t *append_pident(pident_list_t *list, pident_t *p);
-static pident_t *make_pident(var_t *var);
+static declarator_list_t *append_declarator(declarator_list_t *list, declarator_t *p);
+static declarator_t *make_declarator(var_t *var);
 static func_list_t *append_func(func_list_t *list, func_t *func);
 static func_list_t *append_func(func_list_t *list, func_t *func);
-static func_t *make_func(var_t *def, var_list_t *args);
+static func_t *make_func(var_t *def);
 static type_t *make_class(char *name);
 static type_t *make_safearray(type_t *type);
 static type_t *make_builtin(char *name);
 static type_t *make_int(int sign);
 static type_t *make_class(char *name);
 static type_t *make_safearray(type_t *type);
 static type_t *make_builtin(char *name);
 static type_t *make_int(int sign);
+static typelib_t *make_library(const char *name, const attr_list_t *attrs);
+static type_t *make_func_type(var_list_t *args);
+static type_t *make_pointer_type(type_t *ref, attr_list_t *attrs);
+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_type(type_t *type, const char *name, int t);
-static type_t *reg_typedefs(type_t *type, var_list_t *names, attr_list_t *attrs);
-static type_t *find_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_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 var_t *reg_const(var_t *var);
 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 var_t *reg_const(var_t *var);
-static var_t *find_const(char *name, int f);
 
 
-static void write_libid(const char *name, const attr_list_t *attr);
+static void write_libid(const typelib_t *typelib);
 static void write_clsid(type_t *cls);
 static void write_diid(type_t *iface);
 static void write_iid(type_t *iface);
 
 static int compute_method_indexes(type_t *iface);
 static char *gen_name(void);
 static void write_clsid(type_t *cls);
 static void write_diid(type_t *iface);
 static void write_iid(type_t *iface);
 
 static int compute_method_indexes(type_t *iface);
 static char *gen_name(void);
-static void process_typedefs(var_list_t *names);
+static statement_t *process_typedefs(var_list_t *names);
 static void check_arg(var_t *arg);
 static void check_functions(const type_t *iface);
 static void check_arg(var_t *arg);
 static void check_functions(const type_t *iface);
-static void check_all_user_types(ifref_list_t *ifaces);
-static const attr_list_t *check_iface_attrs(const char *name, const attr_list_t *attrs);
+static void check_all_user_types(const statement_list_t *stmts);
+static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs);
 static attr_list_t *check_function_attrs(const char *name, attr_list_t *attrs);
 static attr_list_t *check_typedef_attrs(attr_list_t *attrs);
 static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs);
 static attr_list_t *check_function_attrs(const char *name, attr_list_t *attrs);
 static attr_list_t *check_typedef_attrs(attr_list_t *attrs);
 static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs);
-static const attr_list_t *check_library_attrs(const char *name, const attr_list_t *attrs);
+static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs);
 static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs);
 static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs);
-static const attr_list_t *check_module_attrs(const char *name, const attr_list_t *attrs);
-static const attr_list_t *check_coclass_attrs(const char *name, const attr_list_t *attrs);
+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);
 const char *get_attr_display_name(enum attr_type type);
+static void add_explicit_handle_if_necessary(func_t *func);
+
+static statement_t *make_statement(enum statement_type type);
+static statement_t *make_statement_type_decl(type_t *type);
+static statement_t *make_statement_reference(type_t *type);
+static statement_t *make_statement_declaration(var_t *var);
+static statement_t *make_statement_library(typelib_t *typelib);
+static statement_t *make_statement_cppquote(const char *str);
+static statement_t *make_statement_importlib(const char *str);
+static statement_t *make_statement_module(type_t *type);
+static statement_t *make_statement_import(const char *str);
+static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt);
+static func_list_t *append_func_from_statement(func_list_t *list, statement_t *stmt);
 
 #define tsENUM   1
 #define tsSTRUCT 2
 
 #define tsENUM   1
 #define tsSTRUCT 2
@@ -515,7 +567,7 @@ const char *get_attr_display_name(enum attr_type type);
 #endif
 
 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
 #endif
 
 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 151 "parser.y"
+#line 177 "parser.y"
 typedef union YYSTYPE {
        attr_t *attr;
        attr_list_t *attr_list;
 typedef union YYSTYPE {
        attr_t *attr;
        attr_list_t *attr_list;
@@ -526,10 +578,12 @@ typedef union YYSTYPE {
        type_t *type;
        var_t *var;
        var_list_t *var_list;
        type_t *type;
        var_t *var;
        var_list_t *var_list;
-       pident_t *pident;
-       pident_list_t *pident_list;
+       declarator_t *declarator;
+       declarator_list_t *declarator_list;
        func_t *func;
        func_list_t *func_list;
        func_t *func;
        func_list_t *func_list;
+       statement_t *statement;
+       statement_list_t *stmt_list;
        ifref_t *ifref;
        ifref_list_t *ifref_list;
        char *str;
        ifref_t *ifref;
        ifref_list_t *ifref_list;
        char *str;
@@ -537,9 +591,13 @@ typedef union YYSTYPE {
        unsigned int num;
        double dbl;
        interface_info_t ifinfo;
        unsigned int num;
        double dbl;
        interface_info_t ifinfo;
+       typelib_t *typelib;
+       struct _import_t *import;
+       struct _decl_spec_t *declspec;
+       enum storage_class stgclass;
 } YYSTYPE;
 /* Line 196 of yacc.c.  */
 } YYSTYPE;
 /* Line 196 of yacc.c.  */
-#line 543 "parser.tab.c"
+#line 601 "parser.tab.c"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
@@ -551,7 +609,7 @@ typedef union YYSTYPE {
 
 
 /* Line 219 of yacc.c.  */
 
 
 /* Line 219 of yacc.c.  */
-#line 555 "parser.tab.c"
+#line 613 "parser.tab.c"
 
 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
 # define YYSIZE_T __SIZE_TYPE__
 
 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
 # define YYSIZE_T __SIZE_TYPE__
@@ -702,20 +760,20 @@ union yyalloc
 /* YYFINAL -- State number of the termination state. */
 #define YYFINAL  3
 /* YYLAST -- Last index in YYTABLE.  */
 /* YYFINAL -- State number of the termination state. */
 #define YYFINAL  3
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   1042
+#define YYLAST   2015
 
 /* YYNTOKENS -- Number of terminals. */
 
 /* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS  158
+#define YYNTOKENS  176
 /* YYNNTS -- Number of nonterminals. */
 /* YYNNTS -- Number of nonterminals. */
-#define YYNNTS  78
+#define YYNNTS  87
 /* YYNRULES -- Number of rules. */
 /* YYNRULES -- Number of rules. */
-#define YYNRULES  278
+#define YYNRULES  308
 /* YYNRULES -- Number of states. */
 /* YYNRULES -- Number of states. */
-#define YYNSTATES  507
+#define YYNSTATES  546
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   393
+#define YYMAXUTOK   406
 
 #define YYTRANSLATE(YYX)                                               \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
 #define YYTRANSLATE(YYX)                                               \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -726,16 +784,16 @@ static const unsigned char yytranslate[] =
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,   139,     2,
-     150,   151,   142,   141,   135,   140,   157,   143,     2,     2,
-       2,     2,     2,     2,     2,     2,     2,     2,   137,   149,
-       2,   156,     2,   136,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,   160,     2,     2,     2,   159,   152,     2,
+     171,   172,   157,   156,   147,   155,   167,   158,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,   149,   170,
+     153,   175,   154,   148,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,   154,     2,   155,     2,     2,     2,     2,     2,     2,
+       2,   168,     2,   169,   151,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-       2,     2,     2,   152,   138,   153,   144,     2,     2,     2,
+       2,     2,     2,   173,   150,   174,   161,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -762,7 +820,8 @@ static const unsigned char yytranslate[] =
      105,   106,   107,   108,   109,   110,   111,   112,   113,   114,
      115,   116,   117,   118,   119,   120,   121,   122,   123,   124,
      125,   126,   127,   128,   129,   130,   131,   132,   133,   134,
      105,   106,   107,   108,   109,   110,   111,   112,   113,   114,
      115,   116,   117,   118,   119,   120,   121,   122,   123,   124,
      125,   126,   127,   128,   129,   130,   131,   132,   133,   134,
-     145,   146,   147,   148
+     135,   136,   137,   138,   139,   140,   141,   142,   143,   144,
+     145,   146,   162,   163,   164,   165,   166
 };
 
 #if YYDEBUG
 };
 
 #if YYDEBUG
@@ -772,156 +831,170 @@ static const unsigned short int yyprhs[] =
 {
        0,     0,     3,     5,     6,     9,    12,    16,    19,    22,
       25,    28,    29,    32,    35,    39,    42,    45,    48,    51,
 {
        0,     0,     3,     5,     6,     9,    12,    16,    19,    22,
       25,    28,    29,    32,    35,    39,    42,    45,    48,    51,
-      54,    55,    59,    62,    63,    65,    68,    70,    73,    76,
-      78,    81,    84,    87,    92,    96,   100,   106,   109,   113,
-     118,   119,   121,   123,   125,   129,   131,   136,   140,   141,
-     145,   149,   151,   155,   160,   161,   163,   167,   169,   173,
-     178,   180,   184,   185,   187,   189,   191,   193,   195,   197,
-     202,   207,   209,   211,   213,   215,   217,   219,   224,   229,
-     231,   233,   238,   240,   245,   250,   255,   257,   259,   264,
-     269,   274,   279,   284,   286,   291,   293,   298,   300,   306,
-     308,   310,   315,   317,   319,   321,   323,   325,   327,   329,
-     331,   333,   338,   340,   342,   344,   346,   353,   355,   357,
-     359,   361,   366,   368,   370,   372,   377,   382,   387,   392,
-     394,   396,   401,   406,   408,   410,   412,   414,   416,   418,
-     420,   421,   424,   429,   433,   439,   440,   443,   445,   447,
-     451,   455,   457,   463,   465,   469,   470,   472,   474,   476,
-     478,   480,   482,   484,   490,   494,   498,   502,   506,   510,
-     514,   518,   522,   525,   528,   531,   534,   539,   544,   548,
-     550,   554,   556,   561,   562,   565,   568,   572,   575,   577,
-     582,   586,   587,   589,   590,   592,   594,   596,   598,   600,
-     602,   604,   607,   610,   612,   614,   616,   618,   620,   622,
-     624,   625,   627,   629,   632,   634,   637,   640,   642,   644,
-     647,   650,   653,   659,   660,   663,   666,   669,   672,   675,
-     678,   682,   685,   689,   695,   701,   702,   705,   708,   711,
-     714,   721,   730,   733,   736,   739,   742,   745,   748,   754,
-     757,   760,   763,   765,   770,   772,   776,   778,   780,   784,
-     786,   788,   790,   796,   798,   800,   802,   805,   807,   810,
-     812,   815,   817,   820,   825,   830,   836,   847,   849
+      54,    55,    58,    59,    61,    63,    66,    69,    71,    74,
+      77,    80,    85,    89,    93,    99,   102,   106,   111,   112,
+     114,   116,   118,   122,   124,   128,   131,   135,   139,   140,
+     142,   146,   148,   152,   157,   159,   163,   164,   166,   168,
+     170,   172,   174,   176,   181,   186,   188,   190,   192,   194,
+     196,   198,   203,   205,   207,   212,   214,   219,   224,   226,
+     228,   233,   238,   243,   248,   253,   255,   260,   262,   267,
+     269,   275,   277,   279,   284,   289,   291,   293,   295,   297,
+     299,   301,   303,   305,   307,   312,   314,   316,   318,   320,
+     327,   329,   331,   333,   335,   340,   342,   344,   346,   351,
+     356,   361,   366,   368,   370,   375,   380,   382,   384,   386,
+     388,   390,   392,   394,   395,   398,   403,   407,   408,   411,
+     413,   415,   419,   423,   425,   431,   433,   437,   438,   440,
+     442,   444,   446,   448,   450,   452,   454,   456,   458,   464,
+     468,   472,   476,   480,   484,   488,   492,   496,   500,   504,
+     508,   512,   516,   520,   524,   528,   532,   536,   539,   542,
+     545,   548,   551,   554,   558,   562,   567,   572,   577,   581,
+     583,   587,   589,   591,   592,   595,   600,   604,   607,   610,
+     611,   614,   617,   619,   623,   627,   631,   634,   635,   637,
+     638,   640,   642,   644,   646,   648,   650,   652,   655,   658,
+     660,   662,   664,   666,   668,   670,   672,   673,   675,   677,
+     680,   682,   685,   688,   690,   692,   695,   698,   701,   707,
+     708,   711,   714,   717,   720,   723,   726,   730,   733,   737,
+     743,   749,   750,   753,   756,   759,   762,   769,   778,   781,
+     784,   787,   790,   793,   796,   802,   804,   806,   808,   810,
+     812,   813,   816,   819,   823,   824,   826,   829,   832,   835,
+     839,   842,   844,   846,   850,   853,   858,   860,   864,   866,
+     870,   872,   874,   876,   882,   884,   886,   888,   890,   893,
+     895,   898,   900,   903,   908,   913,   919,   930,   932
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
 static const short int yyrhs[] =
 {
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
 static const short int yyrhs[] =
 {
-     159,     0,    -1,   160,    -1,    -1,   160,   222,    -1,   160,
-     221,    -1,   160,   208,   149,    -1,   160,   210,    -1,   160,
-     225,    -1,   160,   171,    -1,   160,   164,    -1,    -1,   161,
-     222,    -1,   161,   221,    -1,   161,   208,   149,    -1,   161,
-     210,    -1,   161,   225,    -1,   161,   164,    -1,   161,   168,
-      -1,   161,   171,    -1,    -1,   162,   201,   149,    -1,   162,
-     164,    -1,    -1,   149,    -1,   187,   149,    -1,   165,    -1,
-     191,   149,    -1,   197,   149,    -1,   167,    -1,   231,   149,
-      -1,   233,   149,    -1,   234,   149,    -1,    37,   150,     8,
-     151,    -1,    70,     8,   149,    -1,   166,   161,    10,    -1,
-      71,   150,     8,   151,   163,    -1,    80,     3,    -1,   179,
-     169,   152,    -1,   170,   161,   153,   163,    -1,    -1,   174,
-      -1,   132,    -1,   175,    -1,   174,   135,   175,    -1,   173,
-      -1,   179,   232,   226,   176,    -1,   232,   226,   176,    -1,
-      -1,   154,   177,   155,    -1,   154,   142,   155,    -1,   193,
-      -1,   177,   135,   194,    -1,   177,   155,   154,   194,    -1,
-      -1,   179,    -1,   154,   180,   155,    -1,   182,    -1,   180,
-     135,   182,    -1,   180,   155,   154,   182,    -1,     8,    -1,
-     181,   135,     8,    -1,    -1,    13,    -1,    15,    -1,    16,
-      -1,    18,    -1,    19,    -1,    21,    -1,    24,   150,   204,
-     151,    -1,    26,   150,   195,   151,    -1,    33,    -1,    34,
-      -1,    35,    -1,    36,    -1,    38,    -1,    39,    -1,    40,
-     150,   196,   151,    -1,    40,   150,     8,   151,    -1,    41,
-      -1,    42,    -1,    44,   150,     8,   151,    -1,    46,    -1,
-      47,   150,   181,   151,    -1,    48,   150,     8,   151,    -1,
-      48,   150,   196,   151,    -1,    51,    -1,    56,    -1,    58,
-     150,   196,   151,    -1,    59,   150,     8,   151,    -1,    60,
-     150,     8,   151,    -1,    61,   150,   196,   151,    -1,    62,
-     150,     8,   151,    -1,    63,    -1,    65,   150,   196,   151,
-      -1,    66,    -1,    67,   150,   194,   151,    -1,    68,    -1,
-      69,   150,    57,     3,   151,    -1,    72,    -1,    74,    -1,
-      79,   150,   192,   151,    -1,    81,    -1,    85,    -1,    86,
-      -1,    87,    -1,    88,    -1,    89,    -1,    90,    -1,    91,
-      -1,    92,    -1,    94,   150,   230,   151,    -1,    96,    -1,
-      97,    -1,    98,    -1,   100,    -1,   101,   150,   196,   135,
-     196,   151,    -1,   102,    -1,   104,    -1,   105,    -1,   106,
-      -1,   111,   150,   192,   151,    -1,   114,    -1,   116,    -1,
-     117,    -1,   120,   150,   194,   151,    -1,   121,   150,   232,
-     151,    -1,   122,   150,   232,   151,    -1,   128,   150,   183,
-     151,    -1,   129,    -1,   130,    -1,   131,   150,   235,   151,
-      -1,   134,   150,   232,   151,    -1,   230,    -1,     9,    -1,
-       8,    -1,    27,    -1,    54,    -1,    93,    -1,   115,    -1,
-      -1,   185,   186,    -1,    26,   194,   137,   199,    -1,    38,
-     137,   199,    -1,    32,   232,   204,   156,   196,    -1,    -1,
-     189,   135,    -1,   189,    -1,   190,    -1,   189,   135,   190,
-      -1,   204,   156,   196,    -1,   204,    -1,    49,   203,   152,
-     188,   153,    -1,   193,    -1,   192,   135,   193,    -1,    -1,
-     194,    -1,     5,    -1,     6,    -1,     7,    -1,    53,    -1,
-     123,    -1,     3,    -1,   194,   136,   194,   137,   194,    -1,
-     194,   138,   194,    -1,   194,   139,   194,    -1,   194,   141,
-     194,    -1,   194,   140,   194,    -1,   194,   142,   194,    -1,
-     194,   143,   194,    -1,   194,    11,   194,    -1,   194,    12,
-     194,    -1,   144,   194,    -1,   140,   194,    -1,   139,   194,
-      -1,   142,   194,    -1,   150,   232,   151,   194,    -1,   112,
-     150,   232,   151,    -1,   150,   194,   151,    -1,   196,    -1,
-     195,   135,   196,    -1,   194,    -1,    52,    32,   232,   204,
-      -1,    -1,   198,   199,    -1,   200,   149,    -1,   178,   234,
-     149,    -1,   179,   149,    -1,   149,    -1,   178,   232,   226,
-     176,    -1,   178,   232,   226,    -1,    -1,   204,    -1,    -1,
-       3,    -1,     4,    -1,     3,    -1,     4,    -1,    22,    -1,
-     133,    -1,   207,    -1,   109,   207,    -1,   127,   207,    -1,
-     127,    -1,    55,    -1,   110,    -1,    45,    -1,    20,    -1,
-      50,    -1,    57,    -1,    -1,    75,    -1,    75,    -1,   108,
-     206,    -1,   113,    -1,    82,   206,    -1,    64,   206,    -1,
-      76,    -1,    28,    -1,    29,     3,    -1,    29,     4,    -1,
-     179,   208,    -1,   209,   152,   211,   153,   163,    -1,    -1,
-     211,   212,    -1,   178,   222,    -1,    43,     3,    -1,    43,
-       4,    -1,   179,   213,    -1,    95,   137,    -1,   215,   200,
-     149,    -1,    83,   137,    -1,   216,   201,   149,    -1,   214,
-     152,   215,   216,   153,    -1,   214,   152,   219,   149,   153,
-      -1,    -1,   137,     4,    -1,    77,     3,    -1,    77,     4,
-      -1,   179,   219,    -1,   220,   218,   152,   162,   153,   163,
-      -1,   220,   137,     3,   152,   167,   162,   153,   163,    -1,
-     217,   163,    -1,   219,   149,    -1,   213,   149,    -1,    84,
-       3,    -1,    84,     4,    -1,   179,   223,    -1,   224,   152,
-     162,   153,   163,    -1,   142,   226,    -1,    32,   226,    -1,
-     184,   226,    -1,   228,    -1,   228,   150,   172,   151,    -1,
-     204,    -1,   150,   226,   151,    -1,   227,    -1,   226,    -1,
-     229,   135,   226,    -1,   103,    -1,   126,    -1,    99,    -1,
-     118,   203,   152,   198,   153,    -1,   132,    -1,     4,    -1,
-     205,    -1,    32,   232,    -1,   191,    -1,    49,     3,    -1,
-     231,    -1,   118,     3,    -1,   234,    -1,   125,     3,    -1,
-     107,   150,   232,   151,    -1,   124,   178,   232,   229,    -1,
-     125,   203,   152,   198,   153,    -1,   125,   203,   119,   150,
-     200,   151,   202,   152,   185,   153,    -1,     5,    -1,     5,
-     157,     5,    -1
+     177,     0,    -1,   178,    -1,    -1,   178,   242,    -1,   178,
+     241,    -1,   178,   228,   170,    -1,   178,   230,    -1,   178,
+     245,    -1,   178,   189,    -1,   178,   182,    -1,    -1,   179,
+     242,    -1,   179,   241,    -1,   179,   228,   170,    -1,   179,
+     230,    -1,   179,   245,    -1,   179,   182,    -1,   179,   186,
+      -1,   179,   189,    -1,    -1,   180,   182,    -1,    -1,   170,
+      -1,   183,    -1,   207,   170,    -1,   221,   170,    -1,   185,
+      -1,   258,   170,    -1,   260,   170,    -1,   261,   170,    -1,
+      45,   171,     8,   172,    -1,    78,     8,   170,    -1,   184,
+     179,    11,    -1,    79,   171,     8,   172,   181,    -1,    89,
+       3,    -1,   196,   187,   173,    -1,   188,   179,   174,   181,
+      -1,    -1,   192,    -1,   144,    -1,   193,    -1,   192,   147,
+     193,    -1,   191,    -1,   196,   250,   253,    -1,   250,   253,
+      -1,   168,   209,   169,    -1,   168,   157,   169,    -1,    -1,
+     196,    -1,   168,   197,   169,    -1,   199,    -1,   197,   147,
+     199,    -1,   197,   169,   168,   199,    -1,     8,    -1,   198,
+     147,     8,    -1,    -1,    21,    -1,    23,    -1,    24,    -1,
+      26,    -1,    27,    -1,    29,    -1,    32,   171,   224,   172,
+      -1,    34,   171,   211,   172,    -1,    41,    -1,    42,    -1,
+      43,    -1,    44,    -1,    46,    -1,    47,    -1,    48,   171,
+     213,   172,    -1,    49,    -1,    50,    -1,    52,   171,     8,
+     172,    -1,    54,    -1,    55,   171,   198,   172,    -1,    56,
+     171,   213,   172,    -1,    59,    -1,    64,    -1,    66,   171,
+     212,   172,    -1,    67,   171,     8,   172,    -1,    68,   171,
+       8,   172,    -1,    69,   171,   212,   172,    -1,    70,   171,
+       8,   172,    -1,    71,    -1,    73,   171,   212,   172,    -1,
+      74,    -1,    75,   171,   210,   172,    -1,    76,    -1,    77,
+     171,    65,     3,   172,    -1,    80,    -1,    83,    -1,    88,
+     171,   208,   172,    -1,    87,   171,   212,   172,    -1,    90,
+      -1,    94,    -1,    95,    -1,    96,    -1,    98,    -1,    99,
+      -1,   100,    -1,   101,    -1,   102,    -1,   104,   171,   257,
+     172,    -1,   106,    -1,   107,    -1,   108,    -1,   110,    -1,
+     111,   171,   212,   147,   212,   172,    -1,   112,    -1,   115,
+      -1,   116,    -1,   117,    -1,   122,   171,   208,   172,    -1,
+     125,    -1,   128,    -1,   129,    -1,   132,   171,   210,   172,
+      -1,   133,   171,   259,   172,    -1,   134,   171,   259,   172,
+      -1,   140,   171,   200,   172,    -1,   141,    -1,   142,    -1,
+     143,   171,   262,   172,    -1,   146,   171,   259,   172,    -1,
+     257,    -1,    10,    -1,     8,    -1,    35,    -1,    62,    -1,
+     103,    -1,   127,    -1,    -1,   202,   203,    -1,    34,   212,
+     149,   218,    -1,    46,   149,   218,    -1,    -1,   205,   147,
+      -1,   205,    -1,   206,    -1,   205,   147,   206,    -1,   224,
+     175,   212,    -1,   224,    -1,    57,   223,   173,   204,   174,
+      -1,   209,    -1,   208,   147,   209,    -1,    -1,   210,    -1,
+       5,    -1,     6,    -1,     7,    -1,    61,    -1,    97,    -1,
+     135,    -1,     8,    -1,     9,    -1,     3,    -1,   210,   148,
+     210,   149,   210,    -1,   210,    19,   210,    -1,   210,    20,
+     210,    -1,   210,   150,   210,    -1,   210,   151,   210,    -1,
+     210,   152,   210,    -1,   210,    15,   210,    -1,   210,    16,
+     210,    -1,   210,   154,   210,    -1,   210,   153,   210,    -1,
+     210,    17,   210,    -1,   210,    18,   210,    -1,   210,    12,
+     210,    -1,   210,    13,   210,    -1,   210,   156,   210,    -1,
+     210,   155,   210,    -1,   210,   159,   210,    -1,   210,   157,
+     210,    -1,   210,   158,   210,    -1,   160,   210,    -1,   161,
+     210,    -1,   156,   210,    -1,   155,   210,    -1,   152,   210,
+      -1,   157,   210,    -1,   210,    14,     3,    -1,   210,   167,
+       3,    -1,   171,   259,   172,   210,    -1,   123,   171,   259,
+     172,    -1,   210,   168,   210,   169,    -1,   171,   210,   172,
+      -1,   212,    -1,   211,   147,   212,    -1,   210,    -1,   210,
+      -1,    -1,   214,   215,    -1,   195,   250,   255,   170,    -1,
+     195,   261,   170,    -1,   219,   170,    -1,   196,   170,    -1,
+      -1,   217,   216,    -1,   219,   170,    -1,   170,    -1,   195,
+     250,   253,    -1,   195,   250,   253,    -1,   196,   250,   256,
+      -1,   250,   256,    -1,    -1,   224,    -1,    -1,     3,    -1,
+       4,    -1,     3,    -1,     4,    -1,    30,    -1,   145,    -1,
+     227,    -1,   120,   227,    -1,   139,   227,    -1,   139,    -1,
+      63,    -1,   121,    -1,    53,    -1,    28,    -1,    58,    -1,
+      65,    -1,    -1,    84,    -1,    84,    -1,   119,   226,    -1,
+     124,    -1,    91,   226,    -1,    72,   226,    -1,    85,    -1,
+      36,    -1,    37,     3,    -1,    37,     4,    -1,   196,   228,
+      -1,   229,   173,   231,   174,   181,    -1,    -1,   231,   232,
+      -1,   195,   242,    -1,    51,     3,    -1,    51,     4,    -1,
+     196,   233,    -1,   105,   149,    -1,   235,   219,   170,    -1,
+      92,   149,    -1,   236,   220,   170,    -1,   234,   173,   235,
+     236,   174,    -1,   234,   173,   239,   170,   174,    -1,    -1,
+     149,     4,    -1,    86,     3,    -1,    86,     4,    -1,   196,
+     239,    -1,   240,   238,   173,   180,   174,   181,    -1,   240,
+     149,     3,   173,   185,   180,   174,   181,    -1,   237,   181,
+      -1,   239,   170,    -1,   233,   170,    -1,    93,     3,    -1,
+      93,     4,    -1,   196,   243,    -1,   244,   173,   180,   174,
+     181,    -1,    60,    -1,   126,    -1,   114,    -1,    82,    -1,
+      40,    -1,    -1,   249,   248,    -1,   259,   251,    -1,   252,
+     259,   251,    -1,    -1,   252,    -1,   248,   251,    -1,   247,
+     251,    -1,   246,   251,    -1,   157,   249,   253,    -1,   201,
+     253,    -1,   254,    -1,   224,    -1,   171,   253,   172,    -1,
+     254,   194,    -1,   254,   171,   190,   172,    -1,   253,    -1,
+     255,   147,   253,    -1,   253,    -1,   253,   175,   213,    -1,
+     113,    -1,   138,    -1,   109,    -1,   130,   223,   173,   214,
+     174,    -1,   144,    -1,     4,    -1,   225,    -1,   207,    -1,
+      57,     3,    -1,   258,    -1,   130,     3,    -1,   261,    -1,
+     137,     3,    -1,   118,   171,   259,   172,    -1,   136,   195,
+     250,   255,    -1,   137,   223,   173,   217,   174,    -1,   137,
+     223,   131,   171,   219,   172,   222,   173,   202,   174,    -1,
+       5,    -1,     5,   167,     5,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const unsigned short int yyrline[] =
 {
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const unsigned short int yyrline[] =
 {
-       0,   304,   304,   313,   314,   315,   316,   320,   325,   326,
-     327,   330,   331,   332,   333,   334,   338,   339,   340,   341,
-     344,   345,   346,   349,   350,   353,   354,   355,   360,   361,
-     362,   367,   368,   375,   377,   383,   387,   391,   393,   400,
-     404,   405,   408,   411,   412,   413,   417,   422,   428,   429,
-     430,   433,   434,   435,   438,   439,   443,   449,   450,   451,
-     454,   455,   458,   459,   460,   461,   462,   463,   464,   465,
-     466,   467,   468,   469,   470,   471,   472,   473,   474,   475,
-     476,   477,   478,   479,   480,   481,   482,   483,   484,   485,
-     486,   487,   488,   489,   490,   491,   492,   493,   494,   495,
-     496,   497,   498,   499,   500,   501,   502,   503,   504,   505,
-     506,   507,   508,   509,   510,   511,   512,   515,   516,   517,
-     518,   519,   520,   521,   522,   523,   524,   525,   526,   527,
-     528,   529,   530,   531,   535,   536,   541,   542,   543,   544,
-     547,   548,   551,   555,   561,   567,   568,   569,   572,   576,
-     585,   589,   594,   603,   604,   617,   618,   621,   622,   623,
-     624,   625,   626,   627,   628,   629,   630,   631,   632,   633,
-     634,   635,   636,   637,   638,   639,   640,   641,   642,   645,
-     646,   649,   655,   660,   661,   664,   665,   666,   667,   670,
-     678,   687,   688,   691,   692,   693,   696,   698,   701,   702,
-     703,   704,   705,   721,   722,   723,   724,   725,   726,   727,
-     730,   731,   734,   735,   736,   737,   738,   739,   740,   743,
-     744,   750,   759,   766,   767,   771,   774,   775,   778,   791,
-     792,   795,   796,   799,   808,   817,   818,   821,   822,   825,
-     837,   850,   862,   866,   867,   870,   871,   874,   879,   886,
-     887,   888,   892,   895,   902,   903,   904,   911,   912,   916,
-     917,   918,   921,   932,   933,   934,   935,   936,   937,   938,
-     939,   940,   941,   942,   945,   950,   955,   972,   973
+       0,   349,   349,   358,   359,   360,   361,   365,   370,   373,
+     374,   377,   378,   379,   380,   381,   386,   387,   388,   389,
+     392,   393,   396,   397,   401,   402,   408,   411,   412,   418,
+     419,   427,   429,   437,   444,   448,   450,   457,   465,   466,
+     469,   472,   473,   474,   478,   485,   493,   494,   497,   498,
+     502,   508,   509,   510,   513,   514,   517,   518,   519,   520,
+     521,   522,   523,   524,   525,   526,   527,   528,   529,   530,
+     531,   532,   533,   534,   535,   536,   537,   538,   539,   540,
+     541,   542,   543,   544,   545,   546,   547,   548,   549,   550,
+     551,   552,   553,   554,   555,   556,   557,   558,   559,   560,
+     561,   562,   563,   564,   565,   566,   567,   568,   569,   570,
+     574,   575,   576,   577,   578,   579,   580,   581,   582,   583,
+     584,   585,   586,   587,   588,   589,   590,   594,   595,   600,
+     601,   602,   603,   606,   607,   610,   614,   620,   621,   622,
+     625,   629,   638,   642,   647,   656,   657,   670,   671,   674,
+     675,   676,   677,   678,   679,   680,   681,   682,   683,   684,
+     685,   686,   687,   688,   689,   690,   691,   692,   693,   694,
+     695,   696,   697,   698,   699,   700,   701,   702,   703,   704,
+     705,   706,   707,   708,   709,   710,   711,   712,   713,   716,
+     717,   720,   726,   732,   733,   736,   741,   748,   749,   752,
+     753,   757,   758,   761,   769,   778,   784,   790,   791,   794,
+     795,   796,   799,   801,   804,   805,   806,   807,   808,   824,
+     825,   826,   827,   828,   829,   830,   833,   834,   837,   838,
+     839,   840,   841,   842,   843,   846,   847,   853,   862,   869,
+     870,   874,   877,   878,   881,   895,   896,   899,   900,   903,
+     913,   923,   924,   927,   928,   931,   944,   958,   971,   975,
+     976,   979,   980,   983,   988,   996,   997,   998,  1002,  1006,
+    1009,  1010,  1013,  1014,  1018,  1019,  1023,  1024,  1025,  1029,
+    1031,  1032,  1036,  1037,  1038,  1039,  1046,  1047,  1051,  1052,
+    1056,  1057,  1058,  1061,  1072,  1073,  1074,  1075,  1076,  1077,
+    1078,  1079,  1080,  1081,  1084,  1090,  1096,  1113,  1114
 };
 #endif
 
 };
 #endif
 
@@ -931,48 +1004,54 @@ static const unsigned short int yyrline[] =
 static const char *const yytname[] =
 {
   "$end", "error", "$undefined", "aIDENTIFIER", "aKNOWNTYPE", "aNUM",
 static const char *const yytname[] =
 {
   "$end", "error", "$undefined", "aIDENTIFIER", "aKNOWNTYPE", "aNUM",
-  "aHEXNUM", "aDOUBLE", "aSTRING", "aUUID", "aEOF", "SHL", "SHR",
-  "tAGGREGATABLE", "tALLOCATE", "tAPPOBJECT", "tASYNC", "tASYNCUUID",
-  "tAUTOHANDLE", "tBINDABLE", "tBOOLEAN", "tBROADCAST", "tBYTE",
-  "tBYTECOUNT", "tCALLAS", "tCALLBACK", "tCASE", "tCDECL", "tCHAR",
-  "tCOCLASS", "tCODE", "tCOMMSTATUS", "tCONST", "tCONTEXTHANDLE",
-  "tCONTEXTHANDLENOSERIALIZE", "tCONTEXTHANDLESERIALIZE", "tCONTROL",
-  "tCPPQUOTE", "tDEFAULT", "tDEFAULTCOLLELEM", "tDEFAULTVALUE",
+  "aHEXNUM", "aDOUBLE", "aSTRING", "aWSTRING", "aUUID", "aEOF", "SHL",
+  "SHR", "MEMBERPTR", "EQUALITY", "INEQUALITY", "GREATEREQUAL",
+  "LESSEQUAL", "LOGICALOR", "LOGICALAND", "tAGGREGATABLE", "tALLOCATE",
+  "tAPPOBJECT", "tASYNC", "tASYNCUUID", "tAUTOHANDLE", "tBINDABLE",
+  "tBOOLEAN", "tBROADCAST", "tBYTE", "tBYTECOUNT", "tCALLAS", "tCALLBACK",
+  "tCASE", "tCDECL", "tCHAR", "tCOCLASS", "tCODE", "tCOMMSTATUS", "tCONST",
+  "tCONTEXTHANDLE", "tCONTEXTHANDLENOSERIALIZE", "tCONTEXTHANDLESERIALIZE",
+  "tCONTROL", "tCPPQUOTE", "tDEFAULT", "tDEFAULTCOLLELEM", "tDEFAULTVALUE",
   "tDEFAULTVTABLE", "tDISPLAYBIND", "tDISPINTERFACE", "tDLLNAME",
   "tDOUBLE", "tDUAL", "tENDPOINT", "tENTRY", "tENUM", "tERRORSTATUST",
   "tEXPLICITHANDLE", "tEXTERN", "tFALSE", "tFASTCALL", "tFLOAT", "tHANDLE",
   "tHANDLET", "tHELPCONTEXT", "tHELPFILE", "tHELPSTRING",
   "tHELPSTRINGCONTEXT", "tHELPSTRINGDLL", "tHIDDEN", "tHYPER", "tID",
   "tIDEMPOTENT", "tIIDIS", "tIMMEDIATEBIND", "tIMPLICITHANDLE", "tIMPORT",
   "tDEFAULTVTABLE", "tDISPLAYBIND", "tDISPINTERFACE", "tDLLNAME",
   "tDOUBLE", "tDUAL", "tENDPOINT", "tENTRY", "tENUM", "tERRORSTATUST",
   "tEXPLICITHANDLE", "tEXTERN", "tFALSE", "tFASTCALL", "tFLOAT", "tHANDLE",
   "tHANDLET", "tHELPCONTEXT", "tHELPFILE", "tHELPSTRING",
   "tHELPSTRINGCONTEXT", "tHELPSTRINGDLL", "tHIDDEN", "tHYPER", "tID",
   "tIDEMPOTENT", "tIIDIS", "tIMMEDIATEBIND", "tIMPLICITHANDLE", "tIMPORT",
-  "tIMPORTLIB", "tIN", "tINLINE", "tINPUTSYNC", "tINT", "tINT64",
-  "tINTERFACE", "tLCID", "tLENGTHIS", "tLIBRARY", "tLOCAL", "tLONG",
-  "tMETHODS", "tMODULE", "tNONBROWSABLE", "tNONCREATABLE",
-  "tNONEXTENSIBLE", "tOBJECT", "tODL", "tOLEAUTOMATION", "tOPTIONAL",
-  "tOUT", "tPASCAL", "tPOINTERDEFAULT", "tPROPERTIES", "tPROPGET",
-  "tPROPPUT", "tPROPPUTREF", "tPTR", "tPUBLIC", "tRANGE", "tREADONLY",
-  "tREF", "tREQUESTEDIT", "tRESTRICTED", "tRETVAL", "tSAFEARRAY", "tSHORT",
-  "tSIGNED", "tSINGLE", "tSIZEIS", "tSIZEOF", "tSMALL", "tSOURCE",
-  "tSTDCALL", "tSTRICTCONTEXTHANDLE", "tSTRING", "tSTRUCT", "tSWITCH",
-  "tSWITCHIS", "tSWITCHTYPE", "tTRANSMITAS", "tTRUE", "tTYPEDEF", "tUNION",
-  "tUNIQUE", "tUNSIGNED", "tUUID", "tV1ENUM", "tVARARG", "tVERSION",
-  "tVOID", "tWCHAR", "tWIREMARSHAL", "','", "'?'", "':'", "'|'", "'&'",
-  "'-'", "'+'", "'*'", "'/'", "'~'", "CAST", "PPTR", "NEG", "ADDRESSOF",
-  "';'", "'('", "')'", "'{'", "'}'", "'['", "']'", "'='", "'.'", "$accept",
-  "input", "gbl_statements", "imp_statements", "int_statements",
-  "semicolon_opt", "statement", "cppquote", "import_start", "import",
-  "importlib", "libraryhdr", "library_start", "librarydef", "m_args",
-  "no_args", "args", "arg", "array", "array_list", "m_attributes",
-  "attributes", "attrib_list", "str_list", "attribute", "uuid_string",
-  "callconv", "cases", "case", "constdef", "enums", "enum_list", "enum",
-  "enumdef", "m_exprs", "m_expr", "expr", "expr_list_const", "expr_const",
-  "externdef", "fields", "field", "s_field", "funcdef", "m_ident",
-  "t_ident", "ident", "base_type", "m_int", "int_std", "coclass",
-  "coclasshdr", "coclassdef", "coclass_ints", "coclass_int",
-  "dispinterface", "dispinterfacehdr", "dispint_props", "dispint_meths",
-  "dispinterfacedef", "inherit", "interface", "interfacehdr",
-  "interfacedef", "interfacedec", "module", "modulehdr", "moduledef",
-  "pident", "func_ident", "direct_ident", "pident_list", "pointer_type",
-  "structdef", "type", "typedef", "uniondef", "version", 0
+  "tIMPORTLIB", "tIN", "tIN_LINE", "tINLINE", "tINPUTSYNC", "tINT",
+  "tINT64", "tINTERFACE", "tLCID", "tLENGTHIS", "tLIBRARY", "tLOCAL",
+  "tLONG", "tMETHODS", "tMODULE", "tNONBROWSABLE", "tNONCREATABLE",
+  "tNONEXTENSIBLE", "tNULL", "tOBJECT", "tODL", "tOLEAUTOMATION",
+  "tOPTIONAL", "tOUT", "tPASCAL", "tPOINTERDEFAULT", "tPROPERTIES",
+  "tPROPGET", "tPROPPUT", "tPROPPUTREF", "tPTR", "tPUBLIC", "tRANGE",
+  "tREADONLY", "tREF", "tREGISTER", "tREQUESTEDIT", "tRESTRICTED",
+  "tRETVAL", "tSAFEARRAY", "tSHORT", "tSIGNED", "tSINGLE", "tSIZEIS",
+  "tSIZEOF", "tSMALL", "tSOURCE", "tSTATIC", "tSTDCALL",
+  "tSTRICTCONTEXTHANDLE", "tSTRING", "tSTRUCT", "tSWITCH", "tSWITCHIS",
+  "tSWITCHTYPE", "tTRANSMITAS", "tTRUE", "tTYPEDEF", "tUNION", "tUNIQUE",
+  "tUNSIGNED", "tUUID", "tV1ENUM", "tVARARG", "tVERSION", "tVOID",
+  "tWCHAR", "tWIREMARSHAL", "','", "'?'", "':'", "'|'", "'^'", "'&'",
+  "'<'", "'>'", "'-'", "'+'", "'*'", "'/'", "'%'", "'!'", "'~'",
+  "ADDRESSOF", "NEG", "POS", "PPTR", "CAST", "'.'", "'['", "']'", "';'",
+  "'('", "')'", "'{'", "'}'", "'='", "$accept", "input", "gbl_statements",
+  "imp_statements", "int_statements", "semicolon_opt", "statement",
+  "cppquote", "import_start", "import", "importlib", "libraryhdr",
+  "library_start", "librarydef", "m_args", "no_args", "args", "arg",
+  "array", "m_attributes", "attributes", "attrib_list", "str_list",
+  "attribute", "uuid_string", "callconv", "cases", "case", "enums",
+  "enum_list", "enum", "enumdef", "m_exprs", "m_expr", "expr",
+  "expr_list_int_const", "expr_int_const", "expr_const", "fields", "field",
+  "ne_union_field", "ne_union_fields", "union_field", "s_field", "funcdef",
+  "declaration", "m_ident", "t_ident", "ident", "base_type", "m_int",
+  "int_std", "coclass", "coclasshdr", "coclassdef", "coclass_ints",
+  "coclass_int", "dispinterface", "dispinterfacehdr", "dispint_props",
+  "dispint_meths", "dispinterfacedef", "inherit", "interface",
+  "interfacehdr", "interfacedef", "interfacedec", "module", "modulehdr",
+  "moduledef", "storage_cls_spec", "function_specifier", "type_qualifier",
+  "m_type_qual_list", "decl_spec", "m_decl_spec_no_type",
+  "decl_spec_no_type", "declarator", "direct_declarator",
+  "declarator_list", "init_declarator", "pointer_type", "structdef",
+  "type", "typedef", "uniondef", "version", 0
 };
 #endif
 
 };
 #endif
 
@@ -994,43 +1073,48 @@ static const unsigned short int yytoknum[] =
      355,   356,   357,   358,   359,   360,   361,   362,   363,   364,
      365,   366,   367,   368,   369,   370,   371,   372,   373,   374,
      375,   376,   377,   378,   379,   380,   381,   382,   383,   384,
      355,   356,   357,   358,   359,   360,   361,   362,   363,   364,
      365,   366,   367,   368,   369,   370,   371,   372,   373,   374,
      375,   376,   377,   378,   379,   380,   381,   382,   383,   384,
-     385,   386,   387,   388,   389,    44,    63,    58,   124,    38,
-      45,    43,    42,    47,   126,   390,   391,   392,   393,    59,
-      40,    41,   123,   125,    91,    93,    61,    46
+     385,   386,   387,   388,   389,   390,   391,   392,   393,   394,
+     395,   396,   397,   398,   399,   400,   401,    44,    63,    58,
+     124,    94,    38,    60,    62,    45,    43,    42,    47,    37,
+      33,   126,   402,   403,   404,   405,   406,    46,    91,    93,
+      59,    40,    41,   123,   125,    61
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
-static const unsigned char yyr1[] =
+static const unsigned short int yyr1[] =
 {
 {
-       0,   158,   159,   160,   160,   160,   160,   160,   160,   160,
-     160,   161,   161,   161,   161,   161,   161,   161,   161,   161,
-     162,   162,   162,   163,   163,   164,   164,   164,   164,   164,
-     164,   164,   164,   165,   166,   167,   168,   169,   170,   171,
-     172,   172,   173,   174,   174,   174,   175,   175,   176,   176,
-     176,   177,   177,   177,   178,   178,   179,   180,   180,   180,
-     181,   181,   182,   182,   182,   182,   182,   182,   182,   182,
-     182,   182,   182,   182,   182,   182,   182,   182,   182,   182,
-     182,   182,   182,   182,   182,   182,   182,   182,   182,   182,
-     182,   182,   182,   182,   182,   182,   182,   182,   182,   182,
-     182,   182,   182,   182,   182,   182,   182,   182,   182,   182,
-     182,   182,   182,   182,   182,   182,   182,   182,   182,   182,
-     182,   182,   182,   182,   182,   182,   182,   182,   182,   182,
-     182,   182,   182,   182,   183,   183,   184,   184,   184,   184,
-     185,   185,   186,   186,   187,   188,   188,   188,   189,   189,
-     190,   190,   191,   192,   192,   193,   193,   194,   194,   194,
-     194,   194,   194,   194,   194,   194,   194,   194,   194,   194,
-     194,   194,   194,   194,   194,   194,   194,   194,   194,   195,
-     195,   196,   197,   198,   198,   199,   199,   199,   199,   200,
-     201,   202,   202,   203,   203,   203,   204,   204,   205,   205,
-     205,   205,   205,   205,   205,   205,   205,   205,   205,   205,
-     206,   206,   207,   207,   207,   207,   207,   207,   207,   208,
-     208,   209,   210,   211,   211,   212,   213,   213,   214,   215,
-     215,   216,   216,   217,   217,   218,   218,   219,   219,   220,
-     221,   221,   221,   222,   222,   223,   223,   224,   225,   226,
-     226,   226,   226,   227,   228,   228,   228,   229,   229,   230,
-     230,   230,   231,   232,   232,   232,   232,   232,   232,   232,
-     232,   232,   232,   232,   233,   234,   234,   235,   235
+       0,   176,   177,   178,   178,   178,   178,   178,   178,   178,
+     178,   179,   179,   179,   179,   179,   179,   179,   179,   179,
+     180,   180,   181,   181,   182,   182,   182,   182,   182,   182,
+     182,   183,   184,   185,   186,   187,   188,   189,   190,   190,
+     191,   192,   192,   192,   193,   193,   194,   194,   195,   195,
+     196,   197,   197,   197,   198,   198,   199,   199,   199,   199,
+     199,   199,   199,   199,   199,   199,   199,   199,   199,   199,
+     199,   199,   199,   199,   199,   199,   199,   199,   199,   199,
+     199,   199,   199,   199,   199,   199,   199,   199,   199,   199,
+     199,   199,   199,   199,   199,   199,   199,   199,   199,   199,
+     199,   199,   199,   199,   199,   199,   199,   199,   199,   199,
+     199,   199,   199,   199,   199,   199,   199,   199,   199,   199,
+     199,   199,   199,   199,   199,   199,   199,   200,   200,   201,
+     201,   201,   201,   202,   202,   203,   203,   204,   204,   204,
+     205,   205,   206,   206,   207,   208,   208,   209,   209,   210,
+     210,   210,   210,   210,   210,   210,   210,   210,   210,   210,
+     210,   210,   210,   210,   210,   210,   210,   210,   210,   210,
+     210,   210,   210,   210,   210,   210,   210,   210,   210,   210,
+     210,   210,   210,   210,   210,   210,   210,   210,   210,   211,
+     211,   212,   213,   214,   214,   215,   215,   216,   216,   217,
+     217,   218,   218,   219,   220,   221,   221,   222,   222,   223,
+     223,   223,   224,   224,   225,   225,   225,   225,   225,   225,
+     225,   225,   225,   225,   225,   225,   226,   226,   227,   227,
+     227,   227,   227,   227,   227,   228,   228,   229,   230,   231,
+     231,   232,   233,   233,   234,   235,   235,   236,   236,   237,
+     237,   238,   238,   239,   239,   240,   241,   241,   241,   242,
+     242,   243,   243,   244,   245,   246,   246,   246,   247,   248,
+     249,   249,   250,   250,   251,   251,   252,   252,   252,   253,
+     253,   253,   254,   254,   254,   254,   255,   255,   256,   256,
+     257,   257,   257,   258,   259,   259,   259,   259,   259,   259,
+     259,   259,   259,   259,   260,   261,   261,   262,   262
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
@@ -1038,31 +1122,34 @@ static const unsigned char yyr2[] =
 {
        0,     2,     1,     0,     2,     2,     3,     2,     2,     2,
        2,     0,     2,     2,     3,     2,     2,     2,     2,     2,
 {
        0,     2,     1,     0,     2,     2,     3,     2,     2,     2,
        2,     0,     2,     2,     3,     2,     2,     2,     2,     2,
-       0,     3,     2,     0,     1,     2,     1,     2,     2,     1,
-       2,     2,     2,     4,     3,     3,     5,     2,     3,     4,
-       0,     1,     1,     1,     3,     1,     4,     3,     0,     3,
-       3,     1,     3,     4,     0,     1,     3,     1,     3,     4,
-       1,     3,     0,     1,     1,     1,     1,     1,     1,     4,
-       4,     1,     1,     1,     1,     1,     1,     4,     4,     1,
-       1,     4,     1,     4,     4,     4,     1,     1,     4,     4,
-       4,     4,     4,     1,     4,     1,     4,     1,     5,     1,
-       1,     4,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     4,     1,     1,     1,     1,     6,     1,     1,     1,
-       1,     4,     1,     1,     1,     4,     4,     4,     4,     1,
-       1,     4,     4,     1,     1,     1,     1,     1,     1,     1,
-       0,     2,     4,     3,     5,     0,     2,     1,     1,     3,
-       3,     1,     5,     1,     3,     0,     1,     1,     1,     1,
-       1,     1,     1,     5,     3,     3,     3,     3,     3,     3,
-       3,     3,     2,     2,     2,     2,     4,     4,     3,     1,
-       3,     1,     4,     0,     2,     2,     3,     2,     1,     4,
-       3,     0,     1,     0,     1,     1,     1,     1,     1,     1,
-       1,     2,     2,     1,     1,     1,     1,     1,     1,     1,
-       0,     1,     1,     2,     1,     2,     2,     1,     1,     2,
-       2,     2,     5,     0,     2,     2,     2,     2,     2,     2,
-       3,     2,     3,     5,     5,     0,     2,     2,     2,     2,
-       6,     8,     2,     2,     2,     2,     2,     2,     5,     2,
-       2,     2,     1,     4,     1,     3,     1,     1,     3,     1,
-       1,     1,     5,     1,     1,     1,     2,     1,     2,     1,
+       0,     2,     0,     1,     1,     2,     2,     1,     2,     2,
+       2,     4,     3,     3,     5,     2,     3,     4,     0,     1,
+       1,     1,     3,     1,     3,     2,     3,     3,     0,     1,
+       3,     1,     3,     4,     1,     3,     0,     1,     1,     1,
+       1,     1,     1,     4,     4,     1,     1,     1,     1,     1,
+       1,     4,     1,     1,     4,     1,     4,     4,     1,     1,
+       4,     4,     4,     4,     4,     1,     4,     1,     4,     1,
+       5,     1,     1,     4,     4,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     4,     1,     1,     1,     1,     6,
+       1,     1,     1,     1,     4,     1,     1,     1,     4,     4,
+       4,     4,     1,     1,     4,     4,     1,     1,     1,     1,
+       1,     1,     1,     0,     2,     4,     3,     0,     2,     1,
+       1,     3,     3,     1,     5,     1,     3,     0,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     5,     3,
+       3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
+       3,     3,     3,     3,     3,     3,     3,     2,     2,     2,
+       2,     2,     2,     3,     3,     4,     4,     4,     3,     1,
+       3,     1,     1,     0,     2,     4,     3,     2,     2,     0,
+       2,     2,     1,     3,     3,     3,     2,     0,     1,     0,
+       1,     1,     1,     1,     1,     1,     1,     2,     2,     1,
+       1,     1,     1,     1,     1,     1,     0,     1,     1,     2,
+       1,     2,     2,     1,     1,     2,     2,     2,     5,     0,
+       2,     2,     2,     2,     2,     2,     3,     2,     3,     5,
+       5,     0,     2,     2,     2,     2,     6,     8,     2,     2,
+       2,     2,     2,     2,     5,     1,     1,     1,     1,     1,
+       0,     2,     2,     3,     0,     1,     2,     2,     2,     3,
+       2,     1,     1,     3,     2,     4,     1,     3,     1,     3,
+       1,     1,     1,     5,     1,     1,     1,     1,     2,     1,
        2,     1,     2,     4,     4,     5,    10,     1,     3
 };
 
        2,     1,     2,     4,     4,     5,    10,     1,     3
 };
 
@@ -1071,421 +1158,629 @@ static const unsigned char yyr2[] =
    means the default is an error.  */
 static const unsigned short int yydefact[] =
 {
    means the default is an error.  */
 static const unsigned short int yydefact[] =
 {
-       3,     0,     2,     1,     0,     0,     0,     0,   193,     0,
-       0,     0,   193,    54,   193,    62,    10,    26,    11,    29,
-      11,     9,     0,     0,     0,     0,     0,     0,     7,     0,
-       0,    23,     0,   235,     5,     4,     0,     8,     0,     0,
-       0,   219,   220,   264,   207,   198,   218,     0,   206,   193,
-     208,   204,   209,   210,   212,   217,   210,     0,   210,     0,
-     205,   214,   193,   193,   203,   263,   199,   267,   265,   200,
-     269,     0,   271,     0,   226,   227,   194,   195,     0,     0,
-       0,   237,   238,     0,     0,    55,     0,    63,    64,    65,
-      66,    67,    68,     0,     0,    71,    72,    73,    74,    75,
-      76,     0,    79,    80,     0,    82,     0,     0,    86,    87,
-       0,     0,     0,     0,     0,    93,     0,    95,     0,    97,
-       0,    99,   100,     0,   102,   103,   104,   105,   106,   107,
-     108,   109,   110,     0,   112,   113,   114,   261,   115,     0,
-     117,   259,   118,   119,   120,     0,   122,   123,   124,     0,
-       0,     0,   260,     0,   129,   130,     0,     0,     0,    57,
-     133,     0,     0,     0,     0,     0,   221,   228,   239,   247,
-      25,    27,    28,     6,   223,   244,     0,    24,   242,   243,
-       0,     0,    20,    30,    31,    32,   266,   268,   211,   216,
-     215,     0,   213,   201,   270,   272,   202,   196,   197,     0,
-       0,   145,     0,    34,   183,     0,     0,   183,     0,     0,
+       3,     0,     2,     1,   295,   223,   214,   234,     0,   269,
+       0,     0,   222,   209,   224,   265,   220,   225,   226,     0,
+     268,   228,   233,     0,   226,   267,     0,   226,     0,   221,
+     230,   266,   209,    48,   209,   219,   294,   215,    56,    10,
+      24,    11,    27,    11,     9,     0,   297,     0,   296,   216,
+       0,     0,     7,     0,     0,    22,     0,   251,     5,     4,
+       0,     8,   274,   274,   274,     0,     0,   299,   274,     0,
+     301,   235,   236,     0,   242,   243,   298,   211,     0,   227,
+     232,     0,   253,   254,   231,     0,   229,   217,   300,     0,
+       0,    49,   302,     0,   218,    57,    58,    59,    60,    61,
+      62,     0,     0,    65,    66,    67,    68,    69,    70,     0,
+      72,    73,     0,    75,     0,     0,    78,    79,     0,     0,
+       0,     0,     0,    85,     0,    87,     0,    89,     0,    91,
+      92,     0,     0,    95,    96,    97,    98,    99,   100,   101,
+     102,   103,     0,   105,   106,   107,   292,   108,     0,   110,
+     290,   111,   112,   113,     0,   115,   116,   117,     0,     0,
+       0,   291,     0,   122,   123,     0,     0,     0,    51,   126,
+       0,     0,     0,     0,     0,   297,   237,   244,   255,   263,
+       0,   299,   301,    25,    26,     6,   239,   260,     0,    23,
+     258,   259,     0,     0,    20,   278,   275,   277,   276,   212,
+     213,   129,   130,   131,   132,   270,     0,     0,   282,   288,
+     281,   206,   274,    28,   272,    29,    30,     0,   137,    32,
+       0,   193,     0,     0,   199,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     147,     0,     0,   147,     0,     0,     0,     0,     0,     0,
+      56,    50,    33,     0,    17,    18,    19,     0,    15,    13,
+      12,    16,    22,    35,   261,   262,    36,   205,    48,     0,
+      48,     0,     0,   252,    20,     0,     0,     0,   280,     0,
+     147,    38,   284,   273,    31,     0,   139,   140,   143,   303,
+      48,   286,   304,    48,    48,     0,   157,   149,   150,   151,
+     155,   156,   152,   153,     0,   154,     0,     0,     0,     0,
+       0,     0,     0,   191,     0,   189,   192,     0,     0,    54,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,   155,     0,     0,   155,     0,     0,     0,     0,
-       0,     0,    62,    56,    35,     0,    17,    18,    19,     0,
-      15,    13,    12,    16,    23,    37,   245,   246,    38,    54,
-       0,    54,     0,     0,   236,    20,    54,     0,     0,    33,
-       0,   147,   148,   151,   182,    54,   136,     0,   137,   138,
-     139,     0,     0,     0,   254,   257,   256,   252,   274,    54,
-      54,     0,   162,   157,   158,   159,   160,     0,   161,     0,
-       0,     0,     0,     0,   181,     0,   179,     0,     0,     0,
-      60,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,   153,   156,     0,     0,     0,     0,     0,
-       0,   135,   134,     0,   277,     0,     0,    58,    62,     0,
-      14,    39,    23,     0,   224,   229,     0,     0,     0,    54,
-       0,     0,    54,    23,    22,     0,     0,   273,   144,   152,
-     146,     0,   188,   262,     0,    55,   184,     0,   250,   249,
-       0,   251,    40,     0,     0,   275,    69,     0,   174,   173,
-     175,   172,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,    70,    78,    77,    81,     0,    83,
-      84,    85,    88,    89,    90,    91,    92,    94,    96,     0,
-     155,   101,   111,     0,   121,   125,   126,   127,   128,     0,
-     131,   132,    59,     0,   222,   225,   231,     0,   230,   233,
-       0,   234,    20,    23,   248,     0,    21,   149,   150,   271,
-     187,   185,   255,   263,     0,    45,    41,    43,     0,     0,
-     258,   191,     0,   178,     0,   170,   171,     0,   164,   165,
-     167,   166,   168,   169,   180,    61,    98,   154,     0,   278,
-      23,    48,   232,    54,   240,   190,   186,   253,     0,     0,
-      48,     0,   192,   177,   176,     0,   116,    36,   155,   189,
-      23,    44,    48,    47,   140,   163,     0,     0,    51,   241,
-      46,     0,    50,     0,    49,     0,     0,   276,   141,    52,
-       0,     0,    54,    53,    54,   143,   142
+       0,     0,   145,   148,     0,     0,     0,     0,     0,     0,
+     128,   127,     0,   307,     0,     0,    52,    56,     0,    14,
+      37,    22,     0,   240,   245,     0,     0,     0,    48,     0,
+       0,     0,    22,    21,     0,   271,   279,   283,   289,     0,
+       0,   294,     0,    43,    39,    41,     0,     0,   144,   138,
+       0,   293,     0,   194,     0,     0,   305,    49,   200,     0,
+      63,     0,   181,   180,   179,   182,   177,   178,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    64,    71,    74,     0,    76,    77,    80,
+      81,    82,    83,    84,    86,    88,     0,    94,   147,    93,
+     104,     0,   114,   118,   119,   120,   121,     0,   124,   125,
+      53,     0,   238,   241,   247,     0,   246,   249,     0,     0,
+     250,    20,    22,   264,    47,    46,   285,     0,     0,    45,
+     141,   142,     0,   301,   287,   207,   198,   197,     0,   188,
+       0,   170,   171,   183,   164,   165,   168,   169,   159,   160,
+       0,   161,   162,   163,   167,   166,   173,   172,   175,   176,
+     174,   184,     0,   190,    55,    90,   146,     0,   308,    22,
+     203,     0,   248,     0,   256,    42,    44,     0,   196,     0,
+     208,   186,   185,     0,   187,   109,    34,   204,    22,   195,
+     133,   158,   257,     0,     0,     0,   306,   134,     0,    48,
+      48,   202,   136,     0,   135,   201
 };
 
 /* YYDEFGOTO[NTERM-NUM]. */
 static const short int yydefgoto[] =
 {
 };
 
 /* YYDEFGOTO[NTERM-NUM]. */
 static const short int yydefgoto[] =
 {
-      -1,     1,     2,   161,   256,   178,   344,    17,    18,    19,
-     237,   165,    20,   238,   434,   435,   436,   437,   479,   487,
-     345,    85,   158,   301,   159,   323,   273,   491,   498,    23,
-     260,   261,   262,    67,   312,   313,   294,   295,   296,    25,
-     265,   356,   357,   346,   471,    78,   274,    68,   189,    69,
-     239,    27,   240,   249,   334,    29,    30,   251,   339,    31,
-     181,    32,    33,   241,   242,   169,    36,   243,   275,   276,
-     277,   278,   160,    70,   417,    39,    72,   325
+      -1,     1,     2,   170,   275,   190,   363,    40,    41,    42,
+     255,   174,    43,   256,   372,   373,   374,   375,   282,   356,
+      91,   167,   320,   168,   342,   207,   533,   537,   285,   286,
+     287,   175,   331,   332,   313,   314,   315,   317,   290,   383,
+     388,   294,   542,   543,   459,    47,   519,    78,   208,    48,
+      80,    49,   257,    51,   258,   268,   353,    53,    54,   270,
+     358,    55,   193,    56,    57,   259,   260,   179,    60,   261,
+      62,    63,    64,   276,    65,   195,    66,   209,   210,   292,
+     211,   169,   181,    68,    69,   182,   344
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -455
+#define YYPACT_NINF -267
 static const short int yypact[] =
 {
 static const short int yypact[] =
 {
-    -455,    47,   733,  -455,   135,   699,   -87,   145,   151,    35,
-     101,   153,   151,   -53,   151,   908,  -455,  -455,  -455,  -455,
-    -455,  -455,    16,   -42,   -31,   -27,   -16,   -25,  -455,     9,
-      12,    20,    41,    13,  -455,  -455,    43,  -455,    50,    53,
-      57,  -455,  -455,  -455,  -455,  -455,  -455,   699,  -455,   190,
-    -455,  -455,  -455,    71,  -455,  -455,    71,     2,    71,    15,
-    -455,  -455,   194,   201,    15,  -455,  -455,  -455,  -455,  -455,
-    -455,   226,  -455,   203,  -455,  -455,  -455,  -455,    61,   699,
-      60,  -455,  -455,    63,   699,  -455,  -110,  -455,  -455,  -455,
-    -455,  -455,  -455,    11,    70,  -455,  -455,  -455,  -455,  -455,
-    -455,    72,  -455,  -455,    76,  -455,    88,    92,  -455,  -455,
-     102,   106,   108,   109,   125,  -455,   126,  -455,   127,  -455,
-     130,  -455,  -455,   131,  -455,  -455,  -455,  -455,  -455,  -455,
-    -455,  -455,  -455,   134,  -455,  -455,  -455,  -455,  -455,   136,
-    -455,  -455,  -455,  -455,  -455,   137,  -455,  -455,  -455,   138,
-     142,   143,  -455,   144,  -455,  -455,   148,   149,   -98,  -455,
-    -455,   362,   709,   258,   247,   114,  -455,  -455,  -455,  -455,
-    -455,  -455,  -455,  -455,  -455,  -455,   -39,  -455,  -455,  -455,
-     251,   133,  -455,  -455,  -455,  -455,  -455,   150,  -455,  -455,
-    -455,   699,  -455,  -455,   150,   -88,  -455,  -455,  -455,   156,
-     154,   226,   226,  -455,  -455,    99,   163,  -455,   226,    68,
-     303,   292,   293,   452,    68,   296,   306,    68,   307,    68,
-      68,   259,    68,   -48,    68,    68,    68,   699,   699,    31,
-     312,   699,   908,   164,  -455,   169,  -455,  -455,  -455,   172,
-    -455,  -455,  -455,  -455,    20,  -455,  -455,  -455,  -455,   111,
-     185,   -55,   174,   175,  -455,  -455,   735,   177,    68,  -455,
-     173,   196,  -455,   178,  -455,   -17,  -455,    99,  -455,  -455,
-    -455,    99,    99,    99,  -455,  -455,  -455,   179,   198,   -53,
-      -9,   184,  -455,  -455,  -455,  -455,  -455,   187,  -455,    68,
-      68,    68,    68,   491,   594,   -86,  -455,   189,   193,   202,
-    -455,   -83,   207,   210,   211,   212,   214,   215,   216,   217,
-     531,   335,   -82,  -455,   594,   218,   206,   -37,   545,   219,
-     220,  -455,  -455,   222,   188,   224,   225,  -455,   908,   339,
-    -455,  -455,    20,    -7,  -455,  -455,   240,   699,   200,   116,
-     199,   284,   746,    20,  -455,   699,   229,  -455,  -455,  -455,
-     226,    68,  -455,  -455,   699,   230,  -455,   231,  -455,  -455,
-     235,  -455,   275,    99,   236,  -455,  -455,   699,  -455,  -455,
-    -455,  -455,   559,   238,    68,    68,    68,    68,    68,    68,
-      68,    68,    68,    68,  -455,  -455,  -455,  -455,   373,  -455,
-    -455,  -455,  -455,  -455,  -455,  -455,  -455,  -455,  -455,   239,
-      68,  -455,  -455,    68,  -455,  -455,  -455,  -455,  -455,   387,
-    -455,  -455,  -455,   244,  -455,  -455,  -455,    99,  -455,  -455,
-     248,  -455,  -455,    20,  -455,    99,  -455,  -455,  -455,   249,
-    -455,  -455,  -455,   -22,   245,  -455,   266,  -455,   699,    99,
-    -455,   226,   253,  -455,    68,  -455,  -455,   440,   105,    93,
-       0,     0,   261,   261,  -455,  -455,  -455,  -455,   255,  -455,
-      20,   256,  -455,   786,  -455,  -455,  -455,  -455,   399,    99,
-     256,   257,  -455,  -455,  -455,    68,  -455,  -455,   515,  -455,
-      20,  -455,   256,  -455,  -455,   594,    77,   -94,  -455,  -455,
-    -455,    -6,  -455,    68,   262,    68,   276,  -455,  -455,   594,
-      68,   575,   -77,   594,   -77,  -455,  -455
+    -267,    42,  1020,  -267,  -267,  -267,  -267,  -267,    47,  -267,
+     -94,    86,  -267,   144,  -267,  -267,  -267,  -267,    40,   137,
+    -267,  -267,  -267,   150,    40,  -267,   -20,    40,   199,  -267,
+    -267,  -267,   161,    -7,   194,   199,  -267,  -267,  1869,  -267,
+    -267,  -267,  -267,  -267,  -267,  1631,   -14,     4,  -267,  -267,
+      10,    -6,  -267,    12,    21,    38,    43,    73,  -267,  -267,
+      59,  -267,    -3,    -3,    -3,    52,  1744,    55,    -3,    56,
+      63,  -267,  -267,   226,  -267,  -267,    65,  -267,    66,  -267,
+    -267,    70,  -267,  -267,  -267,  1744,  -267,  -267,    65,    69,
+    1674,  -267,  -110,  -108,  -267,  -267,  -267,  -267,  -267,  -267,
+    -267,    77,    78,  -267,  -267,  -267,  -267,  -267,  -267,    79,
+    -267,  -267,    81,  -267,    82,    83,  -267,  -267,    87,    89,
+      91,    93,    98,  -267,    99,  -267,   101,  -267,   110,  -267,
+    -267,   115,   116,  -267,  -267,  -267,  -267,  -267,  -267,  -267,
+    -267,  -267,   117,  -267,  -267,  -267,  -267,  -267,   118,  -267,
+    -267,  -267,  -267,  -267,   120,  -267,  -267,  -267,   129,   130,
+     131,  -267,   138,  -267,  -267,   139,   140,  -107,  -267,  -267,
+     925,   403,   233,   203,    95,  -267,  -267,  -267,  -267,  -267,
+      52,  -267,  -267,  -267,  -267,  -267,  -267,  -267,   -12,  -267,
+    -267,  -267,   208,   135,  -267,  -267,  -267,  -267,  -267,  -267,
+    -267,  -267,  -267,  -267,  -267,  -267,    52,    52,  -267,    84,
+     -42,  -267,    -3,  -267,  -267,  -267,  -267,   113,   212,  -267,
+     141,  -267,    52,   151,  -267,   212,   749,   749,   311,   313,
+     749,   749,   316,   317,   749,   318,   749,   749,   262,   749,
+     749,   -79,   749,   749,   749,  1744,  1744,    97,   323,  1744,
+    1869,   165,  -267,   158,  -267,  -267,  -267,   164,  -267,  -267,
+    -267,  -267,    38,  -267,  -267,  -267,  -267,  -267,  -114,   186,
+     -65,   166,   174,  -267,  -267,    13,    32,   167,  -267,   749,
+     789,  1095,  -267,  -267,  -267,   163,   201,  -267,   175,  -267,
+     -82,  -267,   202,    -7,   -46,   179,  -267,  -267,  -267,  -267,
+    -267,  -267,  -267,  -267,   181,  -267,   749,   749,   749,   749,
+     749,   749,   688,  1390,  -103,  -267,  1390,   185,   188,  -267,
+     -66,   190,   192,   193,   195,   196,   197,   198,  1229,   355,
+     200,   -64,  -267,  1390,   204,   224,   -63,  1272,   205,   206,
+    -267,  -267,   207,   213,   209,   211,  -267,  1869,   365,  -267,
+    -267,    38,   -22,  -267,  -267,   225,  1674,   214,   -38,   215,
+     297,   498,    38,  -267,  1674,  -267,  -267,  -267,  -267,   444,
+     216,   -59,   237,  -267,   239,  -267,  1674,    52,  -267,   212,
+     749,  -267,  1674,  -267,    52,   238,  -267,   241,  -267,   242,
+    -267,  1744,    25,    25,    25,    25,    25,    25,  1295,   243,
+     749,   749,   410,   749,   749,   749,   749,   749,   749,   749,
+     749,   749,   749,   749,   749,   749,   749,   749,   749,   749,
+     413,   749,   749,  -267,  -267,  -267,   409,  -267,  -267,  -267,
+    -267,  -267,  -267,  -267,  -267,  -267,   246,  -267,   749,  -267,
+    -267,   749,  -267,  -267,  -267,  -267,  -267,   414,  -267,  -267,
+    -267,   248,  -267,  -267,  -267,    52,  -267,  -267,  1674,   251,
+    -267,  -267,    38,  -267,  -267,  -267,  -267,  1138,    52,  -267,
+    -267,  -267,    52,   252,  -267,   212,  -267,  -267,   254,  -267,
+     749,   148,   148,  -267,   187,   187,    88,    88,  1497,  1420,
+    1340,  1443,  1466,   864,    88,    88,    61,    61,    25,    25,
+      25,  -267,  1318,  -267,  -267,  -267,  -267,   255,  -267,    38,
+    -267,    52,  -267,   593,  -267,  -267,  -267,  -102,  -267,   256,
+    -267,  -267,    25,   749,  -267,  -267,  -267,  -267,    38,  -267,
+    -267,  1390,  -267,    -8,   749,   275,  -267,  -267,   279,   -28,
+     -28,  -267,  -267,   260,  -267,  -267
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const short int yypgoto[] =
 {
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const short int yypgoto[] =
 {
-    -455,  -455,  -455,   392,  -240,  -237,    23,  -455,  -455,    79,
-    -455,  -455,  -455,   415,  -455,  -455,  -455,   -50,  -358,  -455,
-     -12,    -2,  -455,  -455,  -209,  -455,  -455,  -455,  -455,  -455,
-    -455,  -455,    73,     4,   197,  -370,  -204,  -455,  -200,  -455,
-     221,  -454,  -225,    85,  -455,    48,   -67,  -455,    36,    56,
-      44,  -455,   423,  -455,  -455,   408,  -455,  -455,  -455,  -455,
-    -455,     5,  -455,   432,     3,  -455,  -455,   434,  -238,  -455,
-    -455,  -455,   223,     6,    -3,  -455,     1,  -455
+    -267,  -267,  -267,   389,  -266,  -252,     7,  -267,  -267,    74,
+    -267,  -267,  -267,   433,  -267,  -267,  -267,   -31,  -267,   -27,
+      -2,  -267,  -267,  -235,  -267,  -267,  -267,  -267,  -267,  -267,
+      58,     2,   219,  -247,   -13,  -267,  -220,  -199,  -267,  -267,
+    -267,  -267,   -99,  -174,  -267,  -267,  -267,   112,  -193,  -267,
+     114,    90,    16,  -267,   436,  -267,  -267,   397,  -267,  -267,
+    -267,  -267,  -267,   -25,  -267,   442,     1,  -267,  -267,   443,
+    -267,  -267,   170,  -267,   -44,   -16,    53,  -194,  -267,   -17,
+     277,   217,     5,   -61,  -267,     0,  -267
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -195
+#define YYTABLE_NINF -211
 static const short int yytable[] =
 {
 static const short int yytable[] =
 {
-      22,    84,    71,    40,   199,    35,    24,   331,    38,   206,
-     298,   374,   375,   303,   304,   342,   310,   307,   314,   309,
-     495,   314,   318,   327,   316,    16,   338,   168,   336,   358,
-     457,  -194,   496,   359,   360,   361,     7,   232,    11,   321,
-     322,   493,   207,    46,   186,     4,    26,     3,   505,   383,
-     506,   137,   388,   400,   364,   141,   250,   233,   348,     7,
-      83,   494,    86,    73,  -194,   384,   166,    79,   389,   401,
-      11,   282,   352,   283,   284,   285,   202,    15,   152,    53,
-     282,   205,   283,   284,   285,   368,   369,   370,   371,   372,
-      54,    55,   190,    11,   192,   414,   163,    56,   400,    15,
-     164,    15,   197,   198,   374,   375,   424,   170,   488,    80,
-      83,    86,   483,   -42,   404,   193,   374,   375,   171,   412,
-     196,   286,   172,    58,   490,   440,   266,   174,    61,   -42,
-     286,   267,   352,   173,   263,   264,   353,    15,    41,    42,
-     352,   281,   381,   382,   365,    15,   188,   497,    74,    75,
-     180,   428,   191,   268,    76,    77,    81,    82,   175,    22,
-      22,   208,    40,    40,   176,    24,    24,    38,    38,   177,
-     445,   446,   447,   448,   449,   450,   451,   452,   453,   461,
-     287,   252,   463,   454,   236,   236,   464,   465,   257,   287,
-     179,   288,   269,   187,    77,   182,   314,   194,    77,   183,
-     288,   470,   184,   458,   195,    77,   185,   289,   290,   203,
-     291,   200,   292,   201,   270,   204,   289,   290,   293,   291,
-     209,   292,   210,   477,   319,   320,   211,   293,   326,   197,
-     198,   482,   492,   379,   380,   381,   382,   333,   212,   337,
-     474,   271,   213,   489,   378,   379,   380,   381,   382,   272,
-     246,   247,   214,   354,   253,   254,   215,    40,   216,   217,
-      24,   245,    38,   355,   332,    15,   248,   337,   354,   419,
-      15,   485,   374,   375,   314,   218,   219,   220,   355,    43,
-     221,   222,   370,   263,   223,   255,   224,   225,   226,   499,
-     373,   501,   227,   228,   229,    44,   503,    45,   230,   231,
-     299,   300,  -194,    46,   305,   259,   282,    47,   283,   284,
-     285,   297,   258,   279,   306,   308,   311,   324,   328,   329,
-      48,   330,   335,   340,    49,    50,   349,   341,   347,   362,
-      51,   350,    52,   363,   351,   366,   415,   367,   399,    53,
-     385,   403,   425,    40,   386,   409,    24,   413,    38,   418,
-      54,    55,   421,   387,    10,   429,   286,    56,   390,   439,
-     438,   391,   392,   393,   442,   394,   395,   396,   397,   402,
-     406,   407,   234,   408,   472,   410,   411,   416,   426,   430,
-     431,   455,    57,    58,    59,    60,   432,   441,    61,   444,
-     456,     4,   459,    62,     5,   460,   467,   462,   466,     6,
-      63,   468,    64,    43,   473,     7,   476,   433,    66,   484,
-     478,     8,   162,   502,     9,   287,   500,    21,   481,    44,
-     422,    45,   317,   427,   420,    28,   288,    46,   280,    15,
-     167,    47,    10,   235,    34,   469,    37,     0,     0,    11,
-       0,     0,   289,   290,    48,   291,   315,   292,    49,    50,
-       0,   374,   375,   293,    51,   282,    52,   283,   284,   285,
-     302,     0,     0,    53,    40,   439,   438,    24,     0,    38,
-       0,     0,     0,     0,    54,    55,     0,     0,     0,     0,
-      12,    56,     0,     0,     0,     0,    13,    14,     0,     0,
-     354,     0,   354,     0,   282,    43,   283,   284,   285,     0,
-     355,     0,   355,     0,     0,   286,    57,    58,    59,    60,
-       0,    44,    61,    45,     0,     0,    15,    62,   282,    46,
-     283,   284,   285,    47,    63,     0,    64,     0,     0,     0,
-       0,    65,    66,     0,     0,     0,    48,     0,     0,     0,
-      49,    50,   374,   375,   286,     0,    51,     0,    52,     0,
-       0,     0,     0,    15,     0,    53,   374,   375,     0,     0,
-       0,     0,     0,     0,   287,     0,    54,    55,   286,     0,
-     374,   375,     0,    56,     0,   288,   376,   475,   377,   378,
-     379,   380,   381,   382,     0,     0,   374,   375,     0,     0,
-       0,   289,   290,     0,   291,     0,   292,     0,    57,    58,
-      59,    60,   293,   287,    61,   374,   375,     0,     0,    62,
-       0,     0,     0,     0,   288,     0,    63,     0,    64,     0,
-       0,     0,     0,    65,    66,     0,     0,   287,     0,     0,
-     289,   290,     0,   291,     0,   292,     0,     0,   288,     0,
-       0,   293,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,   289,   290,     0,   486,     0,   292,
-       0,     0,     0,     0,     0,   293,     0,   376,     0,   377,
-     378,   379,   380,   381,   382,     0,     0,     0,     0,     0,
-       0,   376,   398,   377,   378,   379,   380,   381,   382,     0,
-       0,     0,     0,     0,     0,   376,   405,   377,   378,   379,
-     380,   381,   382,    43,     0,     0,     0,     0,     0,     0,
-     443,   376,   504,   377,   378,   379,   380,   381,   382,    44,
-       0,    45,     0,     0,     0,     0,     0,    46,     0,     0,
-     376,    47,   377,   378,   379,   380,   381,   382,     4,     0,
-       0,     5,     0,     0,    48,     0,     6,     0,    49,    50,
-       0,     0,     7,     0,    51,     0,    52,     0,     8,     0,
-       0,     9,     4,    53,     0,     5,     0,     5,     0,     0,
-       6,     0,     6,     0,    54,    55,     7,     0,     5,    10,
-     235,    56,     8,     6,     8,     9,    11,     9,     0,     0,
-       0,     0,     0,     0,     0,     8,     0,     0,     9,     0,
-       0,     0,     0,    10,     0,    10,    57,    58,    59,    60,
-      11,     0,    61,     0,     0,     0,    10,    62,     5,     0,
-       0,     0,     0,     6,    63,     0,    64,    12,     0,     0,
-       0,    65,    66,    13,    14,     8,     0,     0,     9,     0,
+      45,   180,    70,    59,    46,   212,    90,    67,   361,    39,
+     350,   322,   277,   278,   325,   346,   327,     4,    50,   330,
+     178,  -210,   335,   223,   220,   288,   534,   355,   291,    11,
+     146,   321,   295,   370,   150,   199,   200,     9,   535,   402,
+     250,     5,     3,     6,   422,   384,   222,   197,   198,     7,
+      71,    72,   214,     9,    38,   199,   200,    15,    10,   161,
+     351,   176,   251,  -210,    23,   224,    12,   201,   529,   423,
+      13,    14,     9,    15,    23,   402,    16,    73,    17,    20,
+     368,   426,   366,   438,   438,    18,    38,   201,   -40,    74,
+      75,    19,   381,   269,   202,    20,   357,    21,    22,   452,
+     400,   401,   402,    38,    24,   340,   427,   341,   439,   442,
+     463,    25,   450,   -40,   202,   196,   196,   196,    87,   385,
+     389,   196,    38,    31,    79,    94,   280,    25,   386,   281,
+      38,    26,    27,    28,    29,   203,   457,    30,    84,    31,
+      38,    86,   541,    32,    89,    81,    93,    76,    77,    33,
+      34,    85,    35,    82,    83,   203,   183,    36,    37,   204,
+     471,    38,   402,   271,    88,    77,   536,   186,    45,    45,
+      70,    70,    46,    46,   184,    67,    67,   254,   254,   204,
+     185,    38,   187,   469,   338,   339,   288,   362,   345,   205,
+     474,   506,   420,   421,   188,   513,   283,    92,    77,   400,
+     401,   402,   503,   206,   405,   406,   264,   265,   189,   205,
+     514,   272,   273,   191,   316,   199,   200,   316,   417,   418,
+     419,   507,   192,   206,   328,   213,   215,   333,   420,   421,
+     333,   337,   194,   216,   217,     7,   263,   377,  -210,   218,
+     219,   352,   221,   415,   416,   417,   418,   419,   225,   226,
+     227,   399,   228,   229,   230,   420,   421,   526,   231,   279,
+     232,   510,   233,   382,   234,   196,   316,   333,   266,   235,
+     236,    18,   237,   364,   516,    70,   532,    46,   291,   376,
+      67,   238,   520,    21,    22,   284,   239,   240,   241,   242,
+      24,   243,   387,   392,   393,   394,   395,   396,   397,   398,
+     244,   245,   246,   415,   416,   417,   418,   419,   274,   247,
+     248,   249,   455,   289,   538,   420,   421,   527,    27,   318,
+     180,   319,   293,    30,   323,   324,   326,   329,   343,   348,
+     478,   458,   468,   347,   349,   354,   359,   378,   472,   367,
+     413,   414,   415,   416,   417,   418,   419,   360,   379,   384,
+     380,   390,   391,   453,   420,   421,   395,   424,   436,   364,
+     425,    70,   428,    46,   429,   430,    67,   431,   432,   433,
+     434,   441,   437,   451,   454,    19,   440,   444,   445,   446,
+     447,   448,   473,   449,   456,   465,   467,   481,   482,   460,
+     484,   485,   486,   487,   488,   489,   490,   491,   492,   493,
+     494,   495,   496,   497,   498,   499,   500,     4,   502,   466,
+     475,   476,   477,   483,   511,   480,   501,   504,   505,   508,
+     509,   512,   518,   377,   539,   333,   521,   525,   540,   530,
+     545,     5,   171,     6,   461,    44,   515,   470,    52,     7,
+       8,   544,   177,     9,    58,    61,   365,   296,    10,   297,
+     298,   299,   300,   301,    11,   517,    12,   267,   334,     0,
+      13,    14,   336,    15,     0,   376,    16,   522,    17,     0,
+       0,     0,     0,     0,     0,    18,     0,     0,     0,     0,
+       0,    19,   253,     0,     0,    20,     0,    21,    22,    23,
+       0,     0,     0,     0,    24,     0,     0,     0,     0,     0,
+       0,     0,     4,     0,     0,   302,     0,     0,     0,     0,
+     531,   364,     0,    70,     0,    46,     0,    25,    67,     0,
+       0,    26,    27,    28,    29,     0,     5,    30,     6,    31,
+       0,     0,     0,    32,     7,     0,     0,     0,     9,    33,
+      34,   303,    35,    10,     0,     0,     0,    36,    37,     0,
+       0,    12,     0,     0,     0,    13,    14,     0,    15,     0,
+       0,    16,     0,    17,     0,     0,     0,   304,     0,     0,
+      18,    38,     0,     0,     0,     0,    19,   262,     0,   305,
+      20,     0,    21,    22,     0,     0,     0,     0,     0,    24,
+       0,     0,     0,     0,     0,     0,   306,     4,     0,   307,
+     308,   309,     0,     0,   310,   311,     0,     0,     0,     0,
+       0,     0,    25,   464,     0,   312,    26,    27,    28,    29,
+       0,     5,    30,     6,    31,     0,     0,     0,    32,     7,
+       0,     0,     0,     9,    33,    34,     0,    35,    10,     0,
+       0,     0,    36,    37,     0,     0,    12,     0,     0,     0,
+      13,    14,     0,    15,     0,     0,    16,     0,    17,     0,
+       0,     0,     0,     0,     0,    18,    38,     0,     0,     0,
+       0,    19,   462,     0,     0,    20,     0,    21,    22,     0,
+       0,     0,     0,     0,    24,     0,     0,     0,     0,     0,
+       0,   296,     4,   297,   298,   299,   300,   301,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,    25,     0,     0,
+       0,    26,    27,    28,    29,     0,     5,    30,     6,    31,
+       0,     0,     0,    32,     7,     0,     0,     0,     0,    33,
+      34,     0,    35,     0,     0,     0,     0,    36,    37,     0,
+       0,    12,     0,     0,     0,    13,    14,     0,     0,   302,
+       0,    16,   296,    17,   297,   298,   299,   300,   301,     0,
+      18,    38,     0,     0,     0,     0,     0,   528,     0,     0,
+       0,     0,    21,    22,     0,     0,     0,     0,     0,    24,
+       0,     0,     0,     0,     0,   303,     0,     0,     0,     0,
+       0,     0,   296,     0,   297,   298,   299,   300,   301,     0,
+       0,     0,     0,     0,     0,     0,    26,    27,    28,    29,
+     302,   304,    30,     0,     0,     0,     0,     0,    32,     0,
+       0,     0,     0,   305,     0,    34,     0,    35,     0,     0,
+       0,     0,    36,    37,     0,     0,     0,     0,     0,     0,
+     306,     0,     0,   307,   308,   309,   303,     0,   310,   311,
+     302,     0,     0,     0,     0,     0,     0,     0,     0,   312,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   304,     0,     0,     0,   400,   401,   402,   403,
+     404,   405,   406,     0,   305,     0,   303,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,   306,     0,     0,   307,   308,   309,     0,     0,   310,
+     311,     0,   304,     0,     0,     0,     0,     0,     0,     0,
+     312,     0,     0,     0,   305,     0,     0,     0,     0,     4,
+       0,     0,     0,     0,     0,     0,   252,     0,     0,     0,
+       0,   306,     0,     0,   307,   308,   369,     0,     0,   310,
+     311,     0,     0,     5,     0,     6,     0,     0,     0,     0,
+     312,     7,     8,     0,     0,     9,     0,     0,     0,     0,
+      10,     0,     0,     0,     0,     0,    11,     0,    12,     0,
+       0,     0,    13,    14,     0,    15,     0,     0,    16,     0,
+      17,     0,     0,     0,     0,     0,     0,    18,     0,     0,
+       0,     0,     0,    19,   253,     0,     0,    20,     0,    21,
+      22,    23,     0,     0,     0,     0,    24,   413,   414,   415,
+     416,   417,   418,   419,     4,     0,     0,     0,     0,     0,
+       0,   420,   421,     0,     0,     0,     0,     0,     0,    25,
+       0,     0,     0,    26,    27,    28,    29,     0,     5,    30,
+       6,    31,     0,     0,     0,    32,     7,     8,     0,     0,
+       9,    33,    34,     0,    35,    10,     0,     0,     0,    36,
+      37,    11,     0,    12,     0,     0,     0,    13,    14,     0,
+      15,     0,     0,    16,     0,    17,     0,     0,     0,     0,
+       0,     0,    18,    38,     0,     0,     0,     0,    19,     4,
+       0,     0,    20,     0,    21,    22,    23,     0,     0,     0,
+       0,    24,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     5,     0,     6,     0,     0,     0,     0,
+       0,     7,     0,     0,    25,     9,     0,     0,    26,    27,
+      28,    29,     4,     0,    30,     0,    31,     0,    12,     0,
+      32,     0,    13,    14,     0,    15,    33,    34,    16,    35,
+      17,     0,     0,     0,    36,    37,     5,    18,     6,     0,
+       0,     0,     0,     0,     7,     0,     0,    20,     9,    21,
+      22,     0,     0,     0,     0,     0,    24,     0,    38,     0,
+       0,    12,     0,     0,     0,    13,    14,     0,    15,     0,
+       0,    16,     0,    17,     0,     0,     0,     0,     0,    25,
+      18,     0,     0,    26,    27,    28,    29,     0,     0,    30,
+      20,    31,    21,    22,     0,    32,     0,     0,     0,    24,
+       0,     0,    34,     0,    35,     0,     0,     0,     0,   371,
+      37,   400,   401,   402,   403,   404,   405,   406,   407,   408,
+       0,     0,    25,     0,     0,     0,    26,    27,    28,    29,
+       0,     0,    30,    38,    31,     0,     0,     0,    32,     0,
+       0,     0,     0,     0,     0,    34,     0,    35,     0,     0,
+       0,     0,    36,    37,   400,   401,   402,   403,   404,   405,
+     406,   407,   408,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    38,   400,   401,   402,
+     403,   404,   405,   406,   407,   408,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     400,   401,   402,   403,   404,   405,   406,   407,   408,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,   400,   401,   402,   403,   404,   405,   406,   407,
+     408,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,   409,     0,   410,
+     411,   412,   413,   414,   415,   416,   417,   418,   419,     0,
+       0,     0,     0,     0,     0,     0,   420,   421,     0,     0,
+       0,   435,   400,   401,   402,   403,   404,   405,   406,   407,
+     408,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     409,     0,   410,   411,   412,   413,   414,   415,   416,   417,
+     418,   419,   400,   401,   402,   403,   404,   405,   406,   420,
+     421,     0,     0,   409,   443,   410,   411,   412,   413,   414,
+     415,   416,   417,   418,   419,   400,   401,   402,   403,   404,
+     405,   406,   420,   421,     0,     0,   409,   479,   410,   411,
+     412,   413,   414,   415,   416,   417,   418,   419,   400,   401,
+     402,   403,   404,   405,   406,   420,   421,   524,   409,   523,
+     410,   411,   412,   413,   414,   415,   416,   417,   418,   419,
+       0,     0,     0,     0,     0,     0,     0,   420,   421,   400,
+     401,   402,   403,   404,   405,   406,     0,   408,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,   409,     0,
+     410,   411,   412,   413,   414,   415,   416,   417,   418,   419,
+       0,     0,     0,     0,     0,     0,     0,   420,   421,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     410,   411,   412,   413,   414,   415,   416,   417,   418,   419,
+       0,     0,     0,     0,     0,     0,     0,   420,   421,     0,
+       0,     0,     0,     0,   411,   412,   413,   414,   415,   416,
+     417,   418,   419,     0,     0,     0,     0,     0,     0,     0,
+     420,   421,     0,     0,     0,     0,     0,     0,   412,   413,
+     414,   415,   416,   417,   418,   419,     0,     0,     0,     0,
+       0,     0,     0,   420,   421,     4,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,   410,   411,   412,
+     413,   414,   415,   416,   417,   418,   419,     0,     0,     5,
+       0,     6,     0,     0,   420,   421,     0,     7,     8,     0,
+       0,     9,     0,     0,     0,     0,     0,     0,     4,     0,
+       0,     0,    11,     0,    12,     0,     0,     0,    13,    14,
+       0,    15,     0,     0,    16,     0,    17,     0,     0,     0,
+       0,     0,     5,    18,     6,     0,     0,     0,     0,     0,
+       7,     0,     0,    20,     9,    21,    22,    23,     0,     0,
+     172,     0,    24,     0,   173,     0,     0,    12,     0,     0,
+       0,    13,    14,     0,    15,     0,     0,    16,     0,    17,
+       0,     0,     0,     0,     0,    25,    18,     0,     4,    26,
+      27,    28,    29,     0,     0,    30,    20,    31,    21,    22,
+       0,    32,     0,     0,     0,    24,     0,     0,    34,     0,
+      35,     0,     5,     0,     6,    36,    37,     0,     0,     0,
+       7,     0,     0,     0,     0,     0,     0,     0,    25,     0,
+       0,     0,    26,    27,    28,    29,     0,    12,    30,     0,
+      31,    13,    14,     0,    32,     0,     0,    16,     0,    17,
+       0,    34,     0,    35,     0,     0,    18,     0,    36,    37,
+       0,     0,     0,     0,     0,     0,     0,     0,    21,    22,
+       0,     0,     0,     0,     0,    24,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    12,     0,    12,     0,     0,    10,    13,    14,    13,
-      14,     0,   244,    15,    12,     0,     0,     0,     0,     0,
-      13,    14,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,    15,   343,    15,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,   423,
-      15,     0,     0,     0,    12,     0,     0,     0,     0,     0,
-      13,    14,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    87,     0,    88,    89,     0,    90,    91,     0,    92,
-       0,     0,    93,     0,    94,     0,     0,     0,     0,   480,
-      15,    95,    96,    97,    98,     0,    99,   100,   101,   102,
-     103,     0,   104,     0,   105,   106,   107,     0,     0,   108,
-       0,     0,     0,     0,   109,     0,   110,   111,   112,   113,
-     114,   115,     0,   116,   117,   118,   119,   120,     0,     0,
-     121,     0,   122,     0,     0,     0,     0,   123,     0,   124,
-       0,     0,     0,   125,   126,   127,   128,   129,   130,   131,
-     132,     0,   133,     0,   134,   135,   136,   137,   138,   139,
-     140,   141,   142,   143,   144,     0,     0,     0,     0,   145,
-       0,     0,   146,     0,   147,   148,     0,     0,   149,   150,
-     151,     0,     0,     0,   152,     0,   153,   154,   155,   156,
-       0,     0,   157
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,    26,    27,    28,    29,     0,     0,    30,     0,
+       0,     0,     0,     0,    32,     0,     0,     0,     0,     0,
+       0,    34,     0,    35,     0,     0,     0,     0,    36,    37,
+      95,     0,    96,    97,     0,    98,    99,     0,   100,     0,
+       0,   101,     0,   102,     0,     0,     0,     0,     0,     0,
+     103,   104,   105,   106,     0,   107,   108,   109,   110,   111,
+       0,   112,     0,   113,   114,   115,     0,     0,   116,     0,
+       0,     0,     0,   117,     0,   118,   119,   120,   121,   122,
+     123,     0,   124,   125,   126,   127,   128,     0,     0,   129,
+       0,     0,   130,     0,     0,     0,   131,   132,     0,   133,
+       0,     0,     0,   134,   135,   136,     0,   137,   138,   139,
+     140,   141,     0,   142,     0,   143,   144,   145,   146,   147,
+     148,   149,   150,     0,   151,   152,   153,     0,     0,     0,
+       0,   154,     0,     0,   155,     0,     0,   156,   157,     0,
+       0,   158,   159,   160,     0,     0,     0,   161,     0,   162,
+     163,   164,   165,     0,     0,   166
 };
 
 static const short int yycheck[] =
 {
 };
 
 static const short int yycheck[] =
 {
-       2,    13,     5,     2,    71,     2,     2,   244,     2,   119,
-     210,    11,    12,   213,   214,   255,   220,   217,   222,   219,
-      26,   225,   226,   232,   224,     2,   251,    22,    83,   267,
-     400,   119,    38,   271,   272,   273,    43,   135,    77,     8,
-       9,   135,   152,    28,    47,    29,     2,     0,   502,   135,
-     504,    99,   135,   135,   279,   103,    95,   155,   258,    43,
-      12,   155,    14,   150,   152,   151,    22,    32,   151,   151,
-      77,     3,   149,     5,     6,     7,    79,   154,   126,    64,
-       3,    84,     5,     6,     7,   289,   290,   291,   292,   293,
-      75,    76,    56,    77,    58,   332,    80,    82,   135,   154,
-      84,   154,     3,     4,    11,    12,   343,   149,   478,     8,
-      62,    63,   470,   135,   151,    59,    11,    12,   149,   328,
-      64,    53,   149,   108,   482,   363,    27,   152,   113,   151,
-      53,    32,   149,   149,   201,   202,   153,   154,     3,     4,
-     149,   208,   142,   143,   153,   154,    75,   153,     3,     4,
-     137,   351,   150,    54,     3,     4,     3,     4,   149,   161,
-     162,   150,   161,   162,   152,   161,   162,   161,   162,   149,
-     374,   375,   376,   377,   378,   379,   380,   381,   382,   417,
-     112,   176,   422,   383,   161,   162,   423,   425,   191,   112,
-     149,   123,    93,     3,     4,   152,   400,     3,     4,   149,
-     123,   439,   149,   403,     3,     4,   149,   139,   140,   149,
-     142,     8,   144,   152,   115,   152,   139,   140,   150,   142,
-     150,   144,   150,   460,   227,   228,   150,   150,   231,     3,
-       4,   469,   155,   140,   141,   142,   143,   249,   150,   251,
-     444,   142,   150,   480,   139,   140,   141,   142,   143,   150,
-       3,     4,   150,   265,     3,     4,   150,   256,   150,   150,
-     256,     3,   256,   265,   153,   154,   152,   279,   280,   153,
-     154,   475,    11,    12,   478,   150,   150,   150,   280,     4,
-     150,   150,   486,   350,   150,   152,   150,   150,   150,   493,
-     293,   495,   150,   150,   150,    20,   500,    22,   150,   150,
-       8,     8,   152,    28,     8,   151,     3,    32,     5,     6,
-       7,     8,   156,   150,     8,     8,    57,     5,   154,   150,
-      45,   149,   137,   149,    49,    50,   153,   152,   151,   150,
-      55,   135,    57,   135,   156,   151,   333,   150,     3,    64,
-     151,   135,   345,   342,   151,   157,   342,     8,   342,   149,
-      75,    76,   153,   151,    70,   354,    53,    82,   151,   362,
-     362,   151,   151,   151,   367,   151,   151,   151,   151,   151,
-     151,   151,    10,   151,   441,   151,   151,   137,   149,   149,
-     149,     8,   107,   108,   109,   110,   151,   151,   113,   151,
-     151,    29,     5,   118,    32,   151,   151,   149,   149,    37,
-     125,   135,   127,     4,   151,    43,   151,   132,   133,   152,
-     154,    49,    20,   137,    52,   112,   154,     2,   468,    20,
-     341,    22,   225,   350,   339,     2,   123,    28,   207,   154,
-      22,    32,    70,    71,     2,   438,     2,    -1,    -1,    77,
-      -1,    -1,   139,   140,    45,   142,   223,   144,    49,    50,
-      -1,    11,    12,   150,    55,     3,    57,     5,     6,     7,
-       8,    -1,    -1,    64,   463,   468,   468,   463,    -1,   463,
-      -1,    -1,    -1,    -1,    75,    76,    -1,    -1,    -1,    -1,
-     118,    82,    -1,    -1,    -1,    -1,   124,   125,    -1,    -1,
-     502,    -1,   504,    -1,     3,     4,     5,     6,     7,    -1,
-     502,    -1,   504,    -1,    -1,    53,   107,   108,   109,   110,
-      -1,    20,   113,    22,    -1,    -1,   154,   118,     3,    28,
-       5,     6,     7,    32,   125,    -1,   127,    -1,    -1,    -1,
-      -1,   132,   133,    -1,    -1,    -1,    45,    -1,    -1,    -1,
-      49,    50,    11,    12,    53,    -1,    55,    -1,    57,    -1,
-      -1,    -1,    -1,   154,    -1,    64,    11,    12,    -1,    -1,
-      -1,    -1,    -1,    -1,   112,    -1,    75,    76,    53,    -1,
-      11,    12,    -1,    82,    -1,   123,   136,   137,   138,   139,
-     140,   141,   142,   143,    -1,    -1,    11,    12,    -1,    -1,
-      -1,   139,   140,    -1,   142,    -1,   144,    -1,   107,   108,
-     109,   110,   150,   112,   113,    11,    12,    -1,    -1,   118,
-      -1,    -1,    -1,    -1,   123,    -1,   125,    -1,   127,    -1,
-      -1,    -1,    -1,   132,   133,    -1,    -1,   112,    -1,    -1,
-     139,   140,    -1,   142,    -1,   144,    -1,    -1,   123,    -1,
-      -1,   150,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,   139,   140,    -1,   142,    -1,   144,
-      -1,    -1,    -1,    -1,    -1,   150,    -1,   136,    -1,   138,
-     139,   140,   141,   142,   143,    -1,    -1,    -1,    -1,    -1,
-      -1,   136,   151,   138,   139,   140,   141,   142,   143,    -1,
-      -1,    -1,    -1,    -1,    -1,   136,   151,   138,   139,   140,
-     141,   142,   143,     4,    -1,    -1,    -1,    -1,    -1,    -1,
-     151,   136,   137,   138,   139,   140,   141,   142,   143,    20,
-      -1,    22,    -1,    -1,    -1,    -1,    -1,    28,    -1,    -1,
-     136,    32,   138,   139,   140,   141,   142,   143,    29,    -1,
-      -1,    32,    -1,    -1,    45,    -1,    37,    -1,    49,    50,
-      -1,    -1,    43,    -1,    55,    -1,    57,    -1,    49,    -1,
-      -1,    52,    29,    64,    -1,    32,    -1,    32,    -1,    -1,
-      37,    -1,    37,    -1,    75,    76,    43,    -1,    32,    70,
-      71,    82,    49,    37,    49,    52,    77,    52,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    49,    -1,    -1,    52,    -1,
-      -1,    -1,    -1,    70,    -1,    70,   107,   108,   109,   110,
-      77,    -1,   113,    -1,    -1,    -1,    70,   118,    32,    -1,
-      -1,    -1,    -1,    37,   125,    -1,   127,   118,    -1,    -1,
-      -1,   132,   133,   124,   125,    49,    -1,    -1,    52,    -1,
+       2,    45,     2,     2,     2,    66,    33,     2,   274,     2,
+     262,   231,   206,   207,   234,   250,   236,     4,     2,   239,
+      45,   131,   242,   131,    85,   218,    34,    92,   222,    51,
+     109,   230,   225,   280,   113,     3,     4,    40,    46,    14,
+     147,    28,     0,    30,   147,   147,    90,    63,    64,    36,
+       3,     4,    68,    40,   168,     3,     4,    60,    45,   138,
+     174,    45,   169,   173,    86,   173,    53,    35,   170,   172,
+      57,    58,    40,    60,    86,    14,    63,   171,    65,    82,
+     279,   147,   276,   147,   147,    72,   168,    35,   147,     3,
+       4,    78,   174,   105,    62,    82,   270,    84,    85,   351,
+      12,    13,    14,   168,    91,     8,   172,    10,   172,   172,
+     362,   114,   347,   172,    62,    62,    63,    64,    28,   293,
+     294,    68,   168,   126,    84,    35,   168,   114,   174,   171,
+     168,   118,   119,   120,   121,   103,   174,   124,    24,   126,
+     168,    27,   170,   130,    32,     8,    34,     3,     4,   136,
+     137,   171,   139,     3,     4,   103,   170,   144,   145,   127,
+     380,   168,    14,   188,     3,     4,   174,   173,   170,   171,
+     170,   171,   170,   171,   170,   170,   171,   170,   171,   127,
+     170,   168,   170,   377,   245,   246,   379,   174,   249,   157,
+     384,   438,   167,   168,   173,   461,   212,     3,     4,    12,
+      13,    14,   422,   171,    17,    18,     3,     4,   170,   157,
+     462,     3,     4,   170,   227,     3,     4,   230,   157,   158,
+     159,   441,   149,   171,   237,   170,   170,   240,   167,   168,
+     243,   244,   173,   170,     8,    36,     3,   281,   173,   173,
+     170,   268,   173,   155,   156,   157,   158,   159,   171,   171,
+     171,   312,   171,   171,   171,   167,   168,   509,   171,   175,
+     171,   455,   171,   290,   171,   212,   279,   280,   173,   171,
+     171,    72,   171,   275,   468,   275,   528,   275,   472,   281,
+     275,   171,   475,    84,    85,   172,   171,   171,   171,   171,
+      91,   171,   294,   306,   307,   308,   309,   310,   311,   312,
+     171,   171,   171,   155,   156,   157,   158,   159,   173,   171,
+     171,   171,   356,   172,   534,   167,   168,   511,   119,     8,
+     364,     8,   171,   124,     8,     8,     8,    65,     5,   171,
+     391,   358,   376,   168,   170,   149,   170,   174,   382,   172,
+     153,   154,   155,   156,   157,   158,   159,   173,   147,   147,
+     175,   172,   171,   352,   167,   168,   369,   172,     3,   361,
+     172,   361,   172,   361,   172,   172,   361,   172,   172,   172,
+     172,   147,   172,     8,   149,    78,   172,   172,   172,   172,
+     167,   172,   382,   172,   170,   169,   147,   400,   401,   174,
+     403,   404,   405,   406,   407,   408,   409,   410,   411,   412,
+     413,   414,   415,   416,   417,   418,   419,     4,   421,   172,
+     172,   170,   170,     3,   458,   172,     3,     8,   172,     5,
+     172,   170,   170,   467,   149,   438,   172,   172,   149,   173,
+     170,    28,    43,    30,   360,     2,   467,   379,     2,    36,
+      37,   540,    45,    40,     2,     2,   276,     3,    45,     5,
+       6,     7,     8,     9,    51,   472,    53,   180,   241,    -1,
+      57,    58,   243,    60,    -1,   467,    63,   480,    65,    -1,
+      -1,    -1,    -1,    -1,    -1,    72,    -1,    -1,    -1,    -1,
+      -1,    78,    79,    -1,    -1,    82,    -1,    84,    85,    86,
+      -1,    -1,    -1,    -1,    91,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,     4,    -1,    -1,    61,    -1,    -1,    -1,    -1,
+     523,   513,    -1,   513,    -1,   513,    -1,   114,   513,    -1,
+      -1,   118,   119,   120,   121,    -1,    28,   124,    30,   126,
+      -1,    -1,    -1,   130,    36,    -1,    -1,    -1,    40,   136,
+     137,    97,   139,    45,    -1,    -1,    -1,   144,   145,    -1,
+      -1,    53,    -1,    -1,    -1,    57,    58,    -1,    60,    -1,
+      -1,    63,    -1,    65,    -1,    -1,    -1,   123,    -1,    -1,
+      72,   168,    -1,    -1,    -1,    -1,    78,   174,    -1,   135,
+      82,    -1,    84,    85,    -1,    -1,    -1,    -1,    -1,    91,
+      -1,    -1,    -1,    -1,    -1,    -1,   152,     4,    -1,   155,
+     156,   157,    -1,    -1,   160,   161,    -1,    -1,    -1,    -1,
+      -1,    -1,   114,   169,    -1,   171,   118,   119,   120,   121,
+      -1,    28,   124,    30,   126,    -1,    -1,    -1,   130,    36,
+      -1,    -1,    -1,    40,   136,   137,    -1,   139,    45,    -1,
+      -1,    -1,   144,   145,    -1,    -1,    53,    -1,    -1,    -1,
+      57,    58,    -1,    60,    -1,    -1,    63,    -1,    65,    -1,
+      -1,    -1,    -1,    -1,    -1,    72,   168,    -1,    -1,    -1,
+      -1,    78,   174,    -1,    -1,    82,    -1,    84,    85,    -1,
+      -1,    -1,    -1,    -1,    91,    -1,    -1,    -1,    -1,    -1,
+      -1,     3,     4,     5,     6,     7,     8,     9,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,   114,    -1,    -1,
+      -1,   118,   119,   120,   121,    -1,    28,   124,    30,   126,
+      -1,    -1,    -1,   130,    36,    -1,    -1,    -1,    -1,   136,
+     137,    -1,   139,    -1,    -1,    -1,    -1,   144,   145,    -1,
+      -1,    53,    -1,    -1,    -1,    57,    58,    -1,    -1,    61,
+      -1,    63,     3,    65,     5,     6,     7,     8,     9,    -1,
+      72,   168,    -1,    -1,    -1,    -1,    -1,   174,    -1,    -1,
+      -1,    -1,    84,    85,    -1,    -1,    -1,    -1,    -1,    91,
+      -1,    -1,    -1,    -1,    -1,    97,    -1,    -1,    -1,    -1,
+      -1,    -1,     3,    -1,     5,     6,     7,     8,     9,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   118,   119,   120,   121,
+      61,   123,   124,    -1,    -1,    -1,    -1,    -1,   130,    -1,
+      -1,    -1,    -1,   135,    -1,   137,    -1,   139,    -1,    -1,
+      -1,    -1,   144,   145,    -1,    -1,    -1,    -1,    -1,    -1,
+     152,    -1,    -1,   155,   156,   157,    97,    -1,   160,   161,
+      61,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   171,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,   123,    -1,    -1,    -1,    12,    13,    14,    15,
+      16,    17,    18,    -1,   135,    -1,    97,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,   152,    -1,    -1,   155,   156,   157,    -1,    -1,   160,
+     161,    -1,   123,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     171,    -1,    -1,    -1,   135,    -1,    -1,    -1,    -1,     4,
+      -1,    -1,    -1,    -1,    -1,    -1,    11,    -1,    -1,    -1,
+      -1,   152,    -1,    -1,   155,   156,   157,    -1,    -1,   160,
+     161,    -1,    -1,    28,    -1,    30,    -1,    -1,    -1,    -1,
+     171,    36,    37,    -1,    -1,    40,    -1,    -1,    -1,    -1,
+      45,    -1,    -1,    -1,    -1,    -1,    51,    -1,    53,    -1,
+      -1,    -1,    57,    58,    -1,    60,    -1,    -1,    63,    -1,
+      65,    -1,    -1,    -1,    -1,    -1,    -1,    72,    -1,    -1,
+      -1,    -1,    -1,    78,    79,    -1,    -1,    82,    -1,    84,
+      85,    86,    -1,    -1,    -1,    -1,    91,   153,   154,   155,
+     156,   157,   158,   159,     4,    -1,    -1,    -1,    -1,    -1,
+      -1,   167,   168,    -1,    -1,    -1,    -1,    -1,    -1,   114,
+      -1,    -1,    -1,   118,   119,   120,   121,    -1,    28,   124,
+      30,   126,    -1,    -1,    -1,   130,    36,    37,    -1,    -1,
+      40,   136,   137,    -1,   139,    45,    -1,    -1,    -1,   144,
+     145,    51,    -1,    53,    -1,    -1,    -1,    57,    58,    -1,
+      60,    -1,    -1,    63,    -1,    65,    -1,    -1,    -1,    -1,
+      -1,    -1,    72,   168,    -1,    -1,    -1,    -1,    78,     4,
+      -1,    -1,    82,    -1,    84,    85,    86,    -1,    -1,    -1,
+      -1,    91,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    28,    -1,    30,    -1,    -1,    -1,    -1,
+      -1,    36,    -1,    -1,   114,    40,    -1,    -1,   118,   119,
+     120,   121,     4,    -1,   124,    -1,   126,    -1,    53,    -1,
+     130,    -1,    57,    58,    -1,    60,   136,   137,    63,   139,
+      65,    -1,    -1,    -1,   144,   145,    28,    72,    30,    -1,
+      -1,    -1,    -1,    -1,    36,    -1,    -1,    82,    40,    84,
+      85,    -1,    -1,    -1,    -1,    -1,    91,    -1,   168,    -1,
+      -1,    53,    -1,    -1,    -1,    57,    58,    -1,    60,    -1,
+      -1,    63,    -1,    65,    -1,    -1,    -1,    -1,    -1,   114,
+      72,    -1,    -1,   118,   119,   120,   121,    -1,    -1,   124,
+      82,   126,    84,    85,    -1,   130,    -1,    -1,    -1,    91,
+      -1,    -1,   137,    -1,   139,    -1,    -1,    -1,    -1,   144,
+     145,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      -1,    -1,   114,    -1,    -1,    -1,   118,   119,   120,   121,
+      -1,    -1,   124,   168,   126,    -1,    -1,    -1,   130,    -1,
+      -1,    -1,    -1,    -1,    -1,   137,    -1,   139,    -1,    -1,
+      -1,    -1,   144,   145,    12,    13,    14,    15,    16,    17,
+      18,    19,    20,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   168,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      12,    13,    14,    15,    16,    17,    18,    19,    20,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    12,    13,    14,    15,    16,    17,    18,    19,
+      20,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,   148,    -1,   150,
+     151,   152,   153,   154,   155,   156,   157,   158,   159,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,   167,   168,    -1,    -1,
+      -1,   172,    12,    13,    14,    15,    16,    17,    18,    19,
+      20,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     148,    -1,   150,   151,   152,   153,   154,   155,   156,   157,
+     158,   159,    12,    13,    14,    15,    16,    17,    18,   167,
+     168,    -1,    -1,   148,   172,   150,   151,   152,   153,   154,
+     155,   156,   157,   158,   159,    12,    13,    14,    15,    16,
+      17,    18,   167,   168,    -1,    -1,   148,   172,   150,   151,
+     152,   153,   154,   155,   156,   157,   158,   159,    12,    13,
+      14,    15,    16,    17,    18,   167,   168,   169,   148,   149,
+     150,   151,   152,   153,   154,   155,   156,   157,   158,   159,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,   167,   168,    12,
+      13,    14,    15,    16,    17,    18,    -1,    20,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   148,    -1,
+     150,   151,   152,   153,   154,   155,   156,   157,   158,   159,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,   167,   168,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     150,   151,   152,   153,   154,   155,   156,   157,   158,   159,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,   167,   168,    -1,
+      -1,    -1,    -1,    -1,   151,   152,   153,   154,   155,   156,
+     157,   158,   159,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     167,   168,    -1,    -1,    -1,    -1,    -1,    -1,   152,   153,
+     154,   155,   156,   157,   158,   159,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,   167,   168,     4,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,   150,   151,   152,
+     153,   154,   155,   156,   157,   158,   159,    -1,    -1,    28,
+      -1,    30,    -1,    -1,   167,   168,    -1,    36,    37,    -1,
+      -1,    40,    -1,    -1,    -1,    -1,    -1,    -1,     4,    -1,
+      -1,    -1,    51,    -1,    53,    -1,    -1,    -1,    57,    58,
+      -1,    60,    -1,    -1,    63,    -1,    65,    -1,    -1,    -1,
+      -1,    -1,    28,    72,    30,    -1,    -1,    -1,    -1,    -1,
+      36,    -1,    -1,    82,    40,    84,    85,    86,    -1,    -1,
+      89,    -1,    91,    -1,    93,    -1,    -1,    53,    -1,    -1,
+      -1,    57,    58,    -1,    60,    -1,    -1,    63,    -1,    65,
+      -1,    -1,    -1,    -1,    -1,   114,    72,    -1,     4,   118,
+     119,   120,   121,    -1,    -1,   124,    82,   126,    84,    85,
+      -1,   130,    -1,    -1,    -1,    91,    -1,    -1,   137,    -1,
+     139,    -1,    28,    -1,    30,   144,   145,    -1,    -1,    -1,
+      36,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   114,    -1,
+      -1,    -1,   118,   119,   120,   121,    -1,    53,   124,    -1,
+     126,    57,    58,    -1,   130,    -1,    -1,    63,    -1,    65,
+      -1,   137,    -1,   139,    -1,    -1,    72,    -1,   144,   145,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    84,    85,
+      -1,    -1,    -1,    -1,    -1,    91,    -1,    -1,    -1,    -1,
+      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
       -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,   118,    -1,   118,    -1,    -1,    70,   124,   125,   124,
-     125,    -1,   153,   154,   118,    -1,    -1,    -1,    -1,    -1,
-     124,   125,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,   154,   153,   154,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   153,
-     154,    -1,    -1,    -1,   118,    -1,    -1,    -1,    -1,    -1,
-     124,   125,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
-      -1,    13,    -1,    15,    16,    -1,    18,    19,    -1,    21,
-      -1,    -1,    24,    -1,    26,    -1,    -1,    -1,    -1,   153,
-     154,    33,    34,    35,    36,    -1,    38,    39,    40,    41,
-      42,    -1,    44,    -1,    46,    47,    48,    -1,    -1,    51,
-      -1,    -1,    -1,    -1,    56,    -1,    58,    59,    60,    61,
-      62,    63,    -1,    65,    66,    67,    68,    69,    -1,    -1,
-      72,    -1,    74,    -1,    -1,    -1,    -1,    79,    -1,    81,
-      -1,    -1,    -1,    85,    86,    87,    88,    89,    90,    91,
-      92,    -1,    94,    -1,    96,    97,    98,    99,   100,   101,
-     102,   103,   104,   105,   106,    -1,    -1,    -1,    -1,   111,
-      -1,    -1,   114,    -1,   116,   117,    -1,    -1,   120,   121,
-     122,    -1,    -1,    -1,   126,    -1,   128,   129,   130,   131,
-      -1,    -1,   134
+      -1,    -1,   118,   119,   120,   121,    -1,    -1,   124,    -1,
+      -1,    -1,    -1,    -1,   130,    -1,    -1,    -1,    -1,    -1,
+      -1,   137,    -1,   139,    -1,    -1,    -1,    -1,   144,   145,
+      21,    -1,    23,    24,    -1,    26,    27,    -1,    29,    -1,
+      -1,    32,    -1,    34,    -1,    -1,    -1,    -1,    -1,    -1,
+      41,    42,    43,    44,    -1,    46,    47,    48,    49,    50,
+      -1,    52,    -1,    54,    55,    56,    -1,    -1,    59,    -1,
+      -1,    -1,    -1,    64,    -1,    66,    67,    68,    69,    70,
+      71,    -1,    73,    74,    75,    76,    77,    -1,    -1,    80,
+      -1,    -1,    83,    -1,    -1,    -1,    87,    88,    -1,    90,
+      -1,    -1,    -1,    94,    95,    96,    -1,    98,    99,   100,
+     101,   102,    -1,   104,    -1,   106,   107,   108,   109,   110,
+     111,   112,   113,    -1,   115,   116,   117,    -1,    -1,    -1,
+      -1,   122,    -1,    -1,   125,    -1,    -1,   128,   129,    -1,
+      -1,   132,   133,   134,    -1,    -1,    -1,   138,    -1,   140,
+     141,   142,   143,    -1,    -1,   146
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
-static const unsigned char yystos[] =
+static const unsigned short int yystos[] =
 {
 {
-       0,   159,   160,     0,    29,    32,    37,    43,    49,    52,
-      70,    77,   118,   124,   125,   154,   164,   165,   166,   167,
-     170,   171,   179,   187,   191,   197,   208,   209,   210,   213,
-     214,   217,   219,   220,   221,   222,   224,   225,   231,   233,
-     234,     3,     4,     4,    20,    22,    28,    32,    45,    49,
-      50,    55,    57,    64,    75,    76,    82,   107,   108,   109,
-     110,   113,   118,   125,   127,   132,   133,   191,   205,   207,
-     231,   232,   234,   150,     3,     4,     3,     4,   203,    32,
-       8,     3,     4,   203,   178,   179,   203,    13,    15,    16,
-      18,    19,    21,    24,    26,    33,    34,    35,    36,    38,
-      39,    40,    41,    42,    44,    46,    47,    48,    51,    56,
-      58,    59,    60,    61,    62,    63,    65,    66,    67,    68,
-      69,    72,    74,    79,    81,    85,    86,    87,    88,    89,
-      90,    91,    92,    94,    96,    97,    98,    99,   100,   101,
-     102,   103,   104,   105,   106,   111,   114,   116,   117,   120,
-     121,   122,   126,   128,   129,   130,   131,   134,   180,   182,
-     230,   161,   161,    80,    84,   169,   208,   213,   219,   223,
-     149,   149,   149,   149,   152,   149,   152,   149,   163,   149,
-     137,   218,   152,   149,   149,   149,   232,     3,    75,   206,
-     206,   150,   206,   207,     3,     3,   207,     3,     4,   204,
-       8,   152,   232,   149,   152,   232,   119,   152,   150,   150,
-     150,   150,   150,   150,   150,   150,   150,   150,   150,   150,
-     150,   150,   150,   150,   150,   150,   150,   150,   150,   150,
-     150,   150,   135,   155,    10,    71,   164,   168,   171,   208,
-     210,   221,   222,   225,   153,     3,     3,     4,   152,   211,
-      95,   215,   219,     3,     4,   152,   162,   232,   156,   151,
-     188,   189,   190,   204,   204,   198,    27,    32,    54,    93,
-     115,   142,   150,   184,   204,   226,   227,   228,   229,   150,
-     198,   204,     3,     5,     6,     7,    53,   112,   123,   139,
-     140,   142,   144,   150,   194,   195,   196,     8,   196,     8,
-       8,   181,     8,   196,   196,     8,     8,   196,     8,   196,
-     194,    57,   192,   193,   194,   230,   196,   192,   194,   232,
-     232,     8,     9,   183,     5,   235,   232,   182,   154,   150,
-     149,   163,   153,   178,   212,   137,    83,   178,   200,   216,
-     149,   152,   162,   153,   164,   178,   201,   151,   196,   153,
-     135,   156,   149,   153,   178,   179,   199,   200,   226,   226,
-     226,   226,   150,   135,   200,   153,   151,   150,   194,   194,
-     194,   194,   194,   232,    11,    12,   136,   138,   139,   140,
-     141,   142,   143,   135,   151,   151,   151,   151,   135,   151,
-     151,   151,   151,   151,   151,   151,   151,   151,   151,     3,
-     135,   151,   151,   135,   151,   151,   151,   151,   151,   157,
-     151,   151,   182,     8,   163,   222,   137,   232,   149,   153,
-     201,   153,   167,   153,   163,   232,   149,   190,   196,   234,
-     149,   149,   151,   132,   172,   173,   174,   175,   179,   232,
-     226,   151,   232,   151,   151,   194,   194,   194,   194,   194,
-     194,   194,   194,   194,   196,     8,   151,   193,   196,     5,
-     151,   226,   149,   162,   163,   226,   149,   151,   135,   232,
-     226,   202,   204,   151,   194,   137,   151,   163,   154,   176,
-     153,   175,   226,   176,   152,   194,   142,   177,   193,   163,
-     176,   185,   155,   135,   155,    26,    38,   153,   186,   194,
-     154,   194,   137,   194,   137,   199,   199
+       0,   177,   178,     0,     4,    28,    30,    36,    37,    40,
+      45,    51,    53,    57,    58,    60,    63,    65,    72,    78,
+      82,    84,    85,    86,    91,   114,   118,   119,   120,   121,
+     124,   126,   130,   136,   137,   139,   144,   145,   168,   182,
+     183,   184,   185,   188,   189,   196,   207,   221,   225,   227,
+     228,   229,   230,   233,   234,   237,   239,   240,   241,   242,
+     244,   245,   246,   247,   248,   250,   252,   258,   259,   260,
+     261,     3,     4,   171,     3,     4,     3,     4,   223,    84,
+     226,     8,     3,     4,   226,   171,   226,   227,     3,   223,
+     195,   196,     3,   223,   227,    21,    23,    24,    26,    27,
+      29,    32,    34,    41,    42,    43,    44,    46,    47,    48,
+      49,    50,    52,    54,    55,    56,    59,    64,    66,    67,
+      68,    69,    70,    71,    73,    74,    75,    76,    77,    80,
+      83,    87,    88,    90,    94,    95,    96,    98,    99,   100,
+     101,   102,   104,   106,   107,   108,   109,   110,   111,   112,
+     113,   115,   116,   117,   122,   125,   128,   129,   132,   133,
+     134,   138,   140,   141,   142,   143,   146,   197,   199,   257,
+     179,   179,    89,    93,   187,   207,   228,   233,   239,   243,
+     250,   258,   261,   170,   170,   170,   173,   170,   173,   170,
+     181,   170,   149,   238,   173,   251,   252,   251,   251,     3,
+       4,    35,    62,   103,   127,   157,   171,   201,   224,   253,
+     254,   256,   259,   170,   251,   170,   170,     8,   173,   170,
+     259,   173,   250,   131,   173,   171,   171,   171,   171,   171,
+     171,   171,   171,   171,   171,   171,   171,   171,   171,   171,
+     171,   171,   171,   171,   171,   171,   171,   171,   171,   171,
+     147,   169,    11,    79,   182,   186,   189,   228,   230,   241,
+     242,   245,   174,     3,     3,     4,   173,   256,   231,   105,
+     235,   239,     3,     4,   173,   180,   249,   253,   253,   175,
+     168,   171,   194,   251,   172,   204,   205,   206,   224,   172,
+     214,   253,   255,   171,   217,   224,     3,     5,     6,     7,
+       8,     9,    61,    97,   123,   135,   152,   155,   156,   157,
+     160,   161,   171,   210,   211,   212,   210,   213,     8,     8,
+     198,   213,   212,     8,     8,   212,     8,   212,   210,    65,
+     212,   208,   209,   210,   257,   212,   208,   210,   259,   259,
+       8,    10,   200,     5,   262,   259,   199,   168,   171,   170,
+     181,   174,   195,   232,   149,    92,   195,   219,   236,   170,
+     173,   180,   174,   182,   196,   248,   253,   172,   213,   157,
+     209,   144,   190,   191,   192,   193,   196,   250,   174,   147,
+     175,   174,   195,   215,   147,   219,   174,   196,   216,   219,
+     172,   171,   210,   210,   210,   210,   210,   210,   210,   259,
+      12,    13,    14,    15,    16,    17,    18,    19,    20,   148,
+     150,   151,   152,   153,   154,   155,   156,   157,   158,   159,
+     167,   168,   147,   172,   172,   172,   147,   172,   172,   172,
+     172,   172,   172,   172,   172,   172,     3,   172,   147,   172,
+     172,   147,   172,   172,   172,   172,   172,   167,   172,   172,
+     199,     8,   181,   242,   149,   250,   170,   174,   195,   220,
+     174,   185,   174,   181,   169,   169,   172,   147,   250,   253,
+     206,   212,   250,   261,   253,   172,   170,   170,   259,   172,
+     172,   210,   210,     3,   210,   210,   210,   210,   210,   210,
+     210,   210,   210,   210,   210,   210,   210,   210,   210,   210,
+     210,     3,   210,   212,     8,   172,   209,   212,     5,   172,
+     253,   250,   170,   180,   181,   193,   253,   255,   170,   222,
+     224,   172,   210,   149,   169,   172,   181,   253,   174,   170,
+     173,   210,   181,   202,    34,    46,   174,   203,   212,   149,
+     149,   170,   218,   219,   218,   170
 };
 
 #define yyerrok                (yyerrstatus = 0)
 };
 
 #define yyerrok                (yyerrstatus = 0)
@@ -2155,42 +2450,42 @@ yyreduce:
   switch (yyn)
     {
         case 2:
   switch (yyn)
     {
         case 2:
-#line 304 "parser.y"
+#line 349 "parser.y"
     { fix_incomplete();
     { fix_incomplete();
-                                                 check_all_user_types((yyvsp[0].ifref_list));
-                                                 write_proxies((yyvsp[0].ifref_list));
-                                                 write_client((yyvsp[0].ifref_list));
-                                                 write_server((yyvsp[0].ifref_list));
-                                                 write_dlldata((yyvsp[0].ifref_list));
+                                                 check_all_user_types((yyvsp[0].stmt_list));
+                                                 write_proxies((yyvsp[0].stmt_list));
+                                                 write_client((yyvsp[0].stmt_list));
+                                                 write_server((yyvsp[0].stmt_list));
+                                                 write_dlldata((yyvsp[0].stmt_list));
                                                ;}
     break;
 
   case 3:
                                                ;}
     break;
 
   case 3:
-#line 313 "parser.y"
-    { (yyval.ifref_list) = NULL; ;}
+#line 358 "parser.y"
+    { (yyval.stmt_list) = NULL; ;}
     break;
 
   case 4:
     break;
 
   case 4:
-#line 314 "parser.y"
-    { (yyval.ifref_list) = (yyvsp[-1].ifref_list); ;}
+#line 359 "parser.y"
+    { (yyval.stmt_list) = (yyvsp[-1].stmt_list); ;}
     break;
 
   case 5:
     break;
 
   case 5:
-#line 315 "parser.y"
-    { (yyval.ifref_list) = append_ifref( (yyvsp[-1].ifref_list), make_ifref((yyvsp[0].type)) ); ;}
+#line 360 "parser.y"
+    { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type))); ;}
     break;
 
   case 6:
     break;
 
   case 6:
-#line 316 "parser.y"
-    { (yyval.ifref_list) = (yyvsp[-2].ifref_list);
+#line 361 "parser.y"
+    { (yyval.stmt_list) = (yyvsp[-2].stmt_list);
                                                  reg_type((yyvsp[-1].type), (yyvsp[-1].type)->name, 0);
                                                  if (!parse_only && do_header) write_coclass_forward((yyvsp[-1].type));
                                                ;}
     break;
 
   case 7:
                                                  reg_type((yyvsp[-1].type), (yyvsp[-1].type)->name, 0);
                                                  if (!parse_only && do_header) write_coclass_forward((yyvsp[-1].type));
                                                ;}
     break;
 
   case 7:
-#line 320 "parser.y"
-    { (yyval.ifref_list) = (yyvsp[-1].ifref_list);
+#line 365 "parser.y"
+    { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type)));
                                                  add_typelib_entry((yyvsp[0].type));
                                                  reg_type((yyvsp[0].type), (yyvsp[0].type)->name, 0);
                                                  if (!parse_only && do_header) write_coclass_forward((yyvsp[0].type));
                                                  add_typelib_entry((yyvsp[0].type));
                                                  reg_type((yyvsp[0].type), (yyvsp[0].type)->name, 0);
                                                  if (!parse_only && do_header) write_coclass_forward((yyvsp[0].type));
@@ -2198,115 +2493,127 @@ yyreduce:
     break;
 
   case 8:
     break;
 
   case 8:
-#line 325 "parser.y"
-    { (yyval.ifref_list) = (yyvsp[-1].ifref_list); add_typelib_entry((yyvsp[0].type)); ;}
+#line 370 "parser.y"
+    { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_module((yyvsp[0].type)));
+                                                 add_typelib_entry((yyvsp[0].type));
+                                               ;}
     break;
 
   case 9:
     break;
 
   case 9:
-#line 326 "parser.y"
-    { (yyval.ifref_list) = (yyvsp[-1].ifref_list); ;}
+#line 373 "parser.y"
+    { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_library((yyvsp[0].typelib))); ;}
     break;
 
   case 10:
     break;
 
   case 10:
-#line 327 "parser.y"
-    { (yyval.ifref_list) = (yyvsp[-1].ifref_list); ;}
+#line 374 "parser.y"
+    { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), (yyvsp[0].statement)); ;}
     break;
 
   case 11:
     break;
 
   case 11:
-#line 330 "parser.y"
-    {;}
+#line 377 "parser.y"
+    { (yyval.stmt_list) = NULL; ;}
     break;
 
   case 12:
     break;
 
   case 12:
-#line 331 "parser.y"
-    { if (!parse_only) add_typelib_entry((yyvsp[0].type)); ;}
+#line 378 "parser.y"
+    { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_reference((yyvsp[0].type))); if (!parse_only) add_typelib_entry((yyvsp[0].type)); ;}
     break;
 
   case 13:
     break;
 
   case 13:
-#line 332 "parser.y"
-    { if (!parse_only) add_typelib_entry((yyvsp[0].type)); ;}
+#line 379 "parser.y"
+    { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type))); if (!parse_only) add_typelib_entry((yyvsp[0].type)); ;}
     break;
 
   case 14:
     break;
 
   case 14:
-#line 333 "parser.y"
-    { reg_type((yyvsp[-1].type), (yyvsp[-1].type)->name, 0); if (!parse_only && do_header) write_coclass_forward((yyvsp[-1].type)); ;}
+#line 380 "parser.y"
+    { (yyval.stmt_list) = (yyvsp[-2].stmt_list); reg_type((yyvsp[-1].type), (yyvsp[-1].type)->name, 0); if (!parse_only && do_header) write_coclass_forward((yyvsp[-1].type)); ;}
     break;
 
   case 15:
     break;
 
   case 15:
-#line 334 "parser.y"
-    { if (!parse_only) add_typelib_entry((yyvsp[0].type));
+#line 381 "parser.y"
+    { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_type_decl((yyvsp[0].type)));
+                                                 if (!parse_only) add_typelib_entry((yyvsp[0].type));
                                                  reg_type((yyvsp[0].type), (yyvsp[0].type)->name, 0);
                                                  if (!parse_only && do_header) write_coclass_forward((yyvsp[0].type));
                                                ;}
     break;
 
   case 16:
                                                  reg_type((yyvsp[0].type), (yyvsp[0].type)->name, 0);
                                                  if (!parse_only && do_header) write_coclass_forward((yyvsp[0].type));
                                                ;}
     break;
 
   case 16:
-#line 338 "parser.y"
-    { if (!parse_only) add_typelib_entry((yyvsp[0].type)); ;}
+#line 386 "parser.y"
+    { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_module((yyvsp[0].type))); if (!parse_only) add_typelib_entry((yyvsp[0].type)); ;}
     break;
 
   case 17:
     break;
 
   case 17:
-#line 339 "parser.y"
-    {;}
+#line 387 "parser.y"
+    { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), (yyvsp[0].statement)); ;}
     break;
 
   case 18:
     break;
 
   case 18:
-#line 340 "parser.y"
-    {;}
+#line 388 "parser.y"
+    { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_importlib((yyvsp[0].str))); ;}
     break;
 
   case 19:
     break;
 
   case 19:
-#line 341 "parser.y"
-    {;}
+#line 389 "parser.y"
+    { (yyval.stmt_list) = append_statement((yyvsp[-1].stmt_list), make_statement_library((yyvsp[0].typelib))); ;}
     break;
 
   case 20:
     break;
 
   case 20:
-#line 344 "parser.y"
+#line 392 "parser.y"
     { (yyval.func_list) = NULL; ;}
     break;
 
   case 21:
     { (yyval.func_list) = NULL; ;}
     break;
 
   case 21:
-#line 345 "parser.y"
-    { (yyval.func_list) = append_func( (yyvsp[-2].func_list), (yyvsp[-1].func) ); ;}
+#line 393 "parser.y"
+    { (yyval.func_list) = append_func_from_statement( (yyvsp[-1].func_list), (yyvsp[0].statement) ); ;}
     break;
 
     break;
 
-  case 22:
-#line 346 "parser.y"
-    { (yyval.func_list) = (yyvsp[-1].func_list); ;}
+  case 24:
+#line 401 "parser.y"
+    { (yyval.statement) = make_statement_cppquote((yyvsp[0].str)); ;}
     break;
 
   case 25:
     break;
 
   case 25:
-#line 353 "parser.y"
-    { if (!parse_only && do_header) { write_constdef((yyvsp[-1].var)); } ;}
+#line 402 "parser.y"
+    { (yyval.statement) = make_statement_type_decl((yyvsp[-1].type));
+                                                 if (!parse_only && do_header) {
+                                                   write_type_def_or_decl(header, (yyvsp[-1].type), FALSE, NULL);
+                                                   fprintf(header, ";\n\n");
+                                                 }
+                                               ;}
     break;
 
   case 26:
     break;
 
   case 26:
-#line 354 "parser.y"
-    {;}
+#line 408 "parser.y"
+    { (yyval.statement) = make_statement_declaration((yyvsp[-1].var));
+                                                 if (!parse_only && do_header) write_declaration((yyvsp[-1].var), is_in_interface);
+                                               ;}
     break;
 
   case 27:
     break;
 
   case 27:
-#line 355 "parser.y"
-    { if (!parse_only && do_header) {
+#line 411 "parser.y"
+    { (yyval.statement) = make_statement_import((yyvsp[0].str)); ;}
+    break;
+
+  case 28:
+#line 412 "parser.y"
+    { (yyval.statement) = make_statement_type_decl((yyvsp[-1].type));
+                                                 if (!parse_only && do_header) {
                                                    write_type_def_or_decl(header, (yyvsp[-1].type), FALSE, NULL);
                                                    fprintf(header, ";\n\n");
                                                  }
                                                ;}
     break;
 
                                                    write_type_def_or_decl(header, (yyvsp[-1].type), FALSE, NULL);
                                                    fprintf(header, ";\n\n");
                                                  }
                                                ;}
     break;
 
-  case 28:
-#line 360 "parser.y"
-    { if (!parse_only && do_header) { write_externdef((yyvsp[-1].var)); } ;}
-    break;
-
   case 29:
   case 29:
-#line 361 "parser.y"
-    {;}
+#line 418 "parser.y"
+    { (yyval.statement) = (yyvsp[-1].statement); ;}
     break;
 
   case 30:
     break;
 
   case 30:
-#line 362 "parser.y"
-    { if (!parse_only && do_header) {
+#line 419 "parser.y"
+    { (yyval.statement) = make_statement_type_decl((yyvsp[-1].type));
+                                                 if (!parse_only && do_header) {
                                                    write_type_def_or_decl(header, (yyvsp[-1].type), FALSE, NULL);
                                                    fprintf(header, ";\n\n");
                                                  }
                                                    write_type_def_or_decl(header, (yyvsp[-1].type), FALSE, NULL);
                                                    fprintf(header, ";\n\n");
                                                  }
@@ -2314,610 +2621,577 @@ yyreduce:
     break;
 
   case 31:
     break;
 
   case 31:
-#line 367 "parser.y"
-    {;}
+#line 427 "parser.y"
+    { (yyval.str) = (yyvsp[-1].str); if (!parse_only && do_header) fprintf(header, "%s\n", (yyvsp[-1].str)); ;}
     break;
 
   case 32:
     break;
 
   case 32:
-#line 368 "parser.y"
-    { if (!parse_only && do_header) {
-                                                   write_type_def_or_decl(header, (yyvsp[-1].type), FALSE, NULL);
-                                                   fprintf(header, ";\n\n");
-                                                 }
+#line 429 "parser.y"
+    { assert(yychar == YYEMPTY);
+                                                 (yyval.import) = xmalloc(sizeof(struct _import_t));
+                                                 (yyval.import)->name = (yyvsp[-1].str);
+                                                 (yyval.import)->import_performed = do_import((yyvsp[-1].str));
+                                                 if (!(yyval.import)->import_performed) yychar = aEOF;
                                                ;}
     break;
 
   case 33:
                                                ;}
     break;
 
   case 33:
-#line 375 "parser.y"
-    { if (!parse_only && do_header) fprintf(header, "%s\n", (yyvsp[-1].str)); ;}
+#line 437 "parser.y"
+    { (yyval.str) = (yyvsp[-2].import)->name;
+                                                 if ((yyvsp[-2].import)->import_performed) pop_import();
+                                                 free((yyvsp[-2].import));
+                                                 if (!parse_only && do_header) write_import((yyval.str));
+                                               ;}
     break;
 
   case 34:
     break;
 
   case 34:
-#line 377 "parser.y"
-    { assert(yychar == YYEMPTY);
-                                                 (yyval.num) = do_import((yyvsp[-1].str));
-                                                 if (!(yyval.num)) yychar = aEOF;
-                                               ;}
+#line 445 "parser.y"
+    { (yyval.str) = (yyvsp[-2].str); if(!parse_only) add_importlib((yyvsp[-2].str)); ;}
     break;
 
   case 35:
     break;
 
   case 35:
-#line 384 "parser.y"
-    { if ((yyvsp[-2].num)) pop_import(); ;}
-    break;
-
-  case 36:
-#line 388 "parser.y"
-    { if(!parse_only) add_importlib((yyvsp[-2].str)); ;}
-    break;
-
-  case 37:
-#line 391 "parser.y"
+#line 448 "parser.y"
     { (yyval.str) = (yyvsp[0].str); ;}
     break;
 
     { (yyval.str) = (yyvsp[0].str); ;}
     break;
 
-  case 38:
-#line 393 "parser.y"
-    { check_library_attrs((yyvsp[-1].str), (yyvsp[-2].attr_list));
-                                                 if (!parse_only) start_typelib((yyvsp[-1].str), (yyvsp[-2].attr_list));
-                                                 if (!parse_only && do_header) write_library((yyvsp[-1].str), (yyvsp[-2].attr_list));
-                                                 if (!parse_only && do_idfile) write_libid((yyvsp[-1].str), (yyvsp[-2].attr_list));
+  case 36:
+#line 450 "parser.y"
+    { (yyval.typelib) = make_library((yyvsp[-1].str), check_library_attrs((yyvsp[-1].str), (yyvsp[-2].attr_list)));
+                                                 if (!parse_only) start_typelib((yyval.typelib));
+                                                 if (!parse_only && do_header) write_library((yyval.typelib));
+                                                 if (!parse_only && do_idfile) write_libid((yyval.typelib));
                                                  is_inside_library = TRUE;
                                                ;}
     break;
 
                                                  is_inside_library = TRUE;
                                                ;}
     break;
 
-  case 39:
-#line 401 "parser.y"
-    { if (!parse_only) end_typelib(); is_inside_library = FALSE; ;}
+  case 37:
+#line 458 "parser.y"
+    { (yyval.typelib) = (yyvsp[-3].typelib);
+                                                 (yyval.typelib)->stmts = (yyvsp[-2].stmt_list);
+                                                 if (!parse_only) end_typelib();
+                                                 is_inside_library = FALSE;
+                                               ;}
     break;
 
     break;
 
-  case 40:
-#line 404 "parser.y"
+  case 38:
+#line 465 "parser.y"
     { (yyval.var_list) = NULL; ;}
     break;
 
     { (yyval.var_list) = NULL; ;}
     break;
 
-  case 42:
-#line 408 "parser.y"
+  case 40:
+#line 469 "parser.y"
     { (yyval.var_list) = NULL; ;}
     break;
 
     { (yyval.var_list) = NULL; ;}
     break;
 
-  case 43:
-#line 411 "parser.y"
+  case 41:
+#line 472 "parser.y"
     { check_arg((yyvsp[0].var)); (yyval.var_list) = append_var( NULL, (yyvsp[0].var) ); ;}
     break;
 
     { check_arg((yyvsp[0].var)); (yyval.var_list) = append_var( NULL, (yyvsp[0].var) ); ;}
     break;
 
-  case 44:
-#line 412 "parser.y"
+  case 42:
+#line 473 "parser.y"
     { check_arg((yyvsp[0].var)); (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[0].var)); ;}
     break;
 
     { check_arg((yyvsp[0].var)); (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[0].var)); ;}
     break;
 
-  case 46:
-#line 417 "parser.y"
-    { (yyval.var) = (yyvsp[-1].pident)->var;
-                                                 (yyval.var)->attrs = (yyvsp[-3].attr_list);
-                                                 set_type((yyval.var), (yyvsp[-2].type), (yyvsp[-1].pident), (yyvsp[0].array_dims), TRUE);
-                                                 free((yyvsp[-1].pident));
+  case 44:
+#line 478 "parser.y"
+    { (yyval.var) = (yyvsp[0].declarator)->var;
+                                                 (yyval.var)->attrs = (yyvsp[-2].attr_list);
+                                                 if ((yyvsp[-1].declspec)->stgclass != STG_NONE && (yyvsp[-1].declspec)->stgclass != STG_REGISTER)
+                                                   error_loc("invalid storage class for function parameter\n");
+                                                 set_type((yyval.var), (yyvsp[-1].declspec), (yyvsp[0].declarator), TRUE);
+                                                 free((yyvsp[0].declarator));
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 47:
-#line 422 "parser.y"
-    { (yyval.var) = (yyvsp[-1].pident)->var;
-                                                 set_type((yyval.var), (yyvsp[-2].type), (yyvsp[-1].pident), (yyvsp[0].array_dims), TRUE);
-                                                 free((yyvsp[-1].pident));
+  case 45:
+#line 485 "parser.y"
+    { (yyval.var) = (yyvsp[0].declarator)->var;
+                                                 if ((yyvsp[-1].declspec)->stgclass != STG_NONE && (yyvsp[-1].declspec)->stgclass != STG_REGISTER)
+                                                   error_loc("invalid storage class for function parameter\n");
+                                                 set_type((yyval.var), (yyvsp[-1].declspec), (yyvsp[0].declarator), TRUE);
+                                                 free((yyvsp[0].declarator));
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 48:
-#line 428 "parser.y"
-    { (yyval.array_dims) = NULL; ;}
+  case 46:
+#line 493 "parser.y"
+    { (yyval.expr) = (yyvsp[-1].expr); ;}
     break;
 
     break;
 
-  case 49:
-#line 429 "parser.y"
-    { (yyval.array_dims) = (yyvsp[-1].array_dims); ;}
+  case 47:
+#line 494 "parser.y"
+    { (yyval.expr) = make_expr(EXPR_VOID); ;}
+    break;
+
+  case 48:
+#line 497 "parser.y"
+    { (yyval.attr_list) = NULL; ;}
     break;
 
   case 50:
     break;
 
   case 50:
-#line 430 "parser.y"
-    { (yyval.array_dims) = append_array( NULL, make_expr(EXPR_VOID) ); ;}
+#line 502 "parser.y"
+    { (yyval.attr_list) = (yyvsp[-1].attr_list);
+                                                 if (!(yyval.attr_list))
+                                                   error_loc("empty attribute lists unsupported\n");
+                                               ;}
     break;
 
   case 51:
     break;
 
   case 51:
-#line 433 "parser.y"
-    { (yyval.array_dims) = append_array( NULL, (yyvsp[0].expr) ); ;}
+#line 508 "parser.y"
+    { (yyval.attr_list) = append_attr( NULL, (yyvsp[0].attr) ); ;}
     break;
 
   case 52:
     break;
 
   case 52:
-#line 434 "parser.y"
-    { (yyval.array_dims) = append_array( (yyvsp[-2].array_dims), (yyvsp[0].expr) ); ;}
+#line 509 "parser.y"
+    { (yyval.attr_list) = append_attr( (yyvsp[-2].attr_list), (yyvsp[0].attr) ); ;}
     break;
 
   case 53:
     break;
 
   case 53:
-#line 435 "parser.y"
-    { (yyval.array_dims) = append_array( (yyvsp[-3].array_dims), (yyvsp[0].expr) ); ;}
+#line 510 "parser.y"
+    { (yyval.attr_list) = append_attr( (yyvsp[-3].attr_list), (yyvsp[0].attr) ); ;}
     break;
 
   case 54:
     break;
 
   case 54:
-#line 438 "parser.y"
-    { (yyval.attr_list) = NULL; ;}
+#line 513 "parser.y"
+    { (yyval.str_list) = append_str( NULL, (yyvsp[0].str) ); ;}
+    break;
+
+  case 55:
+#line 514 "parser.y"
+    { (yyval.str_list) = append_str( (yyvsp[-2].str_list), (yyvsp[0].str) ); ;}
     break;
 
   case 56:
     break;
 
   case 56:
-#line 443 "parser.y"
-    { (yyval.attr_list) = (yyvsp[-1].attr_list);
-                                                 if (!(yyval.attr_list))
-                                                   error_loc("empty attribute lists unsupported\n");
-                                               ;}
+#line 517 "parser.y"
+    { (yyval.attr) = NULL; ;}
     break;
 
   case 57:
     break;
 
   case 57:
-#line 449 "parser.y"
-    { (yyval.attr_list) = append_attr( NULL, (yyvsp[0].attr) ); ;}
+#line 518 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_AGGREGATABLE); ;}
     break;
 
   case 58:
     break;
 
   case 58:
-#line 450 "parser.y"
-    { (yyval.attr_list) = append_attr( (yyvsp[-2].attr_list), (yyvsp[0].attr) ); ;}
+#line 519 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_APPOBJECT); ;}
     break;
 
   case 59:
     break;
 
   case 59:
-#line 451 "parser.y"
-    { (yyval.attr_list) = append_attr( (yyvsp[-3].attr_list), (yyvsp[0].attr) ); ;}
+#line 520 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_ASYNC); ;}
     break;
 
   case 60:
     break;
 
   case 60:
-#line 454 "parser.y"
-    { (yyval.str_list) = append_str( NULL, (yyvsp[0].str) ); ;}
+#line 521 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_AUTO_HANDLE); ;}
     break;
 
   case 61:
     break;
 
   case 61:
-#line 455 "parser.y"
-    { (yyval.str_list) = append_str( (yyvsp[-2].str_list), (yyvsp[0].str) ); ;}
+#line 522 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_BINDABLE); ;}
     break;
 
   case 62:
     break;
 
   case 62:
-#line 458 "parser.y"
-    { (yyval.attr) = NULL; ;}
+#line 523 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_BROADCAST); ;}
     break;
 
   case 63:
     break;
 
   case 63:
-#line 459 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_AGGREGATABLE); ;}
+#line 524 "parser.y"
+    { (yyval.attr) = make_attrp(ATTR_CALLAS, (yyvsp[-1].var)); ;}
     break;
 
   case 64:
     break;
 
   case 64:
-#line 460 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_APPOBJECT); ;}
+#line 525 "parser.y"
+    { (yyval.attr) = make_attrp(ATTR_CASE, (yyvsp[-1].expr_list)); ;}
     break;
 
   case 65:
     break;
 
   case 65:
-#line 461 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_ASYNC); ;}
+#line 526 "parser.y"
+    { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); ;}
     break;
 
   case 66:
     break;
 
   case 66:
-#line 462 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_AUTO_HANDLE); ;}
+#line 527 "parser.y"
+    { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ ;}
     break;
 
   case 67:
     break;
 
   case 67:
-#line 463 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_BINDABLE); ;}
+#line 528 "parser.y"
+    { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ ;}
     break;
 
   case 68:
     break;
 
   case 68:
-#line 464 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_BROADCAST); ;}
+#line 529 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_CONTROL); ;}
     break;
 
   case 69:
     break;
 
   case 69:
-#line 465 "parser.y"
-    { (yyval.attr) = make_attrp(ATTR_CALLAS, (yyvsp[-1].var)); ;}
+#line 530 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_DEFAULT); ;}
     break;
 
   case 70:
     break;
 
   case 70:
-#line 466 "parser.y"
-    { (yyval.attr) = make_attrp(ATTR_CASE, (yyvsp[-1].expr_list)); ;}
+#line 531 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_DEFAULTCOLLELEM); ;}
     break;
 
   case 71:
     break;
 
   case 71:
-#line 467 "parser.y"
-    { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); ;}
+#line 532 "parser.y"
+    { (yyval.attr) = make_attrp(ATTR_DEFAULTVALUE, (yyvsp[-1].expr)); ;}
     break;
 
   case 72:
     break;
 
   case 72:
-#line 468 "parser.y"
-    { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ ;}
+#line 533 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_DEFAULTVTABLE); ;}
     break;
 
   case 73:
     break;
 
   case 73:
-#line 469 "parser.y"
-    { (yyval.attr) = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ ;}
+#line 534 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_DISPLAYBIND); ;}
     break;
 
   case 74:
     break;
 
   case 74:
-#line 470 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_CONTROL); ;}
+#line 535 "parser.y"
+    { (yyval.attr) = make_attrp(ATTR_DLLNAME, (yyvsp[-1].str)); ;}
     break;
 
   case 75:
     break;
 
   case 75:
-#line 471 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_DEFAULT); ;}
+#line 536 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_DUAL); ;}
     break;
 
   case 76:
     break;
 
   case 76:
-#line 472 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_DEFAULTCOLLELEM); ;}
+#line 537 "parser.y"
+    { (yyval.attr) = make_attrp(ATTR_ENDPOINT, (yyvsp[-1].str_list)); ;}
     break;
 
   case 77:
     break;
 
   case 77:
-#line 473 "parser.y"
-    { (yyval.attr) = make_attrp(ATTR_DEFAULTVALUE_EXPR, (yyvsp[-1].expr)); ;}
+#line 538 "parser.y"
+    { (yyval.attr) = make_attrp(ATTR_ENTRY, (yyvsp[-1].expr)); ;}
     break;
 
   case 78:
     break;
 
   case 78:
-#line 474 "parser.y"
-    { (yyval.attr) = make_attrp(ATTR_DEFAULTVALUE_STRING, (yyvsp[-1].str)); ;}
+#line 539 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_EXPLICIT_HANDLE); ;}
     break;
 
   case 79:
     break;
 
   case 79:
-#line 475 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_DEFAULTVTABLE); ;}
+#line 540 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_HANDLE); ;}
     break;
 
   case 80:
     break;
 
   case 80:
-#line 476 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_DISPLAYBIND); ;}
+#line 541 "parser.y"
+    { (yyval.attr) = make_attrp(ATTR_HELPCONTEXT, (yyvsp[-1].expr)); ;}
     break;
 
   case 81:
     break;
 
   case 81:
-#line 477 "parser.y"
-    { (yyval.attr) = make_attrp(ATTR_DLLNAME, (yyvsp[-1].str)); ;}
+#line 542 "parser.y"
+    { (yyval.attr) = make_attrp(ATTR_HELPFILE, (yyvsp[-1].str)); ;}
     break;
 
   case 82:
     break;
 
   case 82:
-#line 478 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_DUAL); ;}
+#line 543 "parser.y"
+    { (yyval.attr) = make_attrp(ATTR_HELPSTRING, (yyvsp[-1].str)); ;}
     break;
 
   case 83:
     break;
 
   case 83:
-#line 479 "parser.y"
-    { (yyval.attr) = make_attrp(ATTR_ENDPOINT, (yyvsp[-1].str_list)); ;}
+#line 544 "parser.y"
+    { (yyval.attr) = make_attrp(ATTR_HELPSTRINGCONTEXT, (yyvsp[-1].expr)); ;}
     break;
 
   case 84:
     break;
 
   case 84:
-#line 480 "parser.y"
-    { (yyval.attr) = make_attrp(ATTR_ENTRY_STRING, (yyvsp[-1].str)); ;}
+#line 545 "parser.y"
+    { (yyval.attr) = make_attrp(ATTR_HELPSTRINGDLL, (yyvsp[-1].str)); ;}
     break;
 
   case 85:
     break;
 
   case 85:
-#line 481 "parser.y"
-    { (yyval.attr) = make_attrp(ATTR_ENTRY_ORDINAL, (yyvsp[-1].expr)); ;}
+#line 546 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_HIDDEN); ;}
     break;
 
   case 86:
     break;
 
   case 86:
-#line 482 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_EXPLICIT_HANDLE); ;}
+#line 547 "parser.y"
+    { (yyval.attr) = make_attrp(ATTR_ID, (yyvsp[-1].expr)); ;}
     break;
 
   case 87:
     break;
 
   case 87:
-#line 483 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_HANDLE); ;}
+#line 548 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_IDEMPOTENT); ;}
     break;
 
   case 88:
     break;
 
   case 88:
-#line 484 "parser.y"
-    { (yyval.attr) = make_attrp(ATTR_HELPCONTEXT, (yyvsp[-1].expr)); ;}
+#line 549 "parser.y"
+    { (yyval.attr) = make_attrp(ATTR_IIDIS, (yyvsp[-1].expr)); ;}
     break;
 
   case 89:
     break;
 
   case 89:
-#line 485 "parser.y"
-    { (yyval.attr) = make_attrp(ATTR_HELPFILE, (yyvsp[-1].str)); ;}
+#line 550 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_IMMEDIATEBIND); ;}
     break;
 
   case 90:
     break;
 
   case 90:
-#line 486 "parser.y"
-    { (yyval.attr) = make_attrp(ATTR_HELPSTRING, (yyvsp[-1].str)); ;}
+#line 551 "parser.y"
+    { (yyval.attr) = make_attrp(ATTR_IMPLICIT_HANDLE, (yyvsp[-1].str)); ;}
     break;
 
   case 91:
     break;
 
   case 91:
-#line 487 "parser.y"
-    { (yyval.attr) = make_attrp(ATTR_HELPSTRINGCONTEXT, (yyvsp[-1].expr)); ;}
+#line 552 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_IN); ;}
     break;
 
   case 92:
     break;
 
   case 92:
-#line 488 "parser.y"
-    { (yyval.attr) = make_attrp(ATTR_HELPSTRINGDLL, (yyvsp[-1].str)); ;}
+#line 553 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_INPUTSYNC); ;}
     break;
 
   case 93:
     break;
 
   case 93:
-#line 489 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_HIDDEN); ;}
+#line 554 "parser.y"
+    { (yyval.attr) = make_attrp(ATTR_LENGTHIS, (yyvsp[-1].expr_list)); ;}
     break;
 
   case 94:
     break;
 
   case 94:
-#line 490 "parser.y"
-    { (yyval.attr) = make_attrp(ATTR_ID, (yyvsp[-1].expr)); ;}
+#line 555 "parser.y"
+    { (yyval.attr) = make_attrp(ATTR_LIBLCID, (yyvsp[-1].expr)); ;}
     break;
 
   case 95:
     break;
 
   case 95:
-#line 491 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_IDEMPOTENT); ;}
+#line 556 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_LOCAL); ;}
     break;
 
   case 96:
     break;
 
   case 96:
-#line 492 "parser.y"
-    { (yyval.attr) = make_attrp(ATTR_IIDIS, (yyvsp[-1].expr)); ;}
+#line 557 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_NONBROWSABLE); ;}
     break;
 
   case 97:
     break;
 
   case 97:
-#line 493 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_IMMEDIATEBIND); ;}
+#line 558 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_NONCREATABLE); ;}
     break;
 
   case 98:
     break;
 
   case 98:
-#line 494 "parser.y"
-    { (yyval.attr) = make_attrp(ATTR_IMPLICIT_HANDLE, (yyvsp[-1].str)); ;}
+#line 559 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_NONEXTENSIBLE); ;}
     break;
 
   case 99:
     break;
 
   case 99:
-#line 495 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_IN); ;}
+#line 560 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_OBJECT); ;}
     break;
 
   case 100:
     break;
 
   case 100:
-#line 496 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_INPUTSYNC); ;}
+#line 561 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_ODL); ;}
     break;
 
   case 101:
     break;
 
   case 101:
-#line 497 "parser.y"
-    { (yyval.attr) = make_attrp(ATTR_LENGTHIS, (yyvsp[-1].expr_list)); ;}
+#line 562 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_OLEAUTOMATION); ;}
     break;
 
   case 102:
     break;
 
   case 102:
-#line 498 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_LOCAL); ;}
+#line 563 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_OPTIONAL); ;}
     break;
 
   case 103:
     break;
 
   case 103:
-#line 499 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_NONBROWSABLE); ;}
+#line 564 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_OUT); ;}
     break;
 
   case 104:
     break;
 
   case 104:
-#line 500 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_NONCREATABLE); ;}
+#line 565 "parser.y"
+    { (yyval.attr) = make_attrv(ATTR_POINTERDEFAULT, (yyvsp[-1].num)); ;}
     break;
 
   case 105:
     break;
 
   case 105:
-#line 501 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_NONEXTENSIBLE); ;}
+#line 566 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_PROPGET); ;}
     break;
 
   case 106:
     break;
 
   case 106:
-#line 502 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_OBJECT); ;}
-    break;
-
-  case 107:
-#line 503 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_ODL); ;}
-    break;
-
-  case 108:
-#line 504 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_OLEAUTOMATION); ;}
-    break;
-
-  case 109:
-#line 505 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_OPTIONAL); ;}
-    break;
-
-  case 110:
-#line 506 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_OUT); ;}
-    break;
-
-  case 111:
-#line 507 "parser.y"
-    { (yyval.attr) = make_attrv(ATTR_POINTERDEFAULT, (yyvsp[-1].num)); ;}
-    break;
-
-  case 112:
-#line 508 "parser.y"
-    { (yyval.attr) = make_attr(ATTR_PROPGET); ;}
-    break;
-
-  case 113:
-#line 509 "parser.y"
+#line 567 "parser.y"
     { (yyval.attr) = make_attr(ATTR_PROPPUT); ;}
     break;
 
     { (yyval.attr) = make_attr(ATTR_PROPPUT); ;}
     break;
 
-  case 114:
-#line 510 "parser.y"
+  case 107:
+#line 568 "parser.y"
     { (yyval.attr) = make_attr(ATTR_PROPPUTREF); ;}
     break;
 
     { (yyval.attr) = make_attr(ATTR_PROPPUTREF); ;}
     break;
 
-  case 115:
-#line 511 "parser.y"
+  case 108:
+#line 569 "parser.y"
     { (yyval.attr) = make_attr(ATTR_PUBLIC); ;}
     break;
 
     { (yyval.attr) = make_attr(ATTR_PUBLIC); ;}
     break;
 
-  case 116:
-#line 512 "parser.y"
+  case 109:
+#line 571 "parser.y"
     { expr_list_t *list = append_expr( NULL, (yyvsp[-3].expr) );
     { expr_list_t *list = append_expr( NULL, (yyvsp[-3].expr) );
-                                                     list = append_expr( list, (yyvsp[-1].expr) );
-                                                     (yyval.attr) = make_attrp(ATTR_RANGE, list); ;}
+                                                 list = append_expr( list, (yyvsp[-1].expr) );
+                                                 (yyval.attr) = make_attrp(ATTR_RANGE, list); ;}
     break;
 
     break;
 
-  case 117:
-#line 515 "parser.y"
+  case 110:
+#line 574 "parser.y"
     { (yyval.attr) = make_attr(ATTR_READONLY); ;}
     break;
 
     { (yyval.attr) = make_attr(ATTR_READONLY); ;}
     break;
 
-  case 118:
-#line 516 "parser.y"
+  case 111:
+#line 575 "parser.y"
     { (yyval.attr) = make_attr(ATTR_REQUESTEDIT); ;}
     break;
 
     { (yyval.attr) = make_attr(ATTR_REQUESTEDIT); ;}
     break;
 
-  case 119:
-#line 517 "parser.y"
+  case 112:
+#line 576 "parser.y"
     { (yyval.attr) = make_attr(ATTR_RESTRICTED); ;}
     break;
 
     { (yyval.attr) = make_attr(ATTR_RESTRICTED); ;}
     break;
 
-  case 120:
-#line 518 "parser.y"
+  case 113:
+#line 577 "parser.y"
     { (yyval.attr) = make_attr(ATTR_RETVAL); ;}
     break;
 
     { (yyval.attr) = make_attr(ATTR_RETVAL); ;}
     break;
 
-  case 121:
-#line 519 "parser.y"
+  case 114:
+#line 578 "parser.y"
     { (yyval.attr) = make_attrp(ATTR_SIZEIS, (yyvsp[-1].expr_list)); ;}
     break;
 
     { (yyval.attr) = make_attrp(ATTR_SIZEIS, (yyvsp[-1].expr_list)); ;}
     break;
 
-  case 122:
-#line 520 "parser.y"
+  case 115:
+#line 579 "parser.y"
     { (yyval.attr) = make_attr(ATTR_SOURCE); ;}
     break;
 
     { (yyval.attr) = make_attr(ATTR_SOURCE); ;}
     break;
 
-  case 123:
-#line 521 "parser.y"
+  case 116:
+#line 580 "parser.y"
     { (yyval.attr) = make_attr(ATTR_STRICTCONTEXTHANDLE); ;}
     break;
 
     { (yyval.attr) = make_attr(ATTR_STRICTCONTEXTHANDLE); ;}
     break;
 
-  case 124:
-#line 522 "parser.y"
+  case 117:
+#line 581 "parser.y"
     { (yyval.attr) = make_attr(ATTR_STRING); ;}
     break;
 
     { (yyval.attr) = make_attr(ATTR_STRING); ;}
     break;
 
-  case 125:
-#line 523 "parser.y"
+  case 118:
+#line 582 "parser.y"
     { (yyval.attr) = make_attrp(ATTR_SWITCHIS, (yyvsp[-1].expr)); ;}
     break;
 
     { (yyval.attr) = make_attrp(ATTR_SWITCHIS, (yyvsp[-1].expr)); ;}
     break;
 
-  case 126:
-#line 524 "parser.y"
+  case 119:
+#line 583 "parser.y"
     { (yyval.attr) = make_attrp(ATTR_SWITCHTYPE, (yyvsp[-1].type)); ;}
     break;
 
     { (yyval.attr) = make_attrp(ATTR_SWITCHTYPE, (yyvsp[-1].type)); ;}
     break;
 
-  case 127:
-#line 525 "parser.y"
+  case 120:
+#line 584 "parser.y"
     { (yyval.attr) = make_attrp(ATTR_TRANSMITAS, (yyvsp[-1].type)); ;}
     break;
 
     { (yyval.attr) = make_attrp(ATTR_TRANSMITAS, (yyvsp[-1].type)); ;}
     break;
 
-  case 128:
-#line 526 "parser.y"
+  case 121:
+#line 585 "parser.y"
     { (yyval.attr) = make_attrp(ATTR_UUID, (yyvsp[-1].uuid)); ;}
     break;
 
     { (yyval.attr) = make_attrp(ATTR_UUID, (yyvsp[-1].uuid)); ;}
     break;
 
-  case 129:
-#line 527 "parser.y"
+  case 122:
+#line 586 "parser.y"
     { (yyval.attr) = make_attr(ATTR_V1ENUM); ;}
     break;
 
     { (yyval.attr) = make_attr(ATTR_V1ENUM); ;}
     break;
 
-  case 130:
-#line 528 "parser.y"
+  case 123:
+#line 587 "parser.y"
     { (yyval.attr) = make_attr(ATTR_VARARG); ;}
     break;
 
     { (yyval.attr) = make_attr(ATTR_VARARG); ;}
     break;
 
-  case 131:
-#line 529 "parser.y"
+  case 124:
+#line 588 "parser.y"
     { (yyval.attr) = make_attrv(ATTR_VERSION, (yyvsp[-1].num)); ;}
     break;
 
     { (yyval.attr) = make_attrv(ATTR_VERSION, (yyvsp[-1].num)); ;}
     break;
 
-  case 132:
-#line 530 "parser.y"
+  case 125:
+#line 589 "parser.y"
     { (yyval.attr) = make_attrp(ATTR_WIREMARSHAL, (yyvsp[-1].type)); ;}
     break;
 
     { (yyval.attr) = make_attrp(ATTR_WIREMARSHAL, (yyvsp[-1].type)); ;}
     break;
 
-  case 133:
-#line 531 "parser.y"
+  case 126:
+#line 590 "parser.y"
     { (yyval.attr) = make_attrv(ATTR_POINTERTYPE, (yyvsp[0].num)); ;}
     break;
 
     { (yyval.attr) = make_attrv(ATTR_POINTERTYPE, (yyvsp[0].num)); ;}
     break;
 
-  case 135:
-#line 536 "parser.y"
+  case 128:
+#line 595 "parser.y"
     { if (!is_valid_uuid((yyvsp[0].str)))
                                                    error_loc("invalid UUID: %s\n", (yyvsp[0].str));
                                                  (yyval.uuid) = parse_uuid((yyvsp[0].str)); ;}
     break;
 
     { if (!is_valid_uuid((yyvsp[0].str)))
                                                    error_loc("invalid UUID: %s\n", (yyvsp[0].str));
                                                  (yyval.uuid) = parse_uuid((yyvsp[0].str)); ;}
     break;
 
-  case 136:
-#line 541 "parser.y"
+  case 129:
+#line 600 "parser.y"
     { (yyval.str) = (yyvsp[0].str); ;}
     break;
 
     { (yyval.str) = (yyvsp[0].str); ;}
     break;
 
-  case 137:
-#line 542 "parser.y"
+  case 130:
+#line 601 "parser.y"
     { (yyval.str) = (yyvsp[0].str); ;}
     break;
 
     { (yyval.str) = (yyvsp[0].str); ;}
     break;
 
-  case 138:
-#line 543 "parser.y"
+  case 131:
+#line 602 "parser.y"
     { (yyval.str) = (yyvsp[0].str); ;}
     break;
 
     { (yyval.str) = (yyvsp[0].str); ;}
     break;
 
-  case 139:
-#line 544 "parser.y"
+  case 132:
+#line 603 "parser.y"
     { (yyval.str) = (yyvsp[0].str); ;}
     break;
 
     { (yyval.str) = (yyvsp[0].str); ;}
     break;
 
-  case 140:
-#line 547 "parser.y"
+  case 133:
+#line 606 "parser.y"
     { (yyval.var_list) = NULL; ;}
     break;
 
     { (yyval.var_list) = NULL; ;}
     break;
 
-  case 141:
-#line 548 "parser.y"
+  case 134:
+#line 607 "parser.y"
     { (yyval.var_list) = append_var( (yyvsp[-1].var_list), (yyvsp[0].var) ); ;}
     break;
 
     { (yyval.var_list) = append_var( (yyvsp[-1].var_list), (yyvsp[0].var) ); ;}
     break;
 
-  case 142:
-#line 551 "parser.y"
+  case 135:
+#line 610 "parser.y"
     { attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, (yyvsp[-2].expr) ));
                                                  (yyval.var) = (yyvsp[0].var); if (!(yyval.var)) (yyval.var) = make_var(NULL);
                                                  (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a );
                                                ;}
     break;
 
     { attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, (yyvsp[-2].expr) ));
                                                  (yyval.var) = (yyvsp[0].var); if (!(yyval.var)) (yyval.var) = make_var(NULL);
                                                  (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a );
                                                ;}
     break;
 
-  case 143:
-#line 555 "parser.y"
+  case 136:
+#line 614 "parser.y"
     { attr_t *a = make_attr(ATTR_DEFAULT);
                                                  (yyval.var) = (yyvsp[0].var); if (!(yyval.var)) (yyval.var) = make_var(NULL);
                                                  (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a );
                                                ;}
     break;
 
     { attr_t *a = make_attr(ATTR_DEFAULT);
                                                  (yyval.var) = (yyvsp[0].var); if (!(yyval.var)) (yyval.var) = make_var(NULL);
                                                  (yyval.var)->attrs = append_attr( (yyval.var)->attrs, a );
                                                ;}
     break;
 
-  case 144:
-#line 561 "parser.y"
-    { (yyval.var) = reg_const((yyvsp[-2].var));
-                                                 set_type((yyval.var), (yyvsp[-3].type), NULL, NULL, FALSE);
-                                                 (yyval.var)->eval = (yyvsp[0].expr);
-                                               ;}
-    break;
-
-  case 145:
-#line 567 "parser.y"
+  case 137:
+#line 620 "parser.y"
     { (yyval.var_list) = NULL; ;}
     break;
 
     { (yyval.var_list) = NULL; ;}
     break;
 
-  case 146:
-#line 568 "parser.y"
+  case 138:
+#line 621 "parser.y"
     { (yyval.var_list) = (yyvsp[-1].var_list); ;}
     break;
 
     { (yyval.var_list) = (yyvsp[-1].var_list); ;}
     break;
 
-  case 148:
-#line 572 "parser.y"
+  case 140:
+#line 625 "parser.y"
     { if (!(yyvsp[0].var)->eval)
                                                    (yyvsp[0].var)->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */);
                                                   (yyval.var_list) = append_var( NULL, (yyvsp[0].var) );
                                                ;}
     break;
 
     { if (!(yyvsp[0].var)->eval)
                                                    (yyvsp[0].var)->eval = make_exprl(EXPR_NUM, 0 /* default for first enum entry */);
                                                   (yyval.var_list) = append_var( NULL, (yyvsp[0].var) );
                                                ;}
     break;
 
-  case 149:
-#line 576 "parser.y"
+  case 141:
+#line 629 "parser.y"
     { if (!(yyvsp[0].var)->eval)
                                                   {
                                                     var_t *last = LIST_ENTRY( list_tail((yyval.var_list)), var_t, entry );
     { if (!(yyvsp[0].var)->eval)
                                                   {
                                                     var_t *last = LIST_ENTRY( list_tail((yyval.var_list)), var_t, entry );
@@ -2927,23 +3201,23 @@ yyreduce:
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 150:
-#line 585 "parser.y"
+  case 142:
+#line 638 "parser.y"
     { (yyval.var) = reg_const((yyvsp[-2].var));
                                                  (yyval.var)->eval = (yyvsp[0].expr);
                                                   (yyval.var)->type = make_int(0);
                                                ;}
     break;
 
     { (yyval.var) = reg_const((yyvsp[-2].var));
                                                  (yyval.var)->eval = (yyvsp[0].expr);
                                                   (yyval.var)->type = make_int(0);
                                                ;}
     break;
 
-  case 151:
-#line 589 "parser.y"
+  case 143:
+#line 642 "parser.y"
     { (yyval.var) = reg_const((yyvsp[0].var));
                                                   (yyval.var)->type = make_int(0);
                                                ;}
     break;
 
     { (yyval.var) = reg_const((yyvsp[0].var));
                                                   (yyval.var)->type = make_int(0);
                                                ;}
     break;
 
-  case 152:
-#line 594 "parser.y"
+  case 144:
+#line 647 "parser.y"
     { (yyval.type) = get_typev(RPC_FC_ENUM16, (yyvsp[-3].var), tsENUM);
                                                  (yyval.type)->kind = TKIND_ENUM;
                                                  (yyval.type)->fields_or_args = (yyvsp[-1].var_list);
     { (yyval.type) = get_typev(RPC_FC_ENUM16, (yyvsp[-3].var), tsENUM);
                                                  (yyval.type)->kind = TKIND_ENUM;
                                                  (yyval.type)->fields_or_args = (yyvsp[-1].var_list);
@@ -2953,253 +3227,386 @@ yyreduce:
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 153:
-#line 603 "parser.y"
+  case 145:
+#line 656 "parser.y"
     { (yyval.expr_list) = append_expr( NULL, (yyvsp[0].expr) ); ;}
     break;
 
     { (yyval.expr_list) = append_expr( NULL, (yyvsp[0].expr) ); ;}
     break;
 
-  case 154:
-#line 604 "parser.y"
+  case 146:
+#line 657 "parser.y"
     { (yyval.expr_list) = append_expr( (yyvsp[-2].expr_list), (yyvsp[0].expr) ); ;}
     break;
 
     { (yyval.expr_list) = append_expr( (yyvsp[-2].expr_list), (yyvsp[0].expr) ); ;}
     break;
 
-  case 155:
-#line 617 "parser.y"
+  case 147:
+#line 670 "parser.y"
     { (yyval.expr) = make_expr(EXPR_VOID); ;}
     break;
 
     { (yyval.expr) = make_expr(EXPR_VOID); ;}
     break;
 
-  case 157:
-#line 621 "parser.y"
+  case 149:
+#line 674 "parser.y"
     { (yyval.expr) = make_exprl(EXPR_NUM, (yyvsp[0].num)); ;}
     break;
 
     { (yyval.expr) = make_exprl(EXPR_NUM, (yyvsp[0].num)); ;}
     break;
 
-  case 158:
-#line 622 "parser.y"
+  case 150:
+#line 675 "parser.y"
     { (yyval.expr) = make_exprl(EXPR_HEXNUM, (yyvsp[0].num)); ;}
     break;
 
     { (yyval.expr) = make_exprl(EXPR_HEXNUM, (yyvsp[0].num)); ;}
     break;
 
-  case 159:
-#line 623 "parser.y"
+  case 151:
+#line 676 "parser.y"
     { (yyval.expr) = make_exprd(EXPR_DOUBLE, (yyvsp[0].dbl)); ;}
     break;
 
     { (yyval.expr) = make_exprd(EXPR_DOUBLE, (yyvsp[0].dbl)); ;}
     break;
 
-  case 160:
-#line 624 "parser.y"
+  case 152:
+#line 677 "parser.y"
     { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 0); ;}
     break;
 
     { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 0); ;}
     break;
 
-  case 161:
-#line 625 "parser.y"
+  case 153:
+#line 678 "parser.y"
+    { (yyval.expr) = make_exprl(EXPR_NUM, 0); ;}
+    break;
+
+  case 154:
+#line 679 "parser.y"
     { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 1); ;}
     break;
 
     { (yyval.expr) = make_exprl(EXPR_TRUEFALSE, 1); ;}
     break;
 
-  case 162:
-#line 626 "parser.y"
+  case 155:
+#line 680 "parser.y"
+    { (yyval.expr) = make_exprs(EXPR_STRLIT, (yyvsp[0].str)); ;}
+    break;
+
+  case 156:
+#line 681 "parser.y"
+    { (yyval.expr) = make_exprs(EXPR_WSTRLIT, (yyvsp[0].str)); ;}
+    break;
+
+  case 157:
+#line 682 "parser.y"
     { (yyval.expr) = make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str)); ;}
     break;
 
     { (yyval.expr) = make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str)); ;}
     break;
 
-  case 163:
-#line 627 "parser.y"
+  case 158:
+#line 683 "parser.y"
     { (yyval.expr) = make_expr3(EXPR_COND, (yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
     { (yyval.expr) = make_expr3(EXPR_COND, (yyvsp[-4].expr), (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
-  case 164:
-#line 628 "parser.y"
+  case 159:
+#line 684 "parser.y"
+    { (yyval.expr) = make_expr2(EXPR_LOGOR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
+    break;
+
+  case 160:
+#line 685 "parser.y"
+    { (yyval.expr) = make_expr2(EXPR_LOGAND, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
+    break;
+
+  case 161:
+#line 686 "parser.y"
     { (yyval.expr) = make_expr2(EXPR_OR , (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
     { (yyval.expr) = make_expr2(EXPR_OR , (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
-  case 165:
-#line 629 "parser.y"
+  case 162:
+#line 687 "parser.y"
+    { (yyval.expr) = make_expr2(EXPR_XOR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
+    break;
+
+  case 163:
+#line 688 "parser.y"
     { (yyval.expr) = make_expr2(EXPR_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
     { (yyval.expr) = make_expr2(EXPR_AND, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
+  case 164:
+#line 689 "parser.y"
+    { (yyval.expr) = make_expr2(EXPR_EQUALITY, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
+    break;
+
+  case 165:
+#line 690 "parser.y"
+    { (yyval.expr) = make_expr2(EXPR_INEQUALITY, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
+    break;
+
   case 166:
   case 166:
-#line 630 "parser.y"
-    { (yyval.expr) = make_expr2(EXPR_ADD, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
+#line 691 "parser.y"
+    { (yyval.expr) = make_expr2(EXPR_GTR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
   case 167:
     break;
 
   case 167:
-#line 631 "parser.y"
-    { (yyval.expr) = make_expr2(EXPR_SUB, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
+#line 692 "parser.y"
+    { (yyval.expr) = make_expr2(EXPR_LESS, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
   case 168:
     break;
 
   case 168:
-#line 632 "parser.y"
-    { (yyval.expr) = make_expr2(EXPR_MUL, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
+#line 693 "parser.y"
+    { (yyval.expr) = make_expr2(EXPR_GTREQL, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
   case 169:
     break;
 
   case 169:
-#line 633 "parser.y"
-    { (yyval.expr) = make_expr2(EXPR_DIV, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
+#line 694 "parser.y"
+    { (yyval.expr) = make_expr2(EXPR_LESSEQL, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
   case 170:
     break;
 
   case 170:
-#line 634 "parser.y"
+#line 695 "parser.y"
     { (yyval.expr) = make_expr2(EXPR_SHL, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
   case 171:
     { (yyval.expr) = make_expr2(EXPR_SHL, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
   case 171:
-#line 635 "parser.y"
+#line 696 "parser.y"
     { (yyval.expr) = make_expr2(EXPR_SHR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
   case 172:
     { (yyval.expr) = make_expr2(EXPR_SHR, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
   case 172:
-#line 636 "parser.y"
-    { (yyval.expr) = make_expr1(EXPR_NOT, (yyvsp[0].expr)); ;}
+#line 697 "parser.y"
+    { (yyval.expr) = make_expr2(EXPR_ADD, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
   case 173:
     break;
 
   case 173:
-#line 637 "parser.y"
-    { (yyval.expr) = make_expr1(EXPR_NEG, (yyvsp[0].expr)); ;}
+#line 698 "parser.y"
+    { (yyval.expr) = make_expr2(EXPR_SUB, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
   case 174:
     break;
 
   case 174:
-#line 638 "parser.y"
-    { (yyval.expr) = make_expr1(EXPR_ADDRESSOF, (yyvsp[0].expr)); ;}
+#line 699 "parser.y"
+    { (yyval.expr) = make_expr2(EXPR_MOD, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
   case 175:
     break;
 
   case 175:
-#line 639 "parser.y"
-    { (yyval.expr) = make_expr1(EXPR_PPTR, (yyvsp[0].expr)); ;}
+#line 700 "parser.y"
+    { (yyval.expr) = make_expr2(EXPR_MUL, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
   case 176:
     break;
 
   case 176:
-#line 640 "parser.y"
-    { (yyval.expr) = make_exprt(EXPR_CAST, (yyvsp[-2].type), (yyvsp[0].expr)); ;}
+#line 701 "parser.y"
+    { (yyval.expr) = make_expr2(EXPR_DIV, (yyvsp[-2].expr), (yyvsp[0].expr)); ;}
     break;
 
   case 177:
     break;
 
   case 177:
-#line 641 "parser.y"
-    { (yyval.expr) = make_exprt(EXPR_SIZEOF, (yyvsp[-1].type), NULL); ;}
+#line 702 "parser.y"
+    { (yyval.expr) = make_expr1(EXPR_LOGNOT, (yyvsp[0].expr)); ;}
     break;
 
   case 178:
     break;
 
   case 178:
-#line 642 "parser.y"
-    { (yyval.expr) = (yyvsp[-1].expr); ;}
+#line 703 "parser.y"
+    { (yyval.expr) = make_expr1(EXPR_NOT, (yyvsp[0].expr)); ;}
     break;
 
   case 179:
     break;
 
   case 179:
-#line 645 "parser.y"
-    { (yyval.expr_list) = append_expr( NULL, (yyvsp[0].expr) ); ;}
+#line 704 "parser.y"
+    { (yyval.expr) = make_expr1(EXPR_POS, (yyvsp[0].expr)); ;}
     break;
 
   case 180:
     break;
 
   case 180:
-#line 646 "parser.y"
-    { (yyval.expr_list) = append_expr( (yyvsp[-2].expr_list), (yyvsp[0].expr) ); ;}
+#line 705 "parser.y"
+    { (yyval.expr) = make_expr1(EXPR_NEG, (yyvsp[0].expr)); ;}
     break;
 
   case 181:
     break;
 
   case 181:
-#line 649 "parser.y"
-    { (yyval.expr) = (yyvsp[0].expr);
-                                                 if (!(yyval.expr)->is_const)
-                                                     error_loc("expression is not constant\n");
-                                               ;}
+#line 706 "parser.y"
+    { (yyval.expr) = make_expr1(EXPR_ADDRESSOF, (yyvsp[0].expr)); ;}
     break;
 
   case 182:
     break;
 
   case 182:
-#line 655 "parser.y"
-    { (yyval.var) = (yyvsp[0].var);
-                                                 set_type((yyval.var), (yyvsp[-1].type), NULL, NULL, FALSE);
-                                               ;}
+#line 707 "parser.y"
+    { (yyval.expr) = make_expr1(EXPR_PPTR, (yyvsp[0].expr)); ;}
     break;
 
   case 183:
     break;
 
   case 183:
-#line 660 "parser.y"
-    { (yyval.var_list) = NULL; ;}
+#line 708 "parser.y"
+    { (yyval.expr) = make_expr2(EXPR_MEMBER, make_expr1(EXPR_PPTR, (yyvsp[-2].expr)), make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str))); ;}
     break;
 
   case 184:
     break;
 
   case 184:
-#line 661 "parser.y"
-    { (yyval.var_list) = append_var( (yyvsp[-1].var_list), (yyvsp[0].var) ); ;}
+#line 709 "parser.y"
+    { (yyval.expr) = make_expr2(EXPR_MEMBER, (yyvsp[-2].expr), make_exprs(EXPR_IDENTIFIER, (yyvsp[0].str))); ;}
     break;
 
   case 185:
     break;
 
   case 185:
-#line 664 "parser.y"
-    { (yyval.var) = (yyvsp[-1].var); ;}
+#line 710 "parser.y"
+    { (yyval.expr) = make_exprt(EXPR_CAST, (yyvsp[-2].type), (yyvsp[0].expr)); ;}
     break;
 
   case 186:
     break;
 
   case 186:
-#line 665 "parser.y"
-    { (yyval.var) = make_var(NULL); (yyval.var)->type = (yyvsp[-1].type); (yyval.var)->attrs = (yyvsp[-2].attr_list); ;}
+#line 711 "parser.y"
+    { (yyval.expr) = make_exprt(EXPR_SIZEOF, (yyvsp[-1].type), NULL); ;}
     break;
 
   case 187:
     break;
 
   case 187:
-#line 666 "parser.y"
-    { (yyval.var) = make_var(NULL); (yyval.var)->attrs = (yyvsp[-1].attr_list); ;}
+#line 712 "parser.y"
+    { (yyval.expr) = make_expr2(EXPR_ARRAY, (yyvsp[-3].expr), (yyvsp[-1].expr)); ;}
     break;
 
   case 188:
     break;
 
   case 188:
-#line 667 "parser.y"
-    { (yyval.var) = NULL; ;}
+#line 713 "parser.y"
+    { (yyval.expr) = (yyvsp[-1].expr); ;}
     break;
 
   case 189:
     break;
 
   case 189:
-#line 670 "parser.y"
-    { (yyval.var) = (yyvsp[-1].pident)->var;
-                                                 (yyval.var)->attrs = check_field_attrs((yyval.var)->name, (yyvsp[-3].attr_list));
-                                                 set_type((yyval.var), (yyvsp[-2].type), (yyvsp[-1].pident), (yyvsp[0].array_dims), FALSE);
-                                                 free((yyvsp[-1].pident));
+#line 716 "parser.y"
+    { (yyval.expr_list) = append_expr( NULL, (yyvsp[0].expr) ); ;}
+    break;
+
+  case 190:
+#line 717 "parser.y"
+    { (yyval.expr_list) = append_expr( (yyvsp[-2].expr_list), (yyvsp[0].expr) ); ;}
+    break;
+
+  case 191:
+#line 720 "parser.y"
+    { (yyval.expr) = (yyvsp[0].expr);
+                                                 if (!(yyval.expr)->is_const)
+                                                     error_loc("expression is not an integer constant\n");
+                                               ;}
+    break;
+
+  case 192:
+#line 726 "parser.y"
+    { (yyval.expr) = (yyvsp[0].expr);
+                                                 if (!(yyval.expr)->is_const && (yyval.expr)->type != EXPR_STRLIT && (yyval.expr)->type != EXPR_WSTRLIT)
+                                                     error_loc("expression is not constant\n");
+                                               ;}
+    break;
+
+  case 193:
+#line 732 "parser.y"
+    { (yyval.var_list) = NULL; ;}
+    break;
+
+  case 194:
+#line 733 "parser.y"
+    { (yyval.var_list) = append_var_list((yyvsp[-1].var_list), (yyvsp[0].var_list)); ;}
+    break;
+
+  case 195:
+#line 737 "parser.y"
+    { const char *first = LIST_ENTRY(list_head((yyvsp[-1].declarator_list)), declarator_t, entry)->var->name;
+                                                 check_field_attrs(first, (yyvsp[-3].attr_list));
+                                                 (yyval.var_list) = set_var_types((yyvsp[-3].attr_list), (yyvsp[-2].declspec), (yyvsp[-1].declarator_list));
+                                               ;}
+    break;
+
+  case 196:
+#line 741 "parser.y"
+    { var_t *v = make_var(NULL);
+                                                 v->type = (yyvsp[-1].type); v->attrs = (yyvsp[-2].attr_list);
+                                                 (yyval.var_list) = append_var(NULL, v);
+                                               ;}
+    break;
+
+  case 197:
+#line 748 "parser.y"
+    { (yyval.var) = (yyvsp[-1].var); ;}
+    break;
+
+  case 198:
+#line 749 "parser.y"
+    { (yyval.var) = make_var(NULL); (yyval.var)->attrs = (yyvsp[-1].attr_list); ;}
+    break;
+
+  case 199:
+#line 752 "parser.y"
+    { (yyval.var_list) = NULL; ;}
+    break;
+
+  case 200:
+#line 753 "parser.y"
+    { (yyval.var_list) = append_var( (yyvsp[-1].var_list), (yyvsp[0].var) ); ;}
+    break;
+
+  case 201:
+#line 757 "parser.y"
+    { (yyval.var) = (yyvsp[-1].var); ;}
+    break;
+
+  case 202:
+#line 758 "parser.y"
+    { (yyval.var) = NULL; ;}
+    break;
+
+  case 203:
+#line 761 "parser.y"
+    { (yyval.var) = (yyvsp[0].declarator)->var;
+                                                 (yyval.var)->attrs = check_field_attrs((yyval.var)->name, (yyvsp[-2].attr_list));
+                                                 set_type((yyval.var), (yyvsp[-1].declspec), (yyvsp[0].declarator), FALSE);
+                                                 free((yyvsp[0].declarator));
+                                               ;}
+    break;
+
+  case 204:
+#line 769 "parser.y"
+    { var_t *v = (yyvsp[0].declarator)->var;
+                                                 v->attrs = check_function_attrs(v->name, (yyvsp[-2].attr_list));
+                                                 set_type(v, (yyvsp[-1].declspec), (yyvsp[0].declarator), FALSE);
+                                                 free((yyvsp[0].declarator));
+                                                 (yyval.func) = make_func(v);
+                                               ;}
+    break;
+
+  case 205:
+#line 779 "parser.y"
+    { (yyval.var) = (yyvsp[0].declarator)->var;
+                                                 (yyval.var)->attrs = (yyvsp[-2].attr_list);
+                                                 set_type((yyval.var), (yyvsp[-1].declspec), (yyvsp[0].declarator), FALSE);
+                                                 free((yyvsp[0].declarator));
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 190:
-#line 678 "parser.y"
-    { var_t *v = (yyvsp[0].pident)->var;
-                                                 var_list_t *args = (yyvsp[0].pident)->args;
-                                                 v->attrs = check_function_attrs(v->name, (yyvsp[-2].attr_list));
-                                                 set_type(v, (yyvsp[-1].type), (yyvsp[0].pident), NULL, FALSE);
-                                                 free((yyvsp[0].pident));
-                                                 (yyval.func) = make_func(v, args);
+  case 206:
+#line 784 "parser.y"
+    { (yyval.var) = (yyvsp[0].declarator)->var;
+                                                 set_type((yyval.var), (yyvsp[-1].declspec), (yyvsp[0].declarator), FALSE);
+                                                 free((yyvsp[0].declarator));
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 191:
-#line 687 "parser.y"
+  case 207:
+#line 790 "parser.y"
     { (yyval.var) = NULL; ;}
     break;
 
     { (yyval.var) = NULL; ;}
     break;
 
-  case 193:
-#line 691 "parser.y"
+  case 209:
+#line 794 "parser.y"
     { (yyval.var) = NULL; ;}
     break;
 
     { (yyval.var) = NULL; ;}
     break;
 
-  case 194:
-#line 692 "parser.y"
+  case 210:
+#line 795 "parser.y"
     { (yyval.var) = make_var((yyvsp[0].str)); ;}
     break;
 
     { (yyval.var) = make_var((yyvsp[0].str)); ;}
     break;
 
-  case 195:
-#line 693 "parser.y"
+  case 211:
+#line 796 "parser.y"
     { (yyval.var) = make_var((yyvsp[0].str)); ;}
     break;
 
     { (yyval.var) = make_var((yyvsp[0].str)); ;}
     break;
 
-  case 196:
-#line 696 "parser.y"
+  case 212:
+#line 799 "parser.y"
     { (yyval.var) = make_var((yyvsp[0].str)); ;}
     break;
 
     { (yyval.var) = make_var((yyvsp[0].str)); ;}
     break;
 
-  case 197:
-#line 698 "parser.y"
+  case 213:
+#line 801 "parser.y"
     { (yyval.var) = make_var((yyvsp[0].str)); ;}
     break;
 
     { (yyval.var) = make_var((yyvsp[0].str)); ;}
     break;
 
-  case 198:
-#line 701 "parser.y"
+  case 214:
+#line 804 "parser.y"
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
-  case 199:
-#line 702 "parser.y"
+  case 215:
+#line 805 "parser.y"
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
-  case 201:
-#line 704 "parser.y"
+  case 217:
+#line 807 "parser.y"
     { (yyval.type) = (yyvsp[0].type); (yyval.type)->sign = 1; ;}
     break;
 
     { (yyval.type) = (yyvsp[0].type); (yyval.type)->sign = 1; ;}
     break;
 
-  case 202:
-#line 705 "parser.y"
+  case 218:
+#line 808 "parser.y"
     { (yyval.type) = (yyvsp[0].type); (yyval.type)->sign = -1;
                                                  switch ((yyval.type)->type) {
                                                  case RPC_FC_CHAR:  break;
     { (yyval.type) = (yyvsp[0].type); (yyval.type)->sign = -1;
                                                  switch ((yyval.type)->type) {
                                                  case RPC_FC_CHAR:  break;
@@ -3218,91 +3625,91 @@ yyreduce:
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 203:
-#line 721 "parser.y"
+  case 219:
+#line 824 "parser.y"
     { (yyval.type) = make_int(-1); ;}
     break;
 
     { (yyval.type) = make_int(-1); ;}
     break;
 
-  case 204:
-#line 722 "parser.y"
+  case 220:
+#line 825 "parser.y"
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
-  case 205:
-#line 723 "parser.y"
+  case 221:
+#line 826 "parser.y"
     { (yyval.type) = duptype(find_type("float", 0), 1); ;}
     break;
 
     { (yyval.type) = duptype(find_type("float", 0), 1); ;}
     break;
 
-  case 206:
-#line 724 "parser.y"
+  case 222:
+#line 827 "parser.y"
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
-  case 207:
-#line 725 "parser.y"
+  case 223:
+#line 828 "parser.y"
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
-  case 208:
-#line 726 "parser.y"
+  case 224:
+#line 829 "parser.y"
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
-  case 209:
-#line 727 "parser.y"
+  case 225:
+#line 830 "parser.y"
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
-  case 212:
-#line 734 "parser.y"
+  case 228:
+#line 837 "parser.y"
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
-  case 213:
-#line 735 "parser.y"
+  case 229:
+#line 838 "parser.y"
     { (yyval.type) = make_builtin((yyvsp[-1].str)); ;}
     break;
 
     { (yyval.type) = make_builtin((yyvsp[-1].str)); ;}
     break;
 
-  case 214:
-#line 736 "parser.y"
+  case 230:
+#line 839 "parser.y"
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
-  case 215:
-#line 737 "parser.y"
+  case 231:
+#line 840 "parser.y"
     { (yyval.type) = make_builtin((yyvsp[-1].str)); ;}
     break;
 
     { (yyval.type) = make_builtin((yyvsp[-1].str)); ;}
     break;
 
-  case 216:
-#line 738 "parser.y"
+  case 232:
+#line 841 "parser.y"
     { (yyval.type) = make_builtin((yyvsp[-1].str)); ;}
     break;
 
     { (yyval.type) = make_builtin((yyvsp[-1].str)); ;}
     break;
 
-  case 217:
-#line 739 "parser.y"
+  case 233:
+#line 842 "parser.y"
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
-  case 218:
-#line 740 "parser.y"
+  case 234:
+#line 843 "parser.y"
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
     { (yyval.type) = make_builtin((yyvsp[0].str)); ;}
     break;
 
-  case 219:
-#line 743 "parser.y"
+  case 235:
+#line 846 "parser.y"
     { (yyval.type) = make_class((yyvsp[0].str)); ;}
     break;
 
     { (yyval.type) = make_class((yyvsp[0].str)); ;}
     break;
 
-  case 220:
-#line 744 "parser.y"
+  case 236:
+#line 847 "parser.y"
     { (yyval.type) = find_type((yyvsp[0].str), 0);
                                                  if ((yyval.type)->defined) error_loc("multiple definition error\n");
                                                  if ((yyval.type)->kind != TKIND_COCLASS) error_loc("%s was not declared a coclass\n", (yyvsp[0].str));
                                                ;}
     break;
 
     { (yyval.type) = find_type((yyvsp[0].str), 0);
                                                  if ((yyval.type)->defined) error_loc("multiple definition error\n");
                                                  if ((yyval.type)->kind != TKIND_COCLASS) error_loc("%s was not declared a coclass\n", (yyvsp[0].str));
                                                ;}
     break;
 
-  case 221:
-#line 750 "parser.y"
+  case 237:
+#line 853 "parser.y"
     { (yyval.type) = (yyvsp[0].type);
                                                  (yyval.type)->attrs = check_coclass_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
                                                  if (!parse_only && do_header)
     { (yyval.type) = (yyvsp[0].type);
                                                  (yyval.type)->attrs = check_coclass_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
                                                  if (!parse_only && do_header)
@@ -3312,42 +3719,43 @@ yyreduce:
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 222:
-#line 760 "parser.y"
+  case 238:
+#line 863 "parser.y"
     { (yyval.type) = (yyvsp[-4].type);
                                                  (yyval.type)->ifaces = (yyvsp[-2].ifref_list);
                                                  (yyval.type)->defined = TRUE;
                                                ;}
     break;
 
     { (yyval.type) = (yyvsp[-4].type);
                                                  (yyval.type)->ifaces = (yyvsp[-2].ifref_list);
                                                  (yyval.type)->defined = TRUE;
                                                ;}
     break;
 
-  case 223:
-#line 766 "parser.y"
+  case 239:
+#line 869 "parser.y"
     { (yyval.ifref_list) = NULL; ;}
     break;
 
     { (yyval.ifref_list) = NULL; ;}
     break;
 
-  case 224:
-#line 767 "parser.y"
+  case 240:
+#line 870 "parser.y"
     { (yyval.ifref_list) = append_ifref( (yyvsp[-1].ifref_list), (yyvsp[0].ifref) ); ;}
     break;
 
     { (yyval.ifref_list) = append_ifref( (yyvsp[-1].ifref_list), (yyvsp[0].ifref) ); ;}
     break;
 
-  case 225:
-#line 771 "parser.y"
+  case 241:
+#line 874 "parser.y"
     { (yyval.ifref) = make_ifref((yyvsp[0].type)); (yyval.ifref)->attrs = (yyvsp[-1].attr_list); ;}
     break;
 
     { (yyval.ifref) = make_ifref((yyvsp[0].type)); (yyval.ifref)->attrs = (yyvsp[-1].attr_list); ;}
     break;
 
-  case 226:
-#line 774 "parser.y"
+  case 242:
+#line 877 "parser.y"
     { (yyval.type) = get_type(0, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_DISPATCH; ;}
     break;
 
     { (yyval.type) = get_type(0, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_DISPATCH; ;}
     break;
 
-  case 227:
-#line 775 "parser.y"
+  case 243:
+#line 878 "parser.y"
     { (yyval.type) = get_type(0, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_DISPATCH; ;}
     break;
 
     { (yyval.type) = get_type(0, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_DISPATCH; ;}
     break;
 
-  case 228:
-#line 778 "parser.y"
+  case 244:
+#line 881 "parser.y"
     { attr_t *attrs;
     { attr_t *attrs;
+                                                 is_in_interface = TRUE;
                                                  is_object_interface = TRUE;
                                                  (yyval.type) = (yyvsp[0].type);
                                                  if ((yyval.type)->defined) error_loc("multiple definition error\n");
                                                  is_object_interface = TRUE;
                                                  (yyval.type) = (yyvsp[0].type);
                                                  if ((yyval.type)->defined) error_loc("multiple definition error\n");
@@ -3360,73 +3768,76 @@ yyreduce:
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 229:
-#line 791 "parser.y"
+  case 245:
+#line 895 "parser.y"
     { (yyval.var_list) = NULL; ;}
     break;
 
     { (yyval.var_list) = NULL; ;}
     break;
 
-  case 230:
-#line 792 "parser.y"
+  case 246:
+#line 896 "parser.y"
     { (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[-1].var) ); ;}
     break;
 
     { (yyval.var_list) = append_var( (yyvsp[-2].var_list), (yyvsp[-1].var) ); ;}
     break;
 
-  case 231:
-#line 795 "parser.y"
+  case 247:
+#line 899 "parser.y"
     { (yyval.func_list) = NULL; ;}
     break;
 
     { (yyval.func_list) = NULL; ;}
     break;
 
-  case 232:
-#line 796 "parser.y"
+  case 248:
+#line 900 "parser.y"
     { (yyval.func_list) = append_func( (yyvsp[-2].func_list), (yyvsp[-1].func) ); ;}
     break;
 
     { (yyval.func_list) = append_func( (yyvsp[-2].func_list), (yyvsp[-1].func) ); ;}
     break;
 
-  case 233:
-#line 802 "parser.y"
+  case 249:
+#line 906 "parser.y"
     { (yyval.type) = (yyvsp[-4].type);
                                                  (yyval.type)->fields_or_args = (yyvsp[-2].var_list);
                                                  (yyval.type)->funcs = (yyvsp[-1].func_list);
     { (yyval.type) = (yyvsp[-4].type);
                                                  (yyval.type)->fields_or_args = (yyvsp[-2].var_list);
                                                  (yyval.type)->funcs = (yyvsp[-1].func_list);
-                                                 if (!parse_only && do_header) write_dispinterface((yyval.type));
+                                                 if (!parse_only && do_header) write_interface((yyval.type));
                                                  if (!parse_only && do_idfile) write_diid((yyval.type));
                                                  if (!parse_only && do_idfile) write_diid((yyval.type));
+                                                 is_in_interface = FALSE;
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 234:
-#line 809 "parser.y"
+  case 250:
+#line 914 "parser.y"
     { (yyval.type) = (yyvsp[-4].type);
                                                  (yyval.type)->fields_or_args = (yyvsp[-2].type)->fields_or_args;
                                                  (yyval.type)->funcs = (yyvsp[-2].type)->funcs;
     { (yyval.type) = (yyvsp[-4].type);
                                                  (yyval.type)->fields_or_args = (yyvsp[-2].type)->fields_or_args;
                                                  (yyval.type)->funcs = (yyvsp[-2].type)->funcs;
-                                                 if (!parse_only && do_header) write_dispinterface((yyval.type));
+                                                 if (!parse_only && do_header) write_interface((yyval.type));
                                                  if (!parse_only && do_idfile) write_diid((yyval.type));
                                                  if (!parse_only && do_idfile) write_diid((yyval.type));
+                                                 is_in_interface = FALSE;
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 235:
-#line 817 "parser.y"
+  case 251:
+#line 923 "parser.y"
     { (yyval.type) = NULL; ;}
     break;
 
     { (yyval.type) = NULL; ;}
     break;
 
-  case 236:
-#line 818 "parser.y"
+  case 252:
+#line 924 "parser.y"
     { (yyval.type) = find_type2((yyvsp[0].str), 0); ;}
     break;
 
     { (yyval.type) = find_type2((yyvsp[0].str), 0); ;}
     break;
 
-  case 237:
-#line 821 "parser.y"
+  case 253:
+#line 927 "parser.y"
     { (yyval.type) = get_type(RPC_FC_IP, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_INTERFACE; ;}
     break;
 
     { (yyval.type) = get_type(RPC_FC_IP, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_INTERFACE; ;}
     break;
 
-  case 238:
-#line 822 "parser.y"
+  case 254:
+#line 928 "parser.y"
     { (yyval.type) = get_type(RPC_FC_IP, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_INTERFACE; ;}
     break;
 
     { (yyval.type) = get_type(RPC_FC_IP, (yyvsp[0].str), 0); (yyval.type)->kind = TKIND_INTERFACE; ;}
     break;
 
-  case 239:
-#line 825 "parser.y"
+  case 255:
+#line 931 "parser.y"
     { (yyval.ifinfo).interface = (yyvsp[0].type);
                                                  (yyval.ifinfo).old_pointer_default = pointer_default;
                                                  if (is_attr((yyvsp[-1].attr_list), ATTR_POINTERDEFAULT))
                                                    pointer_default = get_attrv((yyvsp[-1].attr_list), ATTR_POINTERDEFAULT);
                                                  is_object_interface = is_object((yyvsp[-1].attr_list));
     { (yyval.ifinfo).interface = (yyvsp[0].type);
                                                  (yyval.ifinfo).old_pointer_default = pointer_default;
                                                  if (is_attr((yyvsp[-1].attr_list), ATTR_POINTERDEFAULT))
                                                    pointer_default = get_attrv((yyvsp[-1].attr_list), ATTR_POINTERDEFAULT);
                                                  is_object_interface = is_object((yyvsp[-1].attr_list));
+                                                 is_in_interface = TRUE;
                                                  if ((yyvsp[0].type)->defined) error_loc("multiple definition error\n");
                                                  (yyvsp[0].type)->attrs = check_iface_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
                                                  (yyvsp[0].type)->defined = TRUE;
                                                  if ((yyvsp[0].type)->defined) error_loc("multiple definition error\n");
                                                  (yyvsp[0].type)->attrs = check_iface_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
                                                  (yyvsp[0].type)->defined = TRUE;
@@ -3434,8 +3845,8 @@ yyreduce:
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 240:
-#line 838 "parser.y"
+  case 256:
+#line 945 "parser.y"
     { (yyval.type) = (yyvsp[-5].ifinfo).interface;
                                                  (yyval.type)->ref = (yyvsp[-4].type);
                                                  (yyval.type)->funcs = (yyvsp[-2].func_list);
     { (yyval.type) = (yyvsp[-5].ifinfo).interface;
                                                  (yyval.type)->ref = (yyvsp[-4].type);
                                                  (yyval.type)->funcs = (yyvsp[-2].func_list);
@@ -3445,11 +3856,12 @@ yyreduce:
                                                  if (!parse_only && local_stubs) write_locals(local_stubs, (yyval.type), TRUE);
                                                  if (!parse_only && do_idfile) write_iid((yyval.type));
                                                  pointer_default = (yyvsp[-5].ifinfo).old_pointer_default;
                                                  if (!parse_only && local_stubs) write_locals(local_stubs, (yyval.type), TRUE);
                                                  if (!parse_only && do_idfile) write_iid((yyval.type));
                                                  pointer_default = (yyvsp[-5].ifinfo).old_pointer_default;
+                                                 is_in_interface = FALSE;
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 241:
-#line 852 "parser.y"
+  case 257:
+#line 960 "parser.y"
     { (yyval.type) = (yyvsp[-7].ifinfo).interface;
                                                  (yyval.type)->ref = find_type2((yyvsp[-5].str), 0);
                                                  if (!(yyval.type)->ref) error_loc("base class '%s' not found in import\n", (yyvsp[-5].str));
     { (yyval.type) = (yyvsp[-7].ifinfo).interface;
                                                  (yyval.type)->ref = find_type2((yyvsp[-5].str), 0);
                                                  if (!(yyval.type)->ref) error_loc("base class '%s' not found in import\n", (yyvsp[-5].str));
@@ -3459,120 +3871,185 @@ yyreduce:
                                                  if (!parse_only && local_stubs) write_locals(local_stubs, (yyval.type), TRUE);
                                                  if (!parse_only && do_idfile) write_iid((yyval.type));
                                                  pointer_default = (yyvsp[-7].ifinfo).old_pointer_default;
                                                  if (!parse_only && local_stubs) write_locals(local_stubs, (yyval.type), TRUE);
                                                  if (!parse_only && do_idfile) write_iid((yyval.type));
                                                  pointer_default = (yyvsp[-7].ifinfo).old_pointer_default;
+                                                 is_in_interface = FALSE;
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 242:
-#line 862 "parser.y"
+  case 258:
+#line 971 "parser.y"
     { (yyval.type) = (yyvsp[-1].type); ;}
     break;
 
     { (yyval.type) = (yyvsp[-1].type); ;}
     break;
 
-  case 243:
-#line 866 "parser.y"
+  case 259:
+#line 975 "parser.y"
     { (yyval.type) = (yyvsp[-1].type); if (!parse_only && do_header) write_forward((yyval.type)); ;}
     break;
 
     { (yyval.type) = (yyvsp[-1].type); if (!parse_only && do_header) write_forward((yyval.type)); ;}
     break;
 
-  case 244:
-#line 867 "parser.y"
+  case 260:
+#line 976 "parser.y"
     { (yyval.type) = (yyvsp[-1].type); if (!parse_only && do_header) write_forward((yyval.type)); ;}
     break;
 
     { (yyval.type) = (yyvsp[-1].type); if (!parse_only && do_header) write_forward((yyval.type)); ;}
     break;
 
-  case 245:
-#line 870 "parser.y"
+  case 261:
+#line 979 "parser.y"
     { (yyval.type) = make_type(0, NULL); (yyval.type)->name = (yyvsp[0].str); (yyval.type)->kind = TKIND_MODULE; ;}
     break;
 
     { (yyval.type) = make_type(0, NULL); (yyval.type)->name = (yyvsp[0].str); (yyval.type)->kind = TKIND_MODULE; ;}
     break;
 
-  case 246:
-#line 871 "parser.y"
+  case 262:
+#line 980 "parser.y"
     { (yyval.type) = make_type(0, NULL); (yyval.type)->name = (yyvsp[0].str); (yyval.type)->kind = TKIND_MODULE; ;}
     break;
 
     { (yyval.type) = make_type(0, NULL); (yyval.type)->name = (yyvsp[0].str); (yyval.type)->kind = TKIND_MODULE; ;}
     break;
 
-  case 247:
-#line 874 "parser.y"
+  case 263:
+#line 983 "parser.y"
     { (yyval.type) = (yyvsp[0].type);
                                                  (yyval.type)->attrs = check_module_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
                                                ;}
     break;
 
     { (yyval.type) = (yyvsp[0].type);
                                                  (yyval.type)->attrs = check_module_attrs((yyvsp[0].type)->name, (yyvsp[-1].attr_list));
                                                ;}
     break;
 
-  case 248:
-#line 880 "parser.y"
+  case 264:
+#line 989 "parser.y"
     { (yyval.type) = (yyvsp[-4].type);
                                                  (yyval.type)->funcs = (yyvsp[-2].func_list);
                                                  /* FIXME: if (!parse_only && do_header) write_module($$); */
                                                ;}
     break;
 
     { (yyval.type) = (yyvsp[-4].type);
                                                  (yyval.type)->funcs = (yyvsp[-2].func_list);
                                                  /* FIXME: if (!parse_only && do_header) write_module($$); */
                                                ;}
     break;
 
-  case 249:
-#line 886 "parser.y"
-    { (yyval.pident) = (yyvsp[0].pident); (yyval.pident)->ptr_level++; ;}
+  case 265:
+#line 996 "parser.y"
+    { (yyval.stgclass) = STG_EXTERN; ;}
     break;
 
     break;
 
-  case 250:
-#line 887 "parser.y"
-    { (yyval.pident) = (yyvsp[0].pident); /* FIXME */ ;}
+  case 266:
+#line 997 "parser.y"
+    { (yyval.stgclass) = STG_STATIC; ;}
     break;
 
     break;
 
-  case 251:
-#line 888 "parser.y"
-    { (yyval.pident) = (yyvsp[0].pident);
-                                                 if ((yyval.pident)->callconv) parser_warning("multiple calling conventions %s, %s for function %s\n", (yyval.pident)->callconv, (yyvsp[-1].str), (yyval.pident)->var->name);
-                                                 (yyval.pident)->callconv = (yyvsp[-1].str);
-                                               ;}
+  case 267:
+#line 998 "parser.y"
+    { (yyval.stgclass) = STG_REGISTER; ;}
     break;
 
     break;
 
-  case 253:
-#line 896 "parser.y"
-    { (yyval.pident) = (yyvsp[-3].pident);
-                                                 (yyvsp[-3].pident)->args = (yyvsp[-1].var_list);
-                                                 (yyvsp[-3].pident)->is_func = TRUE;
-                                               ;}
+  case 268:
+#line 1002 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_INLINE); ;}
     break;
 
     break;
 
-  case 254:
-#line 902 "parser.y"
-    { (yyval.pident) = make_pident((yyvsp[0].var)); ;}
+  case 269:
+#line 1006 "parser.y"
+    { (yyval.attr) = make_attr(ATTR_CONST); ;}
     break;
 
     break;
 
-  case 255:
-#line 903 "parser.y"
-    { (yyval.pident) = (yyvsp[-1].pident); ;}
+  case 270:
+#line 1009 "parser.y"
+    { (yyval.attr_list) = NULL; ;}
     break;
 
     break;
 
-  case 256:
-#line 904 "parser.y"
-    { (yyval.pident) = (yyvsp[0].pident);
-                                                 (yyval.pident)->func_ptr_level = (yyval.pident)->ptr_level;
-                                                 (yyval.pident)->ptr_level = 0;
+  case 271:
+#line 1010 "parser.y"
+    { (yyval.attr_list) = append_attr((yyvsp[-1].attr_list), (yyvsp[0].attr)); ;}
+    break;
+
+  case 272:
+#line 1013 "parser.y"
+    { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[0].declspec), NULL, NULL, STG_NONE); ;}
+    break;
+
+  case 273:
+#line 1015 "parser.y"
+    { (yyval.declspec) = make_decl_spec((yyvsp[-1].type), (yyvsp[-2].declspec), (yyvsp[0].declspec), NULL, STG_NONE); ;}
+    break;
+
+  case 274:
+#line 1018 "parser.y"
+    { (yyval.declspec) = NULL; ;}
+    break;
+
+  case 276:
+#line 1023 "parser.y"
+    { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, (yyvsp[-1].attr), STG_NONE); ;}
+    break;
+
+  case 277:
+#line 1024 "parser.y"
+    { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, (yyvsp[-1].attr), STG_NONE); ;}
+    break;
+
+  case 278:
+#line 1025 "parser.y"
+    { (yyval.declspec) = make_decl_spec(NULL, (yyvsp[0].declspec), NULL, NULL, (yyvsp[-1].stgclass)); ;}
+    break;
+
+  case 279:
+#line 1030 "parser.y"
+    { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type = append_ptrchain_type((yyval.declarator)->type, make_pointer_type(NULL, (yyvsp[-1].attr_list))); ;}
+    break;
+
+  case 280:
+#line 1031 "parser.y"
+    { (yyval.declarator) = (yyvsp[0].declarator); (yyval.declarator)->type->attrs = append_attr((yyval.declarator)->type->attrs, make_attrp(ATTR_CALLCONV, (yyvsp[-1].str))); ;}
+    break;
+
+  case 282:
+#line 1036 "parser.y"
+    { (yyval.declarator) = make_declarator((yyvsp[0].var)); ;}
+    break;
+
+  case 283:
+#line 1037 "parser.y"
+    { (yyval.declarator) = (yyvsp[-1].declarator); ;}
+    break;
+
+  case 284:
+#line 1038 "parser.y"
+    { (yyval.declarator) = (yyvsp[-1].declarator); (yyval.declarator)->array = append_array((yyval.declarator)->array, (yyvsp[0].expr)); ;}
+    break;
+
+  case 285:
+#line 1039 "parser.y"
+    { (yyval.declarator) = (yyvsp[-3].declarator);
+                                                 (yyval.declarator)->func_type = append_ptrchain_type((yyval.declarator)->type, make_func_type((yyvsp[-1].var_list)));
+                                                 (yyval.declarator)->type = NULL;
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 257:
-#line 911 "parser.y"
-    { (yyval.pident_list) = append_pident( NULL, (yyvsp[0].pident) ); ;}
+  case 286:
+#line 1046 "parser.y"
+    { (yyval.declarator_list) = append_declarator( NULL, (yyvsp[0].declarator) ); ;}
     break;
 
     break;
 
-  case 258:
-#line 912 "parser.y"
-    { (yyval.pident_list) = append_pident( (yyvsp[-2].pident_list), (yyvsp[0].pident) ); ;}
+  case 287:
+#line 1047 "parser.y"
+    { (yyval.declarator_list) = append_declarator( (yyvsp[-2].declarator_list), (yyvsp[0].declarator) ); ;}
     break;
 
     break;
 
-  case 259:
-#line 916 "parser.y"
+  case 288:
+#line 1051 "parser.y"
+    { (yyval.declarator) = (yyvsp[0].declarator); ;}
+    break;
+
+  case 289:
+#line 1052 "parser.y"
+    { (yyval.declarator) = (yyvsp[-2].declarator); (yyvsp[-2].declarator)->var->eval = (yyvsp[0].expr); ;}
+    break;
+
+  case 290:
+#line 1056 "parser.y"
     { (yyval.num) = RPC_FC_RP; ;}
     break;
 
     { (yyval.num) = RPC_FC_RP; ;}
     break;
 
-  case 260:
-#line 917 "parser.y"
+  case 291:
+#line 1057 "parser.y"
     { (yyval.num) = RPC_FC_UP; ;}
     break;
 
     { (yyval.num) = RPC_FC_UP; ;}
     break;
 
-  case 261:
-#line 918 "parser.y"
+  case 292:
+#line 1058 "parser.y"
     { (yyval.num) = RPC_FC_FP; ;}
     break;
 
     { (yyval.num) = RPC_FC_FP; ;}
     break;
 
-  case 262:
-#line 921 "parser.y"
+  case 293:
+#line 1061 "parser.y"
     { (yyval.type) = get_typev(RPC_FC_STRUCT, (yyvsp[-3].var), tsSTRUCT);
                                                   /* overwrite RPC_FC_STRUCT with a more exact type */
                                                  (yyval.type)->type = get_struct_type( (yyvsp[-1].var_list) );
     { (yyval.type) = get_typev(RPC_FC_STRUCT, (yyvsp[-3].var), tsSTRUCT);
                                                   /* overwrite RPC_FC_STRUCT with a more exact type */
                                                  (yyval.type)->type = get_struct_type( (yyvsp[-1].var_list) );
@@ -3584,70 +4061,65 @@ yyreduce:
                                                 ;}
     break;
 
                                                 ;}
     break;
 
-  case 263:
-#line 932 "parser.y"
+  case 294:
+#line 1072 "parser.y"
     { (yyval.type) = duptype(find_type("void", 0), 1); ;}
     break;
 
     { (yyval.type) = duptype(find_type("void", 0), 1); ;}
     break;
 
-  case 264:
-#line 933 "parser.y"
+  case 295:
+#line 1073 "parser.y"
     { (yyval.type) = find_type((yyvsp[0].str), 0); ;}
     break;
 
     { (yyval.type) = find_type((yyvsp[0].str), 0); ;}
     break;
 
-  case 265:
-#line 934 "parser.y"
+  case 296:
+#line 1074 "parser.y"
     { (yyval.type) = (yyvsp[0].type); ;}
     break;
 
     { (yyval.type) = (yyvsp[0].type); ;}
     break;
 
-  case 266:
-#line 935 "parser.y"
-    { (yyval.type) = duptype((yyvsp[0].type), 1); (yyval.type)->is_const = TRUE; ;}
-    break;
-
-  case 267:
-#line 936 "parser.y"
+  case 297:
+#line 1075 "parser.y"
     { (yyval.type) = (yyvsp[0].type); ;}
     break;
 
     { (yyval.type) = (yyvsp[0].type); ;}
     break;
 
-  case 268:
-#line 937 "parser.y"
+  case 298:
+#line 1076 "parser.y"
     { (yyval.type) = find_type2((yyvsp[0].str), tsENUM); ;}
     break;
 
     { (yyval.type) = find_type2((yyvsp[0].str), tsENUM); ;}
     break;
 
-  case 269:
-#line 938 "parser.y"
+  case 299:
+#line 1077 "parser.y"
     { (yyval.type) = (yyvsp[0].type); ;}
     break;
 
     { (yyval.type) = (yyvsp[0].type); ;}
     break;
 
-  case 270:
-#line 939 "parser.y"
+  case 300:
+#line 1078 "parser.y"
     { (yyval.type) = get_type(RPC_FC_STRUCT, (yyvsp[0].str), tsSTRUCT); ;}
     break;
 
     { (yyval.type) = get_type(RPC_FC_STRUCT, (yyvsp[0].str), tsSTRUCT); ;}
     break;
 
-  case 271:
-#line 940 "parser.y"
+  case 301:
+#line 1079 "parser.y"
     { (yyval.type) = (yyvsp[0].type); ;}
     break;
 
     { (yyval.type) = (yyvsp[0].type); ;}
     break;
 
-  case 272:
-#line 941 "parser.y"
+  case 302:
+#line 1080 "parser.y"
     { (yyval.type) = find_type2((yyvsp[0].str), tsUNION); ;}
     break;
 
     { (yyval.type) = find_type2((yyvsp[0].str), tsUNION); ;}
     break;
 
-  case 273:
-#line 942 "parser.y"
+  case 303:
+#line 1081 "parser.y"
     { (yyval.type) = make_safearray((yyvsp[-1].type)); ;}
     break;
 
     { (yyval.type) = make_safearray((yyvsp[-1].type)); ;}
     break;
 
-  case 274:
-#line 945 "parser.y"
-    { reg_typedefs((yyvsp[-1].type), (yyvsp[0].pident_list), check_typedef_attrs((yyvsp[-2].attr_list)));
-                                                 process_typedefs((yyvsp[0].pident_list));
+  case 304:
+#line 1085 "parser.y"
+    { reg_typedefs((yyvsp[-1].declspec), (yyvsp[0].declarator_list), check_typedef_attrs((yyvsp[-2].attr_list)));
+                                                 (yyval.statement) = process_typedefs((yyvsp[0].declarator_list));
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 275:
-#line 950 "parser.y"
+  case 305:
+#line 1091 "parser.y"
     { (yyval.type) = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, (yyvsp[-3].var), tsUNION);
                                                  (yyval.type)->kind = TKIND_UNION;
                                                  (yyval.type)->fields_or_args = (yyvsp[-1].var_list);
     { (yyval.type) = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, (yyvsp[-3].var), tsUNION);
                                                  (yyval.type)->kind = TKIND_UNION;
                                                  (yyval.type)->fields_or_args = (yyvsp[-1].var_list);
@@ -3655,8 +4127,8 @@ yyreduce:
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 276:
-#line 957 "parser.y"
+  case 306:
+#line 1098 "parser.y"
     { var_t *u = (yyvsp[-3].var);
                                                  (yyval.type) = get_typev(RPC_FC_ENCAPSULATED_UNION, (yyvsp[-8].var), tsUNION);
                                                  (yyval.type)->kind = TKIND_UNION;
     { var_t *u = (yyvsp[-3].var);
                                                  (yyval.type) = get_typev(RPC_FC_ENCAPSULATED_UNION, (yyvsp[-8].var), tsUNION);
                                                  (yyval.type)->kind = TKIND_UNION;
@@ -3671,13 +4143,13 @@ yyreduce:
                                                ;}
     break;
 
                                                ;}
     break;
 
-  case 277:
-#line 972 "parser.y"
+  case 307:
+#line 1113 "parser.y"
     { (yyval.num) = MAKEVERSION((yyvsp[0].num), 0); ;}
     break;
 
     { (yyval.num) = MAKEVERSION((yyvsp[0].num), 0); ;}
     break;
 
-  case 278:
-#line 973 "parser.y"
+  case 308:
+#line 1114 "parser.y"
     { (yyval.num) = MAKEVERSION((yyvsp[-2].num), (yyvsp[0].num)); ;}
     break;
 
     { (yyval.num) = MAKEVERSION((yyvsp[-2].num), (yyvsp[0].num)); ;}
     break;
 
@@ -3686,7 +4158,7 @@ yyreduce:
     }
 
 /* Line 1126 of yacc.c.  */
     }
 
 /* Line 1126 of yacc.c.  */
-#line 3690 "parser.tab.c"
+#line 4162 "parser.tab.c"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
@@ -3954,7 +4426,7 @@ yyreturn:
 }
 
 
 }
 
 
-#line 976 "parser.y"
+#line 1117 "parser.y"
 
 
 static void decl_builtin(const char *name, unsigned char type)
 
 
 static void decl_builtin(const char *name, unsigned char type)
@@ -4039,229 +4511,125 @@ static attr_list_t *append_attr(attr_list_t *list, attr_t *attr)
     return list;
 }
 
     return list;
 }
 
-static attr_t *make_attr(enum attr_type type)
-{
-  attr_t *a = xmalloc(sizeof(attr_t));
-  a->type = type;
-  a->u.ival = 0;
-  return a;
-}
-
-static attr_t *make_attrv(enum attr_type type, unsigned long val)
+static attr_list_t *move_attr(attr_list_t *dst, attr_list_t *src, enum attr_type type)
 {
 {
-  attr_t *a = xmalloc(sizeof(attr_t));
-  a->type = type;
-  a->u.ival = val;
-  return a;
+  attr_t *attr;
+  if (!src) return dst;
+  LIST_FOR_EACH_ENTRY(attr, src, attr_t, entry)
+    if (attr->type == type)
+    {
+      list_remove(&attr->entry);
+      return append_attr(dst, attr);
+    }
+  return dst;
 }
 
 }
 
-static attr_t *make_attrp(enum attr_type type, void *val)
+static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list)
 {
 {
-  attr_t *a = xmalloc(sizeof(attr_t));
-  a->type = type;
-  a->u.pval = val;
-  return a;
-}
+  struct list *entry;
 
 
-static expr_t *make_expr(enum expr_type type)
-{
-  expr_t *e = xmalloc(sizeof(expr_t));
-  e->type = type;
-  e->ref = NULL;
-  e->u.lval = 0;
-  e->is_const = FALSE;
-  e->cval = 0;
-  return e;
-}
+  if (!old_list) return new_list;
 
 
-static expr_t *make_exprl(enum expr_type type, long val)
-{
-  expr_t *e = xmalloc(sizeof(expr_t));
-  e->type = type;
-  e->ref = NULL;
-  e->u.lval = val;
-  e->is_const = FALSE;
-  /* check for numeric constant */
-  if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE) {
-    /* make sure true/false value is valid */
-    assert(type != EXPR_TRUEFALSE || val == 0 || val == 1);
-    e->is_const = TRUE;
-    e->cval = val;
+  while ((entry = list_head(old_list)))
+  {
+    attr_t *attr = LIST_ENTRY(entry, attr_t, entry);
+    list_remove(entry);
+    new_list = append_attr(new_list, attr);
   }
   }
-  return e;
+  return new_list;
 }
 
 }
 
-static expr_t *make_exprd(enum expr_type type, double val)
+static attr_list_t *dupattrs(const attr_list_t *list)
 {
 {
-  expr_t *e = xmalloc(sizeof(expr_t));
-  e->type = type;
-  e->ref = NULL;
-  e->u.dval = val;
-  e->is_const = TRUE;
-  e->cval = val;
-  return e;
-}
+  attr_list_t *new_list;
+  const attr_t *attr;
 
 
-static expr_t *make_exprs(enum expr_type type, char *val)
-{
-  expr_t *e;
-  e = xmalloc(sizeof(expr_t));
-  e->type = type;
-  e->ref = NULL;
-  e->u.sval = val;
-  e->is_const = FALSE;
-  /* check for predefined constants */
-  if (type == EXPR_IDENTIFIER) {
-    var_t *c = find_const(val, 0);
-    if (c) {
-      e->u.sval = c->name;
-      free(val);
-      e->is_const = TRUE;
-      e->cval = c->eval->cval;
-    }
+  if (!list) return NULL;
+
+  new_list = xmalloc( sizeof(*list) );
+  list_init( new_list );
+  LIST_FOR_EACH_ENTRY(attr, list, const attr_t, entry)
+  {
+    attr_t *new_attr = xmalloc(sizeof(*new_attr));
+    *new_attr = *attr;
+    list_add_tail(new_list, &new_attr->entry);
   }
   }
-  return e;
+  return new_list;
 }
 
 }
 
-static expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr)
+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)
 {
 {
-  expr_t *e;
-  e = xmalloc(sizeof(expr_t));
-  e->type = type;
-  e->ref = expr;
-  e->u.tref = tref;
-  e->is_const = FALSE;
-  /* check for cast of constant expression */
-  if (type == EXPR_SIZEOF) {
-    switch (tref->type) {
-      case RPC_FC_BYTE:
-      case RPC_FC_CHAR:
-      case RPC_FC_SMALL:
-      case RPC_FC_USMALL:
-        e->is_const = TRUE;
-        e->cval = 1;
-        break;
-      case RPC_FC_WCHAR:
-      case RPC_FC_USHORT:
-      case RPC_FC_SHORT:
-        e->is_const = TRUE;
-        e->cval = 2;
-        break;
-      case RPC_FC_LONG:
-      case RPC_FC_ULONG:
-      case RPC_FC_FLOAT:
-      case RPC_FC_ERROR_STATUS_T:
-        e->is_const = TRUE;
-        e->cval = 4;
-        break;
-      case RPC_FC_HYPER:
-      case RPC_FC_DOUBLE:
-        e->is_const = TRUE;
-        e->cval = 8;
-        break;
-    }
+  decl_spec_t *declspec = left ? left : right;
+  if (!declspec)
+  {
+    declspec = xmalloc(sizeof(*declspec));
+    declspec->type = NULL;
+    declspec->attrs = NULL;
+    declspec->stgclass = STG_NONE;
+  }
+  declspec->type = type;
+  if (left && declspec != left)
+  {
+    declspec->attrs = append_attr_list(declspec->attrs, left->attrs);
+    if (declspec->stgclass == STG_NONE)
+      declspec->stgclass = left->stgclass;
+    else if (left->stgclass != STG_NONE)
+      error_loc("only one storage class can be specified\n");
+    assert(!left->type);
+    free(left);
+  }
+  if (right && declspec != right)
+  {
+    declspec->attrs = append_attr_list(declspec->attrs, right->attrs);
+    if (declspec->stgclass == STG_NONE)
+      declspec->stgclass = right->stgclass;
+    else if (right->stgclass != STG_NONE)
+      error_loc("only one storage class can be specified\n");
+    assert(!right->type);
+    free(right);
   }
   }
-  if (type == EXPR_CAST && expr->is_const) {
-    e->is_const = TRUE;
-    e->cval = expr->cval;
+
+  declspec->attrs = append_attr(declspec->attrs, attr);
+  if (declspec->stgclass == STG_NONE)
+    declspec->stgclass = stgclass;
+  else if (stgclass != STG_NONE)
+    error_loc("only one storage class can be specified\n");
+
+  /* apply attributes to type */
+  if (type && declspec->attrs)
+  {
+    attr_list_t *attrs;
+    declspec->type = duptype(type, 1);
+    attrs = dupattrs(type->attrs);
+    declspec->type->attrs = append_attr_list(attrs, declspec->attrs);
+    declspec->attrs = NULL;
   }
   }
-  return e;
+
+  return declspec;
 }
 
 }
 
-static expr_t *make_expr1(enum expr_type type, expr_t *expr)
+static attr_t *make_attr(enum attr_type type)
 {
 {
-  expr_t *e;
-  if (type == EXPR_ADDRESSOF && expr->type != EXPR_IDENTIFIER)
-    error_loc("address-of operator applied to invalid expression\n");
-  e = xmalloc(sizeof(expr_t));
-  e->type = type;
-  e->ref = expr;
-  e->u.lval = 0;
-  e->is_const = FALSE;
-  /* check for compile-time optimization */
-  if (expr->is_const) {
-    e->is_const = TRUE;
-    switch (type) {
-    case EXPR_NEG:
-      e->cval = -expr->cval;
-      break;
-    case EXPR_NOT:
-      e->cval = ~expr->cval;
-      break;
-    default:
-      e->is_const = FALSE;
-      break;
-    }
-  }
-  return e;
+  attr_t *a = xmalloc(sizeof(attr_t));
+  a->type = type;
+  a->u.ival = 0;
+  return a;
 }
 
 }
 
-static expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2)
+static attr_t *make_attrv(enum attr_type type, unsigned long val)
 {
 {
-  expr_t *e;
-  e = xmalloc(sizeof(expr_t));
-  e->type = type;
-  e->ref = expr1;
-  e->u.ext = expr2;
-  e->is_const = FALSE;
-  /* check for compile-time optimization */
-  if (expr1->is_const && expr2->is_const) {
-    e->is_const = TRUE;
-    switch (type) {
-    case EXPR_ADD:
-      e->cval = expr1->cval + expr2->cval;
-      break;
-    case EXPR_SUB:
-      e->cval = expr1->cval - expr2->cval;
-      break;
-    case EXPR_MUL:
-      e->cval = expr1->cval * expr2->cval;
-      break;
-    case EXPR_DIV:
-      e->cval = expr1->cval / expr2->cval;
-      break;
-    case EXPR_OR:
-      e->cval = expr1->cval | expr2->cval;
-      break;
-    case EXPR_AND:
-      e->cval = expr1->cval & expr2->cval;
-      break;
-    case EXPR_SHL:
-      e->cval = expr1->cval << expr2->cval;
-      break;
-    case EXPR_SHR:
-      e->cval = expr1->cval >> expr2->cval;
-      break;
-    default:
-      e->is_const = FALSE;
-      break;
-    }
-  }
-  return e;
+  attr_t *a = xmalloc(sizeof(attr_t));
+  a->type = type;
+  a->u.ival = val;
+  return a;
 }
 
 }
 
-static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3)
+static attr_t *make_attrp(enum attr_type type, void *val)
 {
 {
-  expr_t *e;
-  e = xmalloc(sizeof(expr_t));
-  e->type = type;
-  e->ref = expr1;
-  e->u.ext = expr2;
-  e->ext2 = expr3;
-  e->is_const = FALSE;
-  /* check for compile-time optimization */
-  if (expr1->is_const && expr2->is_const && expr3->is_const) {
-    e->is_const = TRUE;
-    switch (type) {
-    case EXPR_COND:
-      e->cval = expr1->cval ? expr2->cval : expr3->cval;
-      break;
-    default:
-      e->is_const = FALSE;
-      break;
-    }
-  }
-  return e;
+  attr_t *a = xmalloc(sizeof(attr_t));
+  a->type = type;
+  a->u.pval = val;
+  return a;
 }
 
 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)
@@ -4309,7 +4677,7 @@ void set_all_tfswrite(int val)
     node->data.tfswrite = val;
 }
 
     node->data.tfswrite = val;
 }
 
-static type_t *make_type(unsigned char type, type_t *ref)
+type_t *make_type(unsigned char type, type_t *ref)
 {
   type_t *t = alloc_type();
   t->name = NULL;
 {
   type_t *t = alloc_type();
   t->name = NULL;
@@ -4328,72 +4696,102 @@ static type_t *make_type(unsigned char type, type_t *ref)
   t->ptrdesc = 0;
   t->declarray = FALSE;
   t->ignore = (parse_only != 0);
   t->ptrdesc = 0;
   t->declarray = FALSE;
   t->ignore = (parse_only != 0);
-  t->is_const = FALSE;
   t->sign = 0;
   t->defined = FALSE;
   t->written = FALSE;
   t->user_types_registered = FALSE;
   t->tfswrite = FALSE;
   t->sign = 0;
   t->defined = FALSE;
   t->written = FALSE;
   t->user_types_registered = FALSE;
   t->tfswrite = FALSE;
+  t->checked = FALSE;
   t->typelib_idx = -1;
   return t;
 }
 
   t->typelib_idx = -1;
   return t;
 }
 
-static void set_type(var_t *v, type_t *type, const pident_t *pident, array_dims_t *arr,
+static type_t *make_func_type(var_list_t *args)
+{
+  type_t *t = make_type(RPC_FC_FUNCTION, NULL);
+  t->fields_or_args = args;
+  return t;
+}
+
+static type_t *make_pointer_type(type_t *ref, attr_list_t *attrs)
+{
+    type_t *t = make_type(pointer_default, ref);
+    t->attrs = attrs;
+    return t;
+}
+
+static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type)
+{
+  type_t *ptrchain_type;
+  if (!ptrchain)
+    return type;
+  for (ptrchain_type = ptrchain; ptrchain_type->ref; ptrchain_type = ptrchain_type->ref)
+    ;
+  ptrchain_type->ref = type;
+  return ptrchain;
+}
+
+static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
                      int top)
 {
   expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS);
   expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS);
   int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE);
                      int top)
 {
   expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS);
   expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS);
   int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE);
-  int ptr_type = ptr_attr;
   int sizeless, has_varconf;
   expr_t *dim;
   type_t *atype, **ptype;
   int sizeless, has_varconf;
   expr_t *dim;
   type_t *atype, **ptype;
-  int ptr_level = (pident ? pident->ptr_level : 0);
-
-  v->type = type;
+  array_dims_t *arr = decl ? decl->array : NULL;
+  type_t *func_type = decl ? decl->func_type : NULL;
+  type_t *type = decl_spec->type;
 
 
-  if (!ptr_type && top)
-    ptr_type = RPC_FC_RP;
-
-  for ( ; 0 < ptr_level; --ptr_level)
+  if (is_attr(type->attrs, ATTR_INLINE))
   {
   {
-    v->type = make_type(pointer_default, v->type);
-    if (ptr_level == 1 && ptr_type && !arr)
+    if (!func_type)
+      error_loc("inline attribute applied to non-function type\n");
+    else
     {
     {
-      v->type->type = ptr_type;
-      ptr_type = 0;
+      type_t *t;
+      /* move inline attribute from return type node to function node */
+      for (t = func_type; is_ptr(t); t = t->ref)
+        ;
+      t->attrs = move_attr(t->attrs, type->attrs, ATTR_INLINE);
     }
   }
 
     }
   }
 
-  if (ptr_type && !arr)
+  /* add type onto the end of the pointers in pident->type */
+  v->type = append_ptrchain_type(decl ? decl->type : NULL, type);
+  v->stgclass = decl_spec->stgclass;
+
+  /* the highest level of pointer specified should default to the var's ptr attr
+   * or (RPC_FC_RP if not specified and it's a top level ptr), not
+   * pointer_default so we need to fix that up here */
+  if (!arr)
   {
   {
-    if (is_ptr(v->type))
+    const type_t *ptr = NULL;
+    /* pointer attributes on the left side of the type belong to the function
+     * pointer, if one is being declared */
+    type_t **pt = func_type ? &func_type : &v->type;
+    for (ptr = *pt; ptr; )
     {
     {
-      if (v->type->type != ptr_type)
-      {
-        v->type = duptype(v->type, 1);
-        v->type->type = ptr_type;
-      }
+      if (ptr->kind == TKIND_ALIAS)
+        ptr = ptr->orig;
+      else
+        break;
     }
     }
-    else if (!arr && ptr_attr)
-      error_loc("%s: pointer attribute applied to non-pointer type\n", v->name);
-  }
-
-  if (pident && pident->is_func) {
-    int func_ptr_level = pident->func_ptr_level;
-    v->type = make_type(RPC_FC_FUNCTION, v->type);
-    v->type->fields_or_args = pident->args;
-    if (pident->callconv)
-      v->type->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, pident->callconv));
-    else if (is_object_interface) {
-      static char *stdmethodcalltype;
-      if (!stdmethodcalltype) stdmethodcalltype = strdup("STDMETHODCALLTYPE");
-      v->type->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, stdmethodcalltype));
+    if (ptr && is_ptr(ptr) && (ptr_attr || top))
+    {
+      /* duplicate type to avoid changing original type */
+      *pt = duptype(*pt, 1);
+      (*pt)->type = ptr_attr ? ptr_attr : RPC_FC_RP;
     }
     }
-    for (; func_ptr_level > 0; func_ptr_level--)
-      v->type = make_type(ptr_type, v->type);
+    else if (ptr_attr)
+       error_loc("%s: pointer attribute applied to non-pointer type\n", v->name);
   }
 
   }
 
+  if (is_attr(v->attrs, ATTR_STRING) && !is_ptr(v->type) && !arr)
+    error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n",
+              v->name);
+
   sizeless = FALSE;
   if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry)
   {
   sizeless = FALSE;
   if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry)
   {
@@ -4506,6 +4904,54 @@ static void set_type(var_t *v, type_t *type, const pident_t *pident, array_dims_
           break;
         }
   }
           break;
         }
   }
+
+  /* v->type is currently pointing the the type on the left-side of the
+   * declaration, so we need to fix this up so that it is the return type of the
+   * function and make v->type point to the function side of the declaration */
+  if (func_type)
+  {
+    type_t *ft, *t;
+    type_t *return_type = v->type;
+    v->type = func_type;
+    for (ft = v->type; is_ptr(ft); ft = ft->ref)
+      ;
+    assert(ft->type == RPC_FC_FUNCTION);
+    ft->ref = return_type;
+    /* move calling convention attribute, if present, from pointer nodes to
+     * function node */
+    for (t = v->type; is_ptr(t); t = t->ref)
+      ft->attrs = move_attr(ft->attrs, t->attrs, ATTR_CALLCONV);
+    if (is_object_interface && !is_attr(ft->attrs, ATTR_CALLCONV))
+    {
+      static char *stdmethodcalltype;
+      if (!stdmethodcalltype) stdmethodcalltype = strdup("STDMETHODCALLTYPE");
+      ft->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, stdmethodcalltype));
+    }
+  }
+  else
+  {
+    type_t *t;
+    for (t = v->type; is_ptr(t); t = t->ref)
+      if (is_attr(t->attrs, ATTR_CALLCONV))
+        error_loc("calling convention applied to non-function-pointer type\n");
+  }
+}
+
+static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls)
+{
+  declarator_t *decl, *next;
+  var_list_t *var_list = NULL;
+
+  LIST_FOR_EACH_ENTRY_SAFE( decl, next, decls, declarator_t, entry )
+  {
+    var_t *var = decl->var;
+
+    var->attrs = attrs;
+    set_type(var, decl_spec, decl, 0);
+    var_list = append_var(var_list, var);
+    free(decl);
+  }
+  return var_list;
 }
 
 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)
@@ -4540,6 +4986,18 @@ static var_list_t *append_var(var_list_t *list, var_t *var)
     return list;
 }
 
     return list;
 }
 
+static var_list_t *append_var_list(var_list_t *list, var_list_t *vars)
+{
+    if (!vars) return list;
+    if (!list)
+    {
+        list = xmalloc( sizeof(*list) );
+        list_init( list );
+    }
+    list_move_tail( list, vars );
+    return list;
+}
+
 static var_t *make_var(char *name)
 {
   var_t *v = xmalloc(sizeof(var_t));
 static var_t *make_var(char *name)
 {
   var_t *v = xmalloc(sizeof(var_t));
@@ -4547,33 +5005,32 @@ static var_t *make_var(char *name)
   v->type = NULL;
   v->attrs = NULL;
   v->eval = NULL;
   v->type = NULL;
   v->attrs = NULL;
   v->eval = NULL;
+  v->stgclass = STG_NONE;
   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;
 }
 
   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 pident_list_t *append_pident(pident_list_t *list, pident_t *p)
+static declarator_list_t *append_declarator(declarator_list_t *list, declarator_t *d)
 {
 {
-  if (!p) return list;
+  if (!d) return list;
   if (!list) {
     list = xmalloc(sizeof(*list));
     list_init(list);
   }
   if (!list) {
     list = xmalloc(sizeof(*list));
     list_init(list);
   }
-  list_add_tail(list, &p->entry);
+  list_add_tail(list, &d->entry);
   return list;
 }
 
   return list;
 }
 
-static pident_t *make_pident(var_t *var)
+static declarator_t *make_declarator(var_t *var)
 {
 {
-  pident_t *p = xmalloc(sizeof(*p));
-  p->var = var;
-  p->is_func = FALSE;
-  p->ptr_level = 0;
-  p->func_ptr_level = 0;
-  p->args = NULL;
-  p->callconv = NULL;
-  return p;
+  declarator_t *d = xmalloc(sizeof(*d));
+  d->var = var;
+  d->type = NULL;
+  d->func_type = NULL;
+  d->array = NULL;
+  return d;
 }
 
 static func_list_t *append_func(func_list_t *list, func_t *func)
 }
 
 static func_list_t *append_func(func_list_t *list, func_t *func)
@@ -4588,11 +5045,11 @@ static func_list_t *append_func(func_list_t *list, func_t *func)
     return list;
 }
 
     return list;
 }
 
-static func_t *make_func(var_t *def, var_list_t *args)
+static func_t *make_func(var_t *def)
 {
   func_t *f = xmalloc(sizeof(func_t));
   f->def = def;
 {
   func_t *f = xmalloc(sizeof(func_t));
   f->def = def;
-  f->args = args;
+  f->args = def->type->fields_or_args;
   f->ignore = parse_only;
   f->idx = -1;
   return f;
   f->ignore = parse_only;
   f->idx = -1;
   return f;
@@ -4600,7 +5057,7 @@ static func_t *make_func(var_t *def, var_list_t *args)
 
 static type_t *make_class(char *name)
 {
 
 static type_t *make_class(char *name)
 {
-  type_t *c = make_type(0, NULL);
+  type_t *c = make_type(RPC_FC_COCLASS, NULL);
   c->name = name;
   c->kind = TKIND_COCLASS;
   return c;
   c->name = name;
   c->kind = TKIND_COCLASS;
   return c;
@@ -4613,6 +5070,17 @@ static type_t *make_safearray(type_t *type)
   return make_type(pointer_default, sa);
 }
 
   return make_type(pointer_default, sa);
 }
 
+static typelib_t *make_library(const char *name, const attr_list_t *attrs)
+{
+    typelib_t *typelib = xmalloc(sizeof(*typelib));
+    typelib->name = xstrdup(name);
+    typelib->filename = NULL;
+    typelib->attrs = attrs;
+    list_init( &typelib->entries );
+    list_init( &typelib->importlibs );
+    return typelib;
+}
+
 #define HASHMAX 64
 
 static int hash_ident(const char *name)
 #define HASHMAX 64
 
 static int hash_ident(const char *name)
@@ -4688,17 +5156,15 @@ static void fix_incomplete(void)
   }
 }
 
   }
 }
 
-static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *attrs)
+static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, attr_list_t *attrs)
 {
 {
-  type_t *ptr = type;
-  const pident_t *pident;
-  int ptrc = 0;
+  const declarator_t *decl;
   int is_str = is_attr(attrs, ATTR_STRING);
   int is_str = is_attr(attrs, ATTR_STRING);
-  unsigned char ptr_type = get_attrv(attrs, ATTR_POINTERTYPE);
+  type_t *type = decl_spec->type;
 
   if (is_str)
   {
 
   if (is_str)
   {
-    type_t *t = type;
+    type_t *t = decl_spec->type;
     unsigned char c;
 
     while (is_ptr(t))
     unsigned char c;
 
     while (is_ptr(t))
@@ -4707,16 +5173,15 @@ static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *a
     c = t->type;
     if (c != RPC_FC_CHAR && c != RPC_FC_BYTE && c != RPC_FC_WCHAR)
     {
     c = t->type;
     if (c != RPC_FC_CHAR && c != RPC_FC_BYTE && c != RPC_FC_WCHAR)
     {
-      pident = LIST_ENTRY( list_head( pidents ), const pident_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",
-              pident->var->name);
+              decl->var->name);
     }
   }
 
   /* We must generate names for tagless enum, struct or union.
      Typedef-ing a tagless enum, struct or union means we want the typedef
     }
   }
 
   /* We must generate names for tagless enum, struct or union.
      Typedef-ing a tagless enum, struct or union means we want the typedef
-     to be included in a library whether it has other attributes or not,
-     hence the public attribute.  */
+     to be included in a library hence the public attribute.  */
   if ((type->kind == TKIND_ENUM || type->kind == TKIND_RECORD
        || type->kind == TKIND_UNION) && ! type->name && ! parse_only)
   {
   if ((type->kind == TKIND_ENUM || type->kind == TKIND_RECORD
        || type->kind == TKIND_UNION) && ! type->name && ! parse_only)
   {
@@ -4724,52 +5189,21 @@ static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *a
       attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) );
     type->name = gen_name();
   }
       attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) );
     type->name = gen_name();
   }
+  else if (is_attr(attrs, ATTR_UUID) && !is_attr(attrs, ATTR_PUBLIC))
+    attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) );
 
 
-  LIST_FOR_EACH_ENTRY( pident, pidents, const pident_t, entry )
+  LIST_FOR_EACH_ENTRY( decl, decls, const declarator_t, entry )
   {
   {
-    var_t *name = pident->var;
+    var_t *name = decl->var;
 
     if (name->name) {
 
     if (name->name) {
-      type_t *cur = ptr;
-      int cptr = pident->ptr_level;
-      if (cptr > ptrc) {
-        while (cptr > ptrc) {
-          cur = ptr = make_type(pointer_default, cur);
-          ptrc++;
-        }
-      } else {
-        while (cptr < ptrc) {
-          cur = cur->ref;
-          cptr++;
-        }
-      }
-      if (pident->is_func) {
-        int func_ptr_level = pident->func_ptr_level;
-        cur = make_type(RPC_FC_FUNCTION, cur);
-        cur->fields_or_args = pident->args;
-        if (pident->callconv)
-          cur->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, pident->callconv));
-        else if (is_object_interface) {
-          static char *stdmethodcalltype;
-          if (!stdmethodcalltype) stdmethodcalltype = strdup("STDMETHODCALLTYPE");
-          cur->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, stdmethodcalltype));
-        }
-        for (; func_ptr_level > 0; func_ptr_level--)
-          cur = make_type(pointer_default, cur);
-      }
-      cur = alias(cur, name->name);
+      type_t *cur;
+
+      /* set the attributes to allow set_type to do some checks on them */
+      name->attrs = attrs;
+      set_type(name, decl_spec, decl, 0);
+      cur = alias(name->type, name->name);
       cur->attrs = attrs;
       cur->attrs = attrs;
-      if (ptr_type)
-      {
-        if (is_ptr(cur))
-          cur->type = ptr_type;
-        else
-          error_loc("'%s': pointer attribute applied to non-pointer type\n",
-                  cur->name);
-      }
-      else if (is_str && ! is_ptr(cur))
-        error_loc("'%s': [string] attribute applied to non-pointer type\n",
-                cur->name);
 
       if (is_incomplete(cur))
         add_incomplete(cur);
 
       if (is_incomplete(cur))
         add_incomplete(cur);
@@ -4779,7 +5213,7 @@ static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *a
   return type;
 }
 
   return type;
 }
 
-static type_t *find_type(const char *name, int t)
+type_t *find_type(const char *name, int t)
 {
   struct rtype *cur = type_hash[hash_ident(name)];
   while (cur && (cur->t != t || strcmp(cur->name, name)))
 {
   struct rtype *cur = type_hash[hash_ident(name)];
   while (cur && (cur->t != t || strcmp(cur->name, name)))
@@ -5020,7 +5454,7 @@ static var_t *reg_const(var_t *var)
   return var;
 }
 
   return var;
 }
 
-static var_t *find_const(char *name, int f)
+var_t *find_const(const char *name, int f)
 {
   struct rconst *cur = const_hash[hash_ident(name)];
   while (cur && strcmp(cur->name, name))
 {
   struct rconst *cur = const_hash[hash_ident(name)];
   while (cur && strcmp(cur->name, name))
@@ -5032,10 +5466,10 @@ static var_t *find_const(char *name, int f)
   return cur->var;
 }
 
   return cur->var;
 }
 
-static void write_libid(const char *name, const attr_list_t *attr)
+static void write_libid(const typelib_t *typelib)
 {
 {
-  const UUID *uuid = get_attrp(attr, ATTR_UUID);
-  write_guid(idfile, "LIBID", name, uuid);
+  const UUID *uuid = get_attrp(typelib->attrs, ATTR_UUID);
+  write_guid(idfile, "LIBID", typelib->name, uuid);
 }
 
 static void write_clsid(type_t *cls)
 }
 
 static void write_clsid(type_t *cls)
@@ -5101,26 +5535,6 @@ static char *gen_name(void)
   return name;
 }
 
   return name;
 }
 
-static void process_typedefs(pident_list_t *pidents)
-{
-  pident_t *pident, *next;
-
-  if (!pidents) return;
-  LIST_FOR_EACH_ENTRY_SAFE( pident, next, pidents, pident_t, entry )
-  {
-    var_t *var = pident->var;
-    type_t *type = find_type(var->name, 0);
-
-    if (! parse_only && do_header)
-      write_typedef(type);
-    if (in_typelib && type->attrs)
-      add_typelib_entry(type);
-
-    free(pident);
-    free(var);
-  }
-}
-
 struct allowed_attr
 {
     unsigned int dce_compatible : 1;
 struct allowed_attr
 {
     unsigned int dce_compatible : 1;
@@ -5147,22 +5561,21 @@ struct allowed_attr allowed_attr[] =
     /* ATTR_BINDABLE */         { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "bindable" },
     /* ATTR_BROADCAST */        { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "broadcast" },
     /* ATTR_CALLAS */           { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "call_as" },
     /* ATTR_BINDABLE */         { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "bindable" },
     /* ATTR_BROADCAST */        { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "broadcast" },
     /* ATTR_CALLAS */           { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "call_as" },
-    /* ATTR_CALLCONV */         { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
+    /* ATTR_CALLCONV */         { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, NULL },
     /* ATTR_CASE */             { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
     /* ATTR_CASE */             { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
+    /* ATTR_CONST */            { 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, "context_handle" },
     /* ATTR_CONTROL */          { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
     /* ATTR_DEFAULT */          { 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, "default" },
     /* ATTR_DEFAULTCOLLELEM */  { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" },
     /* ATTR_CONTEXTHANDLE */    { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "context_handle" },
     /* ATTR_CONTROL */          { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
     /* ATTR_DEFAULT */          { 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, "default" },
     /* ATTR_DEFAULTCOLLELEM */  { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" },
-    /* ATTR_DEFAULTVALUE_EXPR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "defaultvalue" },
-    /* ATTR_DEFAULTVALUE_STRING */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "defaultvalue" },
+    /* ATTR_DEFAULTVALUE */     { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "defaultvalue" },
     /* ATTR_DEFAULTVTABLE */    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "defaultvtable" },
     /* ATTR_DISPINTERFACE */    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
     /* ATTR_DISPLAYBIND */      { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "displaybind" },
     /* ATTR_DLLNAME */          { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "dllname" },
     /* ATTR_DUAL */             { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "dual" },
     /* ATTR_ENDPOINT */         { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" },
     /* ATTR_DEFAULTVTABLE */    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "defaultvtable" },
     /* ATTR_DISPINTERFACE */    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
     /* ATTR_DISPLAYBIND */      { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "displaybind" },
     /* ATTR_DLLNAME */          { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "dllname" },
     /* ATTR_DUAL */             { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "dual" },
     /* ATTR_ENDPOINT */         { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" },
-    /* ATTR_ENTRY_ORDINAL */    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "entry" },
-    /* ATTR_ENTRY_STRING */     { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "entry" },
+    /* ATTR_ENTRY */            { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "entry" },
     /* ATTR_EXPLICIT_HANDLE */  { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" },
     /* ATTR_HANDLE */           { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "handle" },
     /* ATTR_HELPCONTEXT */      { 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, "helpcontext" },
     /* ATTR_EXPLICIT_HANDLE */  { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" },
     /* ATTR_HANDLE */           { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "handle" },
     /* ATTR_HELPCONTEXT */      { 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, "helpcontext" },
@@ -5177,8 +5590,10 @@ struct allowed_attr allowed_attr[] =
     /* ATTR_IMMEDIATEBIND */    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
     /* ATTR_IMPLICIT_HANDLE */  { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
     /* ATTR_IN */               { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "in" },
     /* ATTR_IMMEDIATEBIND */    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
     /* ATTR_IMPLICIT_HANDLE */  { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
     /* ATTR_IN */               { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "in" },
+    /* ATTR_INLINE */           { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inline" },
     /* ATTR_INPUTSYNC */        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
     /* ATTR_LENGTHIS */         { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, "length_is" },
     /* ATTR_INPUTSYNC */        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
     /* ATTR_LENGTHIS */         { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, "length_is" },
+    /* ATTR_LIBLCID */          { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" },
     /* ATTR_LOCAL */            { 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, "local" },
     /* ATTR_NONBROWSABLE */     { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" },
     /* ATTR_NONCREATABLE */     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "noncreatable" },
     /* ATTR_LOCAL */            { 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, "local" },
     /* ATTR_NONBROWSABLE */     { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" },
     /* ATTR_NONCREATABLE */     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "noncreatable" },
@@ -5218,7 +5633,7 @@ const char *get_attr_display_name(enum attr_type type)
     return allowed_attr[type].display_name;
 }
 
     return allowed_attr[type].display_name;
 }
 
-static const attr_list_t *check_iface_attrs(const char *name, const attr_list_t *attrs)
+static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs)
 {
   const attr_t *attr;
   if (!attrs) return attrs;
 {
   const attr_t *attr;
   if (!attrs) return attrs;
@@ -5289,7 +5704,7 @@ static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs)
   return attrs;
 }
 
   return attrs;
 }
 
-static const attr_list_t *check_library_attrs(const char *name, const attr_list_t *attrs)
+static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs)
 {
   const attr_t *attr;
   if (!attrs) return attrs;
 {
   const attr_t *attr;
   if (!attrs) return attrs;
@@ -5315,7 +5730,7 @@ static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs)
   return attrs;
 }
 
   return attrs;
 }
 
-static const attr_list_t *check_module_attrs(const char *name, const attr_list_t *attrs)
+static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs)
 {
   const attr_t *attr;
   if (!attrs) return attrs;
 {
   const attr_t *attr;
   if (!attrs) return attrs;
@@ -5328,7 +5743,7 @@ static const attr_list_t *check_module_attrs(const char *name, const attr_list_t
   return attrs;
 }
 
   return attrs;
 }
 
-static const attr_list_t *check_coclass_attrs(const char *name, const attr_list_t *attrs)
+static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs)
 {
   const attr_t *attr;
   if (!attrs) return attrs;
 {
   const attr_t *attr;
   if (!attrs) return attrs;
@@ -5341,6 +5756,183 @@ static const attr_list_t *check_coclass_attrs(const char *name, const attr_list_
   return attrs;
 }
 
   return attrs;
 }
 
+static int is_allowed_conf_type(const type_t *type)
+{
+    switch (type->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_ENUM16:
+    case RPC_FC_USHORT:
+    case RPC_FC_LONG:
+    case RPC_FC_ENUM32:
+    case RPC_FC_ULONG:
+        return TRUE;
+    default:
+        return FALSE;
+    }
+}
+
+static int is_ptr_guid_type(const type_t *type)
+{
+    unsigned int align = 0;
+    for (;;)
+    {
+        if (type->kind == TKIND_ALIAS)
+            type = type->orig;
+        else if (is_ptr(type))
+        {
+            type = type->ref;
+            break;
+        }
+        else
+            return FALSE;
+    }
+    return (type_memsize(type, &align) == 16);
+}
+
+static void check_conformance_expr_list(const char *attr_name, const var_t *arg, const type_t *container_type, expr_list_t *expr_list)
+{
+    expr_t *dim;
+    struct expr_loc expr_loc;
+    expr_loc.v = arg;
+    expr_loc.attr = attr_name;
+    if (expr_list) LIST_FOR_EACH_ENTRY(dim, expr_list, expr_t, entry)
+    {
+        if (dim->type != EXPR_VOID)
+        {
+            const type_t *expr_type = expr_resolve_type(&expr_loc, container_type, dim);
+            if (!is_allowed_conf_type(expr_type))
+                error_loc_info(&arg->loc_info, "expression must resolve to integral type <= 32bits for attribute %s\n",
+                               attr_name);
+        }
+    }
+}
+
+static void check_remoting_fields(const var_t *var, type_t *type);
+
+/* checks that properties common to fields and arguments are consistent */
+static void check_field_common(const type_t *container_type,
+                               const char *container_name, const var_t *arg)
+{
+    type_t *type = arg->type;
+    int is_wire_marshal = 0;
+    int is_context_handle = 0;
+    const char *container_type_name = NULL;
+
+    if (is_struct(container_type->type))
+        container_type_name = "struct";
+    else if (is_union(container_type->type))
+        container_type_name = "union";
+    else if (container_type->type == RPC_FC_FUNCTION)
+        container_type_name = "function";
+
+    if (is_attr(arg->attrs, ATTR_LENGTHIS) &&
+        (is_attr(arg->attrs, ATTR_STRING) || is_aliaschain_attr(arg->type, ATTR_STRING)))
+        error_loc_info(&arg->loc_info,
+                       "string and length_is specified for argument %s are mutually exclusive attributes\n",
+                       arg->name);
+
+    if (is_attr(arg->attrs, ATTR_SIZEIS))
+    {
+        expr_list_t *size_is_exprs = get_attrp(arg->attrs, ATTR_SIZEIS);
+        check_conformance_expr_list("size_is", arg, container_type, size_is_exprs);
+    }
+    if (is_attr(arg->attrs, ATTR_LENGTHIS))
+    {
+        expr_list_t *length_is_exprs = get_attrp(arg->attrs, ATTR_LENGTHIS);
+        check_conformance_expr_list("length_is", arg, container_type, length_is_exprs);
+    }
+    if (is_attr(arg->attrs, ATTR_IIDIS))
+    {
+        struct expr_loc expr_loc;
+        expr_t *expr = get_attrp(arg->attrs, ATTR_IIDIS);
+        if (expr->type != EXPR_VOID)
+        {
+            const type_t *expr_type;
+            expr_loc.v = arg;
+            expr_loc.attr = "iid_is";
+            expr_type = expr_resolve_type(&expr_loc, container_type, expr);
+            if (!expr_type || !is_ptr_guid_type(expr_type))
+                error_loc_info(&arg->loc_info, "expression must resolve to pointer to GUID type for attribute iid_is\n");
+        }
+    }
+    if (is_attr(arg->attrs, ATTR_SWITCHIS))
+    {
+        struct expr_loc expr_loc;
+        expr_t *expr = get_attrp(arg->attrs, ATTR_SWITCHIS);
+        if (expr->type != EXPR_VOID)
+        {
+            const type_t *expr_type;
+            expr_loc.v = arg;
+            expr_loc.attr = "switch_is";
+            expr_type = expr_resolve_type(&expr_loc, container_type, expr);
+            if (!expr_type || !is_allowed_conf_type(expr_type))
+                error_loc_info(&arg->loc_info, "expression must resolve to integral type <= 32bits for attribute %s\n",
+                               expr_loc.attr);
+        }
+    }
+
+    /* get fundamental type for the argument */
+    for (;;)
+    {
+        if (is_attr(type->attrs, ATTR_WIREMARSHAL))
+        {
+            is_wire_marshal = 1;
+            break;
+        }
+        if (is_attr(type->attrs, ATTR_CONTEXTHANDLE))
+        {
+            is_context_handle = 1;
+            break;
+        }
+        if (type->kind == TKIND_ALIAS)
+            type = type->orig;
+        else if (is_ptr(type) || is_array(type))
+            type = type->ref;
+        else
+            break;
+    }
+
+    if (type->type == 0 && !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);
+    else if (type->type == RPC_FC_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);
+    else if (!is_wire_marshal && (is_struct(type->type) || is_union(type->type)))
+        check_remoting_fields(arg, type);
+}
+
+static void check_remoting_fields(const var_t *var, type_t *type)
+{
+    const var_t *field;
+    const var_list_t *fields = NULL;
+
+    if (type->checked)
+        return;
+
+    type->checked = TRUE;
+
+    if (is_struct(type->type))
+        fields = type->fields_or_args;
+    else if (is_union(type->type))
+    {
+        if (type->type == RPC_FC_ENCAPSULATED_UNION)
+        {
+            const var_t *uv = LIST_ENTRY(list_tail(type->fields_or_args), const var_t, entry);
+            fields = uv->type->fields_or_args;
+        }
+        else
+            fields = type->fields_or_args;
+    }
+
+    if (fields) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
+        if (field->type) check_field_common(type, type->name, field);
+}
+
 /* checks that arguments for a function make sense for marshalling and unmarshalling */
 static void check_remoting_args(const func_t *func)
 {
 /* checks that arguments for a function make sense for marshalling and unmarshalling */
 static void check_remoting_args(const func_t *func)
 {
@@ -5351,16 +5943,14 @@ static void check_remoting_args(const func_t *func)
     {
         int ptr_level = 0;
         const type_t *type = arg->type;
     {
         int ptr_level = 0;
         const type_t *type = arg->type;
-        int is_wire_marshal = 0;
-        int is_context_handle = 0;
 
         /* get pointer level and fundamental type for the argument */
         for (;;)
         {
 
         /* get pointer level and fundamental type for the argument */
         for (;;)
         {
-            if (!is_wire_marshal && is_attr(type->attrs, ATTR_WIREMARSHAL))
-                is_wire_marshal = 1;
-            if (!is_context_handle && is_attr(type->attrs, ATTR_CONTEXTHANDLE))
-                is_context_handle = 1;
+            if (is_attr(type->attrs, ATTR_WIREMARSHAL))
+                break;
+            if (is_attr(type->attrs, ATTR_CONTEXTHANDLE))
+                break;
             if (type->kind == TKIND_ALIAS)
                 type = type->orig;
             else if (is_ptr(type))
             if (type->kind == TKIND_ALIAS)
                 type = type->orig;
             else if (is_ptr(type))
@@ -5384,15 +5974,52 @@ static void check_remoting_args(const func_t *func)
             }
         }
 
             }
         }
 
-        if (type->type == 0 && !is_attr(arg->attrs, ATTR_IIDIS) && !is_wire_marshal && !is_context_handle)
-            error_loc_info(&arg->loc_info, "parameter \'%s\' of function \'%s\' cannot derive from void *\n", arg->name, funcname);
-        else if (type->type == RPC_FC_FUNCTION)
-            error_loc_info(&arg->loc_info, "parameter \'%s\' of function \'%s\' cannot be a function pointer\n", arg->name, funcname);
+        check_field_common(func->def->type, funcname, arg);
+    }
+}
+
+static void add_explicit_handle_if_necessary(func_t *func)
+{
+    const var_t* explicit_handle_var;
+    const var_t* explicit_generic_handle_var = NULL;
+    const var_t* context_handle_var = NULL;
+
+    /* check for a defined binding handle */
+    explicit_handle_var = get_explicit_handle_var(func);
+    if (!explicit_handle_var)
+    {
+        explicit_generic_handle_var = get_explicit_generic_handle_var(func);
+        if (!explicit_generic_handle_var)
+        {
+            context_handle_var = get_context_handle_var(func);
+            if (!context_handle_var)
+            {
+                /* no explicit handle specified so add
+                 * "[in] handle_t IDL_handle" as the first parameter to the
+                 * 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("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_init( func->def->type->fields_or_args );
+                }
+                list_add_head( func->def->type->fields_or_args, &idl_handle->entry );
+                func->args = func->def->type->fields_or_args;
+            }
+        }
     }
 }
 
 static void check_functions(const type_t *iface)
 {
     }
 }
 
 static void check_functions(const type_t *iface)
 {
+    if (is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE) && iface->funcs)
+    {
+        func_t *func;
+        LIST_FOR_EACH_ENTRY( func, iface->funcs, func_t, entry )
+            add_explicit_handle_if_necessary(func);
+    }
     if (!is_inside_library && !is_attr(iface->attrs, ATTR_LOCAL))
     {
         const func_t *func;
     if (!is_inside_library && !is_attr(iface->attrs, ATTR_LOCAL))
     {
         const func_t *func;
@@ -5404,16 +6031,21 @@ static void check_functions(const type_t *iface)
     }
 }
 
     }
 }
 
-static void check_all_user_types(ifref_list_t *ifrefs)
+static void check_all_user_types(const statement_list_t *stmts)
 {
 {
-  const ifref_t *ifref;
-  const func_t *f;
+  const statement_t *stmt;
 
 
-  if (ifrefs) LIST_FOR_EACH_ENTRY(ifref, ifrefs, const ifref_t, entry)
+  if (stmts) LIST_FOR_EACH_ENTRY(stmt, stmts, const statement_t, entry)
   {
   {
-    const func_list_t *fs = ifref->iface->funcs;
-    if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry)
-      check_for_additional_prototype_types(f->args);
+    if (stmt->type == STMT_LIBRARY)
+      check_all_user_types(stmt->u.lib->stmts);
+    else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
+    {
+      const func_t *f;
+      const func_list_t *fs = stmt->u.type->funcs;
+      if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry)
+        check_for_additional_prototype_types(f->args);
+    }
   }
 }
 
   }
 }
 
@@ -5434,3 +6066,135 @@ int is_valid_uuid(const char *s)
   return s[i] == '\0';
 }
 
   return s[i] == '\0';
 }
 
+static statement_t *make_statement(enum statement_type type)
+{
+    statement_t *stmt = xmalloc(sizeof(*stmt));
+    stmt->type = type;
+    return stmt;
+}
+
+static statement_t *make_statement_type_decl(type_t *type)
+{
+    statement_t *stmt = make_statement(STMT_TYPE);
+    stmt->u.type = type;
+    return stmt;
+}
+
+static statement_t *make_statement_reference(type_t *type)
+{
+    statement_t *stmt = make_statement(STMT_TYPEREF);
+    stmt->u.type = type;
+    return stmt;
+}
+
+static statement_t *make_statement_declaration(var_t *var)
+{
+    statement_t *stmt = make_statement(STMT_DECLARATION);
+    stmt->u.var = var;
+    if (var->stgclass == STG_EXTERN && var->eval)
+        warning("'%s' initialised and declared extern\n", var->name);
+    if (is_const_decl(var))
+    {
+        if (var->eval)
+            reg_const(var);
+    }
+    else if ((var->stgclass == STG_NONE || var->stgclass == STG_REGISTER) &&
+             var->type->type != RPC_FC_FUNCTION)
+        error_loc("instantiation of data is illegal\n");
+    return stmt;
+}
+
+static statement_t *make_statement_library(typelib_t *typelib)
+{
+    statement_t *stmt = make_statement(STMT_LIBRARY);
+    stmt->u.lib = typelib;
+    return stmt;
+}
+
+static statement_t *make_statement_cppquote(const char *str)
+{
+    statement_t *stmt = make_statement(STMT_CPPQUOTE);
+    stmt->u.str = str;
+    return stmt;
+}
+
+static statement_t *make_statement_importlib(const char *str)
+{
+    statement_t *stmt = make_statement(STMT_IMPORTLIB);
+    stmt->u.str = str;
+    return stmt;
+}
+
+static statement_t *make_statement_import(const char *str)
+{
+    statement_t *stmt = make_statement(STMT_IMPORT);
+    stmt->u.str = str;
+    return stmt;
+}
+
+static statement_t *make_statement_module(type_t *type)
+{
+    statement_t *stmt = make_statement(STMT_MODULE);
+    stmt->u.type = type;
+    return stmt;
+}
+
+static statement_t *process_typedefs(declarator_list_t *decls)
+{
+    declarator_t *decl, *next;
+    statement_t *stmt;
+    type_list_t **type_list;
+
+    if (!decls) return NULL;
+
+    stmt = make_statement(STMT_TYPEDEF);
+    stmt->u.type_list = NULL;
+    type_list = &stmt->u.type_list;
+
+    LIST_FOR_EACH_ENTRY_SAFE( decl, next, decls, declarator_t, entry )
+    {
+        var_t *var = decl->var;
+        type_t *type = find_type(var->name, 0);
+        *type_list = xmalloc(sizeof(type_list_t));
+        (*type_list)->type = type;
+        (*type_list)->next = NULL;
+
+        if (! parse_only && do_header)
+            write_typedef(type);
+        if (in_typelib && is_attr(type->attrs, ATTR_PUBLIC))
+            add_typelib_entry(type);
+
+        type_list = &(*type_list)->next;
+        free(decl);
+        free(var);
+    }
+
+    return stmt;
+}
+
+static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt)
+{
+    if (!stmt) return list;
+    if (!list)
+    {
+        list = xmalloc( sizeof(*list) );
+        list_init( list );
+    }
+    list_add_tail( list, &stmt->entry );
+    return list;
+}
+
+static func_list_t *append_func_from_statement(func_list_t *list, statement_t *stmt)
+{
+    if (stmt->type == STMT_DECLARATION)
+    {
+        var_t *var = stmt->u.var;
+        if (var->stgclass == STG_NONE && var->type->type == RPC_FC_FUNCTION)
+        {
+            check_function_attrs(var->name, var->type->attrs);
+            return append_func(list, make_func(stmt->u.var));
+        }
+    }
+    return list;
+}
+
index c0b5e9f..56a57a7 100644 (file)
      aHEXNUM = 261,
      aDOUBLE = 262,
      aSTRING = 263,
      aHEXNUM = 261,
      aDOUBLE = 262,
      aSTRING = 263,
-     aUUID = 264,
-     aEOF = 265,
-     SHL = 266,
-     SHR = 267,
-     tAGGREGATABLE = 268,
-     tALLOCATE = 269,
-     tAPPOBJECT = 270,
-     tASYNC = 271,
-     tASYNCUUID = 272,
-     tAUTOHANDLE = 273,
-     tBINDABLE = 274,
-     tBOOLEAN = 275,
-     tBROADCAST = 276,
-     tBYTE = 277,
-     tBYTECOUNT = 278,
-     tCALLAS = 279,
-     tCALLBACK = 280,
-     tCASE = 281,
-     tCDECL = 282,
-     tCHAR = 283,
-     tCOCLASS = 284,
-     tCODE = 285,
-     tCOMMSTATUS = 286,
-     tCONST = 287,
-     tCONTEXTHANDLE = 288,
-     tCONTEXTHANDLENOSERIALIZE = 289,
-     tCONTEXTHANDLESERIALIZE = 290,
-     tCONTROL = 291,
-     tCPPQUOTE = 292,
-     tDEFAULT = 293,
-     tDEFAULTCOLLELEM = 294,
-     tDEFAULTVALUE = 295,
-     tDEFAULTVTABLE = 296,
-     tDISPLAYBIND = 297,
-     tDISPINTERFACE = 298,
-     tDLLNAME = 299,
-     tDOUBLE = 300,
-     tDUAL = 301,
-     tENDPOINT = 302,
-     tENTRY = 303,
-     tENUM = 304,
-     tERRORSTATUST = 305,
-     tEXPLICITHANDLE = 306,
-     tEXTERN = 307,
-     tFALSE = 308,
-     tFASTCALL = 309,
-     tFLOAT = 310,
-     tHANDLE = 311,
-     tHANDLET = 312,
-     tHELPCONTEXT = 313,
-     tHELPFILE = 314,
-     tHELPSTRING = 315,
-     tHELPSTRINGCONTEXT = 316,
-     tHELPSTRINGDLL = 317,
-     tHIDDEN = 318,
-     tHYPER = 319,
-     tID = 320,
-     tIDEMPOTENT = 321,
-     tIIDIS = 322,
-     tIMMEDIATEBIND = 323,
-     tIMPLICITHANDLE = 324,
-     tIMPORT = 325,
-     tIMPORTLIB = 326,
-     tIN = 327,
-     tINLINE = 328,
-     tINPUTSYNC = 329,
-     tINT = 330,
-     tINT64 = 331,
-     tINTERFACE = 332,
-     tLCID = 333,
-     tLENGTHIS = 334,
-     tLIBRARY = 335,
-     tLOCAL = 336,
-     tLONG = 337,
-     tMETHODS = 338,
-     tMODULE = 339,
-     tNONBROWSABLE = 340,
-     tNONCREATABLE = 341,
-     tNONEXTENSIBLE = 342,
-     tOBJECT = 343,
-     tODL = 344,
-     tOLEAUTOMATION = 345,
-     tOPTIONAL = 346,
-     tOUT = 347,
-     tPASCAL = 348,
-     tPOINTERDEFAULT = 349,
-     tPROPERTIES = 350,
-     tPROPGET = 351,
-     tPROPPUT = 352,
-     tPROPPUTREF = 353,
-     tPTR = 354,
-     tPUBLIC = 355,
-     tRANGE = 356,
-     tREADONLY = 357,
-     tREF = 358,
-     tREQUESTEDIT = 359,
-     tRESTRICTED = 360,
-     tRETVAL = 361,
-     tSAFEARRAY = 362,
-     tSHORT = 363,
-     tSIGNED = 364,
-     tSINGLE = 365,
-     tSIZEIS = 366,
-     tSIZEOF = 367,
-     tSMALL = 368,
-     tSOURCE = 369,
-     tSTDCALL = 370,
-     tSTRICTCONTEXTHANDLE = 371,
-     tSTRING = 372,
-     tSTRUCT = 373,
-     tSWITCH = 374,
-     tSWITCHIS = 375,
-     tSWITCHTYPE = 376,
-     tTRANSMITAS = 377,
-     tTRUE = 378,
-     tTYPEDEF = 379,
-     tUNION = 380,
-     tUNIQUE = 381,
-     tUNSIGNED = 382,
-     tUUID = 383,
-     tV1ENUM = 384,
-     tVARARG = 385,
-     tVERSION = 386,
-     tVOID = 387,
-     tWCHAR = 388,
-     tWIREMARSHAL = 389,
-     CAST = 390,
-     PPTR = 391,
-     NEG = 392,
-     ADDRESSOF = 393
+     aWSTRING = 264,
+     aUUID = 265,
+     aEOF = 266,
+     SHL = 267,
+     SHR = 268,
+     MEMBERPTR = 269,
+     EQUALITY = 270,
+     INEQUALITY = 271,
+     GREATEREQUAL = 272,
+     LESSEQUAL = 273,
+     LOGICALOR = 274,
+     LOGICALAND = 275,
+     tAGGREGATABLE = 276,
+     tALLOCATE = 277,
+     tAPPOBJECT = 278,
+     tASYNC = 279,
+     tASYNCUUID = 280,
+     tAUTOHANDLE = 281,
+     tBINDABLE = 282,
+     tBOOLEAN = 283,
+     tBROADCAST = 284,
+     tBYTE = 285,
+     tBYTECOUNT = 286,
+     tCALLAS = 287,
+     tCALLBACK = 288,
+     tCASE = 289,
+     tCDECL = 290,
+     tCHAR = 291,
+     tCOCLASS = 292,
+     tCODE = 293,
+     tCOMMSTATUS = 294,
+     tCONST = 295,
+     tCONTEXTHANDLE = 296,
+     tCONTEXTHANDLENOSERIALIZE = 297,
+     tCONTEXTHANDLESERIALIZE = 298,
+     tCONTROL = 299,
+     tCPPQUOTE = 300,
+     tDEFAULT = 301,
+     tDEFAULTCOLLELEM = 302,
+     tDEFAULTVALUE = 303,
+     tDEFAULTVTABLE = 304,
+     tDISPLAYBIND = 305,
+     tDISPINTERFACE = 306,
+     tDLLNAME = 307,
+     tDOUBLE = 308,
+     tDUAL = 309,
+     tENDPOINT = 310,
+     tENTRY = 311,
+     tENUM = 312,
+     tERRORSTATUST = 313,
+     tEXPLICITHANDLE = 314,
+     tEXTERN = 315,
+     tFALSE = 316,
+     tFASTCALL = 317,
+     tFLOAT = 318,
+     tHANDLE = 319,
+     tHANDLET = 320,
+     tHELPCONTEXT = 321,
+     tHELPFILE = 322,
+     tHELPSTRING = 323,
+     tHELPSTRINGCONTEXT = 324,
+     tHELPSTRINGDLL = 325,
+     tHIDDEN = 326,
+     tHYPER = 327,
+     tID = 328,
+     tIDEMPOTENT = 329,
+     tIIDIS = 330,
+     tIMMEDIATEBIND = 331,
+     tIMPLICITHANDLE = 332,
+     tIMPORT = 333,
+     tIMPORTLIB = 334,
+     tIN = 335,
+     tIN_LINE = 336,
+     tINLINE = 337,
+     tINPUTSYNC = 338,
+     tINT = 339,
+     tINT64 = 340,
+     tINTERFACE = 341,
+     tLCID = 342,
+     tLENGTHIS = 343,
+     tLIBRARY = 344,
+     tLOCAL = 345,
+     tLONG = 346,
+     tMETHODS = 347,
+     tMODULE = 348,
+     tNONBROWSABLE = 349,
+     tNONCREATABLE = 350,
+     tNONEXTENSIBLE = 351,
+     tNULL = 352,
+     tOBJECT = 353,
+     tODL = 354,
+     tOLEAUTOMATION = 355,
+     tOPTIONAL = 356,
+     tOUT = 357,
+     tPASCAL = 358,
+     tPOINTERDEFAULT = 359,
+     tPROPERTIES = 360,
+     tPROPGET = 361,
+     tPROPPUT = 362,
+     tPROPPUTREF = 363,
+     tPTR = 364,
+     tPUBLIC = 365,
+     tRANGE = 366,
+     tREADONLY = 367,
+     tREF = 368,
+     tREGISTER = 369,
+     tREQUESTEDIT = 370,
+     tRESTRICTED = 371,
+     tRETVAL = 372,
+     tSAFEARRAY = 373,
+     tSHORT = 374,
+     tSIGNED = 375,
+     tSINGLE = 376,
+     tSIZEIS = 377,
+     tSIZEOF = 378,
+     tSMALL = 379,
+     tSOURCE = 380,
+     tSTATIC = 381,
+     tSTDCALL = 382,
+     tSTRICTCONTEXTHANDLE = 383,
+     tSTRING = 384,
+     tSTRUCT = 385,
+     tSWITCH = 386,
+     tSWITCHIS = 387,
+     tSWITCHTYPE = 388,
+     tTRANSMITAS = 389,
+     tTRUE = 390,
+     tTYPEDEF = 391,
+     tUNION = 392,
+     tUNIQUE = 393,
+     tUNSIGNED = 394,
+     tUUID = 395,
+     tV1ENUM = 396,
+     tVARARG = 397,
+     tVERSION = 398,
+     tVOID = 399,
+     tWCHAR = 400,
+     tWIREMARSHAL = 401,
+     ADDRESSOF = 402,
+     NEG = 403,
+     POS = 404,
+     PPTR = 405,
+     CAST = 406
    };
 #endif
 /* Tokens.  */
    };
 #endif
 /* Tokens.  */
 #define aHEXNUM 261
 #define aDOUBLE 262
 #define aSTRING 263
 #define aHEXNUM 261
 #define aDOUBLE 262
 #define aSTRING 263
-#define aUUID 264
-#define aEOF 265
-#define SHL 266
-#define SHR 267
-#define tAGGREGATABLE 268
-#define tALLOCATE 269
-#define tAPPOBJECT 270
-#define tASYNC 271
-#define tASYNCUUID 272
-#define tAUTOHANDLE 273
-#define tBINDABLE 274
-#define tBOOLEAN 275
-#define tBROADCAST 276
-#define tBYTE 277
-#define tBYTECOUNT 278
-#define tCALLAS 279
-#define tCALLBACK 280
-#define tCASE 281
-#define tCDECL 282
-#define tCHAR 283
-#define tCOCLASS 284
-#define tCODE 285
-#define tCOMMSTATUS 286
-#define tCONST 287
-#define tCONTEXTHANDLE 288
-#define tCONTEXTHANDLENOSERIALIZE 289
-#define tCONTEXTHANDLESERIALIZE 290
-#define tCONTROL 291
-#define tCPPQUOTE 292
-#define tDEFAULT 293
-#define tDEFAULTCOLLELEM 294
-#define tDEFAULTVALUE 295
-#define tDEFAULTVTABLE 296
-#define tDISPLAYBIND 297
-#define tDISPINTERFACE 298
-#define tDLLNAME 299
-#define tDOUBLE 300
-#define tDUAL 301
-#define tENDPOINT 302
-#define tENTRY 303
-#define tENUM 304
-#define tERRORSTATUST 305
-#define tEXPLICITHANDLE 306
-#define tEXTERN 307
-#define tFALSE 308
-#define tFASTCALL 309
-#define tFLOAT 310
-#define tHANDLE 311
-#define tHANDLET 312
-#define tHELPCONTEXT 313
-#define tHELPFILE 314
-#define tHELPSTRING 315
-#define tHELPSTRINGCONTEXT 316
-#define tHELPSTRINGDLL 317
-#define tHIDDEN 318
-#define tHYPER 319
-#define tID 320
-#define tIDEMPOTENT 321
-#define tIIDIS 322
-#define tIMMEDIATEBIND 323
-#define tIMPLICITHANDLE 324
-#define tIMPORT 325
-#define tIMPORTLIB 326
-#define tIN 327
-#define tINLINE 328
-#define tINPUTSYNC 329
-#define tINT 330
-#define tINT64 331
-#define tINTERFACE 332
-#define tLCID 333
-#define tLENGTHIS 334
-#define tLIBRARY 335
-#define tLOCAL 336
-#define tLONG 337
-#define tMETHODS 338
-#define tMODULE 339
-#define tNONBROWSABLE 340
-#define tNONCREATABLE 341
-#define tNONEXTENSIBLE 342
-#define tOBJECT 343
-#define tODL 344
-#define tOLEAUTOMATION 345
-#define tOPTIONAL 346
-#define tOUT 347
-#define tPASCAL 348
-#define tPOINTERDEFAULT 349
-#define tPROPERTIES 350
-#define tPROPGET 351
-#define tPROPPUT 352
-#define tPROPPUTREF 353
-#define tPTR 354
-#define tPUBLIC 355
-#define tRANGE 356
-#define tREADONLY 357
-#define tREF 358
-#define tREQUESTEDIT 359
-#define tRESTRICTED 360
-#define tRETVAL 361
-#define tSAFEARRAY 362
-#define tSHORT 363
-#define tSIGNED 364
-#define tSINGLE 365
-#define tSIZEIS 366
-#define tSIZEOF 367
-#define tSMALL 368
-#define tSOURCE 369
-#define tSTDCALL 370
-#define tSTRICTCONTEXTHANDLE 371
-#define tSTRING 372
-#define tSTRUCT 373
-#define tSWITCH 374
-#define tSWITCHIS 375
-#define tSWITCHTYPE 376
-#define tTRANSMITAS 377
-#define tTRUE 378
-#define tTYPEDEF 379
-#define tUNION 380
-#define tUNIQUE 381
-#define tUNSIGNED 382
-#define tUUID 383
-#define tV1ENUM 384
-#define tVARARG 385
-#define tVERSION 386
-#define tVOID 387
-#define tWCHAR 388
-#define tWIREMARSHAL 389
-#define CAST 390
-#define PPTR 391
-#define NEG 392
-#define ADDRESSOF 393
+#define aWSTRING 264
+#define aUUID 265
+#define aEOF 266
+#define SHL 267
+#define SHR 268
+#define MEMBERPTR 269
+#define EQUALITY 270
+#define INEQUALITY 271
+#define GREATEREQUAL 272
+#define LESSEQUAL 273
+#define LOGICALOR 274
+#define LOGICALAND 275
+#define tAGGREGATABLE 276
+#define tALLOCATE 277
+#define tAPPOBJECT 278
+#define tASYNC 279
+#define tASYNCUUID 280
+#define tAUTOHANDLE 281
+#define tBINDABLE 282
+#define tBOOLEAN 283
+#define tBROADCAST 284
+#define tBYTE 285
+#define tBYTECOUNT 286
+#define tCALLAS 287
+#define tCALLBACK 288
+#define tCASE 289
+#define tCDECL 290
+#define tCHAR 291
+#define tCOCLASS 292
+#define tCODE 293
+#define tCOMMSTATUS 294
+#define tCONST 295
+#define tCONTEXTHANDLE 296
+#define tCONTEXTHANDLENOSERIALIZE 297
+#define tCONTEXTHANDLESERIALIZE 298
+#define tCONTROL 299
+#define tCPPQUOTE 300
+#define tDEFAULT 301
+#define tDEFAULTCOLLELEM 302
+#define tDEFAULTVALUE 303
+#define tDEFAULTVTABLE 304
+#define tDISPLAYBIND 305
+#define tDISPINTERFACE 306
+#define tDLLNAME 307
+#define tDOUBLE 308
+#define tDUAL 309
+#define tENDPOINT 310
+#define tENTRY 311
+#define tENUM 312
+#define tERRORSTATUST 313
+#define tEXPLICITHANDLE 314
+#define tEXTERN 315
+#define tFALSE 316
+#define tFASTCALL 317
+#define tFLOAT 318
+#define tHANDLE 319
+#define tHANDLET 320
+#define tHELPCONTEXT 321
+#define tHELPFILE 322
+#define tHELPSTRING 323
+#define tHELPSTRINGCONTEXT 324
+#define tHELPSTRINGDLL 325
+#define tHIDDEN 326
+#define tHYPER 327
+#define tID 328
+#define tIDEMPOTENT 329
+#define tIIDIS 330
+#define tIMMEDIATEBIND 331
+#define tIMPLICITHANDLE 332
+#define tIMPORT 333
+#define tIMPORTLIB 334
+#define tIN 335
+#define tIN_LINE 336
+#define tINLINE 337
+#define tINPUTSYNC 338
+#define tINT 339
+#define tINT64 340
+#define tINTERFACE 341
+#define tLCID 342
+#define tLENGTHIS 343
+#define tLIBRARY 344
+#define tLOCAL 345
+#define tLONG 346
+#define tMETHODS 347
+#define tMODULE 348
+#define tNONBROWSABLE 349
+#define tNONCREATABLE 350
+#define tNONEXTENSIBLE 351
+#define tNULL 352
+#define tOBJECT 353
+#define tODL 354
+#define tOLEAUTOMATION 355
+#define tOPTIONAL 356
+#define tOUT 357
+#define tPASCAL 358
+#define tPOINTERDEFAULT 359
+#define tPROPERTIES 360
+#define tPROPGET 361
+#define tPROPPUT 362
+#define tPROPPUTREF 363
+#define tPTR 364
+#define tPUBLIC 365
+#define tRANGE 366
+#define tREADONLY 367
+#define tREF 368
+#define tREGISTER 369
+#define tREQUESTEDIT 370
+#define tRESTRICTED 371
+#define tRETVAL 372
+#define tSAFEARRAY 373
+#define tSHORT 374
+#define tSIGNED 375
+#define tSINGLE 376
+#define tSIZEIS 377
+#define tSIZEOF 378
+#define tSMALL 379
+#define tSOURCE 380
+#define tSTATIC 381
+#define tSTDCALL 382
+#define tSTRICTCONTEXTHANDLE 383
+#define tSTRING 384
+#define tSTRUCT 385
+#define tSWITCH 386
+#define tSWITCHIS 387
+#define tSWITCHTYPE 388
+#define tTRANSMITAS 389
+#define tTRUE 390
+#define tTYPEDEF 391
+#define tUNION 392
+#define tUNIQUE 393
+#define tUNSIGNED 394
+#define tUUID 395
+#define tV1ENUM 396
+#define tVARARG 397
+#define tVERSION 398
+#define tVOID 399
+#define tWCHAR 400
+#define tWIREMARSHAL 401
+#define ADDRESSOF 402
+#define NEG 403
+#define POS 404
+#define PPTR 405
+#define CAST 406
 
 
 
 
 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
 
 
 
 
 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
-#line 151 "parser.y"
+#line 177 "parser.y"
 typedef union YYSTYPE {
        attr_t *attr;
        attr_list_t *attr_list;
 typedef union YYSTYPE {
        attr_t *attr;
        attr_list_t *attr_list;
@@ -320,10 +346,12 @@ typedef union YYSTYPE {
        type_t *type;
        var_t *var;
        var_list_t *var_list;
        type_t *type;
        var_t *var;
        var_list_t *var_list;
-       pident_t *pident;
-       pident_list_t *pident_list;
+       declarator_t *declarator;
+       declarator_list_t *declarator_list;
        func_t *func;
        func_list_t *func_list;
        func_t *func;
        func_list_t *func_list;
+       statement_t *statement;
+       statement_list_t *stmt_list;
        ifref_t *ifref;
        ifref_list_t *ifref_list;
        char *str;
        ifref_t *ifref;
        ifref_list_t *ifref_list;
        char *str;
@@ -331,9 +359,13 @@ typedef union YYSTYPE {
        unsigned int num;
        double dbl;
        interface_info_t ifinfo;
        unsigned int num;
        double dbl;
        interface_info_t ifinfo;
+       typelib_t *typelib;
+       struct _import_t *import;
+       struct _decl_spec_t *declspec;
+       enum storage_class stgclass;
 } YYSTYPE;
 /* Line 1447 of yacc.c.  */
 } YYSTYPE;
 /* Line 1447 of yacc.c.  */
-#line 337 "parser.tab.h"
+#line 369 "parser.tab.h"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
index 5d00305..fff0adc 100644 (file)
@@ -3,6 +3,7 @@
  * IDL Compiler
  *
  * Copyright 2002 Ove Kaaven
  * IDL Compiler
  *
  * Copyright 2002 Ove Kaaven
+ * Copyright 2006-2008 Robert Shearman
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -37,6 +38,7 @@
 #include "header.h"
 #include "typelib.h"
 #include "typegen.h"
 #include "header.h"
 #include "typelib.h"
 #include "typegen.h"
+#include "expr.h"
 
 #if defined(YYBYACC)
        /* Berkeley yacc (byacc) doesn't seem to know about these */
 
 #if defined(YYBYACC)
        /* Berkeley yacc (byacc) doesn't seem to know about these */
@@ -66,6 +68,7 @@
 #define YYERROR_VERBOSE
 
 unsigned char pointer_default = RPC_FC_UP;
 #define YYERROR_VERBOSE
 
 unsigned char pointer_default = RPC_FC_UP;
+static int is_in_interface = FALSE;
 static int is_object_interface = FALSE;
 /* are we inside a library block? */
 static int is_inside_library = FALSE;
 static int is_object_interface = FALSE;
 /* are we inside a library block? */
 static int is_inside_library = FALSE;
@@ -76,6 +79,19 @@ struct typenode {
   struct list entry;
 };
 
   struct list entry;
 };
 
+struct _import_t
+{
+  char *name;
+  int import_performed;
+};
+
+typedef struct _decl_spec_t
+{
+  type_t *type;
+  attr_list_t *attrs;
+  enum storage_class stgclass;
+} decl_spec_t;
+
 typelist_t incomplete_types = LIST_INIT(incomplete_types);
 
 static void add_incomplete(type_t *t);
 typelist_t incomplete_types = LIST_INIT(incomplete_types);
 
 static void add_incomplete(type_t *t);
@@ -83,65 +99,75 @@ static void fix_incomplete(void);
 
 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 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_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 attr_t *make_attr(enum attr_type type);
 static attr_t *make_attrv(enum attr_type type, unsigned long val);
 static attr_t *make_attrp(enum attr_type type, void *val);
 static attr_t *make_attr(enum attr_type type);
 static attr_t *make_attrv(enum attr_type type, unsigned long val);
 static attr_t *make_attrp(enum attr_type type, void *val);
-static expr_t *make_expr(enum expr_type type);
-static expr_t *make_exprl(enum expr_type type, long val);
-static expr_t *make_exprd(enum expr_type type, double val);
-static expr_t *make_exprs(enum expr_type type, char *val);
-static expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr);
-static expr_t *make_expr1(enum expr_type type, expr_t *expr);
-static expr_t *make_expr2(enum expr_type type, expr_t *exp1, expr_t *exp2);
-static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3);
-static type_t *make_type(unsigned char type, type_t *ref);
 static expr_list_t *append_expr(expr_list_t *list, expr_t *expr);
 static array_dims_t *append_array(array_dims_t *list, expr_t *expr);
 static expr_list_t *append_expr(expr_list_t *list, expr_t *expr);
 static array_dims_t *append_array(array_dims_t *list, expr_t *expr);
-static void set_type(var_t *v, type_t *type, const pident_t *pident, array_dims_t *arr, int top);
+static void set_type(var_t *v, 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 ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface);
 static ifref_t *make_ifref(type_t *iface);
 static var_list_t *append_var(var_list_t *list, var_t *var);
 static ifref_list_t *append_ifref(ifref_list_t *list, ifref_t *iface);
 static ifref_t *make_ifref(type_t *iface);
 static var_list_t *append_var(var_list_t *list, var_t *var);
+static var_list_t *append_var_list(var_list_t *list, var_list_t *vars);
 static var_t *make_var(char *name);
 static var_t *make_var(char *name);
-static pident_list_t *append_pident(pident_list_t *list, pident_t *p);
-static pident_t *make_pident(var_t *var);
+static declarator_list_t *append_declarator(declarator_list_t *list, declarator_t *p);
+static declarator_t *make_declarator(var_t *var);
 static func_list_t *append_func(func_list_t *list, func_t *func);
 static func_list_t *append_func(func_list_t *list, func_t *func);
-static func_t *make_func(var_t *def, var_list_t *args);
+static func_t *make_func(var_t *def);
 static type_t *make_class(char *name);
 static type_t *make_safearray(type_t *type);
 static type_t *make_builtin(char *name);
 static type_t *make_int(int sign);
 static type_t *make_class(char *name);
 static type_t *make_safearray(type_t *type);
 static type_t *make_builtin(char *name);
 static type_t *make_int(int sign);
+static typelib_t *make_library(const char *name, const attr_list_t *attrs);
+static type_t *make_func_type(var_list_t *args);
+static type_t *make_pointer_type(type_t *ref, attr_list_t *attrs);
+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_type(type_t *type, const char *name, int t);
-static type_t *reg_typedefs(type_t *type, var_list_t *names, attr_list_t *attrs);
-static type_t *find_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_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 var_t *reg_const(var_t *var);
 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 var_t *reg_const(var_t *var);
-static var_t *find_const(char *name, int f);
 
 
-static void write_libid(const char *name, const attr_list_t *attr);
+static void write_libid(const typelib_t *typelib);
 static void write_clsid(type_t *cls);
 static void write_diid(type_t *iface);
 static void write_iid(type_t *iface);
 
 static int compute_method_indexes(type_t *iface);
 static char *gen_name(void);
 static void write_clsid(type_t *cls);
 static void write_diid(type_t *iface);
 static void write_iid(type_t *iface);
 
 static int compute_method_indexes(type_t *iface);
 static char *gen_name(void);
-static void process_typedefs(var_list_t *names);
+static statement_t *process_typedefs(var_list_t *names);
 static void check_arg(var_t *arg);
 static void check_functions(const type_t *iface);
 static void check_arg(var_t *arg);
 static void check_functions(const type_t *iface);
-static void check_all_user_types(ifref_list_t *ifaces);
-static const attr_list_t *check_iface_attrs(const char *name, const attr_list_t *attrs);
+static void check_all_user_types(const statement_list_t *stmts);
+static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs);
 static attr_list_t *check_function_attrs(const char *name, attr_list_t *attrs);
 static attr_list_t *check_typedef_attrs(attr_list_t *attrs);
 static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs);
 static attr_list_t *check_function_attrs(const char *name, attr_list_t *attrs);
 static attr_list_t *check_typedef_attrs(attr_list_t *attrs);
 static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs);
-static const attr_list_t *check_library_attrs(const char *name, const attr_list_t *attrs);
+static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs);
 static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs);
 static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs);
-static const attr_list_t *check_module_attrs(const char *name, const attr_list_t *attrs);
-static const attr_list_t *check_coclass_attrs(const char *name, const attr_list_t *attrs);
+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);
 const char *get_attr_display_name(enum attr_type type);
+static void add_explicit_handle_if_necessary(func_t *func);
+
+static statement_t *make_statement(enum statement_type type);
+static statement_t *make_statement_type_decl(type_t *type);
+static statement_t *make_statement_reference(type_t *type);
+static statement_t *make_statement_declaration(var_t *var);
+static statement_t *make_statement_library(typelib_t *typelib);
+static statement_t *make_statement_cppquote(const char *str);
+static statement_t *make_statement_importlib(const char *str);
+static statement_t *make_statement_module(type_t *type);
+static statement_t *make_statement_import(const char *str);
+static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt);
+static func_list_t *append_func_from_statement(func_list_t *list, statement_t *stmt);
 
 #define tsENUM   1
 #define tsSTRUCT 2
 
 #define tsENUM   1
 #define tsSTRUCT 2
@@ -158,10 +184,12 @@ const char *get_attr_display_name(enum attr_type type);
        type_t *type;
        var_t *var;
        var_list_t *var_list;
        type_t *type;
        var_t *var;
        var_list_t *var_list;
-       pident_t *pident;
-       pident_list_t *pident_list;
+       declarator_t *declarator;
+       declarator_list_t *declarator_list;
        func_t *func;
        func_list_t *func_list;
        func_t *func;
        func_list_t *func_list;
+       statement_t *statement;
+       statement_list_t *stmt_list;
        ifref_t *ifref;
        ifref_list_t *ifref_list;
        char *str;
        ifref_t *ifref;
        ifref_list_t *ifref_list;
        char *str;
@@ -169,16 +197,24 @@ const char *get_attr_display_name(enum attr_type type);
        unsigned int num;
        double dbl;
        interface_info_t ifinfo;
        unsigned int num;
        double dbl;
        interface_info_t ifinfo;
+       typelib_t *typelib;
+       struct _import_t *import;
+       struct _decl_spec_t *declspec;
+       enum storage_class stgclass;
 }
 
 %token <str> aIDENTIFIER
 %token <str> aKNOWNTYPE
 %token <num> aNUM aHEXNUM
 %token <dbl> aDOUBLE
 }
 
 %token <str> aIDENTIFIER
 %token <str> aKNOWNTYPE
 %token <num> aNUM aHEXNUM
 %token <dbl> aDOUBLE
-%token <str> aSTRING
+%token <str> aSTRING aWSTRING
 %token <uuid> aUUID
 %token aEOF
 %token SHL SHR
 %token <uuid> aUUID
 %token aEOF
 %token SHL SHR
+%token MEMBERPTR
+%token EQUALITY INEQUALITY
+%token GREATEREQUAL LESSEQUAL
+%token LOGICALOR LOGICALAND
 %token tAGGREGATABLE tALLOCATE tAPPOBJECT tASYNC tASYNCUUID
 %token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT
 %token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS
 %token tAGGREGATABLE tALLOCATE tAPPOBJECT tASYNC tASYNCUUID
 %token tAUTOHANDLE tBINDABLE tBOOLEAN tBROADCAST tBYTE tBYTECOUNT
 %token tCALLAS tCALLBACK tCASE tCDECL tCHAR tCOCLASS tCODE tCOMMSTATUS
@@ -207,7 +243,7 @@ const char *get_attr_display_name(enum attr_type type);
 %token tIMMEDIATEBIND
 %token tIMPLICITHANDLE
 %token tIMPORT tIMPORTLIB
 %token tIMMEDIATEBIND
 %token tIMPLICITHANDLE
 %token tIMPORT tIMPORTLIB
-%token tIN tINLINE
+%token tIN tIN_LINE tINLINE
 %token tINPUTSYNC
 %token tINT tINT64
 %token tINTERFACE
 %token tINPUTSYNC
 %token tINT tINT64
 %token tINTERFACE
@@ -220,6 +256,7 @@ const char *get_attr_display_name(enum attr_type type);
 %token tNONBROWSABLE
 %token tNONCREATABLE
 %token tNONEXTENSIBLE
 %token tNONBROWSABLE
 %token tNONCREATABLE
 %token tNONEXTENSIBLE
+%token tNULL
 %token tOBJECT tODL tOLEAUTOMATION
 %token tOPTIONAL
 %token tOUT
 %token tOBJECT tODL tOLEAUTOMATION
 %token tOPTIONAL
 %token tOUT
@@ -231,6 +268,7 @@ const char *get_attr_display_name(enum attr_type type);
 %token tPUBLIC
 %token tRANGE
 %token tREADONLY tREF
 %token tPUBLIC
 %token tRANGE
 %token tREADONLY tREF
+%token tREGISTER
 %token tREQUESTEDIT
 %token tRESTRICTED
 %token tRETVAL
 %token tREQUESTEDIT
 %token tRESTRICTED
 %token tRETVAL
@@ -241,6 +279,7 @@ const char *get_attr_display_name(enum attr_type type);
 %token tSIZEIS tSIZEOF
 %token tSMALL
 %token tSOURCE
 %token tSIZEIS tSIZEOF
 %token tSMALL
 %token tSOURCE
+%token tSTATIC
 %token tSTDCALL
 %token tSTRICTCONTEXTHANDLE
 %token tSTRING tSTRUCT
 %token tSTDCALL
 %token tSTRICTCONTEXTHANDLE
 %token tSTRING tSTRUCT
@@ -258,13 +297,14 @@ const char *get_attr_display_name(enum attr_type type);
 %token tVOID
 %token tWCHAR tWIREMARSHAL
 
 %token tVOID
 %token tWCHAR tWIREMARSHAL
 
-%type <attr> attribute
-%type <attr_list> m_attributes attributes attrib_list
+%type <attr> attribute type_qualifier function_specifier
+%type <attr_list> m_attributes attributes attrib_list m_type_qual_list
 %type <str_list> str_list
 %type <str_list> str_list
-%type <expr> m_expr expr expr_const
-%type <expr_list> m_exprs /* exprs expr_list */ expr_list_const
-%type <array_dims> array array_list
+%type <expr> m_expr expr expr_const expr_int_const array
+%type <expr_list> m_exprs /* exprs expr_list */ expr_list_int_const
 %type <ifinfo> interfacehdr
 %type <ifinfo> interfacehdr
+%type <stgclass> storage_cls_spec
+%type <declspec> decl_spec decl_spec_no_type m_decl_spec_no_type
 %type <type> inherit interface interfacedef interfacedec
 %type <type> dispinterface dispinterfacehdr dispinterfacedef
 %type <type> module modulehdr moduledef
 %type <type> inherit interface interfacedef interfacedec
 %type <type> dispinterface dispinterfacehdr dispinterfacedef
 %type <type> module modulehdr moduledef
@@ -272,32 +312,37 @@ const char *get_attr_display_name(enum attr_type type);
 %type <type> enumdef structdef uniondef
 %type <type> type
 %type <ifref> coclass_int
 %type <type> enumdef structdef uniondef
 %type <type> type
 %type <ifref> coclass_int
-%type <ifref_list> gbl_statements coclass_ints
-%type <var> arg field s_field case enum constdef externdef
-%type <var_list> m_args no_args args fields cases enums enum_list dispint_props
+%type <ifref_list> coclass_ints
+%type <var> arg ne_union_field union_field s_field case enum declaration
+%type <var_list> m_args no_args args fields ne_union_fields cases enums enum_list dispint_props field
 %type <var> m_ident t_ident ident
 %type <var> m_ident t_ident ident
-%type <pident> pident func_ident direct_ident
-%type <pident_list> pident_list
+%type <declarator> declarator direct_declarator init_declarator
+%type <declarator_list> declarator_list
 %type <func> funcdef
 %type <func_list> int_statements dispint_meths
 %type <type> coclass coclasshdr coclassdef
 %type <num> pointer_type version
 %type <func> funcdef
 %type <func_list> int_statements dispint_meths
 %type <type> coclass coclasshdr coclassdef
 %type <num> pointer_type version
-%type <str> libraryhdr callconv
+%type <str> libraryhdr callconv cppquote importlib import
 %type <uuid> uuid_string
 %type <uuid> uuid_string
-%type <num> import_start
+%type <import> import_start
+%type <typelib> library_start librarydef
+%type <statement> statement typedef
+%type <stmt_list> gbl_statements imp_statements
 
 %left ','
 %right '?' ':'
 
 %left ','
 %right '?' ':'
+%left LOGICALOR
+%left LOGICALAND
 %left '|'
 %left '|'
+%left '^'
 %left '&'
 %left '&'
-%left '-' '+'
-%left '*' '/'
+%left EQUALITY INEQUALITY
+%left '<' '>' LESSEQUAL GREATEREQUAL
 %left SHL SHR
 %left SHL SHR
-%right '~'
-%right CAST
-%right PPTR
-%right NEG
-%right ADDRESSOF
+%left '-' '+'
+%left '*' '/' '%'
+%right '!' '~' CAST PPTR POS NEG ADDRESSOF tSIZEOF
+%left '.' MEMBERPTR '[' ']'
 
 %%
 
 
 %%
 
@@ -312,93 +357,109 @@ input:   gbl_statements                          { fix_incomplete();
 
 gbl_statements:                                        { $$ = NULL; }
        | gbl_statements interfacedec           { $$ = $1; }
 
 gbl_statements:                                        { $$ = NULL; }
        | gbl_statements interfacedec           { $$ = $1; }
-       | gbl_statements interfacedef           { $$ = append_ifref( $1, make_ifref($2) ); }
+       | gbl_statements interfacedef           { $$ = append_statement($1, make_statement_type_decl($2)); }
        | gbl_statements coclass ';'            { $$ = $1;
                                                  reg_type($2, $2->name, 0);
                                                  if (!parse_only && do_header) write_coclass_forward($2);
                                                }
        | gbl_statements coclass ';'            { $$ = $1;
                                                  reg_type($2, $2->name, 0);
                                                  if (!parse_only && do_header) write_coclass_forward($2);
                                                }
-       | gbl_statements coclassdef             { $$ = $1;
+       | gbl_statements coclassdef             { $$ = append_statement($1, make_statement_type_decl($2));
                                                  add_typelib_entry($2);
                                                  reg_type($2, $2->name, 0);
                                                  if (!parse_only && do_header) write_coclass_forward($2);
                                                }
                                                  add_typelib_entry($2);
                                                  reg_type($2, $2->name, 0);
                                                  if (!parse_only && do_header) write_coclass_forward($2);
                                                }
-       | gbl_statements moduledef              { $$ = $1; add_typelib_entry($2); }
-       | gbl_statements librarydef             { $$ = $1; }
-       | gbl_statements statement              { $$ = $1; }
+       | gbl_statements moduledef              { $$ = append_statement($1, make_statement_module($2));
+                                                 add_typelib_entry($2);
+                                               }
+       | gbl_statements librarydef             { $$ = append_statement($1, make_statement_library($2)); }
+       | gbl_statements statement              { $$ = append_statement($1, $2); }
        ;
 
        ;
 
-imp_statements:                                        {}
-       | imp_statements interfacedec           { if (!parse_only) add_typelib_entry($2); }
-       | imp_statements interfacedef           { if (!parse_only) add_typelib_entry($2); }
-       | imp_statements coclass ';'            { reg_type($2, $2->name, 0); if (!parse_only && do_header) write_coclass_forward($2); }
-       | imp_statements coclassdef             { if (!parse_only) add_typelib_entry($2);
+imp_statements:                                        { $$ = NULL; }
+       | imp_statements interfacedec           { $$ = append_statement($1, make_statement_reference($2)); if (!parse_only) add_typelib_entry($2); }
+       | imp_statements interfacedef           { $$ = append_statement($1, make_statement_type_decl($2)); if (!parse_only) add_typelib_entry($2); }
+       | imp_statements coclass ';'            { $$ = $1; reg_type($2, $2->name, 0); if (!parse_only && do_header) write_coclass_forward($2); }
+       | imp_statements coclassdef             { $$ = append_statement($1, make_statement_type_decl($2));
+                                                 if (!parse_only) add_typelib_entry($2);
                                                  reg_type($2, $2->name, 0);
                                                  if (!parse_only && do_header) write_coclass_forward($2);
                                                }
                                                  reg_type($2, $2->name, 0);
                                                  if (!parse_only && do_header) write_coclass_forward($2);
                                                }
-       | imp_statements moduledef              { if (!parse_only) add_typelib_entry($2); }
-       | imp_statements statement              {}
-       | imp_statements importlib              {}
-       | imp_statements librarydef             {}
+       | imp_statements moduledef              { $$ = append_statement($1, make_statement_module($2)); if (!parse_only) add_typelib_entry($2); }
+       | imp_statements statement              { $$ = append_statement($1, $2); }
+       | imp_statements importlib              { $$ = append_statement($1, make_statement_importlib($2)); }
+       | imp_statements librarydef             { $$ = append_statement($1, make_statement_library($2)); }
        ;
 
 int_statements:                                        { $$ = NULL; }
        ;
 
 int_statements:                                        { $$ = NULL; }
-       | int_statements funcdef ';'            { $$ = append_func( $1, $2 ); }
-       | int_statements statement              { $$ = $1; }
+       | int_statements statement              { $$ = append_func_from_statement( $1, $2 ); }
        ;
 
 semicolon_opt:
        | ';'
        ;
 
        ;
 
 semicolon_opt:
        | ';'
        ;
 
-statement: constdef ';'                                { if (!parse_only && do_header) { write_constdef($1); } }
-       | cppquote                              {}
-       | enumdef ';'                           { if (!parse_only && do_header) {
+statement:
+         cppquote                              { $$ = make_statement_cppquote($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");
                                                  }
                                                }
                                                    write_type_def_or_decl(header, $1, FALSE, NULL);
                                                    fprintf(header, ";\n\n");
                                                  }
                                                }
-       | externdef ';'                         { if (!parse_only && do_header) { write_externdef($1); } }
-       | import                                {}
-       | structdef ';'                         { if (!parse_only && do_header) {
+       | declaration ';'                       { $$ = make_statement_declaration($1);
+                                                 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");
                                                  }
                                                }
                                                    write_type_def_or_decl(header, $1, FALSE, NULL);
                                                    fprintf(header, ";\n\n");
                                                  }
                                                }
-       | typedef ';'                           {}
-       | uniondef ';'                          { if (!parse_only && do_header) {
+       | 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");
                                                  }
                                                }
        ;
 
                                                    write_type_def_or_decl(header, $1, FALSE, NULL);
                                                    fprintf(header, ";\n\n");
                                                  }
                                                }
        ;
 
-cppquote: tCPPQUOTE '(' aSTRING ')'            { if (!parse_only && do_header) fprintf(header, "%s\n", $3); }
+cppquote: tCPPQUOTE '(' aSTRING ')'            { $$ = $3; if (!parse_only && do_header) fprintf(header, "%s\n", $3); }
        ;
 import_start: tIMPORT aSTRING ';'              { assert(yychar == YYEMPTY);
        ;
 import_start: tIMPORT aSTRING ';'              { assert(yychar == YYEMPTY);
-                                                 $$ = do_import($2);
-                                                 if (!$$) yychar = aEOF;
+                                                 $$ = xmalloc(sizeof(struct _import_t));
+                                                 $$->name = $2;
+                                                 $$->import_performed = do_import($2);
+                                                 if (!$$->import_performed) yychar = aEOF;
                                                }
        ;
 
                                                }
        ;
 
-import: import_start imp_statements aEOF
-                                               { if ($1) pop_import(); }
+import: import_start imp_statements aEOF       { $$ = $1->name;
+                                                 if ($1->import_performed) pop_import();
+                                                 free($1);
+                                                 if (!parse_only && do_header) write_import($$);
+                                               }
        ;
 
 importlib: tIMPORTLIB '(' aSTRING ')'
        ;
 
 importlib: tIMPORTLIB '(' aSTRING ')'
-          semicolon_opt                        { if(!parse_only) add_importlib($3); }
+          semicolon_opt                        { $$ = $3; if(!parse_only) add_importlib($3); }
        ;
 
 libraryhdr: tLIBRARY aIDENTIFIER               { $$ = $2; }
        ;
        ;
 
 libraryhdr: tLIBRARY aIDENTIFIER               { $$ = $2; }
        ;
-library_start: attributes libraryhdr '{'       { check_library_attrs($2, $1);
-                                                 if (!parse_only) start_typelib($2, $1);
-                                                 if (!parse_only && do_header) write_library($2, $1);
-                                                 if (!parse_only && do_idfile) write_libid($2, $1);
+library_start: attributes libraryhdr '{'       { $$ = make_library($2, check_library_attrs($2, $1));
+                                                 if (!parse_only) start_typelib($$);
+                                                 if (!parse_only && do_header) write_library($$);
+                                                 if (!parse_only && do_idfile) write_libid($$);
                                                  is_inside_library = TRUE;
                                                }
        ;
 librarydef: library_start imp_statements '}'
                                                  is_inside_library = TRUE;
                                                }
        ;
 librarydef: library_start imp_statements '}'
-           semicolon_opt                       { if (!parse_only) end_typelib(); is_inside_library = FALSE; }
+           semicolon_opt                       { $$ = $1;
+                                                 $$->stmts = $2;
+                                                 if (!parse_only) end_typelib();
+                                                 is_inside_library = FALSE;
+                                               }
        ;
 
 m_args:                                                { $$ = NULL; }
        ;
 
 m_args:                                                { $$ = NULL; }
@@ -414,25 +475,23 @@ args:       arg                                   { check_arg($1); $$ = append_var( NULL, $1 ); }
        ;
 
 /* split into two rules to get bison to resolve a tVOID conflict */
        ;
 
 /* split into two rules to get bison to resolve a tVOID conflict */
-arg:     attributes type pident array          { $$ = $3->var;
+arg:     attributes decl_spec declarator       { $$ = $3->var;
                                                  $$->attrs = $1;
                                                  $$->attrs = $1;
-                                                 set_type($$, $2, $3, $4, TRUE);
+                                                 if ($2->stgclass != STG_NONE && $2->stgclass != STG_REGISTER)
+                                                   error_loc("invalid storage class for function parameter\n");
+                                                 set_type($$, $2, $3, TRUE);
                                                  free($3);
                                                }
                                                  free($3);
                                                }
-       | type pident array                     { $$ = $2->var;
-                                                 set_type($$, $1, $2, $3, TRUE);
+       | decl_spec declarator                  { $$ = $2->var;
+                                                 if ($1->stgclass != STG_NONE && $1->stgclass != STG_REGISTER)
+                                                   error_loc("invalid storage class for function parameter\n");
+                                                 set_type($$, $1, $2, TRUE);
                                                  free($2);
                                                }
        ;
 
                                                  free($2);
                                                }
        ;
 
-array:                                         { $$ = NULL; }
-       | '[' array_list ']'                    { $$ = $2; }
-       | '[' '*' ']'                           { $$ = append_array( NULL, make_expr(EXPR_VOID) ); }
-       ;
-
-array_list: m_expr /* size of first dimension is optional */ { $$ = append_array( NULL, $1 ); }
-       | array_list ',' expr                   { $$ = append_array( $1, $3 ); }
-       | array_list ']' '[' expr               { $$ = append_array( $1, $4 ); }
+array:   '[' m_expr ']'                        { $$ = $2; }
+       | '[' '*' ']'                           { $$ = make_expr(EXPR_VOID); }
        ;
 
 m_attributes:                                  { $$ = NULL; }
        ;
 
 m_attributes:                                  { $$ = NULL; }
@@ -463,31 +522,29 @@ attribute:                                        { $$ = NULL; }
        | tBINDABLE                             { $$ = make_attr(ATTR_BINDABLE); }
        | tBROADCAST                            { $$ = make_attr(ATTR_BROADCAST); }
        | tCALLAS '(' ident ')'                 { $$ = make_attrp(ATTR_CALLAS, $3); }
        | tBINDABLE                             { $$ = make_attr(ATTR_BINDABLE); }
        | tBROADCAST                            { $$ = make_attr(ATTR_BROADCAST); }
        | tCALLAS '(' ident ')'                 { $$ = make_attrp(ATTR_CALLAS, $3); }
-       | tCASE '(' expr_list_const ')'         { $$ = make_attrp(ATTR_CASE, $3); }
+       | tCASE '(' expr_list_int_const ')'     { $$ = make_attrp(ATTR_CASE, $3); }
        | tCONTEXTHANDLE                        { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); }
        | tCONTEXTHANDLENOSERIALIZE             { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ }
        | tCONTEXTHANDLESERIALIZE               { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ }
        | tCONTROL                              { $$ = make_attr(ATTR_CONTROL); }
        | tDEFAULT                              { $$ = make_attr(ATTR_DEFAULT); }
        | tDEFAULTCOLLELEM                      { $$ = make_attr(ATTR_DEFAULTCOLLELEM); }
        | tCONTEXTHANDLE                        { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); }
        | tCONTEXTHANDLENOSERIALIZE             { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_DONT_SERIALIZE */ }
        | tCONTEXTHANDLESERIALIZE               { $$ = make_attrv(ATTR_CONTEXTHANDLE, 0); /* RPC_CONTEXT_HANDLE_SERIALIZE */ }
        | tCONTROL                              { $$ = make_attr(ATTR_CONTROL); }
        | tDEFAULT                              { $$ = make_attr(ATTR_DEFAULT); }
        | tDEFAULTCOLLELEM                      { $$ = make_attr(ATTR_DEFAULTCOLLELEM); }
-       | tDEFAULTVALUE '(' expr_const ')'      { $$ = make_attrp(ATTR_DEFAULTVALUE_EXPR, $3); }
-       | tDEFAULTVALUE '(' aSTRING ')'         { $$ = make_attrp(ATTR_DEFAULTVALUE_STRING, $3); }
+       | tDEFAULTVALUE '(' expr_const ')'      { $$ = make_attrp(ATTR_DEFAULTVALUE, $3); }
        | tDEFAULTVTABLE                        { $$ = make_attr(ATTR_DEFAULTVTABLE); }
        | tDISPLAYBIND                          { $$ = make_attr(ATTR_DISPLAYBIND); }
        | tDLLNAME '(' aSTRING ')'              { $$ = make_attrp(ATTR_DLLNAME, $3); }
        | tDUAL                                 { $$ = make_attr(ATTR_DUAL); }
        | tENDPOINT '(' str_list ')'            { $$ = make_attrp(ATTR_ENDPOINT, $3); }
        | tDEFAULTVTABLE                        { $$ = make_attr(ATTR_DEFAULTVTABLE); }
        | tDISPLAYBIND                          { $$ = make_attr(ATTR_DISPLAYBIND); }
        | tDLLNAME '(' aSTRING ')'              { $$ = make_attrp(ATTR_DLLNAME, $3); }
        | tDUAL                                 { $$ = make_attr(ATTR_DUAL); }
        | tENDPOINT '(' str_list ')'            { $$ = make_attrp(ATTR_ENDPOINT, $3); }
-       | tENTRY '(' aSTRING ')'                { $$ = make_attrp(ATTR_ENTRY_STRING, $3); }
-       | tENTRY '(' expr_const ')'             { $$ = make_attrp(ATTR_ENTRY_ORDINAL, $3); }
+       | tENTRY '(' expr_const ')'             { $$ = make_attrp(ATTR_ENTRY, $3); }
        | tEXPLICITHANDLE                       { $$ = make_attr(ATTR_EXPLICIT_HANDLE); }
        | tHANDLE                               { $$ = make_attr(ATTR_HANDLE); }
        | tEXPLICITHANDLE                       { $$ = make_attr(ATTR_EXPLICIT_HANDLE); }
        | tHANDLE                               { $$ = make_attr(ATTR_HANDLE); }
-       | tHELPCONTEXT '(' expr_const ')'       { $$ = make_attrp(ATTR_HELPCONTEXT, $3); }
+       | tHELPCONTEXT '(' expr_int_const ')'   { $$ = make_attrp(ATTR_HELPCONTEXT, $3); }
        | tHELPFILE '(' aSTRING ')'             { $$ = make_attrp(ATTR_HELPFILE, $3); }
        | tHELPSTRING '(' aSTRING ')'           { $$ = make_attrp(ATTR_HELPSTRING, $3); }
        | tHELPFILE '(' aSTRING ')'             { $$ = make_attrp(ATTR_HELPFILE, $3); }
        | tHELPSTRING '(' aSTRING ')'           { $$ = make_attrp(ATTR_HELPSTRING, $3); }
-       | tHELPSTRINGCONTEXT '(' expr_const ')' { $$ = make_attrp(ATTR_HELPSTRINGCONTEXT, $3); }
+       | tHELPSTRINGCONTEXT '(' expr_int_const ')'     { $$ = make_attrp(ATTR_HELPSTRINGCONTEXT, $3); }
        | tHELPSTRINGDLL '(' aSTRING ')'        { $$ = make_attrp(ATTR_HELPSTRINGDLL, $3); }
        | tHIDDEN                               { $$ = make_attr(ATTR_HIDDEN); }
        | tHELPSTRINGDLL '(' aSTRING ')'        { $$ = make_attrp(ATTR_HELPSTRINGDLL, $3); }
        | tHIDDEN                               { $$ = make_attr(ATTR_HIDDEN); }
-       | tID '(' expr_const ')'                { $$ = make_attrp(ATTR_ID, $3); }
+       | tID '(' expr_int_const ')'            { $$ = make_attrp(ATTR_ID, $3); }
        | tIDEMPOTENT                           { $$ = make_attr(ATTR_IDEMPOTENT); }
        | tIIDIS '(' expr ')'                   { $$ = make_attrp(ATTR_IIDIS, $3); }
        | tIMMEDIATEBIND                        { $$ = make_attr(ATTR_IMMEDIATEBIND); }
        | tIDEMPOTENT                           { $$ = make_attr(ATTR_IDEMPOTENT); }
        | tIIDIS '(' expr ')'                   { $$ = make_attrp(ATTR_IIDIS, $3); }
        | tIMMEDIATEBIND                        { $$ = make_attr(ATTR_IMMEDIATEBIND); }
@@ -495,6 +552,7 @@ attribute:                                  { $$ = NULL; }
        | tIN                                   { $$ = make_attr(ATTR_IN); }
        | tINPUTSYNC                            { $$ = make_attr(ATTR_INPUTSYNC); }
        | tLENGTHIS '(' m_exprs ')'             { $$ = make_attrp(ATTR_LENGTHIS, $3); }
        | tIN                                   { $$ = make_attr(ATTR_IN); }
        | tINPUTSYNC                            { $$ = make_attr(ATTR_INPUTSYNC); }
        | tLENGTHIS '(' m_exprs ')'             { $$ = make_attrp(ATTR_LENGTHIS, $3); }
+       | tLCID '(' expr_int_const ')'          { $$ = make_attrp(ATTR_LIBLCID, $3); }
        | tLOCAL                                { $$ = make_attr(ATTR_LOCAL); }
        | tNONBROWSABLE                         { $$ = make_attr(ATTR_NONBROWSABLE); }
        | tNONCREATABLE                         { $$ = make_attr(ATTR_NONCREATABLE); }
        | tLOCAL                                { $$ = make_attr(ATTR_LOCAL); }
        | tNONBROWSABLE                         { $$ = make_attr(ATTR_NONBROWSABLE); }
        | tNONCREATABLE                         { $$ = make_attr(ATTR_NONCREATABLE); }
@@ -509,9 +567,10 @@ attribute:                                 { $$ = NULL; }
        | tPROPPUT                              { $$ = make_attr(ATTR_PROPPUT); }
        | tPROPPUTREF                           { $$ = make_attr(ATTR_PROPPUTREF); }
        | tPUBLIC                               { $$ = make_attr(ATTR_PUBLIC); }
        | tPROPPUT                              { $$ = make_attr(ATTR_PROPPUT); }
        | tPROPPUTREF                           { $$ = make_attr(ATTR_PROPPUTREF); }
        | tPUBLIC                               { $$ = make_attr(ATTR_PUBLIC); }
-       | tRANGE '(' expr_const ',' expr_const ')' { expr_list_t *list = append_expr( NULL, $3 );
-                                                     list = append_expr( list, $5 );
-                                                     $$ = make_attrp(ATTR_RANGE, list); }
+       | tRANGE '(' expr_int_const ',' expr_int_const ')'
+                                               { expr_list_t *list = append_expr( NULL, $3 );
+                                                 list = append_expr( list, $5 );
+                                                 $$ = make_attrp(ATTR_RANGE, list); }
        | tREADONLY                             { $$ = make_attr(ATTR_READONLY); }
        | tREQUESTEDIT                          { $$ = make_attr(ATTR_REQUESTEDIT); }
        | tRESTRICTED                           { $$ = make_attr(ATTR_RESTRICTED); }
        | tREADONLY                             { $$ = make_attr(ATTR_READONLY); }
        | tREQUESTEDIT                          { $$ = make_attr(ATTR_REQUESTEDIT); }
        | tRESTRICTED                           { $$ = make_attr(ATTR_RESTRICTED); }
@@ -548,22 +607,16 @@ cases:                                            { $$ = NULL; }
        | cases case                            { $$ = append_var( $1, $2 ); }
        ;
 
        | cases case                            { $$ = append_var( $1, $2 ); }
        ;
 
-case:    tCASE expr ':' field                  { attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, $2 ));
+case:    tCASE expr_int_const ':' union_field  { attr_t *a = make_attrp(ATTR_CASE, append_expr( NULL, $2 ));
                                                  $$ = $4; if (!$$) $$ = make_var(NULL);
                                                  $$->attrs = append_attr( $$->attrs, a );
                                                }
                                                  $$ = $4; if (!$$) $$ = make_var(NULL);
                                                  $$->attrs = append_attr( $$->attrs, a );
                                                }
-       | tDEFAULT ':' field                    { attr_t *a = make_attr(ATTR_DEFAULT);
+       | tDEFAULT ':' union_field              { attr_t *a = make_attr(ATTR_DEFAULT);
                                                  $$ = $3; if (!$$) $$ = make_var(NULL);
                                                  $$->attrs = append_attr( $$->attrs, a );
                                                }
        ;
 
                                                  $$ = $3; if (!$$) $$ = make_var(NULL);
                                                  $$->attrs = append_attr( $$->attrs, a );
                                                }
        ;
 
-constdef: tCONST type ident '=' expr_const     { $$ = reg_const($3);
-                                                 set_type($$, $2, NULL, NULL, FALSE);
-                                                 $$->eval = $5;
-                                               }
-       ;
-
 enums:                                         { $$ = NULL; }
        | enum_list ','                         { $$ = $1; }
        | enum_list
 enums:                                         { $$ = NULL; }
        | enum_list ','                         { $$ = $1; }
        | enum_list
@@ -582,7 +635,7 @@ enum_list: enum                                     { if (!$1->eval)
                                                }
        ;
 
                                                }
        ;
 
-enum:    ident '=' expr_const                  { $$ = reg_const($1);
+enum:    ident '=' expr_int_const              { $$ = reg_const($1);
                                                  $$->eval = $3;
                                                   $$->type = make_int(0);
                                                }
                                                  $$->eval = $3;
                                                   $$->type = make_int(0);
                                                }
@@ -622,65 +675,115 @@ expr:      aNUM                                  { $$ = make_exprl(EXPR_NUM, $1); }
        | aHEXNUM                               { $$ = make_exprl(EXPR_HEXNUM, $1); }
        | aDOUBLE                               { $$ = make_exprd(EXPR_DOUBLE, $1); }
        | tFALSE                                { $$ = make_exprl(EXPR_TRUEFALSE, 0); }
        | aHEXNUM                               { $$ = make_exprl(EXPR_HEXNUM, $1); }
        | aDOUBLE                               { $$ = make_exprd(EXPR_DOUBLE, $1); }
        | tFALSE                                { $$ = make_exprl(EXPR_TRUEFALSE, 0); }
+       | tNULL                                 { $$ = make_exprl(EXPR_NUM, 0); }
        | tTRUE                                 { $$ = make_exprl(EXPR_TRUEFALSE, 1); }
        | tTRUE                                 { $$ = make_exprl(EXPR_TRUEFALSE, 1); }
+       | aSTRING                               { $$ = make_exprs(EXPR_STRLIT, $1); }
+       | aWSTRING                              { $$ = make_exprs(EXPR_WSTRLIT, $1); }
        | aIDENTIFIER                           { $$ = make_exprs(EXPR_IDENTIFIER, $1); }
        | expr '?' expr ':' expr                { $$ = make_expr3(EXPR_COND, $1, $3, $5); }
        | aIDENTIFIER                           { $$ = make_exprs(EXPR_IDENTIFIER, $1); }
        | expr '?' expr ':' expr                { $$ = make_expr3(EXPR_COND, $1, $3, $5); }
+       | expr LOGICALOR expr                   { $$ = make_expr2(EXPR_LOGOR, $1, $3); }
+       | expr LOGICALAND expr                  { $$ = make_expr2(EXPR_LOGAND, $1, $3); }
        | expr '|' expr                         { $$ = make_expr2(EXPR_OR , $1, $3); }
        | expr '|' expr                         { $$ = make_expr2(EXPR_OR , $1, $3); }
+       | expr '^' expr                         { $$ = make_expr2(EXPR_XOR, $1, $3); }
        | expr '&' expr                         { $$ = make_expr2(EXPR_AND, $1, $3); }
        | expr '&' expr                         { $$ = make_expr2(EXPR_AND, $1, $3); }
+       | expr EQUALITY expr                    { $$ = make_expr2(EXPR_EQUALITY, $1, $3); }
+       | expr INEQUALITY expr                  { $$ = make_expr2(EXPR_INEQUALITY, $1, $3); }
+       | expr '>' expr                         { $$ = make_expr2(EXPR_GTR, $1, $3); }
+       | expr '<' expr                         { $$ = make_expr2(EXPR_LESS, $1, $3); }
+       | expr GREATEREQUAL expr                { $$ = make_expr2(EXPR_GTREQL, $1, $3); }
+       | expr LESSEQUAL expr                   { $$ = make_expr2(EXPR_LESSEQL, $1, $3); }
+       | expr SHL expr                         { $$ = make_expr2(EXPR_SHL, $1, $3); }
+       | expr SHR expr                         { $$ = make_expr2(EXPR_SHR, $1, $3); }
        | expr '+' expr                         { $$ = make_expr2(EXPR_ADD, $1, $3); }
        | expr '-' expr                         { $$ = make_expr2(EXPR_SUB, $1, $3); }
        | expr '+' expr                         { $$ = make_expr2(EXPR_ADD, $1, $3); }
        | expr '-' expr                         { $$ = make_expr2(EXPR_SUB, $1, $3); }
+       | expr '%' expr                         { $$ = make_expr2(EXPR_MOD, $1, $3); }
        | expr '*' expr                         { $$ = make_expr2(EXPR_MUL, $1, $3); }
        | expr '/' expr                         { $$ = make_expr2(EXPR_DIV, $1, $3); }
        | expr '*' expr                         { $$ = make_expr2(EXPR_MUL, $1, $3); }
        | expr '/' expr                         { $$ = make_expr2(EXPR_DIV, $1, $3); }
-       | expr SHL expr                         { $$ = make_expr2(EXPR_SHL, $1, $3); }
-       | expr SHR expr                         { $$ = make_expr2(EXPR_SHR, $1, $3); }
+       | '!' expr                              { $$ = make_expr1(EXPR_LOGNOT, $2); }
        | '~' expr                              { $$ = make_expr1(EXPR_NOT, $2); }
        | '~' expr                              { $$ = make_expr1(EXPR_NOT, $2); }
+       | '+' expr %prec POS                    { $$ = make_expr1(EXPR_POS, $2); }
        | '-' expr %prec NEG                    { $$ = make_expr1(EXPR_NEG, $2); }
        | '-' expr %prec NEG                    { $$ = make_expr1(EXPR_NEG, $2); }
-       | '&' expr %prec ADDRESSOF      { $$ = make_expr1(EXPR_ADDRESSOF, $2); }
+       | '&' expr %prec ADDRESSOF              { $$ = make_expr1(EXPR_ADDRESSOF, $2); }
        | '*' expr %prec PPTR                   { $$ = make_expr1(EXPR_PPTR, $2); }
        | '*' expr %prec PPTR                   { $$ = make_expr1(EXPR_PPTR, $2); }
+       | expr MEMBERPTR aIDENTIFIER            { $$ = make_expr2(EXPR_MEMBER, make_expr1(EXPR_PPTR, $1), make_exprs(EXPR_IDENTIFIER, $3)); }
+       | expr '.' aIDENTIFIER                  { $$ = make_expr2(EXPR_MEMBER, $1, make_exprs(EXPR_IDENTIFIER, $3)); }
        | '(' type ')' expr %prec CAST          { $$ = make_exprt(EXPR_CAST, $2, $4); }
        | tSIZEOF '(' type ')'                  { $$ = make_exprt(EXPR_SIZEOF, $3, NULL); }
        | '(' type ')' expr %prec CAST          { $$ = make_exprt(EXPR_CAST, $2, $4); }
        | tSIZEOF '(' type ')'                  { $$ = make_exprt(EXPR_SIZEOF, $3, NULL); }
+       | expr '[' expr ']'                     { $$ = make_expr2(EXPR_ARRAY, $1, $3); }
        | '(' expr ')'                          { $$ = $2; }
        ;
 
        | '(' expr ')'                          { $$ = $2; }
        ;
 
-expr_list_const: expr_const                     { $$ = append_expr( NULL, $1 ); }
-       | expr_list_const ',' expr_const        { $$ = append_expr( $1, $3 ); }
+expr_list_int_const: expr_int_const            { $$ = append_expr( NULL, $1 ); }
+       | expr_list_int_const ',' expr_int_const        { $$ = append_expr( $1, $3 ); }
        ;
 
        ;
 
-expr_const: expr                               { $$ = $1;
+expr_int_const: expr                           { $$ = $1;
                                                  if (!$$->is_const)
                                                  if (!$$->is_const)
-                                                     error_loc("expression is not constant\n");
+                                                     error_loc("expression is not an integer constant\n");
                                                }
        ;
 
                                                }
        ;
 
-externdef: tEXTERN tCONST type ident           { $$ = $4;
-                                                 set_type($$, $3, NULL, NULL, FALSE);
+expr_const: expr                               { $$ = $1;
+                                                 if (!$$->is_const && $$->type != EXPR_STRLIT && $$->type != EXPR_WSTRLIT)
+                                                     error_loc("expression is not constant\n");
                                                }
        ;
 
 fields:                                                { $$ = NULL; }
                                                }
        ;
 
 fields:                                                { $$ = NULL; }
-       | fields field                          { $$ = append_var( $1, $2 ); }
+       | fields field                          { $$ = append_var_list($1, $2); }
        ;
 
        ;
 
-field:   s_field ';'                           { $$ = $1; }
-       | m_attributes uniondef ';'             { $$ = make_var(NULL); $$->type = $2; $$->attrs = $1; }
+field:   m_attributes decl_spec declarator_list ';'
+                                               { const char *first = LIST_ENTRY(list_head($3), declarator_t, entry)->var->name;
+                                                 check_field_attrs(first, $1);
+                                                 $$ = set_var_types($1, $2, $3);
+                                               }
+       | m_attributes uniondef ';'             { var_t *v = make_var(NULL);
+                                                 v->type = $2; v->attrs = $1;
+                                                 $$ = append_var(NULL, v);
+                                               }
+       ;
+
+ne_union_field:
+         s_field ';'                           { $$ = $1; }
        | attributes ';'                        { $$ = make_var(NULL); $$->attrs = $1; }
        | attributes ';'                        { $$ = make_var(NULL); $$->attrs = $1; }
+       ;
+
+ne_union_fields:                               { $$ = NULL; }
+       | ne_union_fields ne_union_field        { $$ = append_var( $1, $2 ); }
+       ;
+
+union_field:
+         s_field ';'                           { $$ = $1; }
        | ';'                                   { $$ = NULL; }
        ;
 
        | ';'                                   { $$ = NULL; }
        ;
 
-s_field:  m_attributes type pident array       { $$ = $3->var;
+s_field:  m_attributes decl_spec declarator    { $$ = $3->var;
                                                  $$->attrs = check_field_attrs($$->name, $1);
                                                  $$->attrs = check_field_attrs($$->name, $1);
-                                                 set_type($$, $2, $3, $4, FALSE);
+                                                 set_type($$, $2, $3, FALSE);
                                                  free($3);
                                                }
        ;
 
 funcdef:
                                                  free($3);
                                                }
        ;
 
 funcdef:
-         m_attributes type pident              { var_t *v = $3->var;
-                                                 var_list_t *args = $3->args;
+         m_attributes decl_spec declarator     { var_t *v = $3->var;
                                                  v->attrs = check_function_attrs(v->name, $1);
                                                  v->attrs = check_function_attrs(v->name, $1);
-                                                 set_type(v, $2, $3, NULL, FALSE);
+                                                 set_type(v, $2, $3, FALSE);
                                                  free($3);
                                                  free($3);
-                                                 $$ = make_func(v, args);
+                                                 $$ = make_func(v);
+                                               }
+       ;
+
+declaration:
+         attributes decl_spec init_declarator
+                                               { $$ = $3->var;
+                                                 $$->attrs = $1;
+                                                 set_type($$, $2, $3, FALSE);
+                                                 free($3);
+                                               }
+       | decl_spec init_declarator             { $$ = $2->var;
+                                                 set_type($$, $1, $2, FALSE);
+                                                 free($2);
                                                }
        ;
 
                                                }
        ;
 
@@ -776,6 +879,7 @@ dispinterface: tDISPINTERFACE aIDENTIFIER   { $$ = get_type(0, $2, 0); $$->kind =
        ;
 
 dispinterfacehdr: attributes dispinterface     { attr_t *attrs;
        ;
 
 dispinterfacehdr: attributes dispinterface     { attr_t *attrs;
+                                                 is_in_interface = TRUE;
                                                  is_object_interface = TRUE;
                                                  $$ = $2;
                                                  if ($$->defined) error_loc("multiple definition error\n");
                                                  is_object_interface = TRUE;
                                                  $$ = $2;
                                                  if ($$->defined) error_loc("multiple definition error\n");
@@ -802,15 +906,17 @@ dispinterfacedef: dispinterfacehdr '{'
          '}'                                   { $$ = $1;
                                                  $$->fields_or_args = $3;
                                                  $$->funcs = $4;
          '}'                                   { $$ = $1;
                                                  $$->fields_or_args = $3;
                                                  $$->funcs = $4;
-                                                 if (!parse_only && do_header) write_dispinterface($$);
+                                                 if (!parse_only && do_header) write_interface($$);
                                                  if (!parse_only && do_idfile) write_diid($$);
                                                  if (!parse_only && do_idfile) write_diid($$);
+                                                 is_in_interface = FALSE;
                                                }
        | dispinterfacehdr
         '{' interface ';' '}'                  { $$ = $1;
                                                  $$->fields_or_args = $3->fields_or_args;
                                                  $$->funcs = $3->funcs;
                                                }
        | dispinterfacehdr
         '{' interface ';' '}'                  { $$ = $1;
                                                  $$->fields_or_args = $3->fields_or_args;
                                                  $$->funcs = $3->funcs;
-                                                 if (!parse_only && do_header) write_dispinterface($$);
+                                                 if (!parse_only && do_header) write_interface($$);
                                                  if (!parse_only && do_idfile) write_diid($$);
                                                  if (!parse_only && do_idfile) write_diid($$);
+                                                 is_in_interface = FALSE;
                                                }
        ;
 
                                                }
        ;
 
@@ -827,6 +933,7 @@ interfacehdr: attributes interface          { $$.interface = $2;
                                                  if (is_attr($1, ATTR_POINTERDEFAULT))
                                                    pointer_default = get_attrv($1, ATTR_POINTERDEFAULT);
                                                  is_object_interface = is_object($1);
                                                  if (is_attr($1, ATTR_POINTERDEFAULT))
                                                    pointer_default = get_attrv($1, ATTR_POINTERDEFAULT);
                                                  is_object_interface = is_object($1);
+                                                 is_in_interface = TRUE;
                                                  if ($2->defined) error_loc("multiple definition error\n");
                                                  $2->attrs = check_iface_attrs($2->name, $1);
                                                  $2->defined = TRUE;
                                                  if ($2->defined) error_loc("multiple definition error\n");
                                                  $2->attrs = check_iface_attrs($2->name, $1);
                                                  $2->defined = TRUE;
@@ -844,6 +951,7 @@ interfacedef: interfacehdr inherit
                                                  if (!parse_only && local_stubs) write_locals(local_stubs, $$, TRUE);
                                                  if (!parse_only && do_idfile) write_iid($$);
                                                  pointer_default = $1.old_pointer_default;
                                                  if (!parse_only && local_stubs) write_locals(local_stubs, $$, TRUE);
                                                  if (!parse_only && do_idfile) write_iid($$);
                                                  pointer_default = $1.old_pointer_default;
+                                                 is_in_interface = FALSE;
                                                }
 /* MIDL is able to import the definition of a base class from inside the
  * definition of a derived class, I'll try to support it with this rule */
                                                }
 /* MIDL is able to import the definition of a base class from inside the
  * definition of a derived class, I'll try to support it with this rule */
@@ -858,6 +966,7 @@ interfacedef: interfacehdr inherit
                                                  if (!parse_only && local_stubs) write_locals(local_stubs, $$, TRUE);
                                                  if (!parse_only && do_idfile) write_iid($$);
                                                  pointer_default = $1.old_pointer_default;
                                                  if (!parse_only && local_stubs) write_locals(local_stubs, $$, TRUE);
                                                  if (!parse_only && do_idfile) write_iid($$);
                                                  pointer_default = $1.old_pointer_default;
+                                                 is_in_interface = FALSE;
                                                }
        | dispinterfacedef semicolon_opt        { $$ = $1; }
        ;
                                                }
        | dispinterfacedef semicolon_opt        { $$ = $1; }
        ;
@@ -883,33 +992,64 @@ moduledef: modulehdr '{' int_statements '}'
                                                }
        ;
 
                                                }
        ;
 
-pident:   '*' pident %prec PPTR                        { $$ = $2; $$->ptr_level++; }
-       | tCONST pident                         { $$ = $2; /* FIXME */ }
-       | callconv pident                       { $$ = $2;
-                                                 if ($$->callconv) parser_warning("multiple calling conventions %s, %s for function %s\n", $$->callconv, $1, $$->var->name);
-                                                 $$->callconv = $1;
-                                               }
-       | direct_ident
+storage_cls_spec:
+         tEXTERN                               { $$ = STG_EXTERN; }
+       | tSTATIC                               { $$ = STG_STATIC; }
+       | tREGISTER                             { $$ = STG_REGISTER; }
        ;
 
        ;
 
-func_ident: direct_ident '(' m_args ')'
-                                               { $$ = $1;
-                                                 $1->args = $3;
-                                                 $1->is_func = TRUE;
-                                               }
+function_specifier:
+         tINLINE                               { $$ = make_attr(ATTR_INLINE); }
+       ;
+
+type_qualifier:
+         tCONST                                { $$ = make_attr(ATTR_CONST); }
+       ;
+
+m_type_qual_list:                              { $$ = NULL; }
+       | m_type_qual_list type_qualifier       { $$ = append_attr($1, $2); }
+       ;
+
+decl_spec: type m_decl_spec_no_type            { $$ = make_decl_spec($1, $2, NULL, NULL, STG_NONE); }
+       | decl_spec_no_type type m_decl_spec_no_type
+                                               { $$ = make_decl_spec($2, $1, $3, NULL, STG_NONE); }
+       ;
+
+m_decl_spec_no_type:                           { $$ = NULL; }
+       | decl_spec_no_type
        ;
 
        ;
 
-direct_ident: ident                            { $$ = make_pident($1); }
-       | '(' pident ')'                        { $$ = $2; }
-       | func_ident                            { $$ = $1;
-                                                 $$->func_ptr_level = $$->ptr_level;
-                                                 $$->ptr_level = 0;
+decl_spec_no_type:
+         type_qualifier 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); }
+       | storage_cls_spec m_decl_spec_no_type  { $$ = make_decl_spec(NULL, $2, NULL, NULL, $1); }
+       ;
+
+declarator:
+         '*' m_type_qual_list declarator %prec PPTR
+                                               { $$ = $3; $$->type = append_ptrchain_type($$->type, make_pointer_type(NULL, $2)); }
+       | callconv declarator                   { $$ = $2; $$->type->attrs = append_attr($$->type->attrs, make_attrp(ATTR_CALLCONV, $1)); }
+       | direct_declarator
+       ;
+
+direct_declarator:
+         ident                                 { $$ = make_declarator($1); }
+       | '(' declarator ')'                    { $$ = $2; }
+       | direct_declarator array               { $$ = $1; $$->array = append_array($$->array, $2); }
+       | direct_declarator '(' m_args ')'      { $$ = $1;
+                                                 $$->func_type = append_ptrchain_type($$->type, make_func_type($3));
+                                                 $$->type = NULL;
                                                }
        ;
 
                                                }
        ;
 
-pident_list:
-       pident                                  { $$ = append_pident( NULL, $1 ); }
-       | pident_list ',' pident                { $$ = append_pident( $1, $3 ); }
+declarator_list:
+         declarator                            { $$ = append_declarator( NULL, $1 ); }
+       | declarator_list ',' declarator        { $$ = append_declarator( $1, $3 ); }
+       ;
+
+init_declarator:
+         declarator                            { $$ = $1; }
+       | declarator '=' expr_const             { $$ = $1; $1->var->eval = $3; }
        ;
 
 pointer_type:
        ;
 
 pointer_type:
@@ -932,7 +1072,6 @@ structdef: tSTRUCT t_ident '{' fields '}'  { $$ = get_typev(RPC_FC_STRUCT, $2, ts
 type:    tVOID                                 { $$ = duptype(find_type("void", 0), 1); }
        | aKNOWNTYPE                            { $$ = find_type($1, 0); }
        | base_type                             { $$ = $1; }
 type:    tVOID                                 { $$ = duptype(find_type("void", 0), 1); }
        | aKNOWNTYPE                            { $$ = find_type($1, 0); }
        | base_type                             { $$ = $1; }
-       | tCONST type                           { $$ = duptype($2, 1); $$->is_const = TRUE; }
        | enumdef                               { $$ = $1; }
        | tENUM aIDENTIFIER                     { $$ = find_type2($2, tsENUM); }
        | structdef                             { $$ = $1; }
        | enumdef                               { $$ = $1; }
        | tENUM aIDENTIFIER                     { $$ = find_type2($2, tsENUM); }
        | structdef                             { $$ = $1; }
@@ -942,12 +1081,14 @@ type:      tVOID                                 { $$ = duptype(find_type("void", 0), 1); }
        | tSAFEARRAY '(' type ')'               { $$ = make_safearray($3); }
        ;
 
        | tSAFEARRAY '(' type ')'               { $$ = make_safearray($3); }
        ;
 
-typedef: tTYPEDEF m_attributes type pident_list        { reg_typedefs($3, $4, check_typedef_attrs($2));
-                                                 process_typedefs($4);
+typedef: tTYPEDEF m_attributes decl_spec declarator_list
+                                               { reg_typedefs($3, $4, check_typedef_attrs($2));
+                                                 $$ = process_typedefs($4);
                                                }
        ;
 
                                                }
        ;
 
-uniondef: tUNION t_ident '{' fields '}'                { $$ = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, $2, tsUNION);
+uniondef: tUNION t_ident '{' ne_union_fields '}'
+                                               { $$ = get_typev(RPC_FC_NON_ENCAPSULATED_UNION, $2, tsUNION);
                                                  $$->kind = TKIND_UNION;
                                                  $$->fields_or_args = $4;
                                                  $$->defined = TRUE;
                                                  $$->kind = TKIND_UNION;
                                                  $$->fields_or_args = $4;
                                                  $$->defined = TRUE;
@@ -1057,6 +1198,103 @@ static attr_list_t *append_attr(attr_list_t *list, attr_t *attr)
     return list;
 }
 
     return list;
 }
 
+static attr_list_t *move_attr(attr_list_t *dst, attr_list_t *src, enum attr_type type)
+{
+  attr_t *attr;
+  if (!src) return dst;
+  LIST_FOR_EACH_ENTRY(attr, src, attr_t, entry)
+    if (attr->type == type)
+    {
+      list_remove(&attr->entry);
+      return append_attr(dst, attr);
+    }
+  return dst;
+}
+
+static attr_list_t *append_attr_list(attr_list_t *new_list, attr_list_t *old_list)
+{
+  struct list *entry;
+
+  if (!old_list) return new_list;
+
+  while ((entry = list_head(old_list)))
+  {
+    attr_t *attr = LIST_ENTRY(entry, attr_t, entry);
+    list_remove(entry);
+    new_list = append_attr(new_list, attr);
+  }
+  return new_list;
+}
+
+static attr_list_t *dupattrs(const attr_list_t *list)
+{
+  attr_list_t *new_list;
+  const attr_t *attr;
+
+  if (!list) return NULL;
+
+  new_list = xmalloc( sizeof(*list) );
+  list_init( new_list );
+  LIST_FOR_EACH_ENTRY(attr, list, const attr_t, entry)
+  {
+    attr_t *new_attr = xmalloc(sizeof(*new_attr));
+    *new_attr = *attr;
+    list_add_tail(new_list, &new_attr->entry);
+  }
+  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)
+{
+  decl_spec_t *declspec = left ? left : right;
+  if (!declspec)
+  {
+    declspec = xmalloc(sizeof(*declspec));
+    declspec->type = NULL;
+    declspec->attrs = NULL;
+    declspec->stgclass = STG_NONE;
+  }
+  declspec->type = type;
+  if (left && declspec != left)
+  {
+    declspec->attrs = append_attr_list(declspec->attrs, left->attrs);
+    if (declspec->stgclass == STG_NONE)
+      declspec->stgclass = left->stgclass;
+    else if (left->stgclass != STG_NONE)
+      error_loc("only one storage class can be specified\n");
+    assert(!left->type);
+    free(left);
+  }
+  if (right && declspec != right)
+  {
+    declspec->attrs = append_attr_list(declspec->attrs, right->attrs);
+    if (declspec->stgclass == STG_NONE)
+      declspec->stgclass = right->stgclass;
+    else if (right->stgclass != STG_NONE)
+      error_loc("only one storage class can be specified\n");
+    assert(!right->type);
+    free(right);
+  }
+
+  declspec->attrs = append_attr(declspec->attrs, attr);
+  if (declspec->stgclass == STG_NONE)
+    declspec->stgclass = stgclass;
+  else if (stgclass != STG_NONE)
+    error_loc("only one storage class can be specified\n");
+
+  /* apply attributes to type */
+  if (type && declspec->attrs)
+  {
+    attr_list_t *attrs;
+    declspec->type = duptype(type, 1);
+    attrs = dupattrs(type->attrs);
+    declspec->type->attrs = append_attr_list(attrs, declspec->attrs);
+    declspec->attrs = NULL;
+  }
+
+  return declspec;
+}
+
 static attr_t *make_attr(enum attr_type type)
 {
   attr_t *a = xmalloc(sizeof(attr_t));
 static attr_t *make_attr(enum attr_type type)
 {
   attr_t *a = xmalloc(sizeof(attr_t));
@@ -1081,207 +1319,6 @@ static attr_t *make_attrp(enum attr_type type, void *val)
   return a;
 }
 
   return a;
 }
 
-static expr_t *make_expr(enum expr_type type)
-{
-  expr_t *e = xmalloc(sizeof(expr_t));
-  e->type = type;
-  e->ref = NULL;
-  e->u.lval = 0;
-  e->is_const = FALSE;
-  e->cval = 0;
-  return e;
-}
-
-static expr_t *make_exprl(enum expr_type type, long val)
-{
-  expr_t *e = xmalloc(sizeof(expr_t));
-  e->type = type;
-  e->ref = NULL;
-  e->u.lval = val;
-  e->is_const = FALSE;
-  /* check for numeric constant */
-  if (type == EXPR_NUM || type == EXPR_HEXNUM || type == EXPR_TRUEFALSE) {
-    /* make sure true/false value is valid */
-    assert(type != EXPR_TRUEFALSE || val == 0 || val == 1);
-    e->is_const = TRUE;
-    e->cval = val;
-  }
-  return e;
-}
-
-static expr_t *make_exprd(enum expr_type type, double val)
-{
-  expr_t *e = xmalloc(sizeof(expr_t));
-  e->type = type;
-  e->ref = NULL;
-  e->u.dval = val;
-  e->is_const = TRUE;
-  e->cval = val;
-  return e;
-}
-
-static expr_t *make_exprs(enum expr_type type, char *val)
-{
-  expr_t *e;
-  e = xmalloc(sizeof(expr_t));
-  e->type = type;
-  e->ref = NULL;
-  e->u.sval = val;
-  e->is_const = FALSE;
-  /* check for predefined constants */
-  if (type == EXPR_IDENTIFIER) {
-    var_t *c = find_const(val, 0);
-    if (c) {
-      e->u.sval = c->name;
-      free(val);
-      e->is_const = TRUE;
-      e->cval = c->eval->cval;
-    }
-  }
-  return e;
-}
-
-static expr_t *make_exprt(enum expr_type type, type_t *tref, expr_t *expr)
-{
-  expr_t *e;
-  e = xmalloc(sizeof(expr_t));
-  e->type = type;
-  e->ref = expr;
-  e->u.tref = tref;
-  e->is_const = FALSE;
-  /* check for cast of constant expression */
-  if (type == EXPR_SIZEOF) {
-    switch (tref->type) {
-      case RPC_FC_BYTE:
-      case RPC_FC_CHAR:
-      case RPC_FC_SMALL:
-      case RPC_FC_USMALL:
-        e->is_const = TRUE;
-        e->cval = 1;
-        break;
-      case RPC_FC_WCHAR:
-      case RPC_FC_USHORT:
-      case RPC_FC_SHORT:
-        e->is_const = TRUE;
-        e->cval = 2;
-        break;
-      case RPC_FC_LONG:
-      case RPC_FC_ULONG:
-      case RPC_FC_FLOAT:
-      case RPC_FC_ERROR_STATUS_T:
-        e->is_const = TRUE;
-        e->cval = 4;
-        break;
-      case RPC_FC_HYPER:
-      case RPC_FC_DOUBLE:
-        e->is_const = TRUE;
-        e->cval = 8;
-        break;
-    }
-  }
-  if (type == EXPR_CAST && expr->is_const) {
-    e->is_const = TRUE;
-    e->cval = expr->cval;
-  }
-  return e;
-}
-
-static expr_t *make_expr1(enum expr_type type, expr_t *expr)
-{
-  expr_t *e;
-  if (type == EXPR_ADDRESSOF && expr->type != EXPR_IDENTIFIER)
-    error_loc("address-of operator applied to invalid expression\n");
-  e = xmalloc(sizeof(expr_t));
-  e->type = type;
-  e->ref = expr;
-  e->u.lval = 0;
-  e->is_const = FALSE;
-  /* check for compile-time optimization */
-  if (expr->is_const) {
-    e->is_const = TRUE;
-    switch (type) {
-    case EXPR_NEG:
-      e->cval = -expr->cval;
-      break;
-    case EXPR_NOT:
-      e->cval = ~expr->cval;
-      break;
-    default:
-      e->is_const = FALSE;
-      break;
-    }
-  }
-  return e;
-}
-
-static expr_t *make_expr2(enum expr_type type, expr_t *expr1, expr_t *expr2)
-{
-  expr_t *e;
-  e = xmalloc(sizeof(expr_t));
-  e->type = type;
-  e->ref = expr1;
-  e->u.ext = expr2;
-  e->is_const = FALSE;
-  /* check for compile-time optimization */
-  if (expr1->is_const && expr2->is_const) {
-    e->is_const = TRUE;
-    switch (type) {
-    case EXPR_ADD:
-      e->cval = expr1->cval + expr2->cval;
-      break;
-    case EXPR_SUB:
-      e->cval = expr1->cval - expr2->cval;
-      break;
-    case EXPR_MUL:
-      e->cval = expr1->cval * expr2->cval;
-      break;
-    case EXPR_DIV:
-      e->cval = expr1->cval / expr2->cval;
-      break;
-    case EXPR_OR:
-      e->cval = expr1->cval | expr2->cval;
-      break;
-    case EXPR_AND:
-      e->cval = expr1->cval & expr2->cval;
-      break;
-    case EXPR_SHL:
-      e->cval = expr1->cval << expr2->cval;
-      break;
-    case EXPR_SHR:
-      e->cval = expr1->cval >> expr2->cval;
-      break;
-    default:
-      e->is_const = FALSE;
-      break;
-    }
-  }
-  return e;
-}
-
-static expr_t *make_expr3(enum expr_type type, expr_t *expr1, expr_t *expr2, expr_t *expr3)
-{
-  expr_t *e;
-  e = xmalloc(sizeof(expr_t));
-  e->type = type;
-  e->ref = expr1;
-  e->u.ext = expr2;
-  e->ext2 = expr3;
-  e->is_const = FALSE;
-  /* check for compile-time optimization */
-  if (expr1->is_const && expr2->is_const && expr3->is_const) {
-    e->is_const = TRUE;
-    switch (type) {
-    case EXPR_COND:
-      e->cval = expr1->cval ? expr2->cval : expr3->cval;
-      break;
-    default:
-      e->is_const = FALSE;
-      break;
-    }
-  }
-  return e;
-}
-
 static expr_list_t *append_expr(expr_list_t *list, expr_t *expr)
 {
     if (!expr) return list;
 static expr_list_t *append_expr(expr_list_t *list, expr_t *expr)
 {
     if (!expr) return list;
@@ -1327,7 +1364,7 @@ void set_all_tfswrite(int val)
     node->data.tfswrite = val;
 }
 
     node->data.tfswrite = val;
 }
 
-static type_t *make_type(unsigned char type, type_t *ref)
+type_t *make_type(unsigned char type, type_t *ref)
 {
   type_t *t = alloc_type();
   t->name = NULL;
 {
   type_t *t = alloc_type();
   t->name = NULL;
@@ -1346,72 +1383,102 @@ static type_t *make_type(unsigned char type, type_t *ref)
   t->ptrdesc = 0;
   t->declarray = FALSE;
   t->ignore = (parse_only != 0);
   t->ptrdesc = 0;
   t->declarray = FALSE;
   t->ignore = (parse_only != 0);
-  t->is_const = FALSE;
   t->sign = 0;
   t->defined = FALSE;
   t->written = FALSE;
   t->user_types_registered = FALSE;
   t->tfswrite = FALSE;
   t->sign = 0;
   t->defined = FALSE;
   t->written = FALSE;
   t->user_types_registered = FALSE;
   t->tfswrite = FALSE;
+  t->checked = FALSE;
   t->typelib_idx = -1;
   return t;
 }
 
   t->typelib_idx = -1;
   return t;
 }
 
-static void set_type(var_t *v, type_t *type, const pident_t *pident, array_dims_t *arr,
+static type_t *make_func_type(var_list_t *args)
+{
+  type_t *t = make_type(RPC_FC_FUNCTION, NULL);
+  t->fields_or_args = args;
+  return t;
+}
+
+static type_t *make_pointer_type(type_t *ref, attr_list_t *attrs)
+{
+    type_t *t = make_type(pointer_default, ref);
+    t->attrs = attrs;
+    return t;
+}
+
+static type_t *append_ptrchain_type(type_t *ptrchain, type_t *type)
+{
+  type_t *ptrchain_type;
+  if (!ptrchain)
+    return type;
+  for (ptrchain_type = ptrchain; ptrchain_type->ref; ptrchain_type = ptrchain_type->ref)
+    ;
+  ptrchain_type->ref = type;
+  return ptrchain;
+}
+
+static void set_type(var_t *v, decl_spec_t *decl_spec, const declarator_t *decl,
                      int top)
 {
   expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS);
   expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS);
   int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE);
                      int top)
 {
   expr_list_t *sizes = get_attrp(v->attrs, ATTR_SIZEIS);
   expr_list_t *lengs = get_attrp(v->attrs, ATTR_LENGTHIS);
   int ptr_attr = get_attrv(v->attrs, ATTR_POINTERTYPE);
-  int ptr_type = ptr_attr;
   int sizeless, has_varconf;
   expr_t *dim;
   type_t *atype, **ptype;
   int sizeless, has_varconf;
   expr_t *dim;
   type_t *atype, **ptype;
-  int ptr_level = (pident ? pident->ptr_level : 0);
+  array_dims_t *arr = decl ? decl->array : NULL;
+  type_t *func_type = decl ? decl->func_type : NULL;
+  type_t *type = decl_spec->type;
 
 
-  v->type = type;
-
-  if (!ptr_type && top)
-    ptr_type = RPC_FC_RP;
-
-  for ( ; 0 < ptr_level; --ptr_level)
+  if (is_attr(type->attrs, ATTR_INLINE))
   {
   {
-    v->type = make_type(pointer_default, v->type);
-    if (ptr_level == 1 && ptr_type && !arr)
+    if (!func_type)
+      error_loc("inline attribute applied to non-function type\n");
+    else
     {
     {
-      v->type->type = ptr_type;
-      ptr_type = 0;
+      type_t *t;
+      /* move inline attribute from return type node to function node */
+      for (t = func_type; is_ptr(t); t = t->ref)
+        ;
+      t->attrs = move_attr(t->attrs, type->attrs, ATTR_INLINE);
     }
   }
 
     }
   }
 
-  if (ptr_type && !arr)
+  /* add type onto the end of the pointers in pident->type */
+  v->type = append_ptrchain_type(decl ? decl->type : NULL, type);
+  v->stgclass = decl_spec->stgclass;
+
+  /* the highest level of pointer specified should default to the var's ptr attr
+   * or (RPC_FC_RP if not specified and it's a top level ptr), not
+   * pointer_default so we need to fix that up here */
+  if (!arr)
   {
   {
-    if (is_ptr(v->type))
+    const type_t *ptr = NULL;
+    /* pointer attributes on the left side of the type belong to the function
+     * pointer, if one is being declared */
+    type_t **pt = func_type ? &func_type : &v->type;
+    for (ptr = *pt; ptr; )
     {
     {
-      if (v->type->type != ptr_type)
-      {
-        v->type = duptype(v->type, 1);
-        v->type->type = ptr_type;
-      }
+      if (ptr->kind == TKIND_ALIAS)
+        ptr = ptr->orig;
+      else
+        break;
     }
     }
-    else if (!arr && ptr_attr)
-      error_loc("%s: pointer attribute applied to non-pointer type\n", v->name);
-  }
-
-  if (pident && pident->is_func) {
-    int func_ptr_level = pident->func_ptr_level;
-    v->type = make_type(RPC_FC_FUNCTION, v->type);
-    v->type->fields_or_args = pident->args;
-    if (pident->callconv)
-      v->type->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, pident->callconv));
-    else if (is_object_interface) {
-      static char *stdmethodcalltype;
-      if (!stdmethodcalltype) stdmethodcalltype = strdup("STDMETHODCALLTYPE");
-      v->type->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, stdmethodcalltype));
+    if (ptr && is_ptr(ptr) && (ptr_attr || top))
+    {
+      /* duplicate type to avoid changing original type */
+      *pt = duptype(*pt, 1);
+      (*pt)->type = ptr_attr ? ptr_attr : RPC_FC_RP;
     }
     }
-    for (; func_ptr_level > 0; func_ptr_level--)
-      v->type = make_type(ptr_type, v->type);
+    else if (ptr_attr)
+       error_loc("%s: pointer attribute applied to non-pointer type\n", v->name);
   }
 
   }
 
+  if (is_attr(v->attrs, ATTR_STRING) && !is_ptr(v->type) && !arr)
+    error_loc("'%s': [string] attribute applied to non-pointer, non-array type\n",
+              v->name);
+
   sizeless = FALSE;
   if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry)
   {
   sizeless = FALSE;
   if (arr) LIST_FOR_EACH_ENTRY_REV(dim, arr, expr_t, entry)
   {
@@ -1524,6 +1591,54 @@ static void set_type(var_t *v, type_t *type, const pident_t *pident, array_dims_
           break;
         }
   }
           break;
         }
   }
+
+  /* v->type is currently pointing the the type on the left-side of the
+   * declaration, so we need to fix this up so that it is the return type of the
+   * function and make v->type point to the function side of the declaration */
+  if (func_type)
+  {
+    type_t *ft, *t;
+    type_t *return_type = v->type;
+    v->type = func_type;
+    for (ft = v->type; is_ptr(ft); ft = ft->ref)
+      ;
+    assert(ft->type == RPC_FC_FUNCTION);
+    ft->ref = return_type;
+    /* move calling convention attribute, if present, from pointer nodes to
+     * function node */
+    for (t = v->type; is_ptr(t); t = t->ref)
+      ft->attrs = move_attr(ft->attrs, t->attrs, ATTR_CALLCONV);
+    if (is_object_interface && !is_attr(ft->attrs, ATTR_CALLCONV))
+    {
+      static char *stdmethodcalltype;
+      if (!stdmethodcalltype) stdmethodcalltype = strdup("STDMETHODCALLTYPE");
+      ft->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, stdmethodcalltype));
+    }
+  }
+  else
+  {
+    type_t *t;
+    for (t = v->type; is_ptr(t); t = t->ref)
+      if (is_attr(t->attrs, ATTR_CALLCONV))
+        error_loc("calling convention applied to non-function-pointer type\n");
+  }
+}
+
+static var_list_t *set_var_types(attr_list_t *attrs, decl_spec_t *decl_spec, declarator_list_t *decls)
+{
+  declarator_t *decl, *next;
+  var_list_t *var_list = NULL;
+
+  LIST_FOR_EACH_ENTRY_SAFE( decl, next, decls, declarator_t, entry )
+  {
+    var_t *var = decl->var;
+
+    var->attrs = attrs;
+    set_type(var, decl_spec, decl, 0);
+    var_list = append_var(var_list, var);
+    free(decl);
+  }
+  return var_list;
 }
 
 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)
@@ -1558,6 +1673,18 @@ static var_list_t *append_var(var_list_t *list, var_t *var)
     return list;
 }
 
     return list;
 }
 
+static var_list_t *append_var_list(var_list_t *list, var_list_t *vars)
+{
+    if (!vars) return list;
+    if (!list)
+    {
+        list = xmalloc( sizeof(*list) );
+        list_init( list );
+    }
+    list_move_tail( list, vars );
+    return list;
+}
+
 static var_t *make_var(char *name)
 {
   var_t *v = xmalloc(sizeof(var_t));
 static var_t *make_var(char *name)
 {
   var_t *v = xmalloc(sizeof(var_t));
@@ -1565,33 +1692,32 @@ static var_t *make_var(char *name)
   v->type = NULL;
   v->attrs = NULL;
   v->eval = NULL;
   v->type = NULL;
   v->attrs = NULL;
   v->eval = NULL;
+  v->stgclass = STG_NONE;
   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;
 }
 
   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 pident_list_t *append_pident(pident_list_t *list, pident_t *p)
+static declarator_list_t *append_declarator(declarator_list_t *list, declarator_t *d)
 {
 {
-  if (!p) return list;
+  if (!d) return list;
   if (!list) {
     list = xmalloc(sizeof(*list));
     list_init(list);
   }
   if (!list) {
     list = xmalloc(sizeof(*list));
     list_init(list);
   }
-  list_add_tail(list, &p->entry);
+  list_add_tail(list, &d->entry);
   return list;
 }
 
   return list;
 }
 
-static pident_t *make_pident(var_t *var)
+static declarator_t *make_declarator(var_t *var)
 {
 {
-  pident_t *p = xmalloc(sizeof(*p));
-  p->var = var;
-  p->is_func = FALSE;
-  p->ptr_level = 0;
-  p->func_ptr_level = 0;
-  p->args = NULL;
-  p->callconv = NULL;
-  return p;
+  declarator_t *d = xmalloc(sizeof(*d));
+  d->var = var;
+  d->type = NULL;
+  d->func_type = NULL;
+  d->array = NULL;
+  return d;
 }
 
 static func_list_t *append_func(func_list_t *list, func_t *func)
 }
 
 static func_list_t *append_func(func_list_t *list, func_t *func)
@@ -1606,11 +1732,11 @@ static func_list_t *append_func(func_list_t *list, func_t *func)
     return list;
 }
 
     return list;
 }
 
-static func_t *make_func(var_t *def, var_list_t *args)
+static func_t *make_func(var_t *def)
 {
   func_t *f = xmalloc(sizeof(func_t));
   f->def = def;
 {
   func_t *f = xmalloc(sizeof(func_t));
   f->def = def;
-  f->args = args;
+  f->args = def->type->fields_or_args;
   f->ignore = parse_only;
   f->idx = -1;
   return f;
   f->ignore = parse_only;
   f->idx = -1;
   return f;
@@ -1618,7 +1744,7 @@ static func_t *make_func(var_t *def, var_list_t *args)
 
 static type_t *make_class(char *name)
 {
 
 static type_t *make_class(char *name)
 {
-  type_t *c = make_type(0, NULL);
+  type_t *c = make_type(RPC_FC_COCLASS, NULL);
   c->name = name;
   c->kind = TKIND_COCLASS;
   return c;
   c->name = name;
   c->kind = TKIND_COCLASS;
   return c;
@@ -1631,6 +1757,17 @@ static type_t *make_safearray(type_t *type)
   return make_type(pointer_default, sa);
 }
 
   return make_type(pointer_default, sa);
 }
 
+static typelib_t *make_library(const char *name, const attr_list_t *attrs)
+{
+    typelib_t *typelib = xmalloc(sizeof(*typelib));
+    typelib->name = xstrdup(name);
+    typelib->filename = NULL;
+    typelib->attrs = attrs;
+    list_init( &typelib->entries );
+    list_init( &typelib->importlibs );
+    return typelib;
+}
+
 #define HASHMAX 64
 
 static int hash_ident(const char *name)
 #define HASHMAX 64
 
 static int hash_ident(const char *name)
@@ -1706,17 +1843,15 @@ static void fix_incomplete(void)
   }
 }
 
   }
 }
 
-static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *attrs)
+static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, attr_list_t *attrs)
 {
 {
-  type_t *ptr = type;
-  const pident_t *pident;
-  int ptrc = 0;
+  const declarator_t *decl;
   int is_str = is_attr(attrs, ATTR_STRING);
   int is_str = is_attr(attrs, ATTR_STRING);
-  unsigned char ptr_type = get_attrv(attrs, ATTR_POINTERTYPE);
+  type_t *type = decl_spec->type;
 
   if (is_str)
   {
 
   if (is_str)
   {
-    type_t *t = type;
+    type_t *t = decl_spec->type;
     unsigned char c;
 
     while (is_ptr(t))
     unsigned char c;
 
     while (is_ptr(t))
@@ -1725,16 +1860,15 @@ static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *a
     c = t->type;
     if (c != RPC_FC_CHAR && c != RPC_FC_BYTE && c != RPC_FC_WCHAR)
     {
     c = t->type;
     if (c != RPC_FC_CHAR && c != RPC_FC_BYTE && c != RPC_FC_WCHAR)
     {
-      pident = LIST_ENTRY( list_head( pidents ), const pident_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",
-              pident->var->name);
+              decl->var->name);
     }
   }
 
   /* We must generate names for tagless enum, struct or union.
      Typedef-ing a tagless enum, struct or union means we want the typedef
     }
   }
 
   /* We must generate names for tagless enum, struct or union.
      Typedef-ing a tagless enum, struct or union means we want the typedef
-     to be included in a library whether it has other attributes or not,
-     hence the public attribute.  */
+     to be included in a library hence the public attribute.  */
   if ((type->kind == TKIND_ENUM || type->kind == TKIND_RECORD
        || type->kind == TKIND_UNION) && ! type->name && ! parse_only)
   {
   if ((type->kind == TKIND_ENUM || type->kind == TKIND_RECORD
        || type->kind == TKIND_UNION) && ! type->name && ! parse_only)
   {
@@ -1742,52 +1876,21 @@ static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *a
       attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) );
     type->name = gen_name();
   }
       attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) );
     type->name = gen_name();
   }
+  else if (is_attr(attrs, ATTR_UUID) && !is_attr(attrs, ATTR_PUBLIC))
+    attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) );
 
 
-  LIST_FOR_EACH_ENTRY( pident, pidents, const pident_t, entry )
+  LIST_FOR_EACH_ENTRY( decl, decls, const declarator_t, entry )
   {
   {
-    var_t *name = pident->var;
+    var_t *name = decl->var;
 
     if (name->name) {
 
     if (name->name) {
-      type_t *cur = ptr;
-      int cptr = pident->ptr_level;
-      if (cptr > ptrc) {
-        while (cptr > ptrc) {
-          cur = ptr = make_type(pointer_default, cur);
-          ptrc++;
-        }
-      } else {
-        while (cptr < ptrc) {
-          cur = cur->ref;
-          cptr++;
-        }
-      }
-      if (pident->is_func) {
-        int func_ptr_level = pident->func_ptr_level;
-        cur = make_type(RPC_FC_FUNCTION, cur);
-        cur->fields_or_args = pident->args;
-        if (pident->callconv)
-          cur->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, pident->callconv));
-        else if (is_object_interface) {
-          static char *stdmethodcalltype;
-          if (!stdmethodcalltype) stdmethodcalltype = strdup("STDMETHODCALLTYPE");
-          cur->attrs = append_attr(NULL, make_attrp(ATTR_CALLCONV, stdmethodcalltype));
-        }
-        for (; func_ptr_level > 0; func_ptr_level--)
-          cur = make_type(pointer_default, cur);
-      }
-      cur = alias(cur, name->name);
+      type_t *cur;
+
+      /* set the attributes to allow set_type to do some checks on them */
+      name->attrs = attrs;
+      set_type(name, decl_spec, decl, 0);
+      cur = alias(name->type, name->name);
       cur->attrs = attrs;
       cur->attrs = attrs;
-      if (ptr_type)
-      {
-        if (is_ptr(cur))
-          cur->type = ptr_type;
-        else
-          error_loc("'%s': pointer attribute applied to non-pointer type\n",
-                  cur->name);
-      }
-      else if (is_str && ! is_ptr(cur))
-        error_loc("'%s': [string] attribute applied to non-pointer type\n",
-                cur->name);
 
       if (is_incomplete(cur))
         add_incomplete(cur);
 
       if (is_incomplete(cur))
         add_incomplete(cur);
@@ -1797,7 +1900,7 @@ static type_t *reg_typedefs(type_t *type, pident_list_t *pidents, attr_list_t *a
   return type;
 }
 
   return type;
 }
 
-static type_t *find_type(const char *name, int t)
+type_t *find_type(const char *name, int t)
 {
   struct rtype *cur = type_hash[hash_ident(name)];
   while (cur && (cur->t != t || strcmp(cur->name, name)))
 {
   struct rtype *cur = type_hash[hash_ident(name)];
   while (cur && (cur->t != t || strcmp(cur->name, name)))
@@ -2038,7 +2141,7 @@ static var_t *reg_const(var_t *var)
   return var;
 }
 
   return var;
 }
 
-static var_t *find_const(char *name, int f)
+var_t *find_const(const char *name, int f)
 {
   struct rconst *cur = const_hash[hash_ident(name)];
   while (cur && strcmp(cur->name, name))
 {
   struct rconst *cur = const_hash[hash_ident(name)];
   while (cur && strcmp(cur->name, name))
@@ -2050,10 +2153,10 @@ static var_t *find_const(char *name, int f)
   return cur->var;
 }
 
   return cur->var;
 }
 
-static void write_libid(const char *name, const attr_list_t *attr)
+static void write_libid(const typelib_t *typelib)
 {
 {
-  const UUID *uuid = get_attrp(attr, ATTR_UUID);
-  write_guid(idfile, "LIBID", name, uuid);
+  const UUID *uuid = get_attrp(typelib->attrs, ATTR_UUID);
+  write_guid(idfile, "LIBID", typelib->name, uuid);
 }
 
 static void write_clsid(type_t *cls)
 }
 
 static void write_clsid(type_t *cls)
@@ -2119,26 +2222,6 @@ static char *gen_name(void)
   return name;
 }
 
   return name;
 }
 
-static void process_typedefs(pident_list_t *pidents)
-{
-  pident_t *pident, *next;
-
-  if (!pidents) return;
-  LIST_FOR_EACH_ENTRY_SAFE( pident, next, pidents, pident_t, entry )
-  {
-    var_t *var = pident->var;
-    type_t *type = find_type(var->name, 0);
-
-    if (! parse_only && do_header)
-      write_typedef(type);
-    if (in_typelib && type->attrs)
-      add_typelib_entry(type);
-
-    free(pident);
-    free(var);
-  }
-}
-
 struct allowed_attr
 {
     unsigned int dce_compatible : 1;
 struct allowed_attr
 {
     unsigned int dce_compatible : 1;
@@ -2165,22 +2248,21 @@ struct allowed_attr allowed_attr[] =
     /* ATTR_BINDABLE */         { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "bindable" },
     /* ATTR_BROADCAST */        { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "broadcast" },
     /* ATTR_CALLAS */           { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "call_as" },
     /* ATTR_BINDABLE */         { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "bindable" },
     /* ATTR_BROADCAST */        { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "broadcast" },
     /* ATTR_CALLAS */           { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "call_as" },
-    /* ATTR_CALLCONV */         { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
+    /* ATTR_CALLCONV */         { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, NULL },
     /* ATTR_CASE */             { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
     /* ATTR_CASE */             { 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, "case" },
+    /* ATTR_CONST */            { 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, "context_handle" },
     /* ATTR_CONTROL */          { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
     /* ATTR_DEFAULT */          { 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, "default" },
     /* ATTR_DEFAULTCOLLELEM */  { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" },
     /* ATTR_CONTEXTHANDLE */    { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "context_handle" },
     /* ATTR_CONTROL */          { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, "control" },
     /* ATTR_DEFAULT */          { 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, "default" },
     /* ATTR_DEFAULTCOLLELEM */  { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "defaultcollelem" },
-    /* ATTR_DEFAULTVALUE_EXPR */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "defaultvalue" },
-    /* ATTR_DEFAULTVALUE_STRING */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "defaultvalue" },
+    /* ATTR_DEFAULTVALUE */     { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "defaultvalue" },
     /* ATTR_DEFAULTVTABLE */    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "defaultvtable" },
     /* ATTR_DISPINTERFACE */    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
     /* ATTR_DISPLAYBIND */      { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "displaybind" },
     /* ATTR_DLLNAME */          { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "dllname" },
     /* ATTR_DUAL */             { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "dual" },
     /* ATTR_ENDPOINT */         { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" },
     /* ATTR_DEFAULTVTABLE */    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "defaultvtable" },
     /* ATTR_DISPINTERFACE */    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL },
     /* ATTR_DISPLAYBIND */      { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "displaybind" },
     /* ATTR_DLLNAME */          { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, "dllname" },
     /* ATTR_DUAL */             { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "dual" },
     /* ATTR_ENDPOINT */         { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, "endpoint" },
-    /* ATTR_ENTRY_ORDINAL */    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "entry" },
-    /* ATTR_ENTRY_STRING */     { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "entry" },
+    /* ATTR_ENTRY */            { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "entry" },
     /* ATTR_EXPLICIT_HANDLE */  { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" },
     /* ATTR_HANDLE */           { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "handle" },
     /* ATTR_HELPCONTEXT */      { 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, "helpcontext" },
     /* ATTR_EXPLICIT_HANDLE */  { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, "explicit_handle" },
     /* ATTR_HANDLE */           { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, "handle" },
     /* ATTR_HELPCONTEXT */      { 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, "helpcontext" },
@@ -2195,8 +2277,10 @@ struct allowed_attr allowed_attr[] =
     /* ATTR_IMMEDIATEBIND */    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
     /* ATTR_IMPLICIT_HANDLE */  { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
     /* ATTR_IN */               { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "in" },
     /* ATTR_IMMEDIATEBIND */    { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "immediatebind" },
     /* ATTR_IMPLICIT_HANDLE */  { 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, "implicit_handle" },
     /* ATTR_IN */               { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, "in" },
+    /* ATTR_INLINE */           { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inline" },
     /* ATTR_INPUTSYNC */        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
     /* ATTR_LENGTHIS */         { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, "length_is" },
     /* ATTR_INPUTSYNC */        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "inputsync" },
     /* ATTR_LENGTHIS */         { 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, "length_is" },
+    /* ATTR_LIBLCID */          { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, "lcid" },
     /* ATTR_LOCAL */            { 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, "local" },
     /* ATTR_NONBROWSABLE */     { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" },
     /* ATTR_NONCREATABLE */     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "noncreatable" },
     /* ATTR_LOCAL */            { 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, "local" },
     /* ATTR_NONBROWSABLE */     { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, "nonbrowsable" },
     /* ATTR_NONCREATABLE */     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, "noncreatable" },
@@ -2236,7 +2320,7 @@ const char *get_attr_display_name(enum attr_type type)
     return allowed_attr[type].display_name;
 }
 
     return allowed_attr[type].display_name;
 }
 
-static const attr_list_t *check_iface_attrs(const char *name, const attr_list_t *attrs)
+static attr_list_t *check_iface_attrs(const char *name, attr_list_t *attrs)
 {
   const attr_t *attr;
   if (!attrs) return attrs;
 {
   const attr_t *attr;
   if (!attrs) return attrs;
@@ -2307,7 +2391,7 @@ static attr_list_t *check_field_attrs(const char *name, attr_list_t *attrs)
   return attrs;
 }
 
   return attrs;
 }
 
-static const attr_list_t *check_library_attrs(const char *name, const attr_list_t *attrs)
+static attr_list_t *check_library_attrs(const char *name, attr_list_t *attrs)
 {
   const attr_t *attr;
   if (!attrs) return attrs;
 {
   const attr_t *attr;
   if (!attrs) return attrs;
@@ -2333,7 +2417,7 @@ static attr_list_t *check_dispiface_attrs(const char *name, attr_list_t *attrs)
   return attrs;
 }
 
   return attrs;
 }
 
-static const attr_list_t *check_module_attrs(const char *name, const attr_list_t *attrs)
+static attr_list_t *check_module_attrs(const char *name, attr_list_t *attrs)
 {
   const attr_t *attr;
   if (!attrs) return attrs;
 {
   const attr_t *attr;
   if (!attrs) return attrs;
@@ -2346,7 +2430,7 @@ static const attr_list_t *check_module_attrs(const char *name, const attr_list_t
   return attrs;
 }
 
   return attrs;
 }
 
-static const attr_list_t *check_coclass_attrs(const char *name, const attr_list_t *attrs)
+static attr_list_t *check_coclass_attrs(const char *name, attr_list_t *attrs)
 {
   const attr_t *attr;
   if (!attrs) return attrs;
 {
   const attr_t *attr;
   if (!attrs) return attrs;
@@ -2359,6 +2443,183 @@ static const attr_list_t *check_coclass_attrs(const char *name, const attr_list_
   return attrs;
 }
 
   return attrs;
 }
 
+static int is_allowed_conf_type(const type_t *type)
+{
+    switch (type->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_ENUM16:
+    case RPC_FC_USHORT:
+    case RPC_FC_LONG:
+    case RPC_FC_ENUM32:
+    case RPC_FC_ULONG:
+        return TRUE;
+    default:
+        return FALSE;
+    }
+}
+
+static int is_ptr_guid_type(const type_t *type)
+{
+    unsigned int align = 0;
+    for (;;)
+    {
+        if (type->kind == TKIND_ALIAS)
+            type = type->orig;
+        else if (is_ptr(type))
+        {
+            type = type->ref;
+            break;
+        }
+        else
+            return FALSE;
+    }
+    return (type_memsize(type, &align) == 16);
+}
+
+static void check_conformance_expr_list(const char *attr_name, const var_t *arg, const type_t *container_type, expr_list_t *expr_list)
+{
+    expr_t *dim;
+    struct expr_loc expr_loc;
+    expr_loc.v = arg;
+    expr_loc.attr = attr_name;
+    if (expr_list) LIST_FOR_EACH_ENTRY(dim, expr_list, expr_t, entry)
+    {
+        if (dim->type != EXPR_VOID)
+        {
+            const type_t *expr_type = expr_resolve_type(&expr_loc, container_type, dim);
+            if (!is_allowed_conf_type(expr_type))
+                error_loc_info(&arg->loc_info, "expression must resolve to integral type <= 32bits for attribute %s\n",
+                               attr_name);
+        }
+    }
+}
+
+static void check_remoting_fields(const var_t *var, type_t *type);
+
+/* checks that properties common to fields and arguments are consistent */
+static void check_field_common(const type_t *container_type,
+                               const char *container_name, const var_t *arg)
+{
+    type_t *type = arg->type;
+    int is_wire_marshal = 0;
+    int is_context_handle = 0;
+    const char *container_type_name = NULL;
+
+    if (is_struct(container_type->type))
+        container_type_name = "struct";
+    else if (is_union(container_type->type))
+        container_type_name = "union";
+    else if (container_type->type == RPC_FC_FUNCTION)
+        container_type_name = "function";
+
+    if (is_attr(arg->attrs, ATTR_LENGTHIS) &&
+        (is_attr(arg->attrs, ATTR_STRING) || is_aliaschain_attr(arg->type, ATTR_STRING)))
+        error_loc_info(&arg->loc_info,
+                       "string and length_is specified for argument %s are mutually exclusive attributes\n",
+                       arg->name);
+
+    if (is_attr(arg->attrs, ATTR_SIZEIS))
+    {
+        expr_list_t *size_is_exprs = get_attrp(arg->attrs, ATTR_SIZEIS);
+        check_conformance_expr_list("size_is", arg, container_type, size_is_exprs);
+    }
+    if (is_attr(arg->attrs, ATTR_LENGTHIS))
+    {
+        expr_list_t *length_is_exprs = get_attrp(arg->attrs, ATTR_LENGTHIS);
+        check_conformance_expr_list("length_is", arg, container_type, length_is_exprs);
+    }
+    if (is_attr(arg->attrs, ATTR_IIDIS))
+    {
+        struct expr_loc expr_loc;
+        expr_t *expr = get_attrp(arg->attrs, ATTR_IIDIS);
+        if (expr->type != EXPR_VOID)
+        {
+            const type_t *expr_type;
+            expr_loc.v = arg;
+            expr_loc.attr = "iid_is";
+            expr_type = expr_resolve_type(&expr_loc, container_type, expr);
+            if (!expr_type || !is_ptr_guid_type(expr_type))
+                error_loc_info(&arg->loc_info, "expression must resolve to pointer to GUID type for attribute iid_is\n");
+        }
+    }
+    if (is_attr(arg->attrs, ATTR_SWITCHIS))
+    {
+        struct expr_loc expr_loc;
+        expr_t *expr = get_attrp(arg->attrs, ATTR_SWITCHIS);
+        if (expr->type != EXPR_VOID)
+        {
+            const type_t *expr_type;
+            expr_loc.v = arg;
+            expr_loc.attr = "switch_is";
+            expr_type = expr_resolve_type(&expr_loc, container_type, expr);
+            if (!expr_type || !is_allowed_conf_type(expr_type))
+                error_loc_info(&arg->loc_info, "expression must resolve to integral type <= 32bits for attribute %s\n",
+                               expr_loc.attr);
+        }
+    }
+
+    /* get fundamental type for the argument */
+    for (;;)
+    {
+        if (is_attr(type->attrs, ATTR_WIREMARSHAL))
+        {
+            is_wire_marshal = 1;
+            break;
+        }
+        if (is_attr(type->attrs, ATTR_CONTEXTHANDLE))
+        {
+            is_context_handle = 1;
+            break;
+        }
+        if (type->kind == TKIND_ALIAS)
+            type = type->orig;
+        else if (is_ptr(type) || is_array(type))
+            type = type->ref;
+        else
+            break;
+    }
+
+    if (type->type == 0 && !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);
+    else if (type->type == RPC_FC_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);
+    else if (!is_wire_marshal && (is_struct(type->type) || is_union(type->type)))
+        check_remoting_fields(arg, type);
+}
+
+static void check_remoting_fields(const var_t *var, type_t *type)
+{
+    const var_t *field;
+    const var_list_t *fields = NULL;
+
+    if (type->checked)
+        return;
+
+    type->checked = TRUE;
+
+    if (is_struct(type->type))
+        fields = type->fields_or_args;
+    else if (is_union(type->type))
+    {
+        if (type->type == RPC_FC_ENCAPSULATED_UNION)
+        {
+            const var_t *uv = LIST_ENTRY(list_tail(type->fields_or_args), const var_t, entry);
+            fields = uv->type->fields_or_args;
+        }
+        else
+            fields = type->fields_or_args;
+    }
+
+    if (fields) LIST_FOR_EACH_ENTRY( field, type->fields_or_args, const var_t, entry )
+        if (field->type) check_field_common(type, type->name, field);
+}
+
 /* checks that arguments for a function make sense for marshalling and unmarshalling */
 static void check_remoting_args(const func_t *func)
 {
 /* checks that arguments for a function make sense for marshalling and unmarshalling */
 static void check_remoting_args(const func_t *func)
 {
@@ -2369,16 +2630,14 @@ static void check_remoting_args(const func_t *func)
     {
         int ptr_level = 0;
         const type_t *type = arg->type;
     {
         int ptr_level = 0;
         const type_t *type = arg->type;
-        int is_wire_marshal = 0;
-        int is_context_handle = 0;
 
         /* get pointer level and fundamental type for the argument */
         for (;;)
         {
 
         /* get pointer level and fundamental type for the argument */
         for (;;)
         {
-            if (!is_wire_marshal && is_attr(type->attrs, ATTR_WIREMARSHAL))
-                is_wire_marshal = 1;
-            if (!is_context_handle && is_attr(type->attrs, ATTR_CONTEXTHANDLE))
-                is_context_handle = 1;
+            if (is_attr(type->attrs, ATTR_WIREMARSHAL))
+                break;
+            if (is_attr(type->attrs, ATTR_CONTEXTHANDLE))
+                break;
             if (type->kind == TKIND_ALIAS)
                 type = type->orig;
             else if (is_ptr(type))
             if (type->kind == TKIND_ALIAS)
                 type = type->orig;
             else if (is_ptr(type))
@@ -2402,15 +2661,52 @@ static void check_remoting_args(const func_t *func)
             }
         }
 
             }
         }
 
-        if (type->type == 0 && !is_attr(arg->attrs, ATTR_IIDIS) && !is_wire_marshal && !is_context_handle)
-            error_loc_info(&arg->loc_info, "parameter \'%s\' of function \'%s\' cannot derive from void *\n", arg->name, funcname);
-        else if (type->type == RPC_FC_FUNCTION)
-            error_loc_info(&arg->loc_info, "parameter \'%s\' of function \'%s\' cannot be a function pointer\n", arg->name, funcname);
+        check_field_common(func->def->type, funcname, arg);
+    }
+}
+
+static void add_explicit_handle_if_necessary(func_t *func)
+{
+    const var_t* explicit_handle_var;
+    const var_t* explicit_generic_handle_var = NULL;
+    const var_t* context_handle_var = NULL;
+
+    /* check for a defined binding handle */
+    explicit_handle_var = get_explicit_handle_var(func);
+    if (!explicit_handle_var)
+    {
+        explicit_generic_handle_var = get_explicit_generic_handle_var(func);
+        if (!explicit_generic_handle_var)
+        {
+            context_handle_var = get_context_handle_var(func);
+            if (!context_handle_var)
+            {
+                /* no explicit handle specified so add
+                 * "[in] handle_t IDL_handle" as the first parameter to the
+                 * 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("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_init( func->def->type->fields_or_args );
+                }
+                list_add_head( func->def->type->fields_or_args, &idl_handle->entry );
+                func->args = func->def->type->fields_or_args;
+            }
+        }
     }
 }
 
 static void check_functions(const type_t *iface)
 {
     }
 }
 
 static void check_functions(const type_t *iface)
 {
+    if (is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE) && iface->funcs)
+    {
+        func_t *func;
+        LIST_FOR_EACH_ENTRY( func, iface->funcs, func_t, entry )
+            add_explicit_handle_if_necessary(func);
+    }
     if (!is_inside_library && !is_attr(iface->attrs, ATTR_LOCAL))
     {
         const func_t *func;
     if (!is_inside_library && !is_attr(iface->attrs, ATTR_LOCAL))
     {
         const func_t *func;
@@ -2422,16 +2718,21 @@ static void check_functions(const type_t *iface)
     }
 }
 
     }
 }
 
-static void check_all_user_types(ifref_list_t *ifrefs)
+static void check_all_user_types(const statement_list_t *stmts)
 {
 {
-  const ifref_t *ifref;
-  const func_t *f;
+  const statement_t *stmt;
 
 
-  if (ifrefs) LIST_FOR_EACH_ENTRY(ifref, ifrefs, const ifref_t, entry)
+  if (stmts) LIST_FOR_EACH_ENTRY(stmt, stmts, const statement_t, entry)
   {
   {
-    const func_list_t *fs = ifref->iface->funcs;
-    if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry)
-      check_for_additional_prototype_types(f->args);
+    if (stmt->type == STMT_LIBRARY)
+      check_all_user_types(stmt->u.lib->stmts);
+    else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
+    {
+      const func_t *f;
+      const func_list_t *fs = stmt->u.type->funcs;
+      if (fs) LIST_FOR_EACH_ENTRY(f, fs, const func_t, entry)
+        check_for_additional_prototype_types(f->args);
+    }
   }
 }
 
   }
 }
 
@@ -2451,3 +2752,135 @@ int is_valid_uuid(const char *s)
 
   return s[i] == '\0';
 }
 
   return s[i] == '\0';
 }
+
+static statement_t *make_statement(enum statement_type type)
+{
+    statement_t *stmt = xmalloc(sizeof(*stmt));
+    stmt->type = type;
+    return stmt;
+}
+
+static statement_t *make_statement_type_decl(type_t *type)
+{
+    statement_t *stmt = make_statement(STMT_TYPE);
+    stmt->u.type = type;
+    return stmt;
+}
+
+static statement_t *make_statement_reference(type_t *type)
+{
+    statement_t *stmt = make_statement(STMT_TYPEREF);
+    stmt->u.type = type;
+    return stmt;
+}
+
+static statement_t *make_statement_declaration(var_t *var)
+{
+    statement_t *stmt = make_statement(STMT_DECLARATION);
+    stmt->u.var = var;
+    if (var->stgclass == STG_EXTERN && var->eval)
+        warning("'%s' initialised and declared extern\n", var->name);
+    if (is_const_decl(var))
+    {
+        if (var->eval)
+            reg_const(var);
+    }
+    else if ((var->stgclass == STG_NONE || var->stgclass == STG_REGISTER) &&
+             var->type->type != RPC_FC_FUNCTION)
+        error_loc("instantiation of data is illegal\n");
+    return stmt;
+}
+
+static statement_t *make_statement_library(typelib_t *typelib)
+{
+    statement_t *stmt = make_statement(STMT_LIBRARY);
+    stmt->u.lib = typelib;
+    return stmt;
+}
+
+static statement_t *make_statement_cppquote(const char *str)
+{
+    statement_t *stmt = make_statement(STMT_CPPQUOTE);
+    stmt->u.str = str;
+    return stmt;
+}
+
+static statement_t *make_statement_importlib(const char *str)
+{
+    statement_t *stmt = make_statement(STMT_IMPORTLIB);
+    stmt->u.str = str;
+    return stmt;
+}
+
+static statement_t *make_statement_import(const char *str)
+{
+    statement_t *stmt = make_statement(STMT_IMPORT);
+    stmt->u.str = str;
+    return stmt;
+}
+
+static statement_t *make_statement_module(type_t *type)
+{
+    statement_t *stmt = make_statement(STMT_MODULE);
+    stmt->u.type = type;
+    return stmt;
+}
+
+static statement_t *process_typedefs(declarator_list_t *decls)
+{
+    declarator_t *decl, *next;
+    statement_t *stmt;
+    type_list_t **type_list;
+
+    if (!decls) return NULL;
+
+    stmt = make_statement(STMT_TYPEDEF);
+    stmt->u.type_list = NULL;
+    type_list = &stmt->u.type_list;
+
+    LIST_FOR_EACH_ENTRY_SAFE( decl, next, decls, declarator_t, entry )
+    {
+        var_t *var = decl->var;
+        type_t *type = find_type(var->name, 0);
+        *type_list = xmalloc(sizeof(type_list_t));
+        (*type_list)->type = type;
+        (*type_list)->next = NULL;
+
+        if (! parse_only && do_header)
+            write_typedef(type);
+        if (in_typelib && is_attr(type->attrs, ATTR_PUBLIC))
+            add_typelib_entry(type);
+
+        type_list = &(*type_list)->next;
+        free(decl);
+        free(var);
+    }
+
+    return stmt;
+}
+
+static statement_list_t *append_statement(statement_list_t *list, statement_t *stmt)
+{
+    if (!stmt) return list;
+    if (!list)
+    {
+        list = xmalloc( sizeof(*list) );
+        list_init( list );
+    }
+    list_add_tail( list, &stmt->entry );
+    return list;
+}
+
+static func_list_t *append_func_from_statement(func_list_t *list, statement_t *stmt)
+{
+    if (stmt->type == STMT_DECLARATION)
+    {
+        var_t *var = stmt->u.var;
+        if (var->stgclass == STG_NONE && var->type->type == RPC_FC_FUNCTION)
+        {
+            check_function_attrs(var->name, var->type->attrs);
+            return append_func(list, make_func(stmt->u.var));
+        }
+    }
+    return list;
+}
index 69cc859..c2c613c 100644 (file)
@@ -301,23 +301,25 @@ static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
        *yy_cp = '\0'; \
        yy_c_buf_p = yy_cp;
 
        *yy_cp = '\0'; \
        yy_c_buf_p = yy_cp;
 
-#define YY_NUM_RULES 23
-#define YY_END_OF_BUFFER 24
-static yyconst short int yy_accept[113] =
+#define YY_NUM_RULES 32
+#define YY_END_OF_BUFFER 33
+static yyconst short int yy_accept[139] =
     {   0,
     {   0,
-        0,    0,    0,    0,    0,    0,    2,    2,   24,   22,
-       19,   18,    3,   14,   14,   22,   22,   17,   17,    9,
-       19,    1,    8,   23,    4,    8,   14,   14,   11,   11,
-       10,    2,    0,   14,    0,   20,   21,   17,   17,    0,
-        1,    1,    7,    6,    5,   14,    0,   11,   11,    2,
-       15,   13,   17,   14,    0,   11,    0,   17,   14,    0,
-       11,    0,   15,   17,   14,    0,   11,   17,   14,    0,
-       11,   17,   14,    0,   11,   17,   14,    0,   11,   17,
-        0,   14,    0,   16,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    2,    2,
+       33,   31,   21,   20,   31,    3,   31,   31,   16,   16,
+       31,   31,   31,   19,   19,   19,   11,   31,   21,    1,
+       10,   32,    4,   10,    6,   16,   16,   13,   13,   13,
+       12,    2,   26,   30,   24,    0,   16,   16,   16,    0,
+       22,   28,   25,   27,   23,   19,    5,   19,   29,    0,
+        1,    1,    9,    8,    7,   16,    0,   13,   13,    2,
+       17,   16,   16,   15,   19,   16,    0,   13,    0,   15,
+       15,   19,   16,    0,   13,    0,   17,   15,   15,   19,
+       16,    0,   13,   19,   16,    0,   13,   19,   16,    0,
+
+       13,   19,   16,    0,   13,   19,    0,   16,    0,   18,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-       12,    0
+        0,    0,    0,    0,    0,    0,   14,    0
     } ;
 
 static yyconst int yy_ec[256] =
     } ;
 
 static yyconst int yy_ec[256] =
@@ -325,17 +327,17 @@ static yyconst int yy_ec[256] =
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         1,    2,    2,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
         1,    2,    2,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    2,    1,    4,    5,    1,    1,    1,    1,    6,
-        1,    1,    7,    1,    8,    9,    1,   10,   11,   11,
-       11,   11,   11,   11,   11,   11,   11,    1,    1,   12,
-        1,   13,    1,    1,   14,   15,   15,   15,   16,   17,
-       18,   18,   18,   18,   18,   18,   18,   18,   18,   18,
-       18,   19,   20,   18,   18,   18,   18,   18,   21,   18,
-       22,   23,   24,    1,   18,    1,   15,   15,   15,   15,
-
-       25,   15,   18,   18,   18,   18,   18,   18,   18,   18,
-       18,   18,   18,   18,   18,   18,   18,   18,   18,   26,
-       18,   18,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    4,    5,    6,    1,    1,    7,    1,    8,
+        1,    1,    9,    1,   10,   11,    1,   12,   13,   13,
+       13,   13,   13,   13,   13,   13,   13,    1,    1,   14,
+       15,   16,    1,    1,   17,   18,   18,   18,   19,   20,
+       21,   21,   21,   21,   21,   22,   21,   21,   21,   21,
+       21,   23,   24,   21,   25,   21,   21,   26,   27,   21,
+       28,   29,   30,    1,   21,    1,   18,   18,   18,   18,
+
+       31,   18,   21,   21,   21,   21,   21,   32,   21,   21,
+       21,   21,   21,   21,   21,   21,   33,   21,   21,   34,
+       21,   21,    1,   35,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -352,125 +354,182 @@ static yyconst int yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
         1,    1,    1,    1,    1
     } ;
 
-static yyconst int yy_meta[27] =
+static yyconst int yy_meta[36] =
     {   0,
     {   0,
-        1,    1,    2,    1,    1,    1,    1,    1,    1,    3,
-        3,    1,    1,    3,    3,    3,    3,    4,    4,    4,
-        4,    1,    1,    1,    3,    5
+        1,    1,    2,    1,    1,    1,    1,    1,    1,    1,
+        1,    3,    3,    1,    1,    1,    3,    3,    3,    3,
+        4,    4,    4,    4,    4,    4,    4,    1,    1,    1,
+        3,    4,    4,    4,    1
     } ;
 
     } ;
 
-static yyconst short int yy_base[151] =
+static yyconst short int yy_base[175] =
     {   0,
     {   0,
-        0,   25,   25,   28,   42,   31,  265,  264,  266,  269,
-      269,  269,  269,   60,   28,  253,  251,    0,  249,  269,
-       38,  260,  269,  269,  269,   31,   39,   62,   79,    0,
-      269,    0,   31,   35,    0,  269,  269,    0,  244,   72,
-      258,  257,  269,  269,  269,   65,    0,   96,    0,    0,
-      113,    0,  242,   68,    0,  129,  149,  240,   70,    0,
-      151,   72,   74,  229,   81,    0,  168,  224,   91,    0,
-      185,  212,   98,    0,  202,  204,  117,  216,  207,  124,
-        0,  108,  129,  269,    0,    0,    0,  206,    0,    0,
-        0,    0,  201,    0,    0,    0,    0,  200,    0,    0,
-
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-      269,  269,  228,  233,  236,  241,  244,  247,  252,  204,
-      195,  194,  189,  188,  187,  178,  177,  172,  171,  170,
-      161,  160,  155,  150,  149,  148,  139,  138,  134,  133,
-      131,  130,  129,  117,  100,   84,   61,   52,   44,   31
+        0,   34,   34,   38,   39,   42,   71,   44,  268,  267,
+      265,  491,  491,  491,  249,  491,  256,  241,   96,   22,
+       37,  241,   38,    0,  250,  237,  491,  218,   53,  249,
+      491,  491,  491,   33,  491,  119,   23,  142,  165,  245,
+      491,    0,  491,  491,  491,   48,    0,   33,   88,    0,
+      491,  491,  491,  491,  491,    0,  491,  228,  491,   63,
+      241,  240,  491,  491,  491,  185,    0,  207,    0,    0,
+      104,  491,  491,  124,  222,  227,    0,  249,  102,   94,
+      102,  220,  269,    0,  291,  113,  168,  491,  491,  213,
+      311,    0,  333,  212,  353,    0,  375,  217,  395,    0,
+
+      417,  206,  439,  222,  221,   62,    0,  220,  140,  491,
+        0,    0,    0,  219,    0,    0,    0,    0,  218,    0,
+        0,    0,    0,  213,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,  491,  491,  472,  476,
+      478,  482,  486,  219,  218,  212,  211,  210,  209,  208,
+      206,  205,  203,  198,  197,  192,  191,  190,  189,  188,
+      187,  186,  185,  183,  176,  169,  168,  167,  155,  144,
+      140,  137,  130,  110
     } ;
 
     } ;
 
-static yyconst short int yy_def[151] =
+static yyconst short int yy_def[175] =
     {   0,
     {   0,
-      112,    1,  113,  113,    1,    5,  114,  114,  112,  112,
-      112,  112,  112,  112,  112,  112,  112,  115,  115,  112,
-      112,  112,  112,  112,  112,  116,  117,  117,  112,  118,
-      112,  119,  112,  112,  120,  112,  112,  115,  115,  112,
-      112,  112,  112,  112,  112,  121,  121,  112,  118,  119,
-      112,  120,  115,  122,  122,  112,  112,  115,  123,  123,
-      112,  112,   51,  115,  124,  124,  112,  115,  125,  125,
-      112,  115,  126,  126,  112,  115,  112,  112,  118,  115,
-      127,  112,  112,  112,  128,  129,  130,  112,  131,  132,
-      133,  134,  112,  135,  136,  137,  138,  112,  139,  140,
-
-      141,  142,  143,  144,  145,  146,  147,  148,  149,  150,
-      112,    0,  112,  112,  112,  112,  112,  112,  112,  112,
-      112,  112,  112,  112,  112,  112,  112,  112,  112,  112,
-      112,  112,  112,  112,  112,  112,  112,  112,  112,  112,
-      112,  112,  112,  112,  112,  112,  112,  112,  112,  112
+      138,    1,  139,  139,  139,  139,  138,    7,  140,  140,
+      138,  138,  138,  138,  138,  138,  138,  138,  138,   19,
+      138,  138,  138,  141,  141,  141,  138,  138,  138,  138,
+      138,  138,  138,  142,  138,  138,   36,  138,   38,   39,
+      138,  143,  138,  138,  138,  138,   20,  138,  138,  144,
+      138,  138,  138,  138,  138,  141,  138,  141,  138,  138,
+      138,  138,  138,  138,  138,  138,  145,   39,   39,  143,
+      138,  138,  138,  144,  141,  138,  146,   39,  138,  138,
+      138,  141,  138,  147,   39,  138,  138,  138,  138,  141,
+      138,  148,   39,  141,  138,  149,   39,  141,  138,  150,
+
+       39,  141,  138,  138,   39,  141,  151,  103,  138,  138,
+      152,  153,  154,  138,  155,  156,  157,  158,  138,  159,
+      160,  161,  162,  138,  163,  164,  165,  166,  167,  168,
+      169,  170,  171,  172,  173,  174,  138,    0,  138,  138,
+      138,  138,  138,  138,  138,  138,  138,  138,  138,  138,
+      138,  138,  138,  138,  138,  138,  138,  138,  138,  138,
+      138,  138,  138,  138,  138,  138,  138,  138,  138,  138,
+      138,  138,  138,  138
     } ;
 
     } ;
 
-static yyconst short int yy_nxt[296] =
+static yyconst short int yy_nxt[527] =
     {   0,
     {   0,
-       10,   11,   12,   13,   10,   10,   10,   10,   10,   14,
-       15,   16,   17,   18,   18,   18,   18,   18,   18,   19,
-       18,   20,   10,   10,   18,   18,   21,   24,   25,   22,
-       24,   25,   21,  111,   44,   22,   33,   34,   34,   40,
-       51,   51,   41,   33,   34,   34,  110,   26,   46,   46,
-       26,   27,   28,   45,  109,   29,   29,   29,   29,   30,
-       30,   30,   30,  108,   35,   31,   29,   30,   33,   34,
-       34,   46,   46,   40,   54,   54,   41,   59,   59,   65,
-       65,   63,   63,   63,   63,   35,  107,  112,   48,   48,
-       69,   69,   48,   48,   48,   48,   49,   49,   49,   49,
-
-       73,   73,  106,   48,   49,   56,   56,   77,   77,   56,
-       56,   56,   56,   49,   49,   49,   49,   82,   82,  105,
-       56,   49,   51,   51,   81,   83,   82,   82,   57,   84,
-       83,  104,  103,  102,   84,  101,  100,   57,   61,   61,
-       98,   97,   61,   61,   61,   61,   49,   49,   49,   49,
-       96,   95,   93,   61,   49,   62,   62,   92,   63,   63,
-       67,   67,   91,   90,   67,   67,   67,   67,   49,   49,
-       49,   49,   88,   87,   86,   67,   49,   71,   71,   85,
-       78,   71,   71,   71,   71,   49,   49,   49,   49,   74,
-       70,   66,   71,   49,   75,   75,   60,   55,   75,   75,
-
-       75,   75,   49,   49,   49,   49,   52,   99,   94,   75,
-       49,   79,   79,   89,   81,   79,   79,   79,   79,   49,
-       49,   49,   49,   81,   80,   76,   79,   49,   23,   23,
-       23,   23,   23,   32,   32,   32,   32,   32,   38,   38,
-       38,   43,   72,   43,   43,   43,   47,   68,   47,   49,
-       49,   49,   50,   64,   50,   50,   50,   58,   42,   42,
-       53,   42,   39,   37,   36,  112,   24,   24,    9,  112,
-      112,  112,  112,  112,  112,  112,  112,  112,  112,  112,
-      112,  112,  112,  112,  112,  112,  112,  112,  112,  112,
-      112,  112,  112,  112,  112
-
+       12,   13,   14,   15,   16,   12,   17,   12,   12,   18,
+       12,   19,   20,   21,   22,   23,   24,   24,   24,   24,
+       24,   25,   24,   26,   24,   24,   24,   27,   12,   12,
+       24,   24,   24,   24,   28,   29,   32,   64,   33,   30,
+       32,   32,   33,   35,   32,   29,   35,  138,  138,   30,
+       51,   52,   54,   55,   60,  138,  138,   72,   61,   71,
+       71,   65,   34,  109,   60,   72,   34,   34,   61,  110,
+       34,   12,   13,   14,   15,   16,   12,   17,   12,   12,
+       18,   12,   36,   37,   21,   22,   23,   38,   38,   38,
+       38,   39,   40,   39,   39,   39,   39,   39,   27,   12,
+
+       41,   38,   39,   39,   39,   28,   46,   47,   47,   73,
+       86,   86,  137,   87,   87,   71,   71,   48,   88,   73,
+       49,   50,   79,   89,   87,   87,   88,   48,   49,   50,
+       66,   66,  136,   89,   79,   67,   67,   67,   67,  135,
+       48,  109,  134,   49,   50,   80,  133,  110,   81,   67,
+       48,   49,   50,   68,   68,   80,   81,  132,   68,   68,
+       68,   68,   69,   69,   69,   69,   69,   69,   69,  131,
+      130,  129,   68,   69,   69,   69,   69,   69,  128,   87,
+       87,   69,   69,   69,   69,  127,   79,  126,  124,  123,
+      122,  121,  119,  118,  117,   69,   76,   76,   79,  116,
+
+      114,   77,   77,   77,   77,  113,   48,  112,  111,   49,
+      104,  100,   96,   92,   84,   77,   48,   49,   78,   78,
+       77,   74,  125,   78,   78,   78,   78,  120,  115,  138,
+      107,  107,  106,  102,   98,   94,   90,   78,   83,   83,
+       82,   62,   62,   84,   84,   84,   84,   75,   48,   57,
+       62,   49,   59,   58,   57,   53,   45,   84,   48,   49,
+       85,   85,   44,   43,  138,   85,   85,   85,   85,   32,
+       32,  138,  138,  138,  138,  138,  138,  138,  138,   85,
+       91,   91,  138,  138,  138,   92,   92,   92,   92,  138,
+       48,  138,  138,   49,  138,  138,  138,  138,  138,   92,
+
+       48,   49,   93,   93,  138,  138,  138,   93,   93,   93,
+       93,  138,  138,  138,  138,  138,  138,  138,  138,  138,
+      138,   93,   95,   95,  138,  138,  138,   96,   96,   96,
+       96,  138,   48,  138,  138,   49,  138,  138,  138,  138,
+      138,   96,   48,   49,   97,   97,  138,  138,  138,   97,
+       97,   97,   97,  138,  138,  138,  138,  138,  138,  138,
+      138,  138,  138,   97,   99,   99,  138,  138,  138,  100,
+      100,  100,  100,  138,   48,  138,  138,   49,  138,  138,
+      138,  138,  138,  100,   48,   49,  101,  101,  138,  138,
+      138,  101,  101,  101,  101,  138,  138,  138,  138,  138,
+
+      138,  138,  138,  138,  138,  101,  103,  103,  138,  138,
+      138,  104,  104,  104,  104,  138,   48,  138,  138,   49,
+      138,  138,  138,  138,  138,  104,   48,   49,  105,  105,
+      138,  138,  138,  105,  105,  105,  105,  138,  138,  138,
+      138,  138,  138,  138,  138,  138,  138,  105,  107,  138,
+      108,  108,  138,  138,  138,  138,  138,  138,  138,  138,
+       48,  138,  138,   49,  138,  138,  138,  138,  138,  138,
+       48,   49,   31,   31,   31,   31,   42,   42,   42,   42,
+       56,   56,   63,  138,   63,   63,   70,  138,   70,   70,
+       11,  138,  138,  138,  138,  138,  138,  138,  138,  138,
+
+      138,  138,  138,  138,  138,  138,  138,  138,  138,  138,
+      138,  138,  138,  138,  138,  138,  138,  138,  138,  138,
+      138,  138,  138,  138,  138,  138
     } ;
 
     } ;
 
-static yyconst short int yy_chk[296] =
+static yyconst short int yy_chk[527] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,    1,    2,    3,    3,    2,
-        4,    4,    6,  150,   26,    6,   15,   15,   15,   21,
-       33,   33,   21,   34,   34,   34,  149,    3,   27,   27,
-        4,    5,    5,   26,  148,    5,    5,    5,    5,    5,
-        5,    5,    5,  147,   27,    5,    5,    5,   14,   14,
-       14,   28,   28,   40,   46,   46,   40,   54,   54,   59,
-       59,   62,   62,   63,   63,   14,  146,   28,   29,   29,
-       65,   65,   29,   29,   29,   29,   29,   29,   29,   29,
-
-       69,   69,  145,   29,   29,   48,   48,   73,   73,   48,
-       48,   48,   48,   48,   48,   48,   48,   82,   82,  144,
-       48,   48,   51,   51,   77,   80,   77,   77,   51,   80,
-       83,  143,  142,  141,   83,  140,  139,   51,   56,   56,
-      138,  137,   56,   56,   56,   56,   56,   56,   56,   56,
-      136,  135,  134,   56,   56,   57,   57,  133,   57,   57,
-       61,   61,  132,  131,   61,   61,   61,   61,   61,   61,
-       61,   61,  130,  129,  128,   61,   61,   67,   67,  127,
-      126,   67,   67,   67,   67,   67,   67,   67,   67,  125,
-      124,  123,   67,   67,   71,   71,  122,  121,   71,   71,
-
-       71,   71,   71,   71,   71,   71,  120,   98,   93,   71,
-       71,   75,   75,   88,   79,   75,   75,   75,   75,   75,
-       75,   75,   75,   78,   76,   72,   75,   75,  113,  113,
-      113,  113,  113,  114,  114,  114,  114,  114,  115,  115,
-      115,  116,   68,  116,  116,  116,  117,   64,  117,  118,
-      118,  118,  119,   58,  119,  119,  119,   53,   42,   41,
-       39,   22,   19,   17,   16,    9,    8,    7,  112,  112,
-      112,  112,  112,  112,  112,  112,  112,  112,  112,  112,
-      112,  112,  112,  112,  112,  112,  112,  112,  112,  112,
-      112,  112,  112,  112,  112
-
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    2,    3,   34,    3,    2,
+        4,    5,    4,    5,    6,    8,    6,   20,   37,    8,
+       21,   21,   23,   23,   29,   20,   37,   48,   29,   46,
+       46,   34,    3,  106,   60,   48,    4,    5,   60,  106,
+        6,    7,    7,    7,    7,    7,    7,    7,    7,    7,
+        7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
+        7,    7,    7,    7,    7,    7,    7,    7,    7,    7,
+
+        7,    7,    7,    7,    7,    7,   19,   19,   19,   49,
+       79,   79,  174,   79,   79,   71,   71,   19,   80,   49,
+       19,   19,   71,   81,   86,   86,   80,   19,   19,   19,
+       36,   36,  173,   81,   71,   36,   36,   36,   36,  172,
+       36,  109,  171,   36,   36,   74,  170,  109,   74,   36,
+       36,   36,   36,   38,   38,   74,   74,  169,   38,   38,
+       38,   38,   38,   38,   38,   38,   38,   38,   38,  168,
+      167,  166,   38,   38,   38,   38,   39,   39,  165,   87,
+       87,   39,   39,   39,   39,  164,   87,  163,  162,  161,
+      160,  159,  158,  157,  156,   39,   66,   66,   87,  155,
+
+      154,   66,   66,   66,   66,  153,   66,  152,  151,   66,
+      150,  149,  148,  147,  146,   66,   66,   66,   68,   68,
+      145,  144,  124,   68,   68,   68,   68,  119,  114,  108,
+      105,  104,  102,   98,   94,   90,   82,   68,   76,   76,
+       75,   62,   61,   76,   76,   76,   76,   58,   76,   40,
+       30,   76,   28,   26,   25,   22,   18,   76,   76,   76,
+       78,   78,   17,   15,   11,   78,   78,   78,   78,   10,
+        9,    0,    0,    0,    0,    0,    0,    0,    0,   78,
+       83,   83,    0,    0,    0,   83,   83,   83,   83,    0,
+       83,    0,    0,   83,    0,    0,    0,    0,    0,   83,
+
+       83,   83,   85,   85,    0,    0,    0,   85,   85,   85,
+       85,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,   85,   91,   91,    0,    0,    0,   91,   91,   91,
+       91,    0,   91,    0,    0,   91,    0,    0,    0,    0,
+        0,   91,   91,   91,   93,   93,    0,    0,    0,   93,
+       93,   93,   93,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,   93,   95,   95,    0,    0,    0,   95,
+       95,   95,   95,    0,   95,    0,    0,   95,    0,    0,
+        0,    0,    0,   95,   95,   95,   97,   97,    0,    0,
+        0,   97,   97,   97,   97,    0,    0,    0,    0,    0,
+
+        0,    0,    0,    0,    0,   97,   99,   99,    0,    0,
+        0,   99,   99,   99,   99,    0,   99,    0,    0,   99,
+        0,    0,    0,    0,    0,   99,   99,   99,  101,  101,
+        0,    0,    0,  101,  101,  101,  101,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,  101,  103,    0,
+      103,  103,    0,    0,    0,    0,    0,    0,    0,    0,
+      103,    0,    0,  103,    0,    0,    0,    0,    0,    0,
+      103,  103,  139,  139,  139,  139,  140,  140,  140,  140,
+      141,  141,  142,    0,  142,  142,  143,    0,  143,  143,
+      138,  138,  138,  138,  138,  138,  138,  138,  138,  138,
+
+      138,  138,  138,  138,  138,  138,  138,  138,  138,  138,
+      138,  138,  138,  138,  138,  138,  138,  138,  138,  138,
+      138,  138,  138,  138,  138,  138
     } ;
 
 static yy_state_type yy_last_accepting_state;
     } ;
 
 static yy_state_type yy_last_accepting_state;
@@ -511,11 +570,13 @@ char *yytext;
 #define YY_NEVER_INTERACTIVE 1
 #define QUOTE 1
 
 #define YY_NEVER_INTERACTIVE 1
 #define QUOTE 1
 
-#define ATTR 2
+#define WSTRQUOTE 2
 
 
-#define PP_LINE 3
+#define ATTR 3
 
 
-#line 39 "parser.l"
+#define PP_LINE 4
+
+#line 42 "parser.l"
 
 #include "config.h"
 
 
 #include "config.h"
 
@@ -584,7 +645,7 @@ UUID *parse_uuid(const char *u)
  * The flexer starts here
  **************************************************************************
  */
  * The flexer starts here
  **************************************************************************
  */
-#line 588 "parser.yy.c"
+#line 649 "parser.yy.c"
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
 
 /* Macros after this point can all be overridden by user definitions in
  * section 1.
@@ -738,9 +799,9 @@ YY_DECL
        register char *yy_cp, *yy_bp;
        register int yy_act;
 
        register char *yy_cp, *yy_bp;
        register int yy_act;
 
-#line 109 "parser.l"
+#line 112 "parser.l"
 
 
-#line 744 "parser.yy.c"
+#line 805 "parser.yy.c"
 
        if ( yy_init )
                {
 
        if ( yy_init )
                {
@@ -792,13 +853,13 @@ yy_match:
                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                                {
                                yy_current_state = (int) yy_def[yy_current_state];
                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                                {
                                yy_current_state = (int) yy_def[yy_current_state];
-                               if ( yy_current_state >= 113 )
+                               if ( yy_current_state >= 139 )
                                        yy_c = yy_meta[(unsigned int) yy_c];
                                }
                        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
                        ++yy_cp;
                        }
                                        yy_c = yy_meta[(unsigned int) yy_c];
                                }
                        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
                        ++yy_cp;
                        }
-               while ( yy_base[yy_current_state] != 269 );
+               while ( yy_base[yy_current_state] != 491 );
 
 yy_find_action:
                yy_act = yy_accept[yy_current_state];
 
 yy_find_action:
                yy_act = yy_accept[yy_current_state];
@@ -826,12 +887,12 @@ do_action:        /* This label is used only to access EOF actions. */
 
 case 1:
 YY_RULE_SETUP
 
 case 1:
 YY_RULE_SETUP
-#line 110 "parser.l"
+#line 113 "parser.l"
 yy_push_state(PP_LINE);
        YY_BREAK
 case 2:
 YY_RULE_SETUP
 yy_push_state(PP_LINE);
        YY_BREAK
 case 2:
 YY_RULE_SETUP
-#line 111 "parser.l"
+#line 114 "parser.l"
 {
                             int lineno;
                             char *cptr, *fname;
 {
                             int lineno;
                             char *cptr, *fname;
@@ -854,12 +915,12 @@ YY_RULE_SETUP
        YY_BREAK
 case 3:
 YY_RULE_SETUP
        YY_BREAK
 case 3:
 YY_RULE_SETUP
-#line 130 "parser.l"
+#line 133 "parser.l"
 yy_push_state(QUOTE); cbufidx = 0;
        YY_BREAK
 case 4:
 YY_RULE_SETUP
 yy_push_state(QUOTE); cbufidx = 0;
        YY_BREAK
 case 4:
 YY_RULE_SETUP
-#line 131 "parser.l"
+#line 134 "parser.l"
 {
                                yy_pop_state();
                                parser_lval.str = get_buffered_cstring();
 {
                                yy_pop_state();
                                parser_lval.str = get_buffered_cstring();
@@ -867,124 +928,174 @@ YY_RULE_SETUP
                        }
        YY_BREAK
 case 5:
                        }
        YY_BREAK
 case 5:
-#line 137 "parser.l"
+YY_RULE_SETUP
+#line 139 "parser.l"
+yy_push_state(WSTRQUOTE);
+       YY_BREAK
 case 6:
 YY_RULE_SETUP
 case 6:
 YY_RULE_SETUP
-#line 137 "parser.l"
-addcchar(yytext[1]);
+#line 140 "parser.l"
+{
+                               yy_pop_state();
+                               parser_lval.str = get_buffered_cstring();
+                               return aWSTRING;
+                       }
        YY_BREAK
 case 7:
        YY_BREAK
 case 7:
+#line 146 "parser.l"
+case 8:
+YY_RULE_SETUP
+#line 146 "parser.l"
+addcchar(yytext[1]);
+       YY_BREAK
+case 9:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 138 "parser.l"
+#line 147 "parser.l"
 addcchar('\\'); addcchar(yytext[1]);
        YY_BREAK
 addcchar('\\'); addcchar(yytext[1]);
        YY_BREAK
-case 8:
+case 10:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 139 "parser.l"
+#line 148 "parser.l"
 addcchar(yytext[0]);
        YY_BREAK
 addcchar(yytext[0]);
        YY_BREAK
-case 9:
+case 11:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 140 "parser.l"
+#line 149 "parser.l"
 yy_push_state(ATTR); return '[';
        YY_BREAK
 yy_push_state(ATTR); return '[';
        YY_BREAK
-case 10:
+case 12:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 141 "parser.l"
+#line 150 "parser.l"
 yy_pop_state(); return ']';
        YY_BREAK
 yy_pop_state(); return ']';
        YY_BREAK
-case 11:
+case 13:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 142 "parser.l"
+#line 151 "parser.l"
 return attr_token(yytext);
        YY_BREAK
 return attr_token(yytext);
        YY_BREAK
-case 12:
+case 14:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 143 "parser.l"
+#line 152 "parser.l"
 {
                                parser_lval.uuid = parse_uuid(yytext);
                                return aUUID;
                        }
        YY_BREAK
 {
                                parser_lval.uuid = parse_uuid(yytext);
                                return aUUID;
                        }
        YY_BREAK
-case 13:
+case 15:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 147 "parser.l"
+#line 156 "parser.l"
 {
                                parser_lval.num = strtoul(yytext, NULL, 0);
                                return aHEXNUM;
                        }
        YY_BREAK
 {
                                parser_lval.num = strtoul(yytext, NULL, 0);
                                return aHEXNUM;
                        }
        YY_BREAK
-case 14:
+case 16:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 151 "parser.l"
+#line 160 "parser.l"
 {
                                parser_lval.num = strtoul(yytext, NULL, 0);
                                return aNUM;
                        }
        YY_BREAK
 {
                                parser_lval.num = strtoul(yytext, NULL, 0);
                                return aNUM;
                        }
        YY_BREAK
-case 15:
+case 17:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 155 "parser.l"
+#line 164 "parser.l"
 {
                                parser_lval.dbl = strtod(yytext, NULL);
                                return aDOUBLE;
                        }
        YY_BREAK
 {
                                parser_lval.dbl = strtod(yytext, NULL);
                                return aDOUBLE;
                        }
        YY_BREAK
-case 16:
+case 18:
 *yy_cp = yy_hold_char; /* undo effects of setting up yytext */
 yy_c_buf_p = yy_cp -= 1;
 YY_DO_BEFORE_ACTION; /* set up yytext again */
 YY_RULE_SETUP
 *yy_cp = yy_hold_char; /* undo effects of setting up yytext */
 yy_c_buf_p = yy_cp -= 1;
 YY_DO_BEFORE_ACTION; /* set up yytext again */
 YY_RULE_SETUP
-#line 159 "parser.l"
+#line 168 "parser.l"
 return tSAFEARRAY;
        YY_BREAK
 return tSAFEARRAY;
        YY_BREAK
-case 17:
+case 19:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 160 "parser.l"
+#line 169 "parser.l"
 return kw_token(yytext);
        YY_BREAK
 return kw_token(yytext);
        YY_BREAK
-case 18:
+case 20:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 161 "parser.l"
+#line 170 "parser.l"
 line_number++;
        YY_BREAK
 line_number++;
        YY_BREAK
-case 19:
+case 21:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 162 "parser.l"
+#line 171 "parser.l"
 
        YY_BREAK
 
        YY_BREAK
-case 20:
+case 22:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 163 "parser.l"
+#line 172 "parser.l"
 return SHL;
        YY_BREAK
 return SHL;
        YY_BREAK
-case 21:
+case 23:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 164 "parser.l"
+#line 173 "parser.l"
 return SHR;
        YY_BREAK
 return SHR;
        YY_BREAK
-case 22:
+case 24:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 165 "parser.l"
+#line 174 "parser.l"
+return MEMBERPTR;
+       YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 175 "parser.l"
+return EQUALITY;
+       YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 176 "parser.l"
+return INEQUALITY;
+       YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 177 "parser.l"
+return GREATEREQUAL;
+       YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 178 "parser.l"
+return LESSEQUAL;
+       YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 179 "parser.l"
+return LOGICALOR;
+       YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 180 "parser.l"
+return LOGICALAND;
+       YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 181 "parser.l"
 return yytext[0];
        YY_BREAK
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(QUOTE):
 return yytext[0];
        YY_BREAK
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(QUOTE):
+case YY_STATE_EOF(WSTRQUOTE):
 case YY_STATE_EOF(ATTR):
 case YY_STATE_EOF(PP_LINE):
 case YY_STATE_EOF(ATTR):
 case YY_STATE_EOF(PP_LINE):
-#line 166 "parser.l"
+#line 182 "parser.l"
 {
                                if (import_stack_ptr)
                                        return aEOF;
                                else yyterminate();
                        }
        YY_BREAK
 {
                                if (import_stack_ptr)
                                        return aEOF;
                                else yyterminate();
                        }
        YY_BREAK
-case 23:
+case 32:
 YY_RULE_SETUP
 YY_RULE_SETUP
-#line 171 "parser.l"
+#line 187 "parser.l"
 ECHO;
        YY_BREAK
 ECHO;
        YY_BREAK
-#line 988 "parser.yy.c"
+#line 1099 "parser.yy.c"
 
        case YY_END_OF_BUFFER:
                {
 
        case YY_END_OF_BUFFER:
                {
@@ -1275,7 +1386,7 @@ static yy_state_type yy_get_previous_state()
                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                        {
                        yy_current_state = (int) yy_def[yy_current_state];
                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                        {
                        yy_current_state = (int) yy_def[yy_current_state];
-                       if ( yy_current_state >= 113 )
+                       if ( yy_current_state >= 139 )
                                yy_c = yy_meta[(unsigned int) yy_c];
                        }
                yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
                                yy_c = yy_meta[(unsigned int) yy_c];
                        }
                yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1310,11 +1421,11 @@ yy_state_type yy_current_state;
        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                {
                yy_current_state = (int) yy_def[yy_current_state];
        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                {
                yy_current_state = (int) yy_def[yy_current_state];
-               if ( yy_current_state >= 113 )
+               if ( yy_current_state >= 139 )
                        yy_c = yy_meta[(unsigned int) yy_c];
                }
        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
                        yy_c = yy_meta[(unsigned int) yy_c];
                }
        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-       yy_is_jam = (yy_current_state == 112);
+       yy_is_jam = (yy_current_state == 138);
 
        return yy_is_jam ? 0 : yy_current_state;
        }
 
        return yy_is_jam ? 0 : yy_current_state;
        }
@@ -1870,7 +1981,7 @@ int main()
        return 0;
        }
 #endif
        return 0;
        }
 #endif
-#line 171 "parser.l"
+#line 187 "parser.l"
 
 
 #ifndef parser_wrap
 
 
 #ifndef parser_wrap
@@ -1887,6 +1998,7 @@ struct keyword {
 
 static const struct keyword keywords[] = {
        {"FALSE",                       tFALSE},
 
 static const struct keyword keywords[] = {
        {"FALSE",                       tFALSE},
+       {"NULL",                        tNULL},
        {"TRUE",                        tTRUE},
        {"__cdecl",                     tCDECL},
        {"__fastcall",                  tFASTCALL},
        {"TRUE",                        tTRUE},
        {"__cdecl",                     tCDECL},
        {"__fastcall",                  tFASTCALL},
@@ -1899,13 +2011,10 @@ static const struct keyword keywords[] = {
        {"_stdcall",                    tSTDCALL},
        {"boolean",                     tBOOLEAN},
        {"byte",                        tBYTE},
        {"_stdcall",                    tSTDCALL},
        {"boolean",                     tBOOLEAN},
        {"byte",                        tBYTE},
-       {"callback",                    tCALLBACK},
        {"case",                        tCASE},
        {"cdecl",                       tCDECL},
        {"char",                        tCHAR},
        {"coclass",                     tCOCLASS},
        {"case",                        tCASE},
        {"cdecl",                       tCDECL},
        {"char",                        tCHAR},
        {"coclass",                     tCOCLASS},
-       {"code",                        tCODE},
-       {"comm_status",                 tCOMMSTATUS},
        {"const",                       tCONST},
        {"cpp_quote",                   tCPPQUOTE},
        {"default",                     tDEFAULT},
        {"const",                       tCONST},
        {"cpp_quote",                   tCPPQUOTE},
        {"default",                     tDEFAULT},
@@ -1919,7 +2028,7 @@ static const struct keyword keywords[] = {
        {"hyper",                       tHYPER},
        {"import",                      tIMPORT},
        {"importlib",                   tIMPORTLIB},
        {"hyper",                       tHYPER},
        {"import",                      tIMPORT},
        {"importlib",                   tIMPORTLIB},
-       {"in_line",                     tINLINE},
+       {"inline",                      tINLINE},
        {"int",                         tINT},
        {"interface",                   tINTERFACE},
        {"library",                     tLIBRARY},
        {"int",                         tINT},
        {"interface",                   tINTERFACE},
        {"library",                     tLIBRARY},
@@ -1928,10 +2037,12 @@ static const struct keyword keywords[] = {
        {"module",                      tMODULE},
        {"pascal",                      tPASCAL},
        {"properties",                  tPROPERTIES},
        {"module",                      tMODULE},
        {"pascal",                      tPASCAL},
        {"properties",                  tPROPERTIES},
+       {"register",                    tREGISTER},
        {"short",                       tSHORT},
        {"signed",                      tSIGNED},
        {"sizeof",                      tSIZEOF},
        {"short",                       tSHORT},
        {"signed",                      tSIGNED},
        {"sizeof",                      tSIZEOF},
-        {"small",                      tSMALL},
+       {"small",                       tSMALL},
+       {"static",                      tSTATIC},
        {"stdcall",                     tSTDCALL},
        {"struct",                      tSTRUCT},
        {"switch",                      tSWITCH},
        {"stdcall",                     tSTDCALL},
        {"struct",                      tSTRUCT},
        {"switch",                      tSWITCH},
@@ -1956,6 +2067,9 @@ static const struct keyword attr_keywords[] =
         {"broadcast",                   tBROADCAST},
         {"byte_count",                  tBYTECOUNT},
         {"call_as",                     tCALLAS},
         {"broadcast",                   tBROADCAST},
         {"byte_count",                  tBYTECOUNT},
         {"call_as",                     tCALLAS},
+        {"callback",                    tCALLBACK},
+        {"code",                        tCODE},
+        {"comm_status",                 tCOMMSTATUS},
         {"context_handle",              tCONTEXTHANDLE},
         {"context_handle_noserialize",  tCONTEXTHANDLENOSERIALIZE},
         {"context_handle_serialize",    tCONTEXTHANDLENOSERIALIZE},
         {"context_handle",              tCONTEXTHANDLE},
         {"context_handle_noserialize",  tCONTEXTHANDLENOSERIALIZE},
         {"context_handle_serialize",    tCONTEXTHANDLENOSERIALIZE},
@@ -1982,6 +2096,7 @@ static const struct keyword attr_keywords[] =
         {"immediatebind",               tIMMEDIATEBIND},
         {"implicit_handle",             tIMPLICITHANDLE},
         {"in",                          tIN},
         {"immediatebind",               tIMMEDIATEBIND},
         {"implicit_handle",             tIMPLICITHANDLE},
         {"in",                          tIN},
+        {"in_line",                     tIN_LINE},
         {"input_sync",                  tINPUTSYNC},
         {"lcid",                        tLCID},
         {"length_is",                   tLENGTHIS},
         {"input_sync",                  tINPUTSYNC},
         {"lcid",                        tLCID},
         {"length_is",                   tLENGTHIS},
@@ -2086,7 +2201,6 @@ void pop_import(void)
                free(temp_name);
        }
        temp_name = import_stack[ptr].temp_name;
                free(temp_name);
        }
        temp_name = import_stack[ptr].temp_name;
-       free( input_name );
        input_name = import_stack[ptr].input_name;
        line_number = import_stack[ptr].line_number;
        import_stack_ptr--;
        input_name = import_stack[ptr].input_name;
        line_number = import_stack[ptr].line_number;
        import_stack_ptr--;
@@ -2100,20 +2214,11 @@ struct imports {
 int do_import(char *fname)
 {
        FILE *f;
 int do_import(char *fname)
 {
        FILE *f;
-       char *hname, *path, *p;
+       char *path;
        struct imports *import;
        int ptr = import_stack_ptr;
        int ret;
 
        struct imports *import;
        int ptr = import_stack_ptr;
        int ret;
 
-       if (!parse_only && do_header) {
-               hname = dup_basename(fname, ".idl");
-                p = hname + strlen(hname) - 2;
-                if (p <= hname || strcmp( p, ".h" )) strcat(hname, ".h");
-
-               fprintf(header, "#include <%s>\n", hname);
-               free(hname);
-       }
-
        import = first_import;
        while (import && strcmp(import->name, fname))
                import = import->next;
        import = first_import;
        while (import && strcmp(import->name, fname))
                import = import->next;
index e3c89ee..661ea2b 100644 (file)
@@ -35,6 +35,7 @@
 #include "parser.h"
 #include "header.h"
 #include "typegen.h"
 #include "parser.h"
 #include "header.h"
 #include "typegen.h"
+#include "expr.h"
 
 #define END_OF_LIST(list)       \
   do {                          \
 
 #define END_OF_LIST(list)       \
   do {                          \
@@ -88,7 +89,7 @@ static void write_stubdesc(int expr_eval_routines)
   print_proxy( "\n");
 }
 
   print_proxy( "\n");
 }
 
-static void init_proxy(ifref_list_t *ifaces)
+static void init_proxy(const statement_list_t *stmts)
 {
   if (proxy) return;
   if(!(proxy = fopen(proxy_name, "w")))
 {
   if (proxy) return;
   if(!(proxy = fopen(proxy_name, "w")))
@@ -108,7 +109,7 @@ static void init_proxy(ifref_list_t *ifaces)
   print_proxy( "\n");
   print_proxy( "#include \"%s\"\n", header_name);
   print_proxy( "\n");
   print_proxy( "\n");
   print_proxy( "#include \"%s\"\n", header_name);
   print_proxy( "\n");
-  write_formatstringsdecl(proxy, indent, ifaces, need_proxy);
+  write_formatstringsdecl(proxy, indent, stmts, need_proxy);
   write_stubdescproto();
 }
 
   write_stubdescproto();
 }
 
@@ -193,7 +194,7 @@ static void free_variable( const var_t *arg )
   if (size)
   {
     print_proxy( "_StubMsg.MaxCount = " );
   if (size)
   {
     print_proxy( "_StubMsg.MaxCount = " );
-    write_expr(proxy, size, 0);
+    write_expr(proxy, size, 0, 1, NULL, NULL);
     fprintf(proxy, ";\n\n");
     print_proxy( "NdrClearOutParameters( &_StubMsg, ");
     fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset );
     fprintf(proxy, ";\n\n");
     print_proxy( "NdrClearOutParameters( &_StubMsg, ");
     fprintf(proxy, "&__MIDL_TypeFormatString.Format[%u], ", type_offset );
@@ -221,7 +222,7 @@ static void free_variable( const var_t *arg )
     if( iid )
     {
       print_proxy( "_StubMsg.MaxCount = (unsigned long) " );
     if( iid )
     {
       print_proxy( "_StubMsg.MaxCount = (unsigned long) " );
-      write_expr(proxy, iid, 1);
+      write_expr(proxy, iid, 1, 1, NULL, NULL);
       print_proxy( ";\n\n" );
     }
     print_proxy( "NdrClearOutParameters( &_StubMsg, ");
       print_proxy( ";\n\n" );
     }
     print_proxy( "NdrClearOutParameters( &_StubMsg, ");
@@ -600,14 +601,24 @@ static void write_proxy(type_t *iface, unsigned int *proc_offset)
   print_proxy( "\n");
 }
 
   print_proxy( "\n");
 }
 
-static int does_any_iface(const ifref_list_t *ifaces, type_pred_t pred)
+static int does_any_iface(const statement_list_t *stmts, type_pred_t pred)
 {
 {
-  ifref_t *ir;
+  const statement_t *stmt;
 
 
-  if (ifaces)
-    LIST_FOR_EACH_ENTRY(ir, ifaces, ifref_t, entry)
-      if (pred(ir->iface))
-        return TRUE;
+  if (stmts)
+    LIST_FOR_EACH_ENTRY(stmt, stmts, const statement_t, entry)
+    {
+      if (stmt->type == STMT_LIBRARY)
+      {
+          if (does_any_iface(stmt->u.lib->stmts, pred))
+              return TRUE;
+      }
+      else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
+      {
+        if (pred(stmt->u.type))
+          return TRUE;
+      }
+    }
 
   return FALSE;
 }
 
   return FALSE;
 }
@@ -622,34 +633,84 @@ int need_stub(const type_t *iface)
   return !is_object(iface->attrs) && !is_local(iface->attrs);
 }
 
   return !is_object(iface->attrs) && !is_local(iface->attrs);
 }
 
-int need_proxy_file(const ifref_list_t *ifaces)
+int need_proxy_file(const statement_list_t *stmts)
+{
+  return does_any_iface(stmts, need_proxy);
+}
+
+int need_stub_files(const statement_list_t *stmts)
+{
+  return does_any_iface(stmts, need_stub);
+}
+
+static void write_proxy_stmts(const statement_list_t *stmts, unsigned int *proc_offset)
+{
+  const statement_t *stmt;
+  if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
+  {
+    if (stmt->type == STMT_LIBRARY)
+      write_proxy_stmts(stmt->u.lib->stmts, proc_offset);
+    else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
+    {
+      if (need_proxy(stmt->u.type))
+        write_proxy(stmt->u.type, proc_offset);
+    }
+  }
+}
+
+static void write_proxy_iface_name_format(const statement_list_t *stmts, const char *format)
 {
 {
-  return does_any_iface(ifaces, need_proxy);
+  const statement_t *stmt;
+  if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
+  {
+    if (stmt->type == STMT_LIBRARY)
+      write_proxy_iface_name_format(stmt->u.lib->stmts, format);
+    else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
+    {
+      type_t *iface = stmt->u.type;
+      if (iface->ref && iface->funcs && need_proxy(iface))
+        fprintf(proxy, format, iface->name);
+    }
+  }
 }
 
 }
 
-int need_stub_files(const ifref_list_t *ifaces)
+static void write_iid_lookup(const statement_list_t *stmts, const char *file_id, int *c)
 {
 {
-  return does_any_iface(ifaces, need_stub);
+  const statement_t *stmt;
+  if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
+  {
+    if (stmt->type == STMT_LIBRARY)
+      write_iid_lookup(stmt->u.lib->stmts, file_id, c);
+    else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
+    {
+      type_t *iface = stmt->u.type;
+      if(iface->ref && iface->funcs && need_proxy(iface))
+      {
+        fprintf(proxy, "    if (!_%s_CHECK_IID(%d))\n", file_id, *c);
+        fprintf(proxy, "    {\n");
+        fprintf(proxy, "        *pIndex = %d;\n", *c);
+        fprintf(proxy, "        return 1;\n");
+        fprintf(proxy, "    }\n");
+        (*c)++;
+      }
+    }
+  }
 }
 
 }
 
-void write_proxies(ifref_list_t *ifaces)
+void write_proxies(const statement_list_t *stmts)
 {
 {
-  ifref_t *cur;
   int expr_eval_routines;
   char *file_id = proxy_token;
   int c;
   unsigned int proc_offset = 0;
 
   if (!do_proxies) return;
   int expr_eval_routines;
   char *file_id = proxy_token;
   int c;
   unsigned int proc_offset = 0;
 
   if (!do_proxies) return;
-  if (do_everything && !need_proxy_file(ifaces)) return;
+  if (do_everything && !need_proxy_file(stmts)) return;
 
 
-  init_proxy(ifaces);
+  init_proxy(stmts);
   if(!proxy) return;
 
   if(!proxy) return;
 
-  if (ifaces)
-      LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry )
-          if (need_proxy(cur->iface))
-              write_proxy(cur->iface, &proc_offset);
+  write_proxy_stmts(stmts, &proc_offset);
 
   expr_eval_routines = write_expr_eval_routines(proxy, proxy_token);
   if (expr_eval_routines)
 
   expr_eval_routines = write_expr_eval_routines(proxy, proxy_token);
   if (expr_eval_routines)
@@ -661,36 +722,26 @@ void write_proxies(ifref_list_t *ifaces)
   print_proxy( "#error Currently only Wine and WIN32 are supported.\n");
   print_proxy( "#endif\n");
   print_proxy( "\n");
   print_proxy( "#error Currently only Wine and WIN32 are supported.\n");
   print_proxy( "#endif\n");
   print_proxy( "\n");
-  write_procformatstring(proxy, ifaces, need_proxy);
-  write_typeformatstring(proxy, ifaces, need_proxy);
+  write_procformatstring(proxy, stmts, need_proxy);
+  write_typeformatstring(proxy, stmts, need_proxy);
 
   fprintf(proxy, "static const CInterfaceProxyVtbl* const _%s_ProxyVtblList[] =\n", file_id);
   fprintf(proxy, "{\n");
 
   fprintf(proxy, "static const CInterfaceProxyVtbl* const _%s_ProxyVtblList[] =\n", file_id);
   fprintf(proxy, "{\n");
-  if (ifaces)
-      LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry )
-          if(cur->iface->ref && cur->iface->funcs && need_proxy(cur->iface))
-              fprintf(proxy, "    (const CInterfaceProxyVtbl*)&_%sProxyVtbl,\n", cur->iface->name);
-
+  write_proxy_iface_name_format(stmts, "    (const CInterfaceProxyVtbl*)&_%sProxyVtbl,\n");
   fprintf(proxy, "    0\n");
   fprintf(proxy, "};\n");
   fprintf(proxy, "\n");
 
   fprintf(proxy, "static const CInterfaceStubVtbl* const _%s_StubVtblList[] =\n", file_id);
   fprintf(proxy, "{\n");
   fprintf(proxy, "    0\n");
   fprintf(proxy, "};\n");
   fprintf(proxy, "\n");
 
   fprintf(proxy, "static const CInterfaceStubVtbl* const _%s_StubVtblList[] =\n", file_id);
   fprintf(proxy, "{\n");
-  if (ifaces)
-      LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry )
-          if(cur->iface->ref && cur->iface->funcs && need_proxy(cur->iface))
-              fprintf(proxy, "    (const CInterfaceStubVtbl*)&_%sStubVtbl,\n", cur->iface->name);
+  write_proxy_iface_name_format(stmts, "    (const CInterfaceStubVtbl*)&_%sStubVtbl,\n");
   fprintf(proxy, "    0\n");
   fprintf(proxy, "};\n");
   fprintf(proxy, "\n");
 
   fprintf(proxy, "static PCInterfaceName const _%s_InterfaceNamesList[] =\n", file_id);
   fprintf(proxy, "{\n");
   fprintf(proxy, "    0\n");
   fprintf(proxy, "};\n");
   fprintf(proxy, "\n");
 
   fprintf(proxy, "static PCInterfaceName const _%s_InterfaceNamesList[] =\n", file_id);
   fprintf(proxy, "{\n");
-  if (ifaces)
-      LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry )
-          if(cur->iface->ref && cur->iface->funcs && need_proxy(cur->iface))
-              fprintf(proxy, "    \"%s\",\n", cur->iface->name);
+  write_proxy_iface_name_format(stmts, "    \"%s\",\n");
   fprintf(proxy, "    0\n");
   fprintf(proxy, "};\n");
   fprintf(proxy, "\n");
   fprintf(proxy, "    0\n");
   fprintf(proxy, "};\n");
   fprintf(proxy, "\n");
@@ -700,17 +751,7 @@ void write_proxies(ifref_list_t *ifaces)
   fprintf(proxy, "int __stdcall _%s_IID_Lookup(const IID* pIID, int* pIndex)\n", file_id);
   fprintf(proxy, "{\n");
   c = 0;
   fprintf(proxy, "int __stdcall _%s_IID_Lookup(const IID* pIID, int* pIndex)\n", file_id);
   fprintf(proxy, "{\n");
   c = 0;
-  if (ifaces)
-      LIST_FOR_EACH_ENTRY( cur, ifaces, ifref_t, entry )
-          if(cur->iface->ref && cur->iface->funcs && need_proxy(cur->iface))
-          {
-              fprintf(proxy, "    if (!_%s_CHECK_IID(%d))\n", file_id, c);
-              fprintf(proxy, "    {\n");
-              fprintf(proxy, "        *pIndex = %d;\n", c);
-              fprintf(proxy, "        return 1;\n");
-              fprintf(proxy, "    }\n");
-              c++;
-          }
+  write_iid_lookup(stmts, file_id, &c);
   fprintf(proxy, "    return 0;\n");
   fprintf(proxy, "}\n");
   fprintf(proxy, "\n");
   fprintf(proxy, "    return 0;\n");
   fprintf(proxy, "}\n");
   fprintf(proxy, "\n");
index 05aeeb7..582a0cb 100644 (file)
@@ -50,8 +50,6 @@ static void print_server(const char *format, ...)
 
 static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
 {
 
 static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
 {
-    char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE);
-    int explicit_handle = is_attr(iface->attrs, ATTR_EXPLICIT_HANDLE);
     const func_t *func;
     const var_t *var;
     const var_t* explicit_handle_var;
     const func_t *func;
     const var_t *var;
     const var_t* explicit_handle_var;
@@ -60,34 +58,10 @@ static void write_function_stubs(type_t *iface, unsigned int *proc_offset)
     LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry )
     {
         const var_t *def = func->def;
     LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry )
     {
         const var_t *def = func->def;
-        const var_t* context_handle_var = NULL;
-        const var_t* explicit_generic_handle_var = NULL;
         int has_full_pointer = is_full_pointer_function(func);
 
         /* check for a defined binding handle */
         explicit_handle_var = get_explicit_handle_var(func);
         int has_full_pointer = is_full_pointer_function(func);
 
         /* check for a defined binding handle */
         explicit_handle_var = get_explicit_handle_var(func);
-        if (!explicit_handle_var)
-        {
-            explicit_generic_handle_var = get_explicit_generic_handle_var(func);
-            if (!explicit_generic_handle_var)
-                context_handle_var = get_context_handle_var(func);
-        }
-        if (explicit_handle)
-        {
-            if (!explicit_handle_var && !explicit_generic_handle_var && !context_handle_var)
-            {
-                error("%s() does not define an explicit binding handle!\n", def->name);
-                return;
-            }
-        }
-        else if (implicit_handle)
-        {
-            if (explicit_handle_var)
-            {
-                error("%s() must not define a binding handle!\n", def->name);
-                return;
-            }
-        }
 
         fprintf(server, "void __RPC_STUB\n");
         fprintf(server, "%s_", iface->name);
 
         fprintf(server, "void __RPC_STUB\n");
         fprintf(server, "%s_", iface->name);
@@ -413,58 +387,69 @@ static void init_server(void)
 }
 
 
 }
 
 
-void write_server(ifref_list_t *ifaces)
+static void write_server_stmts(const statement_list_t *stmts, int expr_eval_routines, unsigned int *proc_offset)
+{
+    const statement_t *stmt;
+    if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
+    {
+        if (stmt->type == STMT_LIBRARY)
+            write_server_stmts(stmt->u.lib->stmts, expr_eval_routines, proc_offset);
+        else if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
+        {
+            type_t *iface = stmt->u.type;
+            if (!need_stub(iface))
+                continue;
+
+            fprintf(server, "/*****************************************************************************\n");
+            fprintf(server, " * %s interface\n", iface->name);
+            fprintf(server, " */\n");
+            fprintf(server, "\n");
+
+            if (iface->funcs)
+            {
+                write_serverinterfacedecl(iface);
+                write_stubdescdecl(iface);
+
+                write_function_stubs(iface, proc_offset);
+
+                print_server("#if !defined(__RPC_WIN32__)\n");
+                print_server("#error  Invalid build platform for this stub.\n");
+                print_server("#endif\n");
+
+                fprintf(server, "\n");
+                write_stubdescriptor(iface, expr_eval_routines);
+                write_dispatchtable(iface);
+            }
+        }
+    }
+}
+
+void write_server(const statement_list_t *stmts)
 {
     unsigned int proc_offset = 0;
     int expr_eval_routines;
 {
     unsigned int proc_offset = 0;
     int expr_eval_routines;
-    ifref_t *iface;
 
     if (!do_server)
         return;
 
     if (!do_server)
         return;
-    if (do_everything && !need_stub_files(ifaces))
+    if (do_everything && !need_stub_files(stmts))
         return;
 
     init_server();
     if (!server)
         return;
 
         return;
 
     init_server();
     if (!server)
         return;
 
-    write_formatstringsdecl(server, indent, ifaces, need_stub);
+    write_formatstringsdecl(server, indent, stmts, need_stub);
     expr_eval_routines = write_expr_eval_routines(server, server_token);
     if (expr_eval_routines)
         write_expr_eval_routine_list(server, server_token);
     write_user_quad_list(server);
 
     expr_eval_routines = write_expr_eval_routines(server, server_token);
     if (expr_eval_routines)
         write_expr_eval_routine_list(server, server_token);
     write_user_quad_list(server);
 
-    if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, ifref_t, entry )
-    {
-        if (!need_stub(iface->iface))
-            continue;
-
-        fprintf(server, "/*****************************************************************************\n");
-        fprintf(server, " * %s interface\n", iface->iface->name);
-        fprintf(server, " */\n");
-        fprintf(server, "\n");
-
-        if (iface->iface->funcs)
-        {
-            write_serverinterfacedecl(iface->iface);
-            write_stubdescdecl(iface->iface);
-    
-            write_function_stubs(iface->iface, &proc_offset);
-    
-            print_server("#if !defined(__RPC_WIN32__)\n");
-            print_server("#error  Invalid build platform for this stub.\n");
-            print_server("#endif\n");
-
-            fprintf(server, "\n");
-            write_stubdescriptor(iface->iface, expr_eval_routines);
-            write_dispatchtable(iface->iface);
-        }
-    }
+    write_server_stmts(stmts, expr_eval_routines, &proc_offset);
 
     fprintf(server, "\n");
 
 
     fprintf(server, "\n");
 
-    write_procformatstring(server, ifaces, need_stub);
-    write_typeformatstring(server, ifaces, need_stub);
+    write_procformatstring(server, stmts, need_stub);
+    write_typeformatstring(server, stmts, need_stub);
 
     fclose(server);
 }
 
     fclose(server);
 }
index 32e557f..41134d8 100644 (file)
 #include "wine/list.h"
 
 #include "typegen.h"
 #include "wine/list.h"
 
 #include "typegen.h"
+#include "expr.h"
 
 static const func_t *current_func;
 static const type_t *current_structure;
 
 static const func_t *current_func;
 static const type_t *current_structure;
-static const ifref_t *current_iface;
+static const type_t *current_iface;
 
 static struct list expr_eval_routines = LIST_INIT(expr_eval_routines);
 struct expr_eval_routine
 
 static struct list expr_eval_routines = LIST_INIT(expr_eval_routines);
 struct expr_eval_routine
@@ -307,77 +308,6 @@ static const char *get_context_handle_type_name(const type_t *type)
     return NULL;
 }
 
     return NULL;
 }
 
-/* This is actually fairly involved to implement precisely, due to the
-   effects attributes may have and things like that.  Right now this is
-   only used for optimization, so just check for a very small set of
-   criteria that guarantee the types are equivalent; assume every thing
-   else is different.   */
-static int compare_type(const type_t *a, const type_t *b)
-{
-    if (a == b
-        || (a->name
-            && b->name
-            && strcmp(a->name, b->name) == 0))
-        return 0;
-    /* Ordering doesn't need to be implemented yet.  */
-    return 1;
-}
-
-static int compare_expr(const expr_t *a, const expr_t *b)
-{
-    int ret;
-
-    if (a->type != b->type)
-        return a->type - b->type;
-
-    switch (a->type)
-    {
-        case EXPR_NUM:
-        case EXPR_HEXNUM:
-        case EXPR_TRUEFALSE:
-            return a->u.lval - b->u.lval;
-        case EXPR_DOUBLE:
-            return a->u.dval - b->u.dval;
-        case EXPR_IDENTIFIER:
-            return strcmp(a->u.sval, b->u.sval);
-        case EXPR_COND:
-            ret = compare_expr(a->ref, b->ref);
-            if (ret != 0)
-                return ret;
-            ret = compare_expr(a->u.ext, b->u.ext);
-            if (ret != 0)
-                return ret;
-            return compare_expr(a->ext2, b->ext2);
-        case EXPR_OR:
-        case EXPR_AND:
-        case EXPR_ADD:
-        case EXPR_SUB:
-        case EXPR_MUL:
-        case EXPR_DIV:
-        case EXPR_SHL:
-        case EXPR_SHR:
-            ret = compare_expr(a->ref, b->ref);
-            if (ret != 0)
-                return ret;
-            return compare_expr(a->u.ext, b->u.ext);
-        case EXPR_CAST:
-            ret = compare_type(a->u.tref, b->u.tref);
-            if (ret != 0)
-                return ret;
-            /* Fall through.  */
-        case EXPR_NOT:
-        case EXPR_NEG:
-        case EXPR_PPTR:
-        case EXPR_ADDRESSOF:
-            return compare_expr(a->ref, b->ref);
-        case EXPR_SIZEOF:
-            return compare_type(a->u.tref, b->u.tref);
-        case EXPR_VOID:
-            return 0;
-    }
-    return -1;
-}
-
 #define WRITE_FCTYPE(file, fctype, typestring_offset) \
     do { \
         if (file) \
 #define WRITE_FCTYPE(file, fctype, typestring_offset) \
     do { \
         if (file) \
@@ -440,13 +370,13 @@ static void write_formatdesc(FILE *f, int indent, const char *str)
     print_file(f, indent, "\n");
 }
 
     print_file(f, indent, "\n");
 }
 
-void write_formatstringsdecl(FILE *f, int indent, ifref_list_t *ifaces, type_pred_t pred)
+void write_formatstringsdecl(FILE *f, int indent, const statement_list_t *stmts, type_pred_t pred)
 {
     print_file(f, indent, "#define TYPE_FORMAT_STRING_SIZE %d\n",
 {
     print_file(f, indent, "#define TYPE_FORMAT_STRING_SIZE %d\n",
-               get_size_typeformatstring(ifaces, pred));
+               get_size_typeformatstring(stmts, pred));
 
     print_file(f, indent, "#define PROC_FORMAT_STRING_SIZE %d\n",
 
     print_file(f, indent, "#define PROC_FORMAT_STRING_SIZE %d\n",
-               get_size_procformatstring(ifaces, pred));
+               get_size_procformatstring(stmts, pred));
 
     fprintf(f, "\n");
     write_formatdesc(f, indent, "TYPE");
 
     fprintf(f, "\n");
     write_formatdesc(f, indent, "TYPE");
@@ -547,33 +477,23 @@ static size_t write_procformatstring_type(FILE *file, int indent,
     return size;
 }
 
     return size;
 }
 
-void write_procformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred)
+static void write_procformatstring_stmts(FILE *file, int indent, const statement_list_t *stmts, type_pred_t pred)
 {
 {
-    const ifref_t *iface;
-    int indent = 0;
-    const var_t *var;
-
-    print_file(file, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
-    print_file(file, indent, "{\n");
-    indent++;
-    print_file(file, indent, "0,\n");
-    print_file(file, indent, "{\n");
-    indent++;
-
-    if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry )
+    const statement_t *stmt;
+    if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
     {
     {
-        if (!pred(iface->iface))
-            continue;
-
-        if (iface->iface->funcs)
+        if (stmt->type == STMT_TYPE && stmt->u.type->type == RPC_FC_IP)
         {
             const func_t *func;
         {
             const func_t *func;
-            LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry )
+            if (!pred(stmt->u.type))
+                continue;
+            if (stmt->u.type->funcs) LIST_FOR_EACH_ENTRY( func, stmt->u.type->funcs, const func_t, entry )
             {
                 if (is_local(func->def->attrs)) continue;
                 /* emit argument data */
                 if (func->args)
                 {
             {
                 if (is_local(func->def->attrs)) continue;
                 /* emit argument data */
                 if (func->args)
                 {
+                    const var_t *var;
                     LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
                         write_procformatstring_type(file, indent, var->name, var->type, var->attrs, FALSE);
                 }
                     LIST_FOR_EACH_ENTRY( var, func->args, const var_t, entry )
                         write_procformatstring_type(file, indent, var->name, var->type, var->attrs, FALSE);
                 }
@@ -588,7 +508,23 @@ void write_procformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t
                     write_procformatstring_type(file, indent, "return value", get_func_return_type(func), NULL, TRUE);
             }
         }
                     write_procformatstring_type(file, indent, "return value", get_func_return_type(func), NULL, TRUE);
             }
         }
+        else if (stmt->type == STMT_LIBRARY)
+            write_procformatstring_stmts(file, indent, stmt->u.lib->stmts, pred);
     }
     }
+}
+
+void write_procformatstring(FILE *file, const statement_list_t *stmts, type_pred_t pred)
+{
+    int indent = 0;
+
+    print_file(file, indent, "static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n");
+    print_file(file, indent, "{\n");
+    indent++;
+    print_file(file, indent, "0,\n");
+    print_file(file, indent, "{\n");
+    indent++;
+
+    write_procformatstring_stmts(file, indent, stmts, pred);
 
     print_file(file, indent, "0x0\n");
     indent--;
 
     print_file(file, indent, "0x0\n");
     indent--;
@@ -725,6 +661,8 @@ static size_t write_conf_or_var_desc(FILE *file, const type_t *structure,
             error("write_conf_or_var_desc: couldn't find variable %s in structure\n",
                   subexpr->u.sval);
 
             error("write_conf_or_var_desc: couldn't find variable %s in structure\n",
                   subexpr->u.sval);
 
+        correlation_variable = expr_resolve_type(NULL, structure, expr);
+
         offset -= baseoff;
         correlation_variable_type = correlation_variable->type;
 
         offset -= baseoff;
         correlation_variable_type = correlation_variable->type;
 
@@ -753,15 +691,6 @@ static size_t write_conf_or_var_desc(FILE *file, const type_t *structure,
         case RPC_FC_ULONG:
             param_type = RPC_FC_ULONG;
             break;
         case RPC_FC_ULONG:
             param_type = RPC_FC_ULONG;
             break;
-        case RPC_FC_RP:
-        case RPC_FC_UP:
-        case RPC_FC_OP:
-        case RPC_FC_FP:
-            if (sizeof(void *) == 4)  /* FIXME */
-                param_type = RPC_FC_LONG;
-            else
-                param_type = RPC_FC_HYPER;
-            break;
         default:
             error("write_conf_or_var_desc: conformance variable type not supported 0x%x\n",
                 correlation_variable_type);
         default:
             error("write_conf_or_var_desc: conformance variable type not supported 0x%x\n",
                 correlation_variable_type);
@@ -2338,22 +2267,32 @@ static int write_embedded_types(FILE *file, const attr_list_t *attrs, type_t *ty
     return retmask;
 }
 
     return retmask;
 }
 
-static size_t process_tfs(FILE *file, const ifref_list_t *ifaces, type_pred_t pred)
+static size_t process_tfs_stmts(FILE *file, const statement_list_t *stmts,
+                                type_pred_t pred, unsigned int *typeformat_offset)
 {
     const var_t *var;
 {
     const var_t *var;
-    const ifref_t *iface;
-    unsigned int typeformat_offset = 2;
+    const statement_t *stmt;
 
 
-    if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry )
+    if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
     {
     {
-        if (!pred(iface->iface))
+        const type_t *iface;
+        if (stmt->type == STMT_LIBRARY)
+        {
+            process_tfs_stmts(file, stmt->u.lib->stmts, pred, typeformat_offset);
+            continue;
+        }
+        else if (stmt->type != STMT_TYPE || stmt->u.type->type != RPC_FC_IP)
+            continue;
+
+        iface = stmt->u.type;
+        if (!pred(iface))
             continue;
 
             continue;
 
-        if (iface->iface->funcs)
+        if (iface->funcs)
         {
             const func_t *func;
             current_iface = iface;
         {
             const func_t *func;
             current_iface = iface;
-            LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry )
+            LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry )
             {
                 if (is_local(func->def->attrs)) continue;
 
             {
                 if (is_local(func->def->attrs)) continue;
 
@@ -2364,7 +2303,7 @@ static size_t process_tfs(FILE *file, const ifref_list_t *ifaces, type_pred_t pr
                     update_tfsoff(get_func_return_type(func),
                                   write_typeformatstring_var(
                                       file, 2, NULL, get_func_return_type(func),
                     update_tfsoff(get_func_return_type(func),
                                   write_typeformatstring_var(
                                       file, 2, NULL, get_func_return_type(func),
-                                      &v, &typeformat_offset),
+                                      &v, typeformat_offset),
                                   file);
                 }
 
                                   file);
                 }
 
@@ -2375,17 +2314,24 @@ static size_t process_tfs(FILE *file, const ifref_list_t *ifaces, type_pred_t pr
                             var->type,
                             write_typeformatstring_var(
                                 file, 2, func, var->type, var,
                             var->type,
                             write_typeformatstring_var(
                                 file, 2, func, var->type, var,
-                                &typeformat_offset),
+                                typeformat_offset),
                             file);
             }
         }
     }
 
                             file);
             }
         }
     }
 
-    return typeformat_offset + 1;
+    return *typeformat_offset + 1;
+}
+
+static size_t process_tfs(FILE *file, const statement_list_t *stmts, type_pred_t pred)
+{
+    unsigned int typeformat_offset = 2;
+
+    return process_tfs_stmts(file, stmts, pred, &typeformat_offset);
 }
 
 
 }
 
 
-void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred)
+void write_typeformatstring(FILE *file, const statement_list_t *stmts, type_pred_t pred)
 {
     int indent = 0;
 
 {
     int indent = 0;
 
@@ -2398,7 +2344,7 @@ void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t
     print_file(file, indent, "NdrFcShort(0x0),\n");
 
     set_all_tfswrite(TRUE);
     print_file(file, indent, "NdrFcShort(0x0),\n");
 
     set_all_tfswrite(TRUE);
-    process_tfs(file, ifaces, pred);
+    process_tfs(file, stmts, pred);
 
     print_file(file, indent, "0x0\n");
     indent--;
 
     print_file(file, indent, "0x0\n");
     indent--;
@@ -2836,7 +2782,7 @@ static void write_remoting_arg(FILE *file, int indent, const func_t *func,
             if (type->size_is && is_size_needed_for_phase(phase))
             {
                 print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)");
             if (type->size_is && is_size_needed_for_phase(phase))
             {
                 print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)");
-                write_expr(file, type->size_is, 1);
+                write_expr(file, type->size_is, 1, 1, NULL, NULL);
                 fprintf(file, ";\n");
             }
 
                 fprintf(file, ";\n");
             }
 
@@ -2866,7 +2812,7 @@ static void write_remoting_arg(FILE *file, int indent, const func_t *func,
             {
                 print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */
                 print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)");
             {
                 print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */
                 print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)");
-                write_expr(file, type->length_is, 1);
+                write_expr(file, type->length_is, 1, 1, NULL, NULL);
                 fprintf(file, ";\n\n");
             }
             array_type = "VaryingArray";
                 fprintf(file, ";\n\n");
             }
             array_type = "VaryingArray";
@@ -2876,7 +2822,7 @@ static void write_remoting_arg(FILE *file, int indent, const func_t *func,
             if (is_size_needed_for_phase(phase))
             {
                 print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)");
             if (is_size_needed_for_phase(phase))
             {
                 print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)");
-                write_expr(file, type->size_is, 1);
+                write_expr(file, type->size_is, 1, 1, NULL, NULL);
                 fprintf(file, ";\n\n");
             }
             array_type = "ConformantArray";
                 fprintf(file, ";\n\n");
             }
             array_type = "ConformantArray";
@@ -2888,14 +2834,14 @@ static void write_remoting_arg(FILE *file, int indent, const func_t *func,
                 if (type->size_is)
                 {
                     print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)");
                 if (type->size_is)
                 {
                     print_file(file, indent, "_StubMsg.MaxCount = (unsigned long)");
-                    write_expr(file, type->size_is, 1);
+                    write_expr(file, type->size_is, 1, 1, NULL, NULL);
                     fprintf(file, ";\n");
                 }
                 if (type->length_is)
                 {
                     print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */
                     print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)");
                     fprintf(file, ";\n");
                 }
                 if (type->length_is)
                 {
                     print_file(file, indent, "_StubMsg.Offset = (unsigned long)0;\n"); /* FIXME */
                     print_file(file, indent, "_StubMsg.ActualCount = (unsigned long)");
-                    write_expr(file, type->length_is, 1);
+                    write_expr(file, type->length_is, 1, 1, NULL, NULL);
                     fprintf(file, ";\n\n");
                 }
             }
                     fprintf(file, ";\n\n");
                 }
             }
@@ -2959,7 +2905,7 @@ static void write_remoting_arg(FILE *file, int indent, const func_t *func,
                 if ((iid = get_attrp( var->attrs, ATTR_IIDIS )))
                 {
                     print_file( file, indent, "_StubMsg.MaxCount = (unsigned long) " );
                 if ((iid = get_attrp( var->attrs, ATTR_IIDIS )))
                 {
                     print_file( file, indent, "_StubMsg.MaxCount = (unsigned long) " );
-                    write_expr( file, iid, 1 );
+                    write_expr( file, iid, 1, 1, NULL, NULL );
                     fprintf( file, ";\n\n" );
                 }
                 print_phase_function(file, indent, "Pointer", phase, var, start_offset);
                     fprintf( file, ";\n\n" );
                 }
                 print_phase_function(file, indent, "Pointer", phase, var, start_offset);
@@ -2989,13 +2935,13 @@ static void write_remoting_arg(FILE *file, int indent, const func_t *func,
             if ((iid = get_attrp( var->attrs, ATTR_IIDIS )))
             {
                 print_file( file, indent, "_StubMsg.MaxCount = (unsigned long) " );
             if ((iid = get_attrp( var->attrs, ATTR_IIDIS )))
             {
                 print_file( file, indent, "_StubMsg.MaxCount = (unsigned long) " );
-                write_expr( file, iid, 1 );
+                write_expr( file, iid, 1, 1, NULL, NULL );
                 fprintf( file, ";\n\n" );
             }
             else if (sx)
             {
                 print_file(file, indent, "_StubMsg.MaxCount = (unsigned long) ");
                 fprintf( file, ";\n\n" );
             }
             else if (sx)
             {
                 print_file(file, indent, "_StubMsg.MaxCount = (unsigned long) ");
-                write_expr(file, sx, 1);
+                write_expr(file, sx, 1, 1, NULL, NULL);
                 fprintf(file, ";\n\n");
             }
             if (var->type->ref->type == RPC_FC_IP)
                 fprintf(file, ";\n\n");
             }
             if (var->type->ref->type == RPC_FC_IP)
@@ -3061,129 +3007,41 @@ size_t get_size_procformatstring_func(const func_t *func)
     return size;
 }
 
     return size;
 }
 
-size_t get_size_procformatstring(const ifref_list_t *ifaces, type_pred_t pred)
+size_t get_size_procformatstring(const statement_list_t *stmts, type_pred_t pred)
 {
 {
-    const ifref_t *iface;
+    const statement_t *stmt;
     size_t size = 1;
     const func_t *func;
 
     size_t size = 1;
     const func_t *func;
 
-    if (ifaces) LIST_FOR_EACH_ENTRY( iface, ifaces, const ifref_t, entry )
+    if (stmts) LIST_FOR_EACH_ENTRY( stmt, stmts, const statement_t, entry )
     {
     {
-        if (!pred(iface->iface))
+        const type_t *iface;
+        if (stmt->type == STMT_LIBRARY)
+        {
+            size += get_size_procformatstring(stmt->u.lib->stmts, pred) - 1;
+            continue;
+        }
+        else if (stmt->type != STMT_TYPE && stmt->u.type->type != RPC_FC_IP)
+            continue;
+
+        iface = stmt->u.type;
+        if (!pred(iface))
             continue;
 
             continue;
 
-        if (iface->iface->funcs)
-            LIST_FOR_EACH_ENTRY( func, iface->iface->funcs, const func_t, entry )
+        if (iface->funcs)
+            LIST_FOR_EACH_ENTRY( func, iface->funcs, const func_t, entry )
                 if (!is_local(func->def->attrs))
                     size += get_size_procformatstring_func( func );
     }
     return size;
 }
 
                 if (!is_local(func->def->attrs))
                     size += get_size_procformatstring_func( func );
     }
     return size;
 }
 
-size_t get_size_typeformatstring(const ifref_list_t *ifaces, type_pred_t pred)
+size_t get_size_typeformatstring(const statement_list_t *stmts, type_pred_t pred)
 {
     set_all_tfswrite(FALSE);
 {
     set_all_tfswrite(FALSE);
-    return process_tfs(NULL, ifaces, pred);
+    return process_tfs(NULL, stmts, pred);
 }
 
 }
 
-static void write_struct_expr(FILE *h, const expr_t *e, int brackets,
-                              const var_list_t *fields, const char *structvar)
-{
-    switch (e->type) {
-        case EXPR_VOID:
-            break;
-        case EXPR_NUM:
-            fprintf(h, "%lu", e->u.lval);
-            break;
-        case EXPR_HEXNUM:
-            fprintf(h, "0x%lx", e->u.lval);
-            break;
-        case EXPR_DOUBLE:
-            fprintf(h, "%#.15g", e->u.dval);
-            break;
-        case EXPR_TRUEFALSE:
-            if (e->u.lval == 0)
-                fprintf(h, "FALSE");
-            else
-                fprintf(h, "TRUE");
-            break;
-        case EXPR_IDENTIFIER:
-        {
-            const var_t *field;
-            LIST_FOR_EACH_ENTRY( field, fields, const var_t, entry )
-                if (!strcmp(e->u.sval, field->name))
-                {
-                    fprintf(h, "%s->%s", structvar, e->u.sval);
-                    break;
-                }
-
-            if (&field->entry == fields) error("no field found for identifier %s\n", e->u.sval);
-            break;
-        }
-        case EXPR_NEG:
-            fprintf(h, "-");
-            write_struct_expr(h, e->ref, 1, fields, structvar);
-            break;
-        case EXPR_NOT:
-            fprintf(h, "~");
-            write_struct_expr(h, e->ref, 1, fields, structvar);
-            break;
-        case EXPR_PPTR:
-            fprintf(h, "*");
-            write_struct_expr(h, e->ref, 1, fields, structvar);
-            break;
-        case EXPR_CAST:
-            fprintf(h, "(");
-            write_type_decl(h, e->u.tref, NULL);
-            fprintf(h, ")");
-            write_struct_expr(h, e->ref, 1, fields, structvar);
-            break;
-        case EXPR_SIZEOF:
-            fprintf(h, "sizeof(");
-            write_type_decl(h, e->u.tref, NULL);
-            fprintf(h, ")");
-            break;
-        case EXPR_SHL:
-        case EXPR_SHR:
-        case EXPR_MUL:
-        case EXPR_DIV:
-        case EXPR_ADD:
-        case EXPR_SUB:
-        case EXPR_AND:
-        case EXPR_OR:
-            if (brackets) fprintf(h, "(");
-            write_struct_expr(h, e->ref, 1, fields, structvar);
-            switch (e->type) {
-                case EXPR_SHL: fprintf(h, " << "); break;
-                case EXPR_SHR: fprintf(h, " >> "); break;
-                case EXPR_MUL: fprintf(h, " * "); break;
-                case EXPR_DIV: fprintf(h, " / "); break;
-                case EXPR_ADD: fprintf(h, " + "); break;
-                case EXPR_SUB: fprintf(h, " - "); break;
-                case EXPR_AND: fprintf(h, " & "); break;
-                case EXPR_OR:  fprintf(h, " | "); break;
-                default: break;
-            }
-            write_struct_expr(h, e->u.ext, 1, fields, structvar);
-            if (brackets) fprintf(h, ")");
-            break;
-        case EXPR_COND:
-            if (brackets) fprintf(h, "(");
-            write_struct_expr(h, e->ref, 1, fields, structvar);
-            fprintf(h, " ? ");
-            write_struct_expr(h, e->u.ext, 1, fields, structvar);
-            fprintf(h, " : ");
-            write_struct_expr(h, e->ext2, 1, fields, structvar);
-            if (brackets) fprintf(h, ")");
-            break;
-        case EXPR_ADDRESSOF:
-            fprintf(h, "&");
-            write_struct_expr(h, e->ref, 1, fields, structvar);
-            break;
-    }
-}
-
-
 void declare_stub_args( FILE *file, int indent, const func_t *func )
 {
     int in_attr, out_attr;
 void declare_stub_args( FILE *file, int indent, const func_t *func )
 {
     int in_attr, out_attr;
@@ -3279,7 +3137,7 @@ void assign_stub_out_args( FILE *file, int indent, const func_t *func )
                 fprintf(file, " = NdrAllocate(&_StubMsg, ");
                 for ( ; type->size_is ; type = type->ref)
                 {
                 fprintf(file, " = NdrAllocate(&_StubMsg, ");
                 for ( ; type->size_is ; type = type->ref)
                 {
-                    write_expr(file, type->size_is, TRUE);
+                    write_expr(file, type->size_is, TRUE, TRUE, NULL, NULL);
                     fprintf(file, " * ");
                 }
                 size = type_memsize(type, &align);
                     fprintf(file, " * ");
                 }
                 size = type_memsize(type, &align);
@@ -3304,6 +3162,7 @@ void assign_stub_out_args( FILE *file, int indent, const func_t *func )
 int write_expr_eval_routines(FILE *file, const char *iface)
 {
     static const char *var_name = "pS";
 int write_expr_eval_routines(FILE *file, const char *iface)
 {
     static const char *var_name = "pS";
+    static const char *var_name_expr = "pS->";
     int result = 0;
     struct expr_eval_routine *eval;
     unsigned short callback_offset = 0;
     int result = 0;
     struct expr_eval_routine *eval;
     unsigned short callback_offset = 0;
@@ -3311,7 +3170,6 @@ int write_expr_eval_routines(FILE *file, const char *iface)
     LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry)
     {
         const char *name = eval->structure->name;
     LIST_FOR_EACH_ENTRY(eval, &expr_eval_routines, struct expr_eval_routine, entry)
     {
         const char *name = eval->structure->name;
-        const var_list_t *fields = eval->structure->fields_or_args;
         result = 1;
 
         print_file(file, 0, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n",
         result = 1;
 
         print_file(file, 0, "static void __RPC_USER %s_%sExprEval_%04u(PMIDL_STUB_MESSAGE pStubMsg)\n",
@@ -3321,7 +3179,7 @@ int write_expr_eval_routines(FILE *file, const char *iface)
                     name, var_name, name, eval->baseoff);
         print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */
         print_file(file, 1, "pStubMsg->MaxCount = (unsigned long)");
                     name, var_name, name, eval->baseoff);
         print_file(file, 1, "pStubMsg->Offset = 0;\n"); /* FIXME */
         print_file(file, 1, "pStubMsg->MaxCount = (unsigned long)");
-        write_struct_expr(file, eval->expr, 1, fields, var_name);
+        write_expr(file, eval->expr, 1, 1, var_name_expr, eval->structure);
         fprintf(file, ";\n");
         print_file(file, 0, "}\n\n");
         callback_offset++;
         fprintf(file, ";\n");
         print_file(file, 0, "}\n\n");
         callback_offset++;
index 7745454..a1013cb 100644 (file)
@@ -38,15 +38,15 @@ enum remoting_phase
 
 typedef int (*type_pred_t)(const type_t *);
 
 
 typedef int (*type_pred_t)(const type_t *);
 
-void write_formatstringsdecl(FILE *f, int indent, ifref_list_t *ifaces, type_pred_t pred);
-void write_procformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred);
-void write_typeformatstring(FILE *file, const ifref_list_t *ifaces, type_pred_t pred);
+void write_formatstringsdecl(FILE *f, int indent, const statement_list_t *stmts, type_pred_t pred);
+void write_procformatstring(FILE *file, const statement_list_t *stmts, type_pred_t pred);
+void write_typeformatstring(FILE *file, const statement_list_t *stmts, type_pred_t pred);
 void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, enum pass pass, const var_t *var, const char *varname);
 void write_remoting_arguments(FILE *file, int indent, const func_t *func, enum pass pass, enum remoting_phase phase);
 size_t get_size_procformatstring_type(const char *name, const type_t *type, const attr_list_t *attrs);
 size_t get_size_procformatstring_func(const func_t *func);
 void print_phase_basetype(FILE *file, int indent, enum remoting_phase phase, enum pass pass, const var_t *var, const char *varname);
 void write_remoting_arguments(FILE *file, int indent, const func_t *func, enum pass pass, enum remoting_phase phase);
 size_t get_size_procformatstring_type(const char *name, const type_t *type, const attr_list_t *attrs);
 size_t get_size_procformatstring_func(const func_t *func);
-size_t get_size_procformatstring(const ifref_list_t *ifaces, type_pred_t pred);
-size_t get_size_typeformatstring(const ifref_list_t *ifaces, type_pred_t pred);
+size_t get_size_procformatstring(const statement_list_t *stmts, type_pred_t pred);
+size_t get_size_typeformatstring(const statement_list_t *stmts, type_pred_t pred);
 void assign_stub_out_args( FILE *file, int indent, const func_t *func );
 void declare_stub_args( FILE *file, int indent, const func_t *func );
 int write_expr_eval_routines(FILE *file, const char *iface);
 void assign_stub_out_args( FILE *file, int indent, const func_t *func );
 void declare_stub_args( FILE *file, int indent, const func_t *func );
 int write_expr_eval_routines(FILE *file, const char *iface);
index a126deb..4f2b05d 100644 (file)
@@ -172,7 +172,7 @@ unsigned short get_type_vt(type_t *t)
     if (vt) return vt;
   }
 
     if (vt) return vt;
   }
 
-  if (t->kind == TKIND_ALIAS && t->attrs)
+  if (t->kind == TKIND_ALIAS && is_attr(t->attrs, ATTR_PUBLIC))
     return VT_USERDEFINED;
 
   switch (t->type) {
     return VT_USERDEFINED;
 
   switch (t->type) {
@@ -231,6 +231,7 @@ unsigned short get_type_vt(type_t *t)
   case RPC_FC_CPSTRUCT:
   case RPC_FC_CVSTRUCT:
   case RPC_FC_BOGUS_STRUCT:
   case RPC_FC_CPSTRUCT:
   case RPC_FC_CVSTRUCT:
   case RPC_FC_BOGUS_STRUCT:
+  case RPC_FC_COCLASS:
     return VT_USERDEFINED;
   case 0:
     return t->kind == TKIND_PRIMITIVE ? VT_VOID : VT_USERDEFINED;
     return VT_USERDEFINED;
   case 0:
     return t->kind == TKIND_PRIMITIVE ? VT_VOID : VT_USERDEFINED;
@@ -240,20 +241,13 @@ unsigned short get_type_vt(type_t *t)
   return 0;
 }
 
   return 0;
 }
 
-void start_typelib(char *name, const attr_list_t *attrs)
+void start_typelib(typelib_t *typelib_type)
 {
     in_typelib++;
     if (!do_typelib) return;
 
 {
     in_typelib++;
     if (!do_typelib) return;
 
-    typelib = xmalloc(sizeof(*typelib));
-    typelib->name = xstrdup(name);
+    typelib = typelib_type;
     typelib->filename = xstrdup(typelib_name);
     typelib->filename = xstrdup(typelib_name);
-    typelib->attrs = attrs;
-    list_init( &typelib->entries );
-    list_init( &typelib->importlibs );
-
-    if (is_attr(attrs, ATTR_POINTERDEFAULT))
-        pointer_default = get_attrv(attrs, ATTR_POINTERDEFAULT);
 }
 
 void end_typelib(void)
 }
 
 void end_typelib(void)
@@ -262,8 +256,6 @@ void end_typelib(void)
     if (!typelib) return;
 
     create_msft_typelib(typelib);
     if (!typelib) return;
 
     create_msft_typelib(typelib);
-    pointer_default = RPC_FC_UP;
-    return;
 }
 
 void add_typelib_entry(type_t *t)
 }
 
 void add_typelib_entry(type_t *t)
index 9dce14a..486dbb4 100644 (file)
@@ -22,7 +22,7 @@
 #define __WIDL_TYPELIB_H
 
 extern int in_typelib;
 #define __WIDL_TYPELIB_H
 
 extern int in_typelib;
-extern void start_typelib(char *name, const attr_list_t *attrs);
+extern void start_typelib(typelib_t *typelib_type);
 extern void end_typelib(void);
 extern void add_typelib_entry(type_t *t);
 extern void add_importlib(const char *name);
 extern void end_typelib(void);
 extern void add_typelib_entry(type_t *t);
 extern void add_importlib(const char *name);
index 73885c7..3e6fd2d 100644 (file)
@@ -279,13 +279,13 @@ static char *eat_space(char *s)
   return s;
 }
 
   return s;
 }
 
-void write_dlldata(ifref_list_t *ifaces)
+void write_dlldata(const statement_list_t *stmts)
 {
   struct list filenames = LIST_INIT(filenames);
   filename_node_t *node;
   FILE *dlldata;
 
 {
   struct list filenames = LIST_INIT(filenames);
   filename_node_t *node;
   FILE *dlldata;
 
-  if (!do_dlldata || !need_proxy_file(ifaces))
+  if (!do_dlldata || !need_proxy_file(stmts))
     return;
 
   dlldata = fopen(dlldata_name, "r");
     return;
 
   dlldata = fopen(dlldata_name, "r");
index 924b67a..f08a9ae 100644 (file)
@@ -68,9 +68,9 @@ extern FILE* header;
 extern FILE* local_stubs;
 extern FILE* idfile;
 
 extern FILE* local_stubs;
 extern FILE* idfile;
 
-extern void write_proxies(ifref_list_t *ifaces);
-extern void write_client(ifref_list_t *ifaces);
-extern void write_server(ifref_list_t *ifaces);
-extern void write_dlldata(ifref_list_t *ifaces);
+extern void write_proxies(const statement_list_t *stmts);
+extern void write_client(const statement_list_t *stmts);
+extern void write_server(const statement_list_t *stmts);
+extern void write_dlldata(const statement_list_t *stmts);
 
 #endif
 
 #endif
index 7901c19..fe519bd 100644 (file)
@@ -6,6 +6,7 @@
        <include base="wpp">.</include>
        <library>wpp</library>
        <file>client.c</file>
        <include base="wpp">.</include>
        <library>wpp</library>
        <file>client.c</file>
+       <file>expr.c</file>
        <file>hash.c</file>
        <file>header.c</file>
        <file>proxy.c</file>
        <file>hash.c</file>
        <file>header.c</file>
        <file>proxy.c</file>
index 48a426b..de1ea3f 100644 (file)
@@ -43,6 +43,7 @@ typedef GUID UUID;
 #endif
 #define FALSE 0
 
 #endif
 #define FALSE 0
 
+#define RPC_FC_COCLASS  0xfd
 #define RPC_FC_FUNCTION 0xfe
 
 typedef struct _loc_info_t loc_info_t;
 #define RPC_FC_FUNCTION 0xfe
 
 typedef struct _loc_info_t loc_info_t;
@@ -51,7 +52,7 @@ typedef struct _expr_t expr_t;
 typedef struct _type_t type_t;
 typedef struct _typeref_t typeref_t;
 typedef struct _var_t var_t;
 typedef struct _type_t type_t;
 typedef struct _typeref_t typeref_t;
 typedef struct _var_t var_t;
-typedef struct _pident_t pident_t;
+typedef struct _declarator_t declarator_t;
 typedef struct _func_t func_t;
 typedef struct _ifref_t ifref_t;
 typedef struct _typelib_entry_t typelib_entry_t;
 typedef struct _func_t func_t;
 typedef struct _ifref_t ifref_t;
 typedef struct _typelib_entry_t typelib_entry_t;
@@ -60,17 +61,20 @@ typedef struct _importinfo_t importinfo_t;
 typedef struct _typelib_t typelib_t;
 typedef struct _user_type_t user_type_t;
 typedef struct _user_type_t context_handle_t;
 typedef struct _typelib_t typelib_t;
 typedef struct _user_type_t user_type_t;
 typedef struct _user_type_t context_handle_t;
+typedef struct _type_list_t type_list_t;
+typedef struct _statement_t statement_t;
 
 typedef struct list attr_list_t;
 typedef struct list str_list_t;
 typedef struct list func_list_t;
 typedef struct list expr_list_t;
 typedef struct list var_list_t;
 
 typedef struct list attr_list_t;
 typedef struct list str_list_t;
 typedef struct list func_list_t;
 typedef struct list expr_list_t;
 typedef struct list var_list_t;
-typedef struct list pident_list_t;
+typedef struct list declarator_list_t;
 typedef struct list ifref_list_t;
 typedef struct list array_dims_t;
 typedef struct list user_type_list_t;
 typedef struct list context_handle_list_t;
 typedef struct list ifref_list_t;
 typedef struct list array_dims_t;
 typedef struct list user_type_list_t;
 typedef struct list context_handle_list_t;
+typedef struct list statement_list_t;
 
 enum attr_type
 {
 
 enum attr_type
 {
@@ -83,20 +87,19 @@ enum attr_type
     ATTR_CALLAS,
     ATTR_CALLCONV, /* calling convention pseudo-attribute */
     ATTR_CASE,
     ATTR_CALLAS,
     ATTR_CALLCONV, /* calling convention pseudo-attribute */
     ATTR_CASE,
+    ATTR_CONST, /* const pseudo-attribute */
     ATTR_CONTEXTHANDLE,
     ATTR_CONTROL,
     ATTR_DEFAULT,
     ATTR_DEFAULTCOLLELEM,
     ATTR_CONTEXTHANDLE,
     ATTR_CONTROL,
     ATTR_DEFAULT,
     ATTR_DEFAULTCOLLELEM,
-    ATTR_DEFAULTVALUE_EXPR,
-    ATTR_DEFAULTVALUE_STRING,
+    ATTR_DEFAULTVALUE,
     ATTR_DEFAULTVTABLE,
     ATTR_DISPINTERFACE,
     ATTR_DISPLAYBIND,
     ATTR_DLLNAME,
     ATTR_DUAL,
     ATTR_ENDPOINT,
     ATTR_DEFAULTVTABLE,
     ATTR_DISPINTERFACE,
     ATTR_DISPLAYBIND,
     ATTR_DLLNAME,
     ATTR_DUAL,
     ATTR_ENDPOINT,
-    ATTR_ENTRY_ORDINAL,
-    ATTR_ENTRY_STRING,
+    ATTR_ENTRY,
     ATTR_EXPLICIT_HANDLE,
     ATTR_HANDLE,
     ATTR_HELPCONTEXT,
     ATTR_EXPLICIT_HANDLE,
     ATTR_HANDLE,
     ATTR_HELPCONTEXT,
@@ -111,8 +114,10 @@ enum attr_type
     ATTR_IMMEDIATEBIND,
     ATTR_IMPLICIT_HANDLE,
     ATTR_IN,
     ATTR_IMMEDIATEBIND,
     ATTR_IMPLICIT_HANDLE,
     ATTR_IN,
+    ATTR_INLINE,
     ATTR_INPUTSYNC,
     ATTR_LENGTHIS,
     ATTR_INPUTSYNC,
     ATTR_LENGTHIS,
+    ATTR_LIBLCID,
     ATTR_LOCAL,
     ATTR_NONBROWSABLE,
     ATTR_NONCREATABLE,
     ATTR_LOCAL,
     ATTR_NONBROWSABLE,
     ATTR_NONCREATABLE,
@@ -170,6 +175,22 @@ enum expr_type
     EXPR_COND,
     EXPR_TRUEFALSE,
     EXPR_ADDRESSOF,
     EXPR_COND,
     EXPR_TRUEFALSE,
     EXPR_ADDRESSOF,
+    EXPR_MEMBER,
+    EXPR_ARRAY,
+    EXPR_MOD,
+    EXPR_LOGOR,
+    EXPR_LOGAND,
+    EXPR_XOR,
+    EXPR_EQUALITY,
+    EXPR_INEQUALITY,
+    EXPR_GTR,
+    EXPR_LESS,
+    EXPR_GTREQL,
+    EXPR_LESSEQL,
+    EXPR_LOGNOT,
+    EXPR_POS,
+    EXPR_STRLIT,
+    EXPR_WSTRLIT,
 };
 
 enum type_kind
 };
 
 enum type_kind
@@ -186,6 +207,27 @@ enum type_kind
     TKIND_MAX
 };
 
     TKIND_MAX
 };
 
+enum storage_class
+{
+    STG_NONE,
+    STG_STATIC,
+    STG_EXTERN,
+    STG_REGISTER,
+};
+
+enum statement_type
+{
+    STMT_LIBRARY,
+    STMT_DECLARATION,
+    STMT_TYPE,
+    STMT_TYPEREF,
+    STMT_MODULE,
+    STMT_TYPEDEF,
+    STMT_IMPORT,
+    STMT_IMPORTLIB,
+    STMT_CPPQUOTE
+};
+
 struct _loc_info_t
 {
     const char *input_name;
 struct _loc_info_t
 {
     const char *input_name;
@@ -231,7 +273,7 @@ struct _type_t {
   enum type_kind kind;
   unsigned char type;
   struct _type_t *ref;
   enum type_kind kind;
   unsigned char type;
   struct _type_t *ref;
-  const attr_list_t *attrs;
+  attr_list_t *attrs;
   func_list_t *funcs;             /* interfaces and modules */
   var_list_t *fields_or_args;     /* interfaces, structures, enumerations and functions (for args) */
   ifref_list_t *ifaces;           /* coclasses */
   func_list_t *funcs;             /* interfaces and modules */
   var_list_t *fields_or_args;     /* interfaces, structures, enumerations and functions (for args) */
   ifref_list_t *ifaces;           /* coclasses */
@@ -243,11 +285,11 @@ struct _type_t {
   int typelib_idx;
   unsigned int declarray : 1;     /* if declared as an array */
   unsigned int ignore : 1;
   int typelib_idx;
   unsigned int declarray : 1;     /* if declared as an array */
   unsigned int ignore : 1;
-  unsigned int is_const : 1;
   unsigned int defined : 1;
   unsigned int written : 1;
   unsigned int user_types_registered : 1;
   unsigned int tfswrite : 1;   /* if the type needs to be written to the TFS */
   unsigned int defined : 1;
   unsigned int written : 1;
   unsigned int user_types_registered : 1;
   unsigned int tfswrite : 1;   /* if the type needs to be written to the TFS */
+  unsigned int checked : 1;
   int sign : 2;
 };
 
   int sign : 2;
 };
 
@@ -256,6 +298,7 @@ struct _var_t {
   type_t *type;
   attr_list_t *attrs;
   expr_t *eval;
   type_t *type;
   attr_list_t *attrs;
   expr_t *eval;
+  enum storage_class stgclass;
 
   struct _loc_info_t loc_info;
 
 
   struct _loc_info_t loc_info;
 
@@ -263,15 +306,11 @@ struct _var_t {
   struct list entry;
 };
 
   struct list entry;
 };
 
-struct _pident_t {
+struct _declarator_t {
   var_t *var;
   var_t *var;
-  int ptr_level;
-
-  int is_func;
-  /* levels of indirection for function pointers */
-  int func_ptr_level;
-  var_list_t *args;
-  char *callconv;
+  type_t *type;
+  type_t *func_type;
+  array_dims_t *array;
 
   /* parser-internal */
   struct list entry;
 
   /* parser-internal */
   struct list entry;
@@ -330,6 +369,7 @@ struct _typelib_t {
     const attr_list_t *attrs;
     struct list entries;
     struct list importlibs;
     const attr_list_t *attrs;
     struct list entries;
     struct list importlibs;
+    statement_list_t *stmts;
 };
 
 struct _user_type_t {
 };
 
 struct _user_type_t {
@@ -337,6 +377,25 @@ struct _user_type_t {
     const char *name;
 };
 
     const char *name;
 };
 
+struct _type_list_t {
+    type_t *type;
+    struct _type_list_t *next;
+};
+
+struct _statement_t {
+    struct list entry;
+    enum statement_type type;
+    union
+    {
+        ifref_t iface;
+        type_t *type;
+        const char *str;
+        var_t *var;
+        typelib_t *lib;
+        type_list_t *type_list;
+    } u;
+};
+
 extern unsigned char pointer_default;
 
 extern user_type_list_t user_type_list;
 extern unsigned char pointer_default;
 
 extern user_type_list_t user_type_list;
@@ -356,6 +415,10 @@ int cant_be_null(const var_t *v);
 int is_struct(unsigned char tc);
 int is_union(unsigned char tc);
 
 int is_struct(unsigned char tc);
 int is_union(unsigned char tc);
 
+var_t *find_const(const char *name, int f);
+type_t *find_type(const char *name, int t);
+type_t *make_type(unsigned char type, type_t *ref);
+
 static inline type_t *get_func_return_type(const func_t *func)
 {
   return func->def->type->ref;
 static inline type_t *get_func_return_type(const func_t *func)
 {
   return func->def->type->ref;
index 3ecd5c4..4b67a5f 100644 (file)
@@ -960,8 +960,8 @@ static int encode_type(
       {
         int typeinfo_offset;
 
       {
         int typeinfo_offset;
 
-        /* typedef'd types without attributes aren't included in the typelib */
-        while (type->typelib_idx < 0 && type->kind == TKIND_ALIAS && ! type->attrs)
+        /* typedef'd types without public attribute aren't included in the typelib */
+        while (type->typelib_idx < 0 && type->kind == TKIND_ALIAS && !is_attr(type->attrs, ATTR_PUBLIC))
           type = type->orig;
 
         chat("encode_type: VT_USERDEFINED - type %p name = %s type->type %d idx %d\n", type,
           type = type->orig;
 
         chat("encode_type: VT_USERDEFINED - type %p name = %s type->type %d idx %d\n", type,
@@ -984,10 +984,11 @@ static int encode_type(
             case RPC_FC_ENUM16:
                 add_enum_typeinfo(typelib, type);
                 break;
             case RPC_FC_ENUM16:
                 add_enum_typeinfo(typelib, type);
                 break;
+            case RPC_FC_COCLASS:
+                add_coclass_typeinfo(typelib, type);
+                break;
             case 0:
             case 0:
-                if (type->kind == TKIND_COCLASS)
-                    add_coclass_typeinfo(typelib, type);
-                else if (type->kind == TKIND_DISPATCH)
+                if (type->kind == TKIND_DISPATCH)
                     add_dispinterface_typeinfo(typelib, type);
                 else
                     error("encode_type: VT_USERDEFINED - can't yet add typedef's on the fly\n");
                     add_dispinterface_typeinfo(typelib, type);
                 else
                     error("encode_type: VT_USERDEFINED - can't yet add typedef's on the fly\n");
@@ -1180,7 +1181,7 @@ static unsigned long get_ulong_val(unsigned long val, int vt)
     return val;
 }
 
     return val;
 }
 
-static void write_value(msft_typelib_t* typelib, int *out, int vt, void *value)
+static void write_value(msft_typelib_t* typelib, int *out, int vt, const void *value)
 {
     switch(vt) {
     case VT_I2:
 {
     switch(vt) {
     case VT_I2:
@@ -1196,7 +1197,7 @@ static void write_value(msft_typelib_t* typelib, int *out, int vt, void *value)
     case VT_HRESULT:
     case VT_PTR:
       {
     case VT_HRESULT:
     case VT_PTR:
       {
-        const unsigned long lv = get_ulong_val(*(unsigned long*)value, vt);
+        const unsigned long lv = get_ulong_val(*(const unsigned long*)value, vt);
         if((lv & 0x3ffffff) == lv) {
             *out = 0x80000000;
             *out |= vt << 26;
         if((lv & 0x3ffffff) == lv) {
             *out = 0x80000000;
             *out |= vt << 26;
@@ -1212,7 +1213,7 @@ static void write_value(msft_typelib_t* typelib, int *out, int vt, void *value)
       }
     case VT_BSTR:
       {
       }
     case VT_BSTR:
       {
-        char *s = (char *) value;
+        const char *s = (const char *) value;
         int len = strlen(s), seg_len = (len + 6 + 3) & ~0x3;
         int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, seg_len, 0);
         *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt;
         int len = strlen(s), seg_len = (len + 6 + 3) & ~0x3;
         int offset = ctl2_alloc_segment(typelib, MSFT_SEG_CUSTDATA, seg_len, 0);
         *((unsigned short *)&typelib->typelib_segment_data[MSFT_SEG_CUSTDATA][offset]) = vt;
@@ -1302,7 +1303,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int
       {
         num_params++;
         if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
       {
         num_params++;
         if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
-            if(attr->type == ATTR_DEFAULTVALUE_EXPR || attr->type == ATTR_DEFAULTVALUE_STRING)
+            if(attr->type == ATTR_DEFAULTVALUE)
                 num_defaults++;
             else if(attr->type == ATTR_OPTIONAL)
                 num_optional++;
                 num_defaults++;
             else if(attr->type == ATTR_OPTIONAL)
                 num_optional++;
@@ -1326,14 +1327,14 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int
         case ATTR_DISPLAYBIND:
             funcflags |= 0x10; /* FUNCFLAG_FDISPLAYBIND */
             break;
         case ATTR_DISPLAYBIND:
             funcflags |= 0x10; /* FUNCFLAG_FDISPLAYBIND */
             break;
-        case ATTR_ENTRY_ORDINAL:
-            extra_attr = max(extra_attr, 3);
-            entry = expr->cval;
-            entry_is_ord = 1;
-            break;
-        case ATTR_ENTRY_STRING:
+        case ATTR_ENTRY:
             extra_attr = max(extra_attr, 3);
             extra_attr = max(extra_attr, 3);
-            entry = ctl2_alloc_string(typeinfo->typelib, attr->u.pval);
+            if (expr->type == EXPR_STRLIT || expr->type == EXPR_WSTRLIT)
+              entry = ctl2_alloc_string(typeinfo->typelib, attr->u.pval);
+            else {
+              entry = expr->cval;
+              entry_is_ord = 1;
+            }
             break;
         case ATTR_HELPCONTEXT:
             extra_attr = max(extra_attr, 1);
             break;
         case ATTR_HELPCONTEXT:
             extra_attr = max(extra_attr, 1);
@@ -1474,7 +1475,7 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int
        encode_var(typeinfo->typelib, arg->type, arg, paramdata, NULL, NULL, &decoded_size);
         if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
             switch(attr->type) {
        encode_var(typeinfo->typelib, arg->type, arg, paramdata, NULL, NULL, &decoded_size);
         if (arg->attrs) LIST_FOR_EACH_ENTRY( attr, arg->attrs, const attr_t, entry ) {
             switch(attr->type) {
-            case ATTR_DEFAULTVALUE_EXPR:
+            case ATTR_DEFAULTVALUE:
               {
                 int vt;
                 expr_t *expr = (expr_t *)attr->u.pval;
               {
                 int vt;
                 expr_t *expr = (expr_t *)attr->u.pval;
@@ -1483,21 +1484,17 @@ static HRESULT add_func_desc(msft_typeinfo_t* typeinfo, const func_t *func, int
                 else
                     vt = get_type_vt(arg->type);
                 paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */
                 else
                     vt = get_type_vt(arg->type);
                 paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */
-                chat("default value %ld\n", expr->cval);
-                write_value(typeinfo->typelib, defaultdata, vt, &expr->cval);
-                break;
-              }
-            case ATTR_DEFAULTVALUE_STRING:
-              {
-                char *s = (char *)attr->u.pval;
-                int vt;
-                if (arg->type->type == RPC_FC_ENUM16)
-                  vt = VT_INT;
+                if (expr->type == EXPR_STRLIT || expr->type == EXPR_WSTRLIT)
+                {
+                  if (vt != VT_BSTR) error("string default value applied to non-string type\n");
+                  chat("default value '%s'\n", expr->u.sval);
+                  write_value(typeinfo->typelib, defaultdata, vt, expr->u.sval);
+                }
                 else
                 else
-                  vt = get_type_vt(arg->type);
-                paramflags |= 0x30; /* PARAMFLAG_FHASDEFAULT | PARAMFLAG_FOPT */
-                chat("default value '%s'\n", s);
-                write_value(typeinfo->typelib, defaultdata, vt, s);
+                {
+                  chat("default value %ld\n", expr->cval);
+                  write_value(typeinfo->typelib, defaultdata, vt, &expr->cval);
+                }
                 break;
               }
             case ATTR_IN:
                 break;
               }
             case ATTR_IN:
@@ -2320,8 +2317,8 @@ static void set_help_string_context(msft_typelib_t *typelib)
 
 static void set_lcid(msft_typelib_t *typelib)
 {
 
 static void set_lcid(msft_typelib_t *typelib)
 {
-    typelib->typelib_header.lcid2 = 0x0;
-    return;
+    const expr_t *lcid_expr = get_attrp( typelib->typelib->attrs, ATTR_LIBLCID );
+    typelib->typelib_header.lcid2 = lcid_expr ? lcid_expr->cval : 0x0;
 }
 
 static void set_lib_flags(msft_typelib_t *typelib)
 }
 
 static void set_lib_flags(msft_typelib_t *typelib)