widl: Calculate method indices in the parser

Dan Hipschman dsh at linux.ucla.edu
Tue Aug 15 16:23:18 CDT 2006


Currently, "widl oaidl.idl" succeeds, but "widl -p oaidl.idl" fails with
"oaidl.idl:1629: Error: method index mismatch in write_proxy".  This is
because the method indices are computed in one of the calls that writes
header output.  This calculates them in the parser instead.  The generated
proxy and header code isn't changed, but now "widl -p oaidl.idl" works.

ChangeLog:
* Calculate method indices in parser instead of during header generation
---
 tools/widl/header.c |   12 +++---------
 tools/widl/parser.y |   28 ++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/tools/widl/header.c b/tools/widl/header.c
index 6344fb3..0042c63 100644
--- a/tools/widl/header.c
+++ b/tools/widl/header.c
@@ -572,15 +572,13 @@ const var_t *is_callas(const attr_t *a)
   return get_attrp(a, ATTR_CALLAS);
 }
 
-static int write_method_macro(const type_t *iface, const char *name)
+static void write_method_macro(const type_t *iface, const char *name)
 {
-  int idx;
   func_t *cur = iface->funcs;
 
-  if (iface->ref) idx = write_method_macro(iface->ref, name);
-  else idx = 0;
+  if (iface->ref) write_method_macro(iface->ref, name);
 
-  if (!cur) return idx;
+  if (!cur) return;
   while (NEXT_LINK(cur)) cur = NEXT_LINK(cur);
 
   fprintf(header, "/*** %s methods ***/\n", iface->name);
@@ -608,13 +606,9 @@ static int write_method_macro(const type
       for (c=0; c<argc; c++)
 	fprintf(header, ",%c", c+'a');
       fprintf(header, ")\n");
-      if (cur->idx == -1) cur->idx = idx;
-      else if (cur->idx != idx) yyerror("BUG: method index mismatch in write_method_macro");
-      idx++;
     }
     cur = PREV_LINK(cur);
   }
-  return idx;
 }
 
 void write_args(FILE *h, var_t *arg, const char *name, int method, int do_indent)
diff --git a/tools/widl/parser.y b/tools/widl/parser.y
index 73ccf25..745056f 100644
--- a/tools/widl/parser.y
+++ b/tools/widl/parser.y
@@ -101,6 +101,8 @@ 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);
+
 #define tsENUM   1
 #define tsSTRUCT 2
 #define tsUNION  3
@@ -711,6 +713,7 @@ dispinterfacedef: dispinterfacehdr '{'
 						}
 /* FIXME: not sure how to handle this yet
 	| dispinterfacehdr '{' interface '}'	{ $$ = $1;
+						  compute_method_indexes($$);
 						  if (!parse_only && do_header) write_interface($$);
 						  if (!parse_only && do_idfile) write_iid($$);
 						}
@@ -737,6 +740,7 @@ interfacedef: interfacehdr inherit
 	  '{' int_statements '}'		{ $$ = $1;
 						  $$->ref = $2;
 						  $$->funcs = $4;
+						  compute_method_indexes($$);
 						  if (!parse_only && do_header) write_interface($$);
 						  if (!parse_only && do_idfile) write_iid($$);
 						}
@@ -747,6 +751,7 @@ interfacedef: interfacehdr inherit
 						  $$->ref = find_type2($3, 0);
 						  if (!$$->ref) yyerror("base class '%s' not found in import", $3);
 						  $$->funcs = $6;
+						  compute_method_indexes($$);
 						  if (!parse_only && do_header) write_interface($$);
 						  if (!parse_only && do_idfile) write_iid($$);
 						}
@@ -1539,3 +1544,26 @@ static void write_iid(type_t *iface)
   const UUID *uuid = get_attrp(iface->attrs, ATTR_UUID);
   write_guid(idfile, "IID", iface->name, uuid);
 }
+
+static int compute_method_indexes(type_t *iface)
+{
+  int idx;
+  func_t *f = iface->funcs;
+
+  if (iface->ref)
+    idx = compute_method_indexes(iface->ref);
+  else
+    idx = 0;
+
+  if (! f)
+    return idx;
+
+  while (NEXT_LINK(f))
+    f = NEXT_LINK(f);
+
+  for ( ; f ; f = PREV_LINK(f))
+    if (! is_callas(f->def->attrs))
+      f->idx = idx++;
+
+  return idx;
+}



More information about the wine-patches mailing list