--- backend/dwarf.c	2010-04-07 21:26:09.000000000 +0100
+++ backend/dwarf.c	2010-04-07 21:36:08.000000000 +0100
@@ -251,6 +251,7 @@
 static Outbuffer *infobuf;
 
 static AArray *type_table;
+static AArray *functype_table;
 
 #pragma pack(1)
 struct DebugInfoHeader
@@ -752,6 +753,10 @@
     {   delete type_table;
         type_table = NULL;
     }
+    if (functype_table)
+    {   delete functype_table;
+        functype_table = NULL;
+    }
 }
 
 /*****************************************
@@ -1202,6 +1207,16 @@
         DW_AT_encoding,         DW_FORM_data1,
         0,                      0,
     };
+    static unsigned char abbrevWchar[] =
+    {
+        DW_TAG_typedef,
+	0,                      // no children
+	DW_AT_name,             DW_FORM_string,
+	DW_AT_type,             DW_FORM_ref4,
+	DW_AT_decl_file,        DW_FORM_data1,
+	DW_AT_decl_line,        DW_FORM_data2,
+	0,                      0,
+    };
     static unsigned char abbrevTypePointer[] =
     {
         DW_TAG_pointer_type,
@@ -1312,6 +1327,15 @@
     idx = typidx_tab[ty];
     if (idx)
         return idx;
+    if (tyfunc(ty) && functype_table)
+    {    Atype functype;
+         functype.start = *((size_t *)t);
+         functype.end = *((size_t *)t) + sizeof(type);
+         unsigned *pidx;
+         pidx = (unsigned *)functype_table->get(&functype);
+         if (pidx)
+             return *pidx;
+    }
     const char *name;
     unsigned char ate;
     ate = tyuns(t->Tty) ? DW_ATE_unsigned : DW_ATE_signed;
@@ -1370,6 +1394,7 @@
             infobuf->write32(nextidx);          // DW_AT_type
             break;
 
+        case TYnref:
         case TYnptr:
             if (!t->Tkey)
                 goto Lnptr;
@@ -1444,7 +1469,9 @@
             else
                 abuf.writeByte(0);      // no children
             abuf.writeByte(DW_AT_prototyped);   abuf.writeByte(DW_FORM_flag);
-            abuf.writeByte(DW_AT_type);         abuf.writeByte(DW_FORM_ref4);
+	    if (nextidx != 0) // Don't write DW_AT_type for void
+	    {   abuf.writeByte(DW_AT_type);		abuf.writeByte(DW_FORM_ref4);
+	    }
             abuf.writeByte(0);                  abuf.writeByte(0);
             code = dwarf_abbrev_code(abuf.buf, abuf.size());
 
@@ -1466,8 +1493,8 @@
             if (params)
                 infobuf->write32(idxsibling);   // DW_AT_sibling
             infobuf->writeByte(1);              // DW_AT_prototyped
-            infobuf->write32(nextidx);          // DW_AT_type
-
+            if (nextidx != 0)
+                infobuf->write32(nextidx);      // DW_AT_type
             if (params)
             {
                 for (param_t *p = t->Tparamtypes; p; p = p->Pnext)
@@ -1480,6 +1507,14 @@
                 idxsibling = infobuf->size();
                 *(unsigned *)(infobuf->buf + siblingoffset) = idxsibling;
             }
+            if (!functype_table)
+                functype_table = new AArray(&ti_atype, sizeof(unsigned));
+            Atype functype;
+            functype.start = *((size_t *)t);
+            functype.end = *((size_t *)t) + sizeof(type);
+            unsigned *pidx;
+            pidx = (unsigned *)functype_table->get(&functype);
+            *pidx = idx;
             break;
         }
 
@@ -1533,16 +1568,19 @@
             break;
         }
 
-#if 0
         case TYwchar_t:
-            DW_TAG_typedef
-            children = 0
-            DW_AT_name                  DW_FORM_strp    00000170 'wchar_t'
-            DW_AT_decl_file             DW_FORM_data1   03
-            DW_AT_decl_line             DW_FORM_data2   0145
-            DW_AT_type                  DW_FORM_ref4    00000076 (long int)
-            DW_AT_0x00                  DW_FORM_0x00
-#endif
+	{
+            unsigned code = dwarf_abbrev_code(abbrevWchar, sizeof(abbrevWchar));
+            unsigned typebase = dwarf_typidx(tsint);
+            idx = infobuf->size();
+            infobuf->writeuLEB128(code);        // abbreviation code
+            infobuf->writeString("wchar_t");    // DW_AT_name
+            infobuf->write32(typebase);         // DW_AT_type
+            infobuf->writeByte(1);              // DW_AT_decl_file
+            infobuf->writeWord(1);              // DW_AT_decl_line
+            typidx_tab[ty] = idx;
+            break;
+       }
 
         case TYstruct:
         {
