Index: trunk/src/emx/src/emxomf/stabshll.c
===================================================================
--- trunk/src/emx/src/emxomf/stabshll.c	(revision 309)
+++ trunk/src/emx/src/emxomf/stabshll.c	(revision 310)
@@ -126,4 +126,5 @@
   const char *name;             /* The field name */
   const char *sname;            /* Static name */
+  const char *mnglname;         /* Mangled name for methods. (#456) */
   int flags;                    /* Member flags (visibility) */
 };
@@ -184,4 +185,5 @@
           struct type *ret;     /* Return type */
           struct type *args;    /* Argument types */
+          struct type *domain;  /* Domain type (C++ member) (#456) */
           int arg_count;        /* Number of arguments */
         } func;
@@ -220,4 +222,5 @@
           int flags;            /* Member flags (visibility etc.) */
           const char *name;     /* Name of the member function */
+          const char *mnglname; /* Mangled Name of the member function. (#456) */
         } memfunc;
       struct
@@ -664,5 +667,6 @@
               && p->d.memfunc.offset == src->d.memfunc.offset
               && p->d.memfunc.flags == src->d.memfunc.flags
-              && p->d.memfunc.name == src->d.memfunc.name)
+              && p->d.memfunc.name == src->d.memfunc.name
+              && p->d.memfunc.mnglname == src->d.memfunc.mnglname)
             return p;
           break;
@@ -1488,4 +1492,6 @@
 
       ++parse_ptr;
+      args_grow.count = 0;  /* ASSUMES we can safely use args_grow/args_list. */
+      t2 = NULL;            /* t2=Domain type; t1=Return type; */
       if (*parse_ptr == '#')
         {
@@ -1501,19 +1507,38 @@
             goto syntax;
           t1 = parse_type (NULL); /* Return type */
+          /* Arguments */
           while (*parse_ptr != ';')
             {
               if (!parse_char (','))
                 goto syntax;
-              t2 = parse_type (NULL); /* Argument type */
+              grow_by (&args_grow, 1);
+              args_list[args_grow.count++] = parse_type (NULL); /* Argument type */
             }
           ++parse_ptr;
         }
 
+      t3 = NULL;
+      #if 0
+      if (args_grow.count)
+        {
+          t.tag = ty_args;
+          t.index = -1;
+          t.d.args.count = args_grow.count;
+          t.d.args.list = xmalloc (args_grow.count * sizeof (*args_list));
+          memcpy (t.d.args.list, args_list, args_grow.count * sizeof (*args_list));
+          t3 = type_add (&t);
+          free (t.d.args.list);
+        }
+      #endif
+
       /* Make a function type from the return type t1 */
-
       t.tag = ty_func;
       t.d.func.ret = t1;
-      t.d.func.args = NULL;
-      t.d.func.arg_count = 0;
+      t.d.func.domain = t2;
+      t.d.func.args = t3;
+      t.d.func.arg_count = args_grow.count;
+      args_grow.count = 0;
+      t1 = type_add(&t);
+
       break;
 
@@ -1704,4 +1729,5 @@
           tf->flags = VIS_PUBLIC;
           tf->name = strpool_addn (str_pool, parse_ptr, n);
+          tf->mnglname = NULL;
           parse_ptr = p1 + 1;
           if (*parse_ptr == ':')
@@ -1711,6 +1737,13 @@
               do
                 {
+                  const char * pszMangled;
+
                   t1 = parse_type (NULL);
                   offset = 0;
+                  if (t1 == NULL || t1->tag != ty_func)
+                    {
+                      no_warning ("Invalid member function type");
+                      goto syntax;
+                    }
 
                   if (*parse_ptr != ':')
@@ -1720,6 +1753,8 @@
                     }
                   ++parse_ptr;
+                  pszMangled = parse_ptr;
                   if (!parse_mangled_args ())
                     goto syntax;
+                  tf->mnglname = strpool_addn(str_pool, pszMangled, parse_ptr - pszMangled - 1); /* ASSUMES not extra spaces! */
                   tf->flags = parse_visibility () | MEMBER_FUNCTION;
                   switch (*parse_ptr)
@@ -1776,4 +1811,14 @@
                         ++parse_ptr;
                     }
+                  /* Contstructor / Destructor hack -
+                   * TODO: verify that this doesn't really work with overloaded constructors and fix it.
+                   */
+                  if (!(tf->flags & MEMBER_STATIC))
+                    {
+                      if (!strcmp(tf->name, "__comp_ctor") || !strcmp(tf->name, "__base_ctor"))
+                          tf->flags |= MEMBER_CTOR;
+                      else if (!strcmp(tf->name, "__comp_dtor") || !strcmp(tf->name, "__base_dtor"))
+                          tf->flags |= MEMBER_DTOR;
+                    }
                   tf->type = t1;
                   tf->offset = offset;
@@ -1874,4 +1919,5 @@
                   t.d.memfunc.type = t2;
                   t.d.memfunc.name = tmp_fields[i].name;
+                  t.d.memfunc.mnglname = tmp_fields[i].mnglname;
                   t.d.memfunc.flags = tmp_fields[i].flags;
                   t.d.memfunc.offset = tmp_fields[i].offset;
@@ -2694,23 +2740,4 @@
 
 
-/**
- * Checks if the given name is likely to be a C++ method.
- *
- * @returns 1 if C++ method.
- * @returns 0 if not method.
- * @param   pszName     Pointer to the name.
- * @remark  Can also, if need, look around for symbols, types and stuff, but
- *          will no alter any parser state.
- */
-static int isCxxMethod(const char* pszName)
-{
-    /* not perfect, but probably close enought */
-    return cplusplus_flag
-        && pszName[0] == '_'
-        && pszName[1] == 'Z'
-        && pszName[2] == 'N';
-}
-
-
 /* Define a function.  SYMBOL points to the sym_ptr entry.  The
    function arguments are taken from the args_list array.  Several
@@ -2738,41 +2765,51 @@
   proc_start_addr = symbol->n_value;
 
-  if (args_grow.count == 0)
-    t1 = NULL;
-  else
-    {
-      t.tag = ty_args;
-      t.index = -1;
-      t.d.args.count = args_grow.count;
-      t.d.args.list = xmalloc (args_grow.count * sizeof (*args_list));
-      memcpy (t.d.args.list, args_list, args_grow.count * sizeof (*args_list));
-      t1 = type_add (&t);
-      free (t.d.args.list);
-    }
-  last_fun_type.d.func.args = t1;
-  last_fun_type.d.func.arg_count = args_grow.count;
-  t2 = type_add (&last_fun_type);
-  make_type (t2, &ti);
-  if (isCxxMethod(name))
-    {
-      /* kso #456 2003-06-05: TODO - check for methods somehow */
-      sst_start (cplusplus_flag ? SST_CPPproc : SST_proc);
+  /* now let's see if there is a memfunc for this name. */
+  for (t1 = type_head; t1; t1 = t1->next)
+    if (    t1->tag == ty_memfunc
+        &&  t.d.memfunc.mnglname
+        &&  !strcmp (t1->d.memfunc.mnglname, name))
+      break;
+
+  if (t1)
+    { /* C++ member function */
+      sst_start (SST_memfunc);
       r.r_address = sst.size;
       buffer_dword (&sst, symbol->n_value); /* Segment offset */
-      buffer_word (&sst, ti);       /* Type index */
+      buffer_word (&sst, t1->index);        /* Type index */
       proc_patch_base = sst.size;
       buffer_dword (&sst, 0);       /* Length of proc */
       buffer_word (&sst, 0);        /* Length of prologue */
       buffer_dword (&sst, 0);       /* Length of prologue and body */
-      buffer_word (&sst, 0);        /* Class type (for member functions) */
+      t2 = t1->d.memfunc.type;
+      ti = 0;
+      if (t2 && t2->tag == ty_func && t2->d.func.domain)
+          ti = t2->d.func.domain->index;
+      else
+          warning (" Can't figure out which class method '%s' is a member of!", name);
+      buffer_word (&sst, ti);        /* Class type (for member functions) */
       buffer_byte (&sst, 8);        /* 32-bit near */
-      if (cplusplus_flag)
-        buffer_enc (&sst, name);    /* Proc name */
+      buffer_enc (&sst, name);      /* Proc name */
+      sst_end ();
+    }
+  else
+    {
+      if (args_grow.count == 0)
+        t1 = NULL;
       else
-        buffer_nstr (&sst, name);   /* Proc name */
-      sst_end ();
-    }
-  else
-    {
+        {
+          t.tag = ty_args;
+          t.index = -1;
+          t.d.args.count = args_grow.count;
+          t.d.args.list = xmalloc (args_grow.count * sizeof (*args_list));
+          memcpy (t.d.args.list, args_list, args_grow.count * sizeof (*args_list));
+          t1 = type_add (&t);
+          free (t.d.args.list);
+        }
+      last_fun_type.d.func.args = t1;
+      last_fun_type.d.func.arg_count = args_grow.count;
+      t2 = type_add (&last_fun_type);
+      make_type (t2, &ti);
+
       sst_start (cplusplus_flag ? SST_CPPproc : SST_proc);
       r.r_address = sst.size;
@@ -3062,9 +3099,14 @@
           else
             {/* kso #456 2003-06-05: We need a begin to catch the parameters. */
-              //block_begin (proc_start_addr);
+              struct relocation_info r = {0};
               sst_start (SST_begin);
-              buffer_dword (&sst, proc_start_addr); /* Segment offset */
-              buffer_dword (&sst, 10); /* Length */
+              r.r_address = sst.size;
+              buffer_dword (&sst, proc_start_addr);         /* Segment offset */
+              buffer_dword (&sst, text_size - proc_start_addr); /* Length */
               sst_end ();
+              r.r_length = 2;
+              r.r_symbolnum = N_TEXT;
+              buffer_mem (&sst_reloc, &r, sizeof (r));
+              prologue_length = 0;
             }
 
@@ -3140,5 +3182,5 @@
   buffer_byte (&sst, lang);
   buffer_nstr (&sst, "    ");       /* Compiler options */
-  buffer_nstr (&sst, "");           /* Compiler date */
+  buffer_nstr (&sst, __DATE__);     /* Compiler date */
   buffer_mem (&sst, &ts, sizeof (ts));
   sst_end ();
