Index: trunk/src/emx/src/emxomf/stabshll.c
===================================================================
--- trunk/src/emx/src/emxomf/stabshll.c	(revision 318)
+++ trunk/src/emx/src/emxomf/stabshll.c	(revision 319)
@@ -264,4 +264,8 @@
 static const char *parse_ptr;
 
+/* Start of the stabs string we're parsing. Usful when printing
+   messages. */
+static const char *parse_start;
+
 /* The next HLL type index.  When creating a complex type, this index
    is used.  Then, this variable is incremented. */
@@ -345,15 +349,6 @@
 static int unnamed_struct_number;
 
-#ifndef HLL_DEBUG
-/* Suppress several kinds of warnings since newer gccs generates lots of
-   warnings... */
-
-static void no_warning (char *format, ...)
-{
-  (void)format;
-}
-#else
+/* kso #456 2003-06-11: Reversed quiet workaround. */
 #define no_warning warning
-#endif
 
 
@@ -555,10 +550,12 @@
   int i;
 
-  if (src->tag == ty_alias)
-    abort ();
   for (p = type_head; p != NULL; p = p->next)
     if (p->tag == src->tag)
       switch (p->tag)
         {
+        case ty_alias:
+          if (p->d.alias == src->d.alias)
+            return p;
+          break;
         case ty_stabs_ref:
           if (p->d.stabs_ref == src->d.stabs_ref)
@@ -610,5 +607,7 @@
         case ty_func:
           if (p->d.func.ret == src->d.func.ret
-              && p->d.func.args == src->d.func.args)
+              && p->d.func.args == src->d.func.args
+              && p->d.func.domain == src->d.func.domain
+              && p->d.func.arg_count == src->d.func.arg_count)
             return p;
           break;
@@ -740,7 +739,7 @@
 #ifdef HLL_DEBUG
   printf ("  type: stabs %d => HLL 0x%x\n", number, hll->index);
+#endif
   if (stype_list[number-1] != NULL && stype_list[number-1] != hll)
     warning ("Type stabs %d allready mapped to HLL 0x%x, new HLL 0x%x!!\n", number, stype_list[number-1]->index, hll->index);
-#endif
 
   stype_list[number-1] = hll;
@@ -941,7 +940,14 @@
           return 4;
         case 0x89:              /* 64 bit real */
+        case 0x8c:              /* 64 bit complex */
           return 8;
         case 0x8a:              /* 80 bit real (96 bits of storage) */
           return 12;
+        case 0x8d:              /* 128 bit complex */
+          return 16;
+        case 0x8e:              /* 160 bit complex */
+          return 24;
+        case 0x8f:              /* 256 bit complex (birds invention) */
+          return 32;
         }
       error ("type_size: Unknown primitive type: %d", tp->index);
@@ -1214,5 +1220,6 @@
   if (*parse_ptr != c)
     {
-      no_warning ("Invalid symbol data: `%c' expected", c);
+      no_warning ("Invalid symbol data: `%c' expected, found '%c' (off %ld)\n stabs: %s",
+                  c, *parse_ptr, parse_ptr - parse_start, parse_start);
       return FALSE;
     }
@@ -1278,4 +1285,15 @@
   char tmp[32];
 
+  /* Some names have only spaces for gdb safety, let's make an
+     fake name for those. */
+  if (type_name != NULL)
+    {
+      const char *psz = type_name;
+      while (*psz == ' ' || *psz == '\t')
+          psz++;
+      if (!*psz)
+          type_name = NULL;
+    }
+
   if (type_name == NULL)
     {
@@ -1284,4 +1302,37 @@
     }
   return strpool_add (str_pool, type_name);
+}
+
+/**
+ * Finds the next colon in the string and returns pointer to it.
+ * For C++ template support, colons within <> are not considered.
+ *
+ * @returns Pointer to next colon within psz.
+ * @returns NULL if not found.
+ * @param   psz     String to search.
+ */
+static const char *nextcolon(const char *psz)
+{
+    int cNesting;                       /* <> level */
+
+    for (cNesting = 0;;psz++)
+      switch (*psz)
+        {
+          case '<':
+            cNesting++;
+            break;
+          case '>':
+            cNesting--;
+            break;
+          case ':':
+            if (cNesting <= 0)
+              return psz;
+            break;
+          case '\0':
+            return NULL;
+        }
+      psz++;
+
+    return NULL;
 }
 
@@ -1457,17 +1508,25 @@
     case 'k':
 
-      /* A const type: k<type> */
+      /* A const type: k<type>
+         HLL don't have const typedefs afaik, so we just make it an alias. */
 
       ++parse_ptr;
-      if (!parse_number (&num1))
-          goto syntax;
-
-      result = stype_find (num1);
-      if (result == NULL)
-        {
-          t.tag = ty_stabs_ref;
-          t.d.stabs_ref = num1;
-        }
-      break;
+      t1 = parse_type (NULL);
+      t.tag = ty_alias;
+      t.d.alias = t1;
+      break;
+
+   case 'B':
+
+      /* A volatile type: B<type>
+         This is a SUN extension, and right now we don't care to generate
+         specific HLL for it and stick with an alias. */
+
+      ++parse_ptr;
+      t1 = parse_type (NULL);
+      t.tag = ty_alias;
+      t.d.alias = t1;
+      break;
+
 
     case '&':
@@ -1500,4 +1559,5 @@
           if (!parse_char (';'))
             goto syntax;
+          no_warning ("We don't understand '##' methods.");
         }
       else
@@ -1519,5 +1579,5 @@
 
       t3 = NULL;
-      #if 0
+      #if 0 /* this doesn't really seems to be required, but can just as well leave it in. */
       if (args_grow.count)
         {
@@ -1614,5 +1674,5 @@
         }
       ++parse_ptr;
-      p1 = strchr (parse_ptr, ':');
+      p1 = nextcolon (parse_ptr);
       if (p1 == NULL)
         {
@@ -1705,5 +1765,9 @@
                   break;
                 case ty_struc:
-                  struct_to_class (t1);
+                  /* kso #456 2003-06-11: Don't mess with forward defines! */
+                  if (!(   (t1->d.struc.flags & STRUC_FORWARD)
+                        && t1->d.struc.types == NULL
+                        && t1->d.struc.fields == NULL))
+                    struct_to_class (t1);
                   break;
                 default:
@@ -1718,5 +1782,5 @@
       while (*parse_ptr != ';')
         {
-          p1 = strchr (parse_ptr, ':');
+          p1 = nextcolon (parse_ptr);
           if (p1 == NULL)
             {
@@ -2024,5 +2088,5 @@
       while (*parse_ptr != ';')
         {
-          p1 = strchr (parse_ptr, ':');
+          p1 = nextcolon (parse_ptr);
           if (p1 == NULL)
             {
@@ -2118,4 +2182,5 @@
       t.tag = ty_func;
       t.d.func.ret = t1;
+      t.d.func.domain = NULL;
       t.d.func.args = NULL;
       t.d.func.arg_count = 0;
@@ -2134,5 +2199,7 @@
 
 syntax:
-  no_warning ("syntax error in stabs: %c", *parse_ptr);
+  no_warning ("syntax error in stabs: %c (off %ld)\n stabs: %s",
+              *parse_ptr, parse_ptr - parse_start, parse_start);
+
   grow_free (&g1);
   t.tag = ty_prim;
@@ -2153,5 +2220,6 @@
   tp = parse_type (type_name);
   if (*parse_ptr != 0)
-    no_warning ("unexpected character at end of stabs type: %c", *parse_ptr);
+      no_warning ("unexpected character at end of stabs type: %c (off %ld)\n stabs: %s",
+                  *parse_ptr, parse_ptr - parse_start, parse_start);
   return tp;
 }
@@ -2530,5 +2598,5 @@
 
   alloc_flag = concat_symbols (index, &str);
-  p = strchr (str, ':');
+  p = nextcolon (str);
   if (p != NULL)
     {
@@ -2540,5 +2608,5 @@
       printf ("LSYM/LCSYM/GSYM/PSYM/RSYM/STSYM/FUN %s\n", str);
 #endif
-      parse_ptr = p + 1;
+      parse_start = parse_ptr = p + 1;
       switch (*parse_ptr)
         {
@@ -2660,5 +2728,5 @@
   if (s->n_type != N_FUN)
     return FALSE;
-  p = strchr (str_ptr + s->n_un.n_strx, ':');
+  p = nextcolon (str_ptr + s->n_un.n_strx);
   if (p == NULL)
     return FALSE;
@@ -2755,5 +2823,5 @@
 
   str = str_ptr + symbol->n_un.n_strx;
-  p = strchr (str, ':');
+  p = nextcolon (str);
   if (p == NULL)
     abort ();
@@ -2774,8 +2842,11 @@
   if (t1)
     { /* C++ member function */
+      ti = t1->index;
+      if (ti == -1)
+        make_type (t1, &ti);
       sst_start (SST_memfunc);
       r.r_address = sst.size;
       buffer_dword (&sst, symbol->n_value); /* Segment offset */
-      buffer_word (&sst, t1->index);        /* Type index */
+      buffer_word (&sst, ti);       /* Type index */
       proc_patch_base = sst.size;
       buffer_dword (&sst, 0);       /* Length of proc */
@@ -2876,5 +2947,5 @@
   symbol = &sym_ptr[*index];
   alloc_flag = concat_symbols (index, &str);
-  p = strchr (str, ':');
+  p = nextcolon (str);
   if (p != NULL)
     {
@@ -2886,5 +2957,5 @@
       printf ("%s %s\n", msg, str);
 #endif
-      parse_ptr = p + 1;
+      parse_start = parse_ptr = p + 1;
       switch (*parse_ptr)
         {
@@ -3072,4 +3143,5 @@
           last_fun_type.tag = ty_func;
           last_fun_type.index = -1;
+          last_fun_type.d.func.domain = NULL;
           last_fun_type.d.func.ret = parse_type (NULL);
 
@@ -3143,11 +3215,22 @@
 {
   if (name != NULL)
-    {
+    { /* kso #456 2003-06-11: Templates can make very long names.
+         Clip them and let the debugger burn on them if it doesn't like it. */
+      char  achName[256];
+      int   cch = strlen(name);
+      if (cch > 250)
+        {
+          warning ("type_tag: name is longer than 250 bytes (%d).", cch);
+          cch = 250;
+        }
+      memcpy (achName, name, cch);
+      achName[cch] = '\0';
+
       sst_start (type);
       buffer_word (&sst, index);
       if (type == SST_class)
-        buffer_enc (&sst, name);
+        buffer_enc (&sst, achName);
       else
-        buffer_nstr (&sst, name);
+        buffer_nstr (&sst, achName);
       sst_end ();
     }
@@ -3313,4 +3396,7 @@
           type_tag (SST_class, t1->index, t1->d.class.name);
           break;
+        case ty_enu:
+          type_tag (SST_tag, t1->index, t1->d.enu.name);
+          break;
         default:
           break;
