Index: /trunk/src/gcc/gcc/config/i386/emx.c
===================================================================
--- /trunk/src/gcc/gcc/config/i386/emx.c	(revision 596)
+++ /trunk/src/gcc/gcc/config/i386/emx.c	(revision 597)
@@ -35,6 +35,6 @@
 #define PTR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
 #endif
-#if 0 /* debug */
-const char *code(tree node)
+#ifdef BIRD_DEBUG
+static const char *code(tree node)
 {
     if (node)
@@ -44,16 +44,16 @@
             case FUNCTION_TYPE: return "FUNCTION_TYPE";
             case FUNCTION_DECL: return "FUNCTION_DECL";
-            case METHOD_TYPE:   return "METHOD_TYPE"; 
-            case FIELD_DECL:    return "FIELD_DECL"; 
-            case TYPE_DECL:     return "TYPE_DECL"; 
-            case POINTER_TYPE:  return "POINTER_TYPE"; 
-            case VOID_TYPE:  return "VOID_TYPE"; 
-            case INTEGER_TYPE:  return "INTEGER_TYPE"; 
-            case CHAR_TYPE:  return "CHAR_TYPE"; 
-            case SET_TYPE:  return "SET_TYPE"; 
-            case ARRAY_TYPE:  return "ARRAY_TYPE"; 
-            case RECORD_TYPE:  return "RECORD_TYPE"; 
-            case QUAL_UNION_TYPE:  return "QUAL_UNION_TYPE"; 
-            case UNION_TYPE:  return "UNION_TYPE"; 
+            case METHOD_TYPE:   return "METHOD_TYPE";
+            case FIELD_DECL:    return "FIELD_DECL";
+            case TYPE_DECL:     return "TYPE_DECL";
+            case POINTER_TYPE:  return "POINTER_TYPE";
+            case VOID_TYPE:  return "VOID_TYPE";
+            case INTEGER_TYPE:  return "INTEGER_TYPE";
+            case CHAR_TYPE:  return "CHAR_TYPE";
+            case SET_TYPE:  return "SET_TYPE";
+            case ARRAY_TYPE:  return "ARRAY_TYPE";
+            case RECORD_TYPE:  return "RECORD_TYPE";
+            case QUAL_UNION_TYPE:  return "QUAL_UNION_TYPE";
+            case UNION_TYPE:  return "UNION_TYPE";
             default:
                 break;
@@ -63,26 +63,37 @@
 }
 
+void dump (tree node);
 void dump (tree node)
 {
-    const char *psz = "";
-    tree        type = TREE_TYPE (node);
-    tree        type2 = type ? TREE_TYPE(type) : NULL;
-
-    fprintf(stderr, "dbg: node=%d %s type=%d %s type_type=%d %s\n", 
+    tree        type, type2, context;
+    if (!node)
+        return;
+
+    type = TREE_TYPE (node);
+    type2 = type ? TREE_TYPE(type) : NULL;
+    context = DECL_P (node) ? DECL_CONTEXT (node) : NULL_TREE;
+    fprintf(stderr, "dbg: node=%d %s type=%d %s type_type=%d %s context=%d %s\n",
             TREE_CODE(node), code(node),
             type ? TREE_CODE(type) : -1, code(type),
-            type2 ? TREE_CODE(type2) : -1, code(type2));
-}
-#endif 
+            type2 ? TREE_CODE(type2) : -1, code(type2),
+            context ? TREE_CODE(context) : -1, code(context));
+}
+
+#define dfprintf(a) fprintf a
+#define DUMP(node) dump(node)
+#else
+#define dfprintf(a) do {} while (0)
+#define DUMP(node) do {} while (0)
+#endif
+
 
 tree ix86_handle_system_attribute (tree *node, tree name, tree args,
   int flags, bool *no_add_attrs)
 {
-  tree type;
-  size_t sl;
-  const char *oldsym;
-  char *newsym;
-
+  tree          type;
   (void)args; (void)flags;
+
+dfprintf ((stderr, "dbg: %s flags=%x\n", __FUNCTION__, flags));
+DUMP (*node);
 
   type = TREE_TYPE (*node);
@@ -91,28 +102,51 @@
       {
         case FUNCTION_TYPE:
-          oldsym = IDENTIFIER_POINTER (DECL_NAME (*node));
-          sl = strlen (oldsym);
-          newsym = xmalloc (sl + 2);
-          /* Specifying '*' as first symbol character tells gcc (see varasm.c,
-             function assemble_name()) to output the label as-is rather than
-             invoking the ASM_OUTPUT_LABELREF macro (which prepends a underscore) */
-          newsym [0] = '*';
-          memcpy (newsym + 1, oldsym, sl + 1);
-          SET_DECL_ASSEMBLER_NAME (*node, get_identifier (newsym));
-          break;
+          {
+            tree          context;
+            size_t        sl;
+            const char *  oldsym;
+            char *        newsym;
+
+            /* typedef and field may end up here. they should not get their name changed! */
+            if (TREE_CODE (*node) == FIELD_DECL | TREE_CODE (*node) == TYPE_DECL)
+                return NULL_TREE;
+
+            /* class method (static) ends up here too, they should be get their
+               name changed. Try check if context is RECORD_TYPE and pray that
+               means it's a class...
+               @todo: verify the class detection here! CLASSTYPE_DECLARED_CLASS?  */
+            context = DECL_CONTEXT (*node);
+            DUMP ((context));
+            if (context && (    TREE_CODE (context) == RECORD_TYPE
+                            ||  TREE_CODE (context) == UNION_TYPE))
+              return NULL_TREE;
+            /** @todo more decl code checks? */
+
+
+            /* _System mangling!
+               Specifying '*' as first symbol character tells gcc (see varasm.c,
+               function assemble_name()) to output the label as-is rather than
+               invoking the ASM_OUTPUT_LABELREF macro (which prepends a underscore) */
+            oldsym = IDENTIFIER_POINTER (DECL_NAME (*node));
+            sl = strlen (oldsym);
+            newsym = xmalloc (sl + 2);
+            newsym [0] = '*';
+            memcpy (newsym + 1, oldsym, sl + 1);
+            SET_DECL_ASSEMBLER_NAME (*node, get_identifier (newsym));
+            dfprintf((stderr, "dbg: name change: %s -> %s\n", oldsym, newsym));
+            return NULL_TREE;
+          }
         case POINTER_TYPE:
           /* Pointer-to-a-function type is allowed */
 	  if (TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE
            && TREE_CODE (TREE_TYPE (type)) != METHOD_TYPE)
-            goto warn;
-/*@@@@@todo: not finished*/
-          break;
+            break;
         case METHOD_TYPE:
         case FIELD_DECL:
         case TYPE_DECL:
           /* Not a error but no action either */
+          return NULL_TREE;
+        default:
           break;
-        default:
-          goto warn;
       }
   else if (TREE_CODE (*node) == POINTER_TYPE && type)
@@ -122,19 +156,28 @@
           case FUNCTION_TYPE:
           case METHOD_TYPE:
+            return NULL_TREE;
+          default:
             break;
-          default:
-            goto warn;
         }
     }
-  else
-    {
-warn: warning ("`%s' attribute only applies to functions and function types",
-               IDENTIFIER_POINTER (name));
-      *no_add_attrs = true;
-      /*dump(*node); */
-    }
+  /* potential warnings get here */
+
+  /* IF there is a function in the works, we don't complain and
+     make sure _System is tried again on the function declaration.
+     OR if this is a function type we need to pass it up to the
+     declaration which is likely to be a some kind of type or field.
+     */
+  if (   (flags & (int)ATTR_FLAG_FUNCTION_NEXT)
+      || TREE_CODE (*node) == FUNCTION_TYPE
+      || TREE_CODE (*node) == METHOD_TYPE)
+    return tree_cons (name, args, NULL_TREE);
+
+  warning ("`%s' attribute only applies to functions and function types",
+           IDENTIFIER_POINTER (name));
+  *no_add_attrs = true;
 
   return NULL_TREE;
 }
+
 
 tree ix86_handle_optlink_attribute (tree *node, tree name, tree args,
@@ -157,5 +200,5 @@
           typeset = type;
         case FIELD_DECL:                /* how come these needs mangling? */
-        case TYPE_DECL:                 
+        case TYPE_DECL:
           id = DECL_ASSEMBLER_NAME (*node);
           /* Remove the leading underscore */
@@ -196,5 +239,5 @@
                IDENTIFIER_POINTER (name));
       *no_add_attrs = true;
-      /*dump(*node); */
+      DUMP (*node);
     }
 
