diff -ru gpc-20040516.orig/p/config-lang.in gpc-20040516/p/config-lang.in
--- gpc-20040516.orig/p/config-lang.in	2004-05-13 00:48:32.000000000 +0200
+++ gpc-20040516/p/config-lang.in	2004-07-06 19:08:51.000000000 +0200
@@ -28,19 +28,50 @@
 stagestuff="gpc\$(exeext) gpc-cross\$(exeext) gpc1\$(exeext) gpcpp\$(exeext) libgpc.a"
 gtfiles="\$(srcdir)/p/gpc.h \$(srcdir)/p/declarations.c \$(srcdir)/p/module.c \$(srcdir)/p/predef.c"
 
+echo "in p/config-lang.in"
+echo "srcdir=$srcdir"
+echo "pwd=`pwd`"
+
+(
+if [ -f "$srcdir/version.c" ]
+then
+  MY_SRCDIR="$srcdir"
+  gcc_version_h="gcc-version.h"
+else
+  MY_SRCDIR="$srcdir/gcc"
+  gcc_version_h="gcc/gcc-version.h"
+  [ -d gcc ] || mkdir gcc
+fi
+
+# Check if running first time
+if [ -r "$gcc_version_h" ] ; then
+  echo "Not first time"
+  exit
+fi
+echo "First time"
+
+srcdir="$MY_SRCDIR"
+
 version=`grep version_string "$srcdir/version.c" | sed -e 's/[^"]*"//;s/[ "].*//'`
 mainversion="$version"
 gcc3=n
 if echo $version | grep '2\.9' > /dev/null || echo $version | grep '3\.[1-9]' > /dev/null; then
-  echo '#define EGCS' > gcc-version.h
+  echo '#define EGCS' > "$gcc_version_h"
   if echo $version | grep '2\.95\.[3-9]' > /dev/null || echo $version | grep '3\.[1-9]' > /dev/null; then
-    echo '#define GCC_2_95_3' >> gcc-version.h
+    echo '#define GCC_2_95_3' >> "$gcc_version_h"
   fi
   if echo $version | grep '2\.9[6-9]' > /dev/null || echo $version | grep '3\.[1-9]' > /dev/null; then
     gcc3=y
-    echo '#define EGCS97' >> gcc-version.h
+    echo '#define EGCS97' >> "$gcc_version_h"
     if echo $version | grep '3\.[3-9]' > /dev/null; then
-      echo '#define GCC_3_3' >> gcc-version.h
+      echo '#define GCC_3_3' >> "$gcc_version_h"
+      if echo $version | grep '^3\.[4-9]' > /dev/null; then
+          echo '#define GCC_3_4' >> "$gcc_version_h"
+          if echo $version | grep '^3\.[5-9]' > /dev/null; then
+              echo '#define GCC_3_5' >> "$gcc_version_h"
+          fi
+      fi
+
 #      echo "" >&2
 #      echo "***" >&2
 #      echo "*** Detected GCC version $mainversion." >&2
@@ -56,7 +87,7 @@
     fi
   fi
 else
-  echo "/* empty */" > gcc-version.h
+  echo "/* empty */" > "$gcc_version_h"
 fi
 
 for x in 2.95.1 2.95.2 2.95.3 2.95.3-5 2.95.3-6 2.95.3-8 2.95.4; do
@@ -119,3 +150,5 @@
     echo "# empty" > "$srcdir/p/Makefile.in"
   fi
 fi
+) || exit 1
+
diff -ru gpc-20040516.orig/p/cpp_predef.h gpc-20040516/p/cpp_predef.h
--- gpc-20040516.orig/p/cpp_predef.h	2004-07-06 19:20:30.000000000 +0200
+++ gpc-20040516/p/cpp_predef.h	2004-07-06 19:08:51.000000000 +0200
@@ -0,0 +1 @@
+#define GPC_CPP_PREDEFINES CPP_PREDEFINES
diff -ru gpc-20040516.orig/p/declarations.c gpc-20040516/p/declarations.c
--- gpc-20040516.orig/p/declarations.c	2004-05-12 02:39:11.000000000 +0200
+++ gpc-20040516/p/declarations.c	2004-07-06 19:12:30.000000000 +0200
@@ -214,13 +214,14 @@
 static tree shadow_one_level PARAMS ((tree, tree));
 static int resolve_forward_decl PARAMS ((tree));
 static tree get_parm_info PARAMS ((tree, int));
-static tree lookup_name_current_level PARAMS ((tree));
 static tree lookup_c_type PARAMS ((const char *));
 static tree make_real PARAMS ((double));
 static tree gpc_builtin_function PARAMS ((const char *, const char *, int, tree, tree));
 #if defined (EGCS97) && !defined (GCC_3_3)
 static void mark_binding_level PARAMS ((void *));
 #endif
+static tree mangle_name PARAMS ((tree));
+static int same_imported PARAMS ((tree, tree));
 
 /* Nonzero if we are currently in the global binding level. */
 int
@@ -228,7 +229,7 @@
 {
   if (size_volatile)
     return -1;
-  return current_binding_level == global_binding_level;
+  return pascal_global_bindings_p ();
 }
 
 int
@@ -479,6 +480,36 @@
   return get_identifier (copy);
 }
 
+static tree
+mangle_name (name)
+     tree name;
+{
+  assert (current_module);
+  return pascal_mangle_names(NULL, IDENTIFIER_POINTER (name));
+}
+
+tree
+pascal_mangle_names(object_name, name)
+     const char * object_name;
+     const char * name;
+{
+  static long serial_no = 0;
+  char serial_str[22];
+  const char * object_sep;
+  const char * mn = IDENTIFIER_POINTER (current_module->assembler_name);
+  sprintf(serial_str, "%ld", serial_no++);
+  if (!object_name)
+    {
+      object_name = "";
+      object_sep = "";
+    }
+  else 
+    object_sep = "_";
+  return get_identifier (ACONCAT ((
+        mn, "_S", serial_str, object_sep, object_name, "_", 
+        name, NULL)));
+}
+
 /* Parameters. */
 
 tree
@@ -766,17 +797,60 @@
   return error_mark_node;
 }
 
+int 
+same_imported (x, y)
+    tree x, y;
+{
+  tree tx = TREE_TYPE (x);
+  tree ty = TREE_TYPE (y);
+  if (TREE_CODE (x) != TREE_CODE (y))
+    return 0;
+  if (TREE_CODE (x) != CONST_DECL &&
+      TYPE_MAIN_VARIANT (tx) != TYPE_MAIN_VARIANT (ty))
+    return 0; 
+  switch (TREE_CODE (x))
+    {
+      case TYPE_DECL:
+        if (PASCAL_TYPE_BINDABLE (tx) != PASCAL_TYPE_BINDABLE (ty))
+          return 0;
+        /* FALLTHROUGH */
+      case CONST_DECL:
+        /* @@@@@@@ We should really compare _values_ -- below we
+           check if we have the same expression */
+        if (DECL_INITIAL (x) == DECL_INITIAL (y))
+          return 1;
+        break;
+      case FUNCTION_DECL:
+      case VAR_DECL:
+        /* @@ Not clear what to do if user specifies the same linker
+           name for two objects (different normal Pascal declarations
+           never give the same linker name). */
+        if (DECL_EXTERNAL (x) && DECL_EXTERNAL (y) &&
+            DECL_ASSEMBLER_NAME (x) == DECL_ASSEMBLER_NAME (y))
+          return 1;
+        break; 
+      default:
+        return 0;
+    }
+  return 0;
+}
+
 /* Record a decl-node X as belonging to the current lexical scope.
    Check for errors (such as redeclarations in the same scope).
    Returns either X or a forward decl. If a forward decl is returned,
    it may have been smashed to agree with what X says. */
+
+
 tree
 pushdecl (x)
      tree x;
 {
-  tree t, name = DECL_NAME (x);
-
+  tree t;
+  tree name = DECL_NAME (x);
+  int weak = 0;
   CHK_EM (TREE_TYPE (x));
+  assert (!PASCAL_DECL_WEAK (x));
+  assert (!PASCAL_DECL_IMPORTED (x));
 
   /* @@ Can happen when called from the backend. */
   if (!name)
@@ -795,12 +869,17 @@
     warning ("local external declaration of `%s'", IDENTIFIER_NAME (name));
 
   t = lookup_name_current_level (name);
-
   /* Overloading an operator is ok. The decl is a dummy placeholder.
      No need to replace it with another one. */
   if (t && TREE_CODE (t) == OPERATOR_DECL && TREE_CODE (x) == OPERATOR_DECL)
     return t;
 
+  if (t && PASCAL_DECL_WEAK (t))
+    {
+	t = NULL_TREE;
+	weak = 1;
+    }
+    
   if (t && (TREE_CODE (t) != FUNCTION_DECL || TREE_CODE (x) != FUNCTION_DECL
             || DECL_INITIAL (t) || !comptypes (TREE_TYPE (x), TREE_TYPE (t))))
     {
@@ -867,6 +946,7 @@
     }
 
   /* Install the new declaration. */
+  if (!weak) 
   t = IDENTIFIER_VALUE (name);
   IDENTIFIER_VALUE (name) = x;
 
@@ -894,6 +974,61 @@
   return x;
 }
 
+tree
+pushdecl_import (x, is_weak)
+      tree x;
+      int is_weak;
+{
+  tree name = DECL_NAME (x);
+  tree old = lookup_name_current_level (name);
+  int old_weak = 0;
+  assert (!PASCAL_DECL_WEAK (x));
+
+  if (old && PASCAL_DECL_WEAK (old))
+    {
+      old = 0;
+      old_weak = 1;
+    }
+
+  /* `uses' do not override declarations from current module/unit */ 
+  if (old && is_weak)
+    return old;
+
+  /* Overloading an operator is ok. The decl is a dummy placeholder.
+     No need to replace it with another one. */
+  if (old && TREE_CODE (old) == OPERATOR_DECL && TREE_CODE (x) == OPERATOR_DECL)
+    return old;
+
+  /* If the same thing is imported multiple times we just ignore
+     second declaration, unless it is principal identifier of
+     a constant */
+  if (old && PASCAL_DECL_IMPORTED (old) && same_imported (old, x))
+    {
+      if (TREE_CODE (x) == CONST_DECL && PASCAL_CST_PRINCIPAL_ID (x))
+        {
+          old = 0;
+          old_weak = 1;
+        }
+      else
+        return old;
+    }
+
+  if (old)
+    {
+      error_with_decl (x, "redeclaration of `%s'");
+      error_with_decl (old, " previous declaration");
+      return old;
+    }
+
+  if (!old_weak)
+    old = IDENTIFIER_VALUE (name);
+  if (old)
+    current_binding_level->shadowed = 
+         tree_cons (name, old, current_binding_level->shadowed);
+  PASCAL_DECL_WEAK (x) = is_weak;
+  return pushdecl_nocheck (x);
+}
+
 /* Record a decl-node X as belonging to the current lexical scope
    uncondionally and without any errors etc. (unlike pushdecl).
    For module imports and implicit declarations. */
@@ -1043,7 +1178,7 @@
 }
 
 /* Similar to `lookup_name' but look only at current scope. */
-static tree
+tree
 lookup_name_current_level (name)
      tree name;
 {
@@ -1078,9 +1213,19 @@
         return;
       if (co->warn_id_case && IDENTIFIER_SPELLING_FILE (id))
         {
+#ifndef GCC_3_4
           warning_with_file_and_line (filename, line, "capitalisation of `%s' doesn't match", spelling);
           warning_with_file_and_line (IDENTIFIER_SPELLING_FILE (id), IDENTIFIER_SPELLING_LINENO (id),
                                       " previous capitalisation `%s'", IDENTIFIER_SPELLING (id));
+#else
+          location_t loc_aux;
+          loc_aux.file = filename;
+          loc_aux.line = line;
+          warning ("%Hcapitalisation of identifier `%s' doesn't match", &loc_aux, spelling);
+          loc_aux.file = IDENTIFIER_SPELLING_FILE (id);
+          loc_aux.line = IDENTIFIER_SPELLING_LINENO (id);
+          warning ("%H previous capitalisation `%s'", &loc_aux, IDENTIFIER_SPELLING (id));
+#endif
         }
     }
   IDENTIFIER_SPELLING (id) = PERMANENT_STRING (spelling);
@@ -1168,6 +1313,33 @@
 }
 
 tree
+build_qualified_id (interface_id, id)
+     tree interface_id, id;
+{
+  tree qid = get_identifier (ACONCAT (
+           (IDENTIFIER_POINTER (interface_id),
+           ".",
+           (IDENTIFIER_POINTER (id)),
+           NULL)));
+  PASCAL_QUALIFIED_ID (qid) = 1;
+  return qid;
+}
+
+tree
+build_qualified_or_component_acces (id1, id2)
+     tree id1, id2;
+{
+  tree decl = lookup_name (id1);
+  if (decl && (TREE_CODE (decl) != NAMESPACE_DECL))
+    {
+      decl = check_identifier(id1);
+      return build_component_ref (undo_schema_dereference (decl), id2);
+    }
+  else
+    return check_identifier (build_qualified_id (id1, id2));
+}
+
+tree
 check_identifier (id)
      tree id;
 {
@@ -1300,6 +1472,11 @@
 {
   tree endlink;
 
+#ifndef EGCS97
+  /* Make identifier nodes long enough for the language-specific slots. */
+  set_identifier_size (sizeof (struct lang_identifier));
+#endif
+
 #if defined (EGCS97) && !defined (GCC_3_3)
   ggc_add_tree_root (pascal_global_trees, PTI_MAX);
   ggc_add_root (&current_binding_level, 1, sizeof (current_binding_level), mark_binding_level);
@@ -2056,7 +2233,7 @@
   else if (DECL_EXTERNAL (d))
     SET_DECL_ASSEMBLER_NAME (d, de_capitalize (name));
   else
-    SET_DECL_ASSEMBLER_NAME (d, name);
+    SET_DECL_ASSEMBLER_NAME (d, mangle_name (name));
 
   rest_of_decl_compilation (d, 0, !DECL_CONTEXT (d), 1 /* for GPC */);
 
@@ -2233,12 +2410,12 @@
 
 /* Compare two routine declarations. If arguments is NULL_TREE, it is not checked. */
 void
-check_routine_decl (arguments, restype, resvar, structor, old, filename, lineno)
+check_routine_decl (arguments, restype, resvar, structor, old, filename, line)
      tree arguments, restype, resvar;
      int structor;
      tree old;
      filename_t filename;
-     int lineno;
+     int line;
 {
   int mismatch = 0;
   if (arguments)
@@ -2267,7 +2444,15 @@
     {
       /* Say `routine' since there might be a mismatch in whether it's
          supposed to be a procedure, function or structor. */
-      error_with_file_and_line (filename, lineno, "routine definition does not match previous declaration");
+#ifndef GCC_3_4
+      error_with_file_and_line (filename, line, "routine definition does not match previous declaration");
+#else
+      location_t loc_aux;
+      loc_aux.file = filename;
+      loc_aux.line = line;
+      error ("%Hroutine definition does not match previous declaration", 
+              &loc_aux);
+#endif
       error_with_decl (old, " previous declaration");
     }
 }
@@ -2313,11 +2498,14 @@
 
   if (old && (!was_forward || TREE_CODE (old) != FUNCTION_DECL || DECL_INITIAL (old)))
     {
+      if (!PASCAL_DECL_WEAK (old))
+        {
       error ("redeclaration of `%s'", IDENTIFIER_NAME (name));
       error_with_decl (old, " previous declaration");
-      old = NULL_TREE;
       redeclaration = 1;
     }
+      old = NULL_TREE;
+    }
 
   if (old)
     {
@@ -2390,7 +2578,7 @@
       if (!PASCAL_METHOD_HEADING (foobar) /*&& !current_module->main_program*/
           && !(old && DECL_EXTERNAL (old)))
         TREE_PUBLIC (decl) = 0;
-      SET_DECL_ASSEMBLER_NAME (decl, DECL_NAME (decl));
+      SET_DECL_ASSEMBLER_NAME (decl, mangle_name (DECL_NAME (decl)));
     }
 
   if (is_extern && local)
@@ -2421,7 +2609,13 @@
     SET_DECL_LANG_OPERATOR_DECL (decl, operator_decl);
 
   if (local)
+    {
+#ifdef GCC_3_4
+      DECL_CONTEXT (decl) = current_function_decl;
+      SET_DECL_ASSEMBLER_NAME (decl, NULL);
+#endif
     push_function_context ();
+    }
 
   current_function_decl = decl;
 
@@ -2456,7 +2650,11 @@
   DECL_ARGUMENTS (decl) = getdecls ();
 
   /* Initialize the RTL code for the function. */
+#ifndef GCC_3_4
   init_function_start (decl, input_filename, lineno);
+#else
+  init_function_start (decl) ;
+#endif
 
   /* Set up parameters and prepare for return. */
   expand_function_start (decl, 0);
@@ -2549,7 +2747,11 @@
 #else
   make_decl_rtl (decl, NULL);
 #endif
+#ifndef GCC_3_4
   init_function_start (decl, input_filename, lineno);
+#else
+  init_function_start (decl);
+#endif
 #ifndef EGCS97
   /* To avoid crashing when compiling a unit with `-O3', see obstack_empty_p in tree.c:restore_tree_status() */
   preserve_initializer ();
@@ -2598,7 +2800,11 @@
     }
 
   /* Generate rtl for function exit. */
+#ifndef GCC_3_4
   expand_function_end (input_filename, lineno, 0);
+#else
+  expand_function_end ();
+#endif
 
 #ifndef EGCS97
   /* So we can tell if jump_optimize sets it to 1. */
@@ -2659,7 +2865,9 @@
       tree v = convert (r, build_int_2 (c, 0));
       PASCAL_TREE_FRESH_CST (v) = 1;
       DECL_INITIAL (decl) = TREE_VALUE (id) = v;
+      PASCAL_CST_PRINCIPAL_ID (decl) = 1;
       pushdecl (decl);
+      handle_autoexport (TREE_PURPOSE (id));
       if (!TREE_CHAIN (id))
         TYPE_MAX_VALUE (r) = v;
     }
@@ -2860,7 +3068,9 @@
      tree list;
 {
   for (; list; list = TREE_CHAIN (list))
+    {
     IDENTIFIER_VALUE (TREE_PURPOSE (list)) = TREE_VALUE (list);
+    }
 }
 
 tree
@@ -3081,17 +3291,37 @@
       TREE_STATIC (d) = !!(qualifiers & VQ_STATIC);
       if (TREE_STATIC (d) + DECL_EXTERNAL (d) + DECL_REGISTER (d) > 1)
         error ("multiple storage classes in variable declaration");
+      {
+        tree assembler_name0 = 0;
       if (pascal_global_bindings_p ())
         {
-          TREE_PUBLIC (d) = !TREE_STATIC (d) && !DECL_REGISTER (d) &&
-            (DECL_EXTERNAL (d) || !current_module->implementation || assembler_name);
+            TREE_PUBLIC (d) = !TREE_STATIC (d) && !DECL_REGISTER (d)
+              && (DECL_EXTERNAL (d) || !current_module->implementation 
+                || assembler_name);
+	    if (TREE_PUBLIC (d) && !assembler_name && !DECL_EXTERNAL (d))
+	      assembler_name0 = mangle_name(TREE_VALUE (v));
           TREE_STATIC (d) = !DECL_EXTERNAL (d);
         }
       else
         TREE_PUBLIC (d) = DECL_EXTERNAL (d);
       DECL_COMMON (d) = !TREE_PUBLIC (d);
-      SET_DECL_ASSEMBLER_NAME (d, assembler_name ? check_assembler_name (assembler_name)
-        : (qualifiers & VQ_EXTERNAL) ? de_capitalize (TREE_VALUE (v)) : TREE_VALUE (v));
+        if (assembler_name0)
+          SET_DECL_ASSEMBLER_NAME (d, assembler_name0);
+        else
+          { 
+            tree new_name = assembler_name;
+            if (new_name)
+              new_name = check_assembler_name (new_name);
+            else if (qualifiers & VQ_EXTERNAL)
+              new_name = de_capitalize (TREE_VALUE (v));
+            else 
+#ifdef GCC_3_4
+            if (pascal_global_bindings_p ()) 
+#endif
+              new_name = TREE_VALUE (v);
+            SET_DECL_ASSEMBLER_NAME (d, new_name);
+          }
+      }
       pascal_decl_attributes (&d, attributes);
       if (DECL_EXTERNAL (d) || TREE_STATIC (d))
         {
diff -ru gpc-20040516.orig/p/expressions.c gpc-20040516/p/expressions.c
--- gpc-20040516.orig/p/expressions.c	2004-05-12 01:37:37.000000000 +0200
+++ gpc-20040516/p/expressions.c	2004-07-06 19:08:51.000000000 +0200
@@ -855,7 +855,7 @@
                   build_array_ref (sval, build_binary_op (PLUS_EXPR, len1, integer_one_node, 0)), NOP_EXPR, exp2));
               else
                 expand_expr_stmt (build_memcpy (
-                  build (PLUS_EXPR, cstring_type_node, str_addr, len1, 0),
+                  build (PLUS_EXPR, cstring_type_node, str_addr, len1),
                   build1 (ADDR_EXPR, cstring_type_node, PASCAL_STRING_VALUE (exp2)), len2));
 
               /* Save the combined length of strings */
@@ -1438,10 +1438,17 @@
       if (TREE_CODE (factor) == STRING_CST)
         {
           tree length = build_int_2 (TREE_STRING_LENGTH (factor) - 1, 0);
+#ifndef GCC_3_4
           factor = build (CONSTRUCTOR, build_pascal_string_schema (length), NULL_TREE,
                      tree_cons (NULL_TREE, length,
                      tree_cons (NULL_TREE, length,
                      build_tree_list (NULL_TREE, factor))));
+#else
+          factor = build_constructor (build_pascal_string_schema (length),
+                     tree_cons (NULL_TREE, length,
+                     tree_cons (NULL_TREE, length,
+                     build_tree_list (NULL_TREE, factor))));
+#endif
           /* Make this a valid lvalue for taking addresses. */
           TREE_CONSTANT (factor) = 1;
           TREE_STATIC (factor) = 1;
@@ -1867,7 +1874,9 @@
     case NEGATE_EXPR:
     case ABS_EXPR:
     case FLOAT_EXPR:
+#ifndef GCC_3_4
     case FFS_EXPR:
+#endif
       /* These don't change whether an object is non-zero or zero. */
       return truthvalue_conversion (TREE_OPERAND (expr, 0));
 
@@ -2108,7 +2117,9 @@
       break;
 
     case BIT_AND_EXPR:
+#ifndef GCC_3_4
     case BIT_ANDTC_EXPR:
+#endif
     case BIT_IOR_EXPR:
     case BIT_XOR_EXPR:
       if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
@@ -3121,14 +3132,20 @@
           return error_mark_node;
         }
       if (TREE_CODE (pointer) == ADDR_EXPR
+#ifndef GCC_3_4
           && !flag_volatile
+#endif
           && (TREE_TYPE (TREE_OPERAND (pointer, 0)) == t))
         return TREE_OPERAND (pointer, 0);
 
       ref = build1 (INDIRECT_REF, t, pointer);
       TREE_READONLY (ref) = TYPE_READONLY (t);
       TREE_THIS_VOLATILE (ref) = TYPE_VOLATILE (t);
-      TREE_SIDE_EFFECTS (ref) = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer) || flag_volatile;
+      TREE_SIDE_EFFECTS (ref) = TYPE_VOLATILE (t) || TREE_SIDE_EFFECTS (pointer)
+#ifndef GCC_3_4
+ || flag_volatile
+#endif
+       ;
       prediscriminate_schema (ref);
       return ref;
     }
diff -ru gpc-20040516.orig/p/gbe.h gpc-20040516/p/gbe.h
--- gpc-20040516.orig/p/gbe.h	2004-04-08 14:30:41.000000000 +0200
+++ gpc-20040516/p/gbe.h	2004-07-06 19:08:51.000000000 +0200
@@ -102,6 +102,17 @@
 #endif
 
 #include "system.h"
+#ifdef GCC_3_4
+#define CONCAT2(a,b) a##b
+#define STRINGX(s) #s
+#define lineno input_line
+#define warning_with_decl(x, y) (warning ("%H" y, &DECL_SOURCE_LOCATION (x), \
+        DECL_NAME (x)?IDENTIFIER_POINTER (DECL_NAME (x)):0))
+#define error_with_decl(x, y) (error("%H" y, &DECL_SOURCE_LOCATION (x), \
+        DECL_NAME (x)?IDENTIFIER_POINTER (DECL_NAME (x)):0))
+#include "coretypes.h"
+#include "tm.h"
+#endif
 #include <signal.h>
 #include "tree.h"
 #ifdef EGCS97
diff -ru gpc-20040516.orig/p/gpc.c gpc-20040516/p/gpc.c
--- gpc-20040516.orig/p/gpc.c	2004-01-01 00:25:07.000000000 +0100
+++ gpc-20040516/p/gpc.c	2004-07-06 19:08:51.000000000 +0200
@@ -95,6 +95,13 @@
 #endif
 #include "config.h"
 #include "system.h"
+#ifdef GCC_3_4
+#include "coretypes.h"
+#include "multilib.h" /* before tm.h */
+#include "tm.h"
+#else
+#include "multilib.h" 
+#endif
 #include <signal.h>
 #if ! defined( SIGCHLD ) && defined( SIGCLD )
 #  define SIGCHLD SIGCLD
@@ -161,6 +168,16 @@
 
 #define lang_specific_extra_outfiles 0
 
+#ifndef EGCS97
+#undef bool
+#define bool int
+#undef false
+#define false 0
+#undef true 
+#define true 1
+#define ISIDNUM(c) (isalnum(c)||(c) == '_')
+#endif
+
 extern int lang_specific_pre_link PARAMS ((void));
 int
 lang_specific_pre_link ()
@@ -234,7 +251,7 @@
 #include <sys/resource.h>
 #endif
 #if defined (HAVE_DECL_GETRUSAGE) && !HAVE_DECL_GETRUSAGE
-extern int getrusage PARAMS ((int, struct rusage *));
+extern int getrusage (int, struct rusage *);
 #endif
 
 #ifdef EGCS97
@@ -335,6 +352,14 @@
 
 #endif
 
+#ifndef GCC_3_4
+static const struct {
+	  const char *name, *value;
+} configure_default_options[1] = { {NULL, NULL} }; 
+#define IS_ABSOLUTE_PATH(STR) IS_ABSOLUTE_PATHNAME (STR)
+#endif
+
+
 #ifndef VMS
 /* FIXME: the location independence code for VMS is hairier than this,
    and hasn't been written.  */
@@ -345,8 +370,10 @@
 
 static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
 
+#ifndef GCC_3_3
 #define obstack_chunk_alloc xmalloc
 #define obstack_chunk_free free
+#endif
 
 #ifndef GET_ENVIRONMENT
 #define GET_ENVIRONMENT(VAR,NAME)     do { (VAR) = getenv (NAME); } while (0)
@@ -434,11 +461,37 @@
 
 static int report_times;
 
+/* Nonzero means place this string before uses of /, so that include
+   and library files can be found in an alternate location.  */
+
+#ifdef TARGET_SYSTEM_ROOT
+static const char *target_system_root = TARGET_SYSTEM_ROOT;
+#else
+static const char *target_system_root = 0;
+#endif
+
+/* Nonzero means pass the updated target_system_root to the compiler.  */
+
+static int target_system_root_changed;
+
+/* Nonzero means append this string to target_system_root.  */
+
+static const char *target_sysroot_suffix = 0;
+
+/* Nonzero means append this string to target_system_root for headers.  */
+
+static const char *target_sysroot_hdrs_suffix = 0;
+
 /* Nonzero means write "temp" files in source directory
    and use the source file's name in them, and don't delete them.  */
 
 static int save_temps_flag;
 
+/* Nonzero means use pipes to communicate between subprocesses.
+   Overridden by either of the above two flags.  */
+
+static int use_pipes;
+
 /* The compiler version.  */
 
 static const char *compiler_version;
@@ -503,74 +556,79 @@
 /* Forward declaration for prototypes.  */
 struct path_prefix;
 
-static void init_spec           PARAMS ((void));
+static void init_spec (void);
 #if !defined (GCC_3_3) && !defined (VMS)
-static char **split_directories PARAMS ((const char *, int *));
-static void free_split_directories PARAMS ((char **));
-static char *make_relative_prefix PARAMS ((const char *, const char *, const char *));
-#endif
-static void store_arg           PARAMS ((const char *, int, int));
-static char *load_specs         PARAMS ((const char *));
-static void read_specs          PARAMS ((const char *, int));
-static void set_spec            PARAMS ((const char *, const char *));
-static struct compiler *lookup_compiler PARAMS ((const char *, size_t, const char *));
-static char *build_search_list  PARAMS ((struct path_prefix *, const char *, int));
-static void putenv_from_prefixes PARAMS ((struct path_prefix *, const char *));
-static int access_check         PARAMS ((const char *, int));
-static char *find_a_file        PARAMS ((struct path_prefix *, const char *,
-                                         int, int));
-static void add_prefix          PARAMS ((struct path_prefix *, const char *,
-                                         const char *, int, int, int *, int));
-static void translate_options   PARAMS ((int *, const char *const **));
-static char *skip_whitespace    PARAMS ((char *));
-static void delete_if_ordinary  PARAMS ((const char *));
-static void delete_temp_files   PARAMS ((void));
-static void delete_failure_queue PARAMS ((void));
-static void clear_failure_queue PARAMS ((void));
-static int check_live_switch    PARAMS ((int, int));
-static const char *handle_braces PARAMS ((const char *));
-static const struct spec_function *lookup_spec_function PARAMS ((const char *));
-static const char *eval_spec_function   PARAMS ((const char *, const char *));
-static const char *handle_spec_function PARAMS ((const char *));
-static char *save_string        PARAMS ((const char *, int));
-static void set_collect_gcc_options PARAMS ((void));
-static int do_spec_1            PARAMS ((const char *, int, const char *));
-static int do_spec_2            PARAMS ((const char *));
-static void do_self_spec        PARAMS ((const char *));
-static const char *find_file    PARAMS ((const char *));
-static int is_directory         PARAMS ((const char *, const char *, int));
-static void validate_switches   PARAMS ((const char *));
-static void validate_all_switches PARAMS ((void));
-static void give_switch         PARAMS ((int, int, int));
-static int used_arg             PARAMS ((const char *, int));
-static int default_arg          PARAMS ((const char *, int));
-static void set_multilib_dir    PARAMS ((void));
-static void print_multilib_info PARAMS ((void));
-static void perror_with_name    PARAMS ((const char *));
-static void pfatal_pexecute     PARAMS ((const char *, const char *))
-  ATTRIBUTE_NORETURN;
-static void notice              PARAMS ((const char *, ...))
-  ATTRIBUTE_PRINTF_1;
-static void display_help        PARAMS ((void));
-static void add_preprocessor_option     PARAMS ((const char *, int));
-static void add_assembler_option        PARAMS ((const char *, int));
-static void add_linker_option           PARAMS ((const char *, int));
-static void process_command             PARAMS ((int, const char *const *));
-static int execute                      PARAMS ((void));
-static void alloc_args                  PARAMS ((void));
-static void clear_args                  PARAMS ((void));
-static void fatal_error                 PARAMS ((int));
+static char **split_directories (const char *, int *);
+static void free_split_directories (char **);
+static char *make_relative_prefix (const char *, const char *, const char *);
+#endif
+static void store_arg (const char *, int, int);
+static char *load_specs (const char *);
+static void read_specs (const char *, int);
+static void set_spec (const char *, const char *);
+static struct compiler *lookup_compiler (const char *, size_t, const char *);
+static char *build_search_list (struct path_prefix *, const char *, int);
+static void putenv_from_prefixes (struct path_prefix *, const char *);
+static int access_check (const char *, int);
+static char *find_a_file (struct path_prefix *, const char *, int, int);
+static void add_prefix (struct path_prefix *, const char *, const char *,
+			int, int, int *, int);
+static void add_sysrooted_prefix (struct path_prefix *, const char *,
+				  const char *, int, int, int *, int);
+static void translate_options (int *, const char *const **);
+static char *skip_whitespace (char *);
+static void delete_if_ordinary (const char *);
+static void delete_temp_files (void);
+static void delete_failure_queue (void);
+static void clear_failure_queue (void);
+static int check_live_switch (int, int);
+static const char *handle_braces (const char *);
+static inline bool input_suffix_matches (const char *, const char *);
+static inline bool switch_matches (const char *, const char *, int);
+static inline void mark_matching_switches (const char *, const char *, int);
+static inline void process_marked_switches (void);
+static const char *process_brace_body (const char *, const char *, const char *, int, int);
+static const struct spec_function *lookup_spec_function (const char *);
+static const char *eval_spec_function (const char *, const char *);
+static const char *handle_spec_function (const char *);
+static char *save_string (const char *, int);
+static void set_collect_gcc_options (void);
+static int do_spec_1 (const char *, int, const char *);
+static int do_spec_2 (const char *);
+static void do_option_spec (const char *, const char *);
+static void do_self_spec (const char *);
+static const char *find_file (const char *);
+static int is_directory (const char *, const char *, int);
+static const char *validate_switches (const char *);
+static void validate_all_switches (void);
+static inline void validate_switches_from_spec (const char *);
+static void give_switch (int, int);
+static int used_arg (const char *, int);
+static int default_arg (const char *, int);
+static void set_multilib_dir (void);
+static void print_multilib_info (void);
+static void perror_with_name (const char *);
+static void pfatal_pexecute (const char *, const char *) ATTRIBUTE_NORETURN;
+static void notice (const char *, ...) ATTRIBUTE_PRINTF_1;
+static void display_help (void);
+static void add_preprocessor_option (const char *, int);
+static void add_assembler_option (const char *, int);
+static void add_linker_option (const char *, int);
+static void process_command (int, const char **);
+static int execute (void);
+static void alloc_args (void);
+static void clear_args (void);
+static void fatal_error (int);
 #ifdef ENABLE_SHARED_LIBGCC
-static void init_gcc_specs              PARAMS ((struct obstack *,
-                                                 const char *, const char *,
-                                                 const char *));
+static void init_gcc_specs (struct obstack *, const char *, const char *,
+			    const char *);
 #endif
 #if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
-static const char *convert_filename     PARAMS ((const char *, int, int));
+static const char *convert_filename (const char *, int, int);
 #endif
 
-static const char *if_exists_spec_function PARAMS ((int, const char **));
-static const char *if_exists_else_spec_function PARAMS ((int, const char **));
+static const char *if_exists_spec_function (int, const char **);
+static const char *if_exists_else_spec_function (int, const char **);
 
 /* The Specs Language
 
@@ -605,6 +663,12 @@
         with a file name chosen once per compilation, without regard
         to any appended suffix (which was therefore treated just like
         ordinary text), making such attacks more likely to succeed.
+ %|SUFFIX
+	like %g, but if -pipe is in effect, expands simply to "-".
+ %mSUFFIX
+        like %g, but if -pipe is in effect, expands to nothing.  (We have both
+	%| and %m to accommodate differences between system assemblers; see
+	the AS_NEEDS_DASH_FOR_PIPED_INPUT target macro.)
  %uSUFFIX
         like %g, but generates a new temporary file name even if %uSUFFIX
         was already seen.
@@ -633,6 +697,7 @@
  %w     marks the argument containing or following the %w as the
         "output file" of this compilation.  This puts the argument
         into the sequence of arguments that %o will substitute later.
+ %V	indicates that this compilation produces no "output file".
  %W{...}
         like %{...} but mark last argument supplied within
         as a file to be deleted on failure.
@@ -651,12 +716,9 @@
         except that %g, %u, and %U do not currently support additional
         SUFFIX characters following %O as they would following, for
         example, `.o'.
- %p     substitutes the standard macro predefinitions for the
-        current target machine.  Use this when running cpp.
- %P     like %p, but puts `__' before and after the name of each macro.
-        (Except macros that already have __.)
-        This is for ANSI C.
- %I     Substitute a -iprefix option made from GCC_EXEC_PREFIX.
+ %I	Substitute any of -iprefix (made from GCC_EXEC_PREFIX), -isysroot
+	(made from TARGET_SYSTEM_ROOT), and -isystem (made from COMPILER_PATH
+	and -B options) as necessary.
  %s     current argument is the name of a library or startup file of some sort.
         Search for that file in a standard list of directories
         and substitute the full name found.
@@ -667,12 +729,6 @@
  %X     Output the accumulated linker options specified by compilations.
  %Y     Output the accumulated assembler options specified by compilations.
  %Z     Output the accumulated preprocessor options specified by compilations.
- %v1    Substitute the major version number of GCC.
-        (For version 2.5.3, this is 2.)
- %v2    Substitute the minor version number of GCC.
-        (For version 2.5.3, this is 5.)
- %v3    Substitute the patch level number of GCC.
-        (For version 2.5.3, this is 3.)
  %a     process ASM_SPEC as a spec.
         This allows config.h to specify part of the spec for running as.
  %A     process ASM_FINAL_SPEC as a spec.  A capital A is actually
@@ -690,10 +746,15 @@
  %C     process CPP_SPEC as a spec.
  %1     process CC1_SPEC as a spec.
  %2     process CC1PLUS_SPEC as a spec.
- %|     output "-" if the input for the current command is coming from a pipe.
  %*     substitute the variable part of a matched option.  (See below.)
         Note that each comma in the substituted string is replaced by
         a single space.
+ %<S    remove all occurrences of -S from the command line.
+        Note - this command is position dependent.  % commands in the
+        spec string before this one will see -S, % commands in the
+        spec string after this one will not.
+ %<S*	remove all occurrences of all switches beginning with -S from the
+        command line.
  %:function(args)
         Call the named function FUNCTION, passing it ARGS.  ARGS is
         first processed as a nested spec string, then split into an
@@ -708,33 +769,40 @@
         arguments.  CC considers `-o foo' as being one switch whose
         name starts with `o'.  %{o*} would substitute this text,
         including the space; thus, two arguments would be generated.
- %{^S*} likewise, but don't put a blank between a switch and any args.
  %{S*&T*} likewise, but preserve order of S and T options (the order
         of S and T in the spec is not significant).  Can be any number
         of ampersand-separated variables; for each the wild card is
         optional.  Useful for CPP as %{D*&U*&A*}.
- %{S*:X} substitutes X if one or more switches whose names start with -S are
-        specified to CC.  Note that the tail part of the -S option
-        (i.e. the part matched by the `*') will be substituted for each
-        occurrence of %* within X.
- %{<S}  remove all occurrences of -S from the command line.
-        Note - this option is position dependent.  % commands in the
-        spec string before this option will see -S, % commands in the
-        spec string after this option will not.
- %{S:X} substitutes X, but only if the -S switch was given to CC.
- %{!S:X} substitutes X, but only if the -S switch was NOT given to CC.
- %{|S:X} like %{S:X}, but if no S switch, substitute `-'.
- %{|!S:X} like %{!S:X}, but if there is an S switch, substitute `-'.
- %{.S:X} substitutes X, but only if processing a file with suffix S.
- %{!.S:X} substitutes X, but only if NOT processing a file with suffix S.
- %{S|P:X} substitutes X if either -S or -P was given to CC.  This may be
-          combined with ! and . as above binding stronger than the OR.
+
+ %{S:X}   substitutes X, if the -S switch was given to CC.
+ %{!S:X}  substitutes X, if the -S switch was NOT given to CC.
+ %{S*:X}  substitutes X if one or more switches whose names start
+          with -S was given to CC.  Normally X is substituted only
+          once, no matter how many such switches appeared.  However,
+          if %* appears somewhere in X, then X will be substituted
+          once for each matching switch, with the %* replaced by the
+          part of that switch that matched the '*'.
+ %{.S:X}  substitutes X, if processing a file with suffix S.
+ %{!.S:X} substitutes X, if NOT processing a file with suffix S.
+
+ %{S|T:X} substitutes X if either -S or -T was given to CC.  This may be
+	  combined with !, ., and * as above binding stronger than the OR.
+	  If %* appears in X, all of the alternatives must be starred, and
+	  only the first matching alternative is substituted.
+ %{S:X;   if S was given to CC, substitutes X;
+   T:Y;   else if T was given to CC, substitutes Y;
+    :D}   else substitutes D.  There can be as many clauses as you need.
+          This may be combined with ., !, |, and * as above.
+
  %(Spec) processes a specification defined in a specs file as *Spec:
  %[Spec] as above, but put __ around -D arguments
 
-The conditional text X in a %{S:X} or %{!S:X} construct may contain
+The conditional text X in a %{S:X} or similar construct may contain
 other nested % constructs or spaces, or even newlines.  They are
-processed as usual, as described above.
+processed as usual, as described above.  Trailing white space in X is
+ignored.  White space may also appear anywhere on the left side of the
+colon in these constructs, except between . or * and the corresponding
+word.
 
 The -O, -f, -m, and -W switches are handled specifically in these
 constructs.  If another value of -O or the negated form of a -f, -m, or
@@ -864,6 +932,14 @@
 #define LINK_GCC_C_SEQUENCE_SPEC "%G %L %G"
 #endif
 
+#ifndef LINK_PIE_SPEC
+#ifdef HAVE_LD_PIE
+#define LINK_PIE_SPEC "%{pie:-pie} "
+#else
+#define LINK_PIE_SPEC "%{pie:} "
+#endif
+#endif
+
 /* -u* was put back because both BSD and SysV seem to support it.  */
 /* %{static:} simply prevents an error message if the target machine
    doesn't handle -static.  */
@@ -873,9 +949,10 @@
 #ifndef LINK_COMMAND_SPEC
 #define LINK_COMMAND_SPEC "\
 %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
-    %(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r} %{s} %{t}\
-    %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
-    %{static:} %{L*} %(link_libgcc) %o %{!nostdlib:%{!nodefaultlibs:%(link_gcc_c_sequence)}}\
+    %(linker) %l " LINK_PIE_SPEC "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
+    %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
+    %{static:} %{L*} %(link_libgcc) %o %{fprofile-arcs|fprofile-generate:-lgcov}\
+    %{!nostdlib:%{!nodefaultlibs:%(link_gcc_c_sequence)}}\
     %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
 #endif
 
@@ -893,9 +970,24 @@
 # define STARTFILE_PREFIX_SPEC ""
 #endif
 
+#ifndef SYSROOT_SUFFIX_SPEC
+# define SYSROOT_SUFFIX_SPEC ""
+#endif
+
+#ifndef SYSROOT_HEADERS_SUFFIX_SPEC
+# define SYSROOT_HEADERS_SUFFIX_SPEC ""
+#endif
+
+#ifndef GCC_3_3
+#include "cpp_predef.h"
+#else
+# define GPC_CPP_PREDEFINES ""
+#endif
+
+
 static const char *asm_debug = "";
 static const char *cpp_spec = CPP_SPEC;
-static const char *cpp_predefines = CPP_PREDEFINES;
+static const char *cpp_predefines = GPC_CPP_PREDEFINES;
 static const char *cc1_spec = CC1_SPEC;
 static const char *cc1plus_spec = CC1PLUS_SPEC;
 static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
@@ -911,6 +1003,8 @@
 static const char *link_command_spec = LINK_COMMAND_SPEC;
 static const char *link_libgcc_spec = LINK_LIBGCC_SPEC;
 static const char *startfile_prefix_spec = STARTFILE_PREFIX_SPEC;
+static const char *sysroot_suffix_spec = SYSROOT_SUFFIX_SPEC;
+static const char *sysroot_hdrs_suffix_spec = SYSROOT_HEADERS_SUFFIX_SPEC;
 
 /* Standard options to cpp, cc1, and as, to reduce duplication in specs.
    There should be no need to override these in target dependent files,
@@ -928,16 +1022,13 @@
    therefore no dependency entry, confuses make into thinking a .o
    file that happens to exist is up-to-date.  */
 static const char *cpp_unique_options =
-"%{C:%{!E:%eGNU C does not support -C without using -E}}\
- %{CC:%{!E:%eGNU C does not support -CC without using -E}}\
+"%{C|CC:%{!E:%eGCC does not support -C or -CC without -E}}\
  %{nostdinc*} %{C} %{CC} %{v} %{I*} %{P} %I\
  %{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\
  %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
  %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
  %{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}}\
- %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2 -D__GNUC_PATCHLEVEL__=%v3}\
- %{!undef:%{!ansi:%{!std=*:%p}%{std=gnu*:%p}} %P} %{trigraphs}\
- %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
+ %{trigraphs} %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
  %{E|M|MM:%W{o*}}";
 
 /* This contains cpp options which are common with cc1_options and are passed
@@ -947,7 +1038,7 @@
    in turn cause preprocessor symbols to be defined specially.  */
 static const char *cpp_options =
 "%(cpp_unique_options) %1 %{m*} %{std*} %{ansi} %{W*&pedantic*} %{w} %{f*}\
- %{O*} %{undef}";
+ %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*} %{undef}";
 
 /* This contains cpp options which are not passed when the preprocessor
    output will be used by another program.  */
@@ -969,7 +1060,15 @@
 "%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}";
 
 static const char *invoke_as =
+#ifdef GCC_3_4
+#ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
+"%{!S:-o %|.s |\n as %(asm_options) %|.s %A }";
+#else
+"%{!S:-o %|.s |\n as %(asm_options) %m.s %A }";
+#endif
+#else
 "%{!S:-o %{|!pipe:%g.s} |\n as %(asm_options) %{!pipe:%g.s} %A }";
+#endif
 
 /* Some compilers have limits on line lengths, and the multilib_select
    and/or multilib_matches strings can be very long, so we build them at
@@ -979,7 +1078,6 @@
 static const char *multilib_matches;
 static const char *multilib_defaults;
 static const char *multilib_exclusions;
-#include "multilib.h"
 
 /* Check whether a particular argument is a default argument.  */
 
@@ -995,6 +1093,19 @@
 
 static const char *const driver_self_specs[] = { DRIVER_SELF_SPECS };
 
+#ifndef OPTION_DEFAULT_SPECS
+#define OPTION_DEFAULT_SPECS { "", "" }
+#endif
+
+struct default_spec
+{
+  const char *name;
+  const char *spec;
+};
+
+static const struct default_spec
+  option_default_specs[] = { OPTION_DEFAULT_SPECS };
+
 struct user_specs
 {
   struct user_specs *next;
@@ -1093,7 +1204,7 @@
   {".m",  "#Objective-C", 0}, {".mi",  "#Objective-C", 0},
   {".cc", "#C++", 0}, {".cxx", "#C++", 0}, {".cpp", "#C++", 0},
   {".cp", "#C++", 0}, {".c++", "#C++", 0}, {".C", "#C++", 0},
-  {".ii", "#C++", 0},
+  {".CPP", "#C++", 0}, {".ii", "#C++", 0},
   {".ads", "#Ada", 0}, {".adb", "#Ada", 0},
   {".f", "#Fortran", 0}, {".for", "#Fortran", 0}, {".fpp", "#Fortran", 0},
   {".F", "#Fortran", 0}, {".FOR", "#Fortran", 0}, {".FPP", "#Fortran", 0},
@@ -1112,8 +1223,9 @@
           %{traditional|ftraditional:\
 %eGNU C no longer supports -traditional without -E}\
           %{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
-                %(cpp_options) %{save-temps:%b.i} %{!save-temps:%g.i} \n\
-                    cc1 -fpreprocessed %{save-temps:%b.i} %{!save-temps:%g.i} %(cc1_options)}\
+		%(cpp_options) -o %{save-temps:%b.i} %{!save-temps:%g.i} \n\
+		    cc1 -fpreprocessed %{save-temps:%b.i} %{!save-temps:%g.i} \
+			%(cc1_options)}\
           %{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\
                 cc1 %(cpp_unique_options) %(cc1_options)}}}\
         %{!fsyntax-only:%(invoke_as)}}}}", 0},
@@ -1149,9 +1261,20 @@
     %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0},
   {".h", "@c-header", 0},
   {"@c-header",
-   "%{!E:%ecompilation of header file requested} \
-    %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)",
-   0},
+   /* cc1 has an integrated ISO C preprocessor.  We should invoke the
+      external preprocessor if -save-temps is given.  */
+     "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
+      %{!E:%{!M:%{!MM:\
+	  %{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
+		%(cpp_options) -o %{save-temps:%b.i} %{!save-temps:%g.i} \n\
+		    cc1 -fpreprocessed %{save-temps:%b.i} %{!save-temps:%g.i} \
+			%(cc1_options)\
+                        -o %g.s %{!o*:--output-pch=%i.gch}\
+                        %W{o*:--output-pch=%*}%V}\
+	  %{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\
+		cc1 %(cpp_unique_options) %(cc1_options)\
+                    -o %g.s %{!o*:--output-pch=%i.gch}\
+                    %W{o*:--output-pch=%*}%V}}}}}}", 0},
   {".i", "@cpp-output", 0},
   {"@cpp-output",
    "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0},
@@ -1160,12 +1283,21 @@
    "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0},
   {".S", "@assembler-with-cpp", 0},
   {"@assembler-with-cpp",
+#ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
    "%(trad_capable_cpp) -lang-asm %(cpp_options)\
       %{E|M|MM:%(cpp_debug_options)}\
-      %{!M:%{!MM:%{!E:%{!S:-o %{|!pipe:%g.s} |\n\
-       as %(asm_debug) %(asm_options) %{!pipe:%g.s} %A }}}}", 0},
+      %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
+       as %(asm_debug) %(asm_options) %|.s %A }}}}"
+#else
+   "%(trad_capable_cpp) -lang-asm %(cpp_options)\
+      %{E|M|MM:%(cpp_debug_options)}\
+      %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
+       as %(asm_debug) %(asm_options) %m.s %A }}}}"
+#endif
+   , 0},
+
 #include "specs.h"
-  /* Mark end of table */
+  /* Mark end of table.  */
   {0, 0, 0}
 };
 
@@ -1258,6 +1390,7 @@
    {"--param", "--param", "a"},
    {"--pedantic", "-pedantic", 0},
    {"--pedantic-errors", "-pedantic-errors", 0},
+   {"--pie", "-pie", 0},
    {"--pipe", "-pipe", 0},
    {"--prefix", "-B", "a"},
    {"--preprocess", "-E", 0},
@@ -1280,14 +1413,12 @@
    {"--static", "-static", 0},
    {"--std", "-std=", "aj"},
    {"--symbolic", "-symbolic", 0},
-   {"--target", "-b", "a"},
    {"--time", "-time", 0},
    {"--trace-includes", "-H", 0},
    {"--traditional", "-traditional", 0},
    {"--traditional-cpp", "-traditional-cpp", 0},
    {"--trigraphs", "-trigraphs", 0},
    {"--undefine-macro", "-U", "aj"},
-   {"--use-version", "-V", "a"},
    {"--user-dependencies", "-MM", 0},
    {"--verbose", "-v", 0},
    {"--warn-", "-W", "*j"},
@@ -1313,9 +1444,7 @@
    and store its length in *ARGVC.  */
 
 static void
-translate_options (argcp, argvp)
-     int *argcp;
-     const char *const **argvp;
+translate_options (int *argcp, const char *const **argvp)
 {
   int i;
   int argc = *argcp;
@@ -1325,8 +1454,7 @@
 #else
   int newvsize = (argc + 2) * 2 * sizeof (const char *);
 #endif
-  const char **newv =
-    (const char **) xmalloc (newvsize);
+  const char **newv = xmalloc (newvsize);
   int newindex = 0;
 
   i = 0;
@@ -1356,7 +1484,7 @@
                 }
 
               newvsize += spaces * sizeof (const char *);
-              newv = (const char **) xrealloc (newv, newvsize);
+	      newv =  xrealloc (newv, newvsize);
 
               sp = target_option_translations[tott_idx].replacements;
               np = xstrdup (sp);
@@ -1500,6 +1628,10 @@
             nskip += 1;
           else if (! strcmp (p, "Xlinker"))
             nskip += 1;
+	  else if (! strcmp (p, "Xpreprocessor"))
+	    nskip += 1;
+	  else if (! strcmp (p, "Xassembler"))
+	    nskip += 1;
 
           /* Watch out for an option at the end of the command line that
              is missing arguments, and avoid skipping past the end of the
@@ -1552,8 +1684,7 @@
 }
 
 static char *
-skip_whitespace (p)
-     char *p;
+skip_whitespace (char *p)
 {
   while (1)
     {
@@ -1622,6 +1753,10 @@
 
 static const char *gcc_exec_prefix;
 
+/* Adjusted value of standard_libexec_prefix.  */
+
+static const char *gcc_libexec_prefix;
+
 /* Default prefixes to attach to command names.  */
 
 #ifdef CROSS_COMPILE  /* Don't use these prefixes for a cross compiler.  */
@@ -1655,9 +1790,18 @@
 #ifndef STANDARD_BINDIR_PREFIX
 #define STANDARD_BINDIR_PREFIX "/usr/local/bin"
 #endif
+#ifndef STANDARD_LIBEXEC_PREFIX
+#define STANDARD_LIBEXEC_PREFIX "/usr/local/libexec/gcc/"
+#endif
+
 
 static const char *const standard_exec_prefix = STANDARD_EXEC_PREFIX;
+#ifndef GCC_3_4
 static const char *const standard_exec_prefix_1 = "/usr/lib/gcc/";
+#else
+static const char *const standard_exec_prefix_1 = "/usr/libexec/gcc/";
+#endif
+static const char *const standard_exec_prefix_2 = "/usr/lib/gcc/";
 static const char *md_exec_prefix = MD_EXEC_PREFIX;
 
 static const char *md_startfile_prefix = MD_STARTFILE_PREFIX;
@@ -1671,6 +1815,8 @@
 
 static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
 
+static const char *standard_libexec_prefix = STANDARD_LIBEXEC_PREFIX;
+
 /* Subdirectory to use for locating libraries.  Set by
    set_multilib_dir based on the compilation options.  */
 
@@ -1741,6 +1887,8 @@
   INIT_STATIC_SPEC ("md_startfile_prefix",      &md_startfile_prefix),
   INIT_STATIC_SPEC ("md_startfile_prefix_1",    &md_startfile_prefix_1),
   INIT_STATIC_SPEC ("startfile_prefix_spec",    &startfile_prefix_spec),
+  INIT_STATIC_SPEC ("sysroot_suffix_spec",	&sysroot_suffix_spec),
+  INIT_STATIC_SPEC ("sysroot_hdrs_suffix_spec",	&sysroot_hdrs_suffix_spec),
 };
 
 #ifdef EXTRA_SPECS              /* additional specs needed */
@@ -1781,11 +1929,8 @@
 
 #ifdef ENABLE_SHARED_LIBGCC
 static void
-init_gcc_specs (obstack, shared_name, static_name, eh_name)
-     struct obstack *obstack;
-     const char *shared_name;
-     const char *static_name;
-     const char *eh_name;
+init_gcc_specs (struct obstack *obstack, const char *shared_name,
+		const char *static_name, const char *eh_name)
 {
   char *buf;
 
@@ -1810,7 +1955,7 @@
 /* Initialize the specs lookup routines.  */
 
 static void
-init_spec ()
+init_spec (void)
 {
   struct spec_list *next = (struct spec_list *) 0;
   struct spec_list *sl   = (struct spec_list *) 0;
@@ -1823,8 +1968,8 @@
     notice ("Using built-in specs.\n");
 
 #ifdef EXTRA_SPECS
-  extra_specs = (struct spec_list *)
-    xcalloc (sizeof (struct spec_list), ARRAY_SIZE (extra_specs_1));
+  extra_specs = xcalloc (sizeof (struct spec_list),
+			 ARRAY_SIZE (extra_specs_1));
 
   for (i = ARRAY_SIZE (extra_specs_1) - 1; i >= 0; i--)
     {
@@ -1895,7 +2040,12 @@
 #endif
                             ,
                             "-lgcc",
-                            "-lgcc_eh");
+			    "-lgcc_eh"
+#ifdef USE_LIBUNWIND_EXCEPTIONS
+			    " -lunwind"
+#endif
+			    );
+
             p += 5;
             in_sep = 0;
           }
@@ -1911,7 +2061,11 @@
 #endif
                             ,
                             "libgcc.a%s",
-                            "libgcc_eh.a%s");
+			    "libgcc_eh.a%s"
+#ifdef USE_LIBUNWIND_EXCEPTIONS
+			    " -lunwind"
+#endif
+			    );
             p += 10;
             in_sep = 0;
           }
@@ -1951,9 +2105,7 @@
    current spec.  */
 
 static void
-set_spec (name, spec)
-     const char *name;
-     const char *spec;
+set_spec (const char *name, const char *spec)
 {
   struct spec_list *sl;
   const char *old_spec;
@@ -1981,7 +2133,7 @@
   if (!sl)
     {
       /* Not found - make it.  */
-      sl = (struct spec_list *) xmalloc (sizeof (struct spec_list));
+      sl = xmalloc (sizeof (struct spec_list));
       sl->name = xstrdup (name);
       sl->name_len = name_len;
       sl->ptr_spec = &sl->ptr;
@@ -2003,7 +2155,7 @@
 
   /* Free the old spec.  */
   if (old_spec && sl->alloc_p)
-    free ((PTR) old_spec);
+    free ((void *) old_spec);
 
   sl->alloc_p = 1;
 }
@@ -2050,16 +2202,16 @@
 /* Allocate the argument vector.  */
 
 static void
-alloc_args ()
+alloc_args (void)
 {
   argbuf_length = 10;
-  argbuf = (const char **) xmalloc (argbuf_length * sizeof (const char *));
+  argbuf = xmalloc (argbuf_length * sizeof (const char *));
 }
 
 /* Clear out the vector of arguments (after a command is executed).  */
 
 static void
-clear_args ()
+clear_args (void)
 {
   argbuf_index = 0;
 }
@@ -2072,14 +2224,10 @@
     and the file should be deleted if this compilation fails.  */
 
 static void
-store_arg (arg, delete_always, delete_failure)
-     const char *arg;
-     int delete_always, delete_failure;
+store_arg (const char *arg, int delete_always, int delete_failure)
 {
   if (argbuf_index + 1 == argbuf_length)
-    argbuf
-      = (const char **) xrealloc (argbuf,
-                                  (argbuf_length *= 2) * sizeof (const char *));
+    argbuf = xrealloc (argbuf, (argbuf_length *= 2) * sizeof (const char *));
 
   argbuf[argbuf_index++] = arg;
   argbuf[argbuf_index] = 0;
@@ -2093,8 +2241,7 @@
    a single \n.  */
 
 static char *
-load_specs (filename)
-     const char *filename;
+load_specs (const char *filename)
 {
   int desc;
   int readlen;
@@ -2158,9 +2305,7 @@
    Anything invalid in the file is a fatal error.  */
 
 static void
-read_specs (filename, main_p)
-     const char *filename;
-     int main_p;
+read_specs (const char *filename, int main_p)
 {
   char *buffer;
   char *p;
@@ -2302,7 +2447,7 @@
 
               set_spec (p2, *(sl->ptr_spec));
               if (sl->alloc_p)
-                free ((PTR) *(sl->ptr_spec));
+		free ((void *) *(sl->ptr_spec));
 
               *(sl->ptr_spec) = "";
               sl->alloc_p = 0;
@@ -2372,9 +2517,8 @@
         {
           /* Add this pair to the vector.  */
           compilers
-            = ((struct compiler *)
-               xrealloc (compilers,
-                         (n_compilers + 2) * sizeof (struct compiler)));
+	    = xrealloc (compilers,
+			(n_compilers + 2) * sizeof (struct compiler));
 
           compilers[n_compilers].suffix = suffix;
           compilers[n_compilers].spec = spec;
@@ -2430,10 +2574,7 @@
    otherwise delete it in any case.  */
 
 void
-record_temp_file (filename, always_delete, fail_delete)
-     const char *filename;
-     int always_delete;
-     int fail_delete;
+record_temp_file (const char *filename, int always_delete, int fail_delete)
 {
   char *const name = xstrdup (filename);
 
@@ -2444,7 +2585,7 @@
         if (! strcmp (name, temp->name))
           goto already1;
 
-      temp = (struct temp_file *) xmalloc (sizeof (struct temp_file));
+      temp = xmalloc (sizeof (struct temp_file));
       temp->next = always_delete_queue;
       temp->name = name;
       always_delete_queue = temp;
@@ -2459,7 +2600,7 @@
         if (! strcmp (name, temp->name))
           goto already2;
 
-      temp = (struct temp_file *) xmalloc (sizeof (struct temp_file));
+      temp = xmalloc (sizeof (struct temp_file));
       temp->next = failure_delete_queue;
       temp->name = name;
       failure_delete_queue = temp;
@@ -2471,8 +2612,7 @@
 /* Delete all the temporary files whose names we previously recorded.  */
 
 static void
-delete_if_ordinary (name)
-     const char *name;
+delete_if_ordinary (const char *name)
 {
   struct stat st;
 #ifdef DEBUG
@@ -2494,7 +2634,7 @@
 }
 
 static void
-delete_temp_files ()
+delete_temp_files (void)
 {
   struct temp_file *temp;
 
@@ -2524,7 +2664,7 @@
 /* Delete all the files to be deleted on error.  */
 
 static void
-delete_failure_queue ()
+delete_failure_queue (void)
 {
   struct temp_file *temp;
 
@@ -2533,7 +2673,7 @@
 }
 
 static void
-clear_failure_queue ()
+clear_failure_queue (void)
 {
   failure_delete_queue = 0;
 }
@@ -2545,10 +2685,8 @@
    It is also used by the --print-search-dirs flag.  */
 
 static char *
-build_search_list (paths, prefix, check_dir_p)
-     struct path_prefix *paths;
-     const char *prefix;
-     int check_dir_p;
+build_search_list (struct path_prefix *paths, const char *prefix,
+		   int check_dir_p)
 {
   int suffix_len = (machine_suffix) ? strlen (machine_suffix) : 0;
   int just_suffix_len
@@ -2607,9 +2745,7 @@
    for collect.  */
 
 static void
-putenv_from_prefixes (paths, env_var)
-     struct path_prefix *paths;
-     const char *env_var;
+putenv_from_prefixes (struct path_prefix *paths, const char *env_var)
 {
   putenv (build_search_list (paths, env_var, 1));
 }
@@ -2858,9 +2994,7 @@
    except that it never considers directories to be executable.  */
 
 static int
-access_check (name, mode)
-     const char *name;
-     int mode;
+access_check (const char *name, int mode)
 {
   if (mode == X_OK)
     {
@@ -2879,10 +3013,8 @@
    Return 0 if not found, otherwise return its name, allocated with malloc.  */
 
 static char *
-find_a_file (pprefix, name, mode, multilib)
-     struct path_prefix *pprefix;
-     const char *name;
-     int mode, multilib;
+find_a_file (struct path_prefix *pprefix, const char *name, int mode,
+	     int multilib)
 {
   char *temp;
   const char *const file_suffix =
@@ -2924,7 +3056,7 @@
 
   /* Determine the filename to execute (special case for absolute paths).  */
 
-  if (IS_ABSOLUTE_PATHNAME (name))
+  if (IS_ABSOLUTE_PATH (name))
     {
       if (access (name, mode) == 0)
         {
@@ -3042,7 +3174,7 @@
   PREFIX_PRIORITY_LAST
 };
 
-/* Add an entry for PREFIX in PLIST.  The PLIST is kept in assending
+/* Add an entry for PREFIX in PLIST.  The PLIST is kept in ascending
    order according to PRIORITY.  Within each PRIORITY, new entries are
    appended.
 
@@ -3057,15 +3189,9 @@
    2 means try both machine_suffix and just_machine_suffix.  */
 
 static void
-add_prefix (pprefix, prefix, component, priority, require_machine_suffix,
-            warn, os_multilib)
-     struct path_prefix *pprefix;
-     const char *prefix;
-     const char *component;
-     /* enum prefix_priority */ int priority;
-     int require_machine_suffix;
-     int *warn;
-     int os_multilib;
+add_prefix (struct path_prefix *pprefix, const char *prefix,
+	    const char *component, /* enum prefix_priority */ int priority,
+	    int require_machine_suffix, int *warn, int os_multilib)
 {
   struct prefix_list *pl, **prev;
   int len;
@@ -3075,14 +3201,14 @@
        prev = &(*prev)->next)
     ;
 
-  /* Keep track of the longest prefix */
+  /* Keep track of the longest prefix.  */
 
   prefix = update_path (prefix, component);
   len = strlen (prefix);
   if (len > pprefix->max_len)
     pprefix->max_len = len;
 
-  pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list));
+  pl = xmalloc (sizeof (struct prefix_list));
   pl->prefix = prefix;
   pl->require_machine_suffix = require_machine_suffix;
   pl->used_flag_ptr = warn;
@@ -3091,11 +3217,36 @@
   if (warn)
     *warn = 0;
 
-  /* Insert after PREV */
+  /* Insert after PREV.  */
   pl->next = (*prev);
   (*prev) = pl;
 }
 
+/* Same as add_prefix, but prepending target_system_root to prefix.  */
+static void
+add_sysrooted_prefix (struct path_prefix *pprefix, const char *prefix,
+		      const char *component,
+		      /* enum prefix_priority */ int priority,
+		      int require_machine_suffix, int *warn, int os_multilib)
+{
+  if (!IS_ABSOLUTE_PATH (prefix))
+    abort ();
+
+  if (target_system_root)
+    {
+      if (target_sysroot_suffix)
+	  prefix = concat (target_sysroot_suffix, prefix, NULL);
+      prefix = concat (target_system_root, prefix, NULL);
+
+      /* We have to override this because GCC's notion of sysroot
+	 moves along with GCC.  */
+      component = "GCC";
+    }
+
+  add_prefix (pprefix, prefix, component, priority,
+	      require_machine_suffix, warn, os_multilib);
+}
+
 /* Execute the command specified by the arguments on the current line of spec.
    When using pipes, this includes several piped-together commands
    with `|' between them.
@@ -3103,7 +3254,7 @@
    Return 0 if successful, -1 if failed.  */
 
 static int
-execute ()
+execute (void)
 {
   int i;
   int n_commands;               /* # of command.  */
@@ -3126,7 +3277,7 @@
       n_commands++;
 
   /* Get storage for each command.  */
-  commands = (struct command *) alloca (n_commands * sizeof (struct command));
+  commands = alloca (n_commands * sizeof (struct command));
 
   /* Split argbuf into its separate piped processes,
      and record info about each one.
@@ -3196,7 +3347,14 @@
         }
       fflush (stderr);
       if (verbose_only_flag != 0)
+        {
+	  /* verbose_only_flag should act as if the spec was
+	     executed, so increment execution_count before
+	     returning.  This prevents spurious warnings about
+	     unused linker input files, etc.  */
+	  execution_count++;
         return 0;
+        }
 #ifdef DEBUG
       notice ("\nGo ahead? (y or n) ");
       fflush (stderr);
@@ -3211,7 +3369,7 @@
     }
 
 #ifdef ENABLE_VALGRIND_CHECKING
-  /* Run the each command through valgrind.  To simplifiy prepending the
+  /* Run the each command through valgrind.  To simplify prepending the
      path to valgrind and the option "-q" (for quiet operation unless
      something triggers), we allocate a separate argv array.  */
 
@@ -3259,7 +3417,7 @@
         pfatal_pexecute (errmsg_fmt, errmsg_arg);
 
       if (string != commands[i].prog)
-        free ((PTR) string);
+	free ((void *) string);
     }
 
   execution_count++;
@@ -3361,7 +3519,7 @@
    0 when initialized
    1 if the switch is true in a conditional spec,
    -1 if false (overridden by a later switch)
-   -2 if this switch should be ignored (used in %{<S})
+   -2 if this switch should be ignored (used in %<S)
    The `validated' field is nonzero if any spec has looked at this switch;
    if it remains zero at the end of the run, it must be meaningless.  */
 
@@ -3395,6 +3553,11 @@
 
 int n_infiles;
 
+/* True if multiple input files are being compiled to a single
+   assembly file.  */
+
+static bool combine_inputs;
+
 /* This counts the number of libraries added by lang_specific_driver, so that
    we can tell if there were any user supplied any files or libraries.  */
 
@@ -3420,10 +3583,8 @@
    is true if we should look for an object suffix.  */
 
 static const char *
-convert_filename (name, do_exe, do_obj)
-     const char *name;
-     int do_exe ATTRIBUTE_UNUSED;
-     int do_obj ATTRIBUTE_UNUSED;
+convert_filename (const char *name, int do_exe ATTRIBUTE_UNUSED,
+		  int do_obj ATTRIBUTE_UNUSED)
 {
 #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
   int i;
@@ -3473,7 +3634,7 @@
 
 /* Display the command line switches accepted by gcc.  */
 static void
-display_help ()
+display_help (void)
 {
   printf (_("Usage: %s [options] file...\n"), programname);
   fputs (_("Options:\n"), stdout);
@@ -3498,6 +3659,8 @@
   fputs (_("  -Wa,<options>            Pass comma-separated <options> on to the assembler\n"), stdout);
   fputs (_("  -Wp,<options>            Pass comma-separated <options> on to the preprocessor\n"), stdout);
   fputs (_("  -Wl,<options>            Pass comma-separated <options> on to the linker\n"), stdout);
+  fputs (_("  -Xassembler <arg>        Pass <arg> on to the assembler\n"), stdout);
+  fputs (_("  -Xpreprocessor <arg>     Pass <arg> on to the preprocessor\n"), stdout);
   fputs (_("  -Xlinker <arg>           Pass <arg> on to the linker\n"), stdout);
   fputs (_("  -save-temps              Do not delete intermediate files\n"), stdout);
   fputs (_("  -pipe                    Use pipes rather than intermediate files\n"), stdout);
@@ -3531,18 +3694,14 @@
 }
 
 static void
-add_preprocessor_option (option, len)
-     const char *option;
-     int len;
+add_preprocessor_option (const char *option, int len)
 {
   n_preprocessor_options++;
 
   if (! preprocessor_options)
-    preprocessor_options
-      = (char **) xmalloc (n_preprocessor_options * sizeof (char *));
+    preprocessor_options = xmalloc (n_preprocessor_options * sizeof (char *));
   else
-    preprocessor_options
-      = (char **) xrealloc (preprocessor_options,
+    preprocessor_options = xrealloc (preprocessor_options,
                             n_preprocessor_options * sizeof (char *));
 
   preprocessor_options [n_preprocessor_options - 1] =
@@ -3550,36 +3709,28 @@
 }
 
 static void
-add_assembler_option (option, len)
-     const char *option;
-     int len;
+add_assembler_option (const char *option, int len)
 {
   n_assembler_options++;
 
   if (! assembler_options)
-    assembler_options
-      = (char **) xmalloc (n_assembler_options * sizeof (char *));
+    assembler_options = xmalloc (n_assembler_options * sizeof (char *));
   else
-    assembler_options
-      = (char **) xrealloc (assembler_options,
+    assembler_options = xrealloc (assembler_options,
                             n_assembler_options * sizeof (char *));
 
   assembler_options [n_assembler_options - 1] = save_string (option, len);
 }
 
 static void
-add_linker_option (option, len)
-     const char *option;
-     int len;
+add_linker_option (const char *option, int len)
 {
   n_linker_options++;
 
   if (! linker_options)
-    linker_options
-      = (char **) xmalloc (n_linker_options * sizeof (char *));
+    linker_options = xmalloc (n_linker_options * sizeof (char *));
   else
-    linker_options
-      = (char **) xrealloc (linker_options,
+    linker_options = xrealloc (linker_options,
                             n_linker_options * sizeof (char *));
 
   linker_options [n_linker_options - 1] = save_string (option, len);
@@ -3589,9 +3740,7 @@
    Store its length in `n_switches'.  */
 
 static void
-process_command (argc, argv)
-     int argc;
-     const char *const *argv;
+process_command (int argc, const char **argv)
 {
   int i;
   const char *temp;
@@ -3687,34 +3836,55 @@
   /* Set up the default search paths.  If there is no GCC_EXEC_PREFIX,
      see if we can create it from the pathname specified in argv[0].  */
 
+  gcc_libexec_prefix = standard_libexec_prefix;
 #ifndef VMS
   /* FIXME: make_relative_prefix doesn't yet work for VMS.  */
   if (!gcc_exec_prefix)
     {
       gcc_exec_prefix = make_relative_prefix (argv[0], standard_bindir_prefix,
                                               standard_exec_prefix);
+      gcc_libexec_prefix = make_relative_prefix (argv[0], 
+						 standard_bindir_prefix,
+						 standard_libexec_prefix);
       if (gcc_exec_prefix)
         putenv (concat ("GCC_EXEC_PREFIX=", gcc_exec_prefix, NULL));
     }
+  else
+    gcc_libexec_prefix = make_relative_prefix (gcc_exec_prefix,
+					       standard_exec_prefix,
+					       standard_libexec_prefix);
+#else
 #endif
 
   if (gcc_exec_prefix)
     {
       int len = strlen (gcc_exec_prefix);
-
+#ifndef GCC_3_4
       if (len > (int) sizeof ("/lib/gcc-lib/") - 1
+#else
+      if (len > (int) sizeof ("/lib/gcc/") - 1
+#endif
           && (IS_DIR_SEPARATOR (gcc_exec_prefix[len-1])))
         {
+#ifndef GCC_3_4
           temp = gcc_exec_prefix + len - sizeof ("/lib/gcc-lib/") + 1;
+#else
+	  temp = gcc_exec_prefix + len - sizeof ("/lib/gcc/") + 1;
+#endif
           if (IS_DIR_SEPARATOR (*temp)
               && strncmp (temp + 1, "lib", 3) == 0
-              && IS_DIR_SEPARATOR (temp[4])
+	      && IS_DIR_SEPARATOR (temp[5])
+#ifndef GCC_3_4
               && strncmp (temp + 5, "gcc-lib", 7) == 0)
             len -= sizeof ("/lib/gcc-lib/") - 1;
+#else
+	      && strncmp (temp + 5, "gcc", 3) == 0)
+	    len -= sizeof ("/lib/gcc/") - 1;
+#endif
         }
 
       set_std_prefix (gcc_exec_prefix, len);
-      add_prefix (&exec_prefixes, gcc_exec_prefix, "GCC",
+      add_prefix (&exec_prefixes, gcc_libexec_prefix, "GCC",
                   PREFIX_PRIORITY_LAST, 0, NULL, 0);
       add_prefix (&startfile_prefixes, gcc_exec_prefix, "GCC",
                   PREFIX_PRIORITY_LAST, 0, NULL, 0);
@@ -3727,7 +3897,7 @@
   if (temp)
     {
       const char *startp, *endp;
-      char *nstore = (char *) alloca (strlen (temp) + 3);
+      char *nstore = alloca (strlen (temp) + 3);
 
       startp = endp = temp;
       while (1)
@@ -3762,7 +3932,7 @@
   if (temp && *cross_compile == '0')
     {
       const char *startp, *endp;
-      char *nstore = (char *) alloca (strlen (temp) + 3);
+      char *nstore = alloca (strlen (temp) + 3);
 
       startp = endp = temp;
       while (1)
@@ -3795,7 +3965,7 @@
   if (temp && *cross_compile == '0')
     {
       const char *startp, *endp;
-      char *nstore = (char *) alloca (strlen (temp) + 3);
+      char *nstore = alloca (strlen (temp) + 3);
 
       startp = endp = temp;
       while (1)
@@ -3829,11 +3999,11 @@
 #endif
 
   /* Convert new-style -- options to old-style.  */
-  translate_options (&argc, &argv);
+  translate_options (&argc, (const char *const **) &argv);
 
 #ifdef LANG_SPECIFIC_DRIVER
   /* Do language-specific adjustment/addition of flags.  */
-  lang_specific_driver (&argc, &argv, &added_libraries);
+  lang_specific_driver (&argc, (const char *const **) &argv, &added_libraries);
 #endif
 
   /* Scan argv twice.  Here, the first time, just count how many switches
@@ -3866,8 +4036,8 @@
         {
           /* translate_options () has turned --version into -fversion.  */
           printf (_("%s %s, based on gcc-%s\n"), programname, GPC_RELEASE_STRING, version_string);
-          fputs (_("Copyright (C) 1987-2004 Free Software Foundation, Inc.\n"),
-                 stdout);
+	  printf ("Copyright %s 2004 Free Software Foundation, Inc.\n",
+		  _("(C)"));
           fputs (_("This is free software; see the source for copying conditions.  There is NO\n\
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"),
                  stdout);
@@ -3974,6 +4144,20 @@
           n_infiles++;
           i++;
         }
+      else if (strcmp (argv[i], "-Xpreprocessor") == 0)
+	{
+	  if (i + 1 == argc)
+	    fatal ("argument to `-Xpreprocessor' is missing");
+
+	  add_preprocessor_option (argv[i+1], strlen (argv[i+1]));
+	}
+      else if (strcmp (argv[i], "-Xassembler") == 0)
+	{
+	  if (i + 1 == argc)
+	    fatal ("argument to `-Xassembler' is missing");
+
+	  add_assembler_option (argv[i+1], strlen (argv[i+1]));
+	}
       else if (strcmp (argv[i], "-l") == 0)
         {
           if (i + 1 == argc)
@@ -3991,8 +4175,7 @@
         }
       else if (strcmp (argv[i], "-specs") == 0)
         {
-          struct user_specs *user = (struct user_specs *)
-            xmalloc (sizeof (struct user_specs));
+	  struct user_specs *user = xmalloc (sizeof (struct user_specs));
           if (++i >= argc)
             fatal ("argument to `-specs' is missing");
 
@@ -4006,8 +4189,7 @@
         }
       else if (strncmp (argv[i], "-specs=", 7) == 0)
         {
-          struct user_specs *user = (struct user_specs *)
-            xmalloc (sizeof (struct user_specs));
+	  struct user_specs *user = xmalloc (sizeof (struct user_specs));
           if (strlen (argv[i]) == 7)
             fatal ("argument to `-specs=' is missing");
 
@@ -4021,6 +4203,13 @@
         }
       else if (strcmp (argv[i], "-time") == 0)
         report_times = 1;
+      else if (strcmp (argv[i], "-pipe") == 0)
+	{
+	  /* -pipe has to go into the switches array as well as
+	     setting a flag.  */
+	  use_pipes = 1;
+	  n_switches++;
+	}
       else if (strcmp (argv[i], "-###") == 0)
         {
           /* This is similar to -v except that there is no execution
@@ -4176,8 +4365,7 @@
               for (j = 0; j < ARRAY_SIZE (modify_target); j++)
                 if (! strcmp (argv[i], modify_target[j].sw))
                   {
-                    char *new_name
-                      = (char *) xmalloc (strlen (modify_target[j].str)
+		    char *new_name = xmalloc (strlen (modify_target[j].str)
                                           + strlen (spec_machine));
                     const char *p, *r;
                     char *q;
@@ -4223,8 +4411,20 @@
         }
     }
 
-  if (have_c && have_o && lang_n_infiles > 1)
-    fatal ("cannot specify -o with -c or -S and multiple compilations");
+  combine_inputs = (have_c && have_o && lang_n_infiles > 1);
+
+  if ((save_temps_flag || report_times) && use_pipes)
+    {
+      /* -save-temps overrides -pipe, so that temp files are produced */
+      if (save_temps_flag)
+	error ("warning: -pipe ignored because -save-temps specified");
+      /* -time overrides -pipe because we can't get correct stats when
+	 multiple children are running at once.  */
+      else if (report_times)
+	error ("warning: -pipe ignored because -time specified");
+
+      use_pipes = 0;
+    }
 
   /* Set up the search paths before we go looking for config files.  */
 
@@ -4233,17 +4433,21 @@
   /* Use 2 as fourth arg meaning try just the machine as a suffix,
      as well as trying the machine and the version.  */
 #ifndef OS2
-  add_prefix (&exec_prefixes, standard_exec_prefix, "GCC",
+  add_prefix (&exec_prefixes, standard_libexec_prefix, "GCC",
               PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
+  add_prefix (&exec_prefixes, standard_libexec_prefix, "BINUTILS",
+	      PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
   add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS",
               PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
   add_prefix (&exec_prefixes, standard_exec_prefix_1, "BINUTILS",
               PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
+  add_prefix (&exec_prefixes, standard_exec_prefix_2, "BINUTILS",
+	      PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
 #endif
 
   add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS",
               PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
-  add_prefix (&startfile_prefixes, standard_exec_prefix_1, "BINUTILS",
+  add_prefix (&startfile_prefixes, standard_exec_prefix_2, "BINUTILS",
               PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
 
   tooldir_prefix = concat (tooldir_base_prefix, spec_machine,
@@ -4256,7 +4460,7 @@
      directories, so that we can search both the user specified directory
      and the standard place.  */
 
-  if (!IS_ABSOLUTE_PATHNAME (tooldir_prefix))
+  if (!IS_ABSOLUTE_PATH (tooldir_prefix))
     {
       if (gcc_exec_prefix)
         {
@@ -4286,14 +4490,31 @@
               concat (tooldir_prefix, "lib", dir_separator_str, NULL),
               "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
 
+#if defined(TARGET_SYSTEM_ROOT_RELOCATABLE) && !defined(VMS)
+  /* If the normal TARGET_SYSTEM_ROOT is inside of $exec_prefix,
+     then consider it to relocate with the rest of the GCC installation
+     if GCC_EXEC_PREFIX is set.
+     ``make_relative_prefix'' is not compiled for VMS, so don't call it.  */
+  if (target_system_root && gcc_exec_prefix)
+    {
+      char *tmp_prefix = make_relative_prefix (argv[0],
+					       standard_bindir_prefix,
+					       target_system_root);
+      if (tmp_prefix && access_check (tmp_prefix, F_OK) == 0)
+	{
+	  target_system_root = tmp_prefix;
+	  target_system_root_changed = 1;
+	}
+    }
+#endif
+
   /* More prefixes are enabled in main, after we read the specs file
      and determine whether this is cross-compilation or not.  */
 
   /* Then create the space for the vectors and scan again.  */
 
-  switches = ((struct switchstr *)
-              xmalloc ((n_switches + 1) * sizeof (struct switchstr)));
-  infiles = (struct infile *) xmalloc ((n_infiles + 1) * sizeof (struct infile));
+  switches = xmalloc ((n_switches + 1) * sizeof (struct switchstr));
+  infiles = xmalloc ((n_infiles + 1) * sizeof (struct infile));
   n_switches = 0;
   n_infiles = 0;
   last_language_n_infiles = -1;
@@ -4375,6 +4596,16 @@
           infiles[n_infiles].language = "*";
           infiles[n_infiles++].name = argv[++i];
         }
+      else if (strcmp (argv[i], "-Xassembler") == 0)
+	{
+	  infiles[n_infiles].language = "*";
+	  infiles[n_infiles++].name = argv[++i];
+	}
+      else if (strcmp (argv[i], "-Xpreprocessor") == 0)
+	{
+	  infiles[n_infiles].language = "*";
+	  infiles[n_infiles++].name = argv[++i];
+	}
       else if (strcmp (argv[i], "-l") == 0)
         { /* POSIX allows separation of -l and the lib arg;
              canonicalize by concatenating -l with its arg */
@@ -4392,17 +4623,6 @@
         ;
       else if (strcmp (argv[i], "-time") == 0)
         ;
-      else if ((save_temps_flag || report_times)
-               && strcmp (argv[i], "-pipe") == 0)
-        {
-          /* -save-temps overrides -pipe, so that temp files are produced */
-          if (save_temps_flag)
-            error ("warning: -pipe ignored because -save-temps specified");
-          /* -time overrides -pipe because we can't get correct stats when
-             multiple children are running at once.  */
-          else if (report_times)
-            error ("warning: -pipe ignored because -time specified");
-        }
       else if (strcmp (argv[i], "-###") == 0)
         ;
       else if (argv[i][0] == '-' && argv[i][1] != 0)
@@ -4443,7 +4663,7 @@
               if (i + n_args >= argc)
                 fatal ("argument to `-%s' is missing", p);
               switches[n_switches].args
-                = (const char **) xmalloc ((n_args + 1) * sizeof(const char *));
+		= xmalloc ((n_args + 1) * sizeof(const char *));
               while (j < n_args)
                 switches[n_switches].args[j++] = argv[++i];
               /* Null-terminate the vector.  */
@@ -4453,13 +4673,12 @@
             {
               /* On some systems, ld cannot handle some options without
                  a space.  So split the option from its argument.  */
-              char *part1 = (char *) xmalloc (2);
+	      char *part1 = xmalloc (2);
               part1[0] = c;
               part1[1] = '\0';
 
               switches[n_switches].part1 = part1;
-              switches[n_switches].args
-                = (const char **) xmalloc (2 * sizeof (const char *));
+	      switches[n_switches].args = xmalloc (2 * sizeof (const char *));
               switches[n_switches].args[0] = xstrdup (p+1);
               switches[n_switches].args[1] = 0;
             }
@@ -4469,10 +4688,11 @@
           switches[n_switches].live_cond = SWITCH_OK;
           switches[n_switches].validated = 0;
           switches[n_switches].ordering = 0;
-          /* These are always valid, since gcc.c itself understands it.  */
+	  /* These are always valid, since gcc.c itself understands them.  */
           if (!strcmp (p, "save-temps")
               || !strcmp (p, "static-libgcc")
-              || !strcmp (p, "shared-libgcc"))
+	      || !strcmp (p, "shared-libgcc")
+	      || !strcmp (p, "pipe"))
             switches[n_switches].validated = 1;
           else
             {
@@ -4539,11 +4759,11 @@
   infiles[n_infiles].name = 0;
 }
 
-/* Store switches not filtered out by %{<S} in spec in COLLECT_GCC_OPTIONS
+/* Store switches not filtered out by %<S in spec in COLLECT_GCC_OPTIONS
    and place that in the environment.  */
 
 static void
-set_collect_gcc_options ()
+set_collect_gcc_options (void)
 {
   int i;
   int first_time;
@@ -4605,7 +4825,7 @@
    sans all directory names, and basename_length is the number
    of characters starting there excluding the suffix .c or whatever.  */
 
-const char *input_filename;
+static const char *input_filename;
 static int input_file_number;
 size_t input_filename_length;
 static int basename_length;
@@ -4648,8 +4868,7 @@
    Returns 0 if the spec is successfully processed; -1 if failed.  */
 
 int
-do_spec (spec)
-     const char *spec;
+do_spec (const char *spec)
 {
   int value;
 
@@ -4680,9 +4899,11 @@
 }
 
 static int
-do_spec_2 (spec)
-     const char *spec;
+do_spec_2 (const char *spec)
 {
+  const char *string;
+  int result;
+
   clear_args ();
   arg_going = 0;
   delete_this_arg = 0;
@@ -4691,7 +4912,22 @@
   input_from_pipe = 0;
   suffix_subst = NULL;
 
-  return do_spec_1 (spec, 0, NULL);
+  result = do_spec_1 (spec, 0, NULL);
+
+  /* End any pending argument.  */
+  if (arg_going)
+    {
+      obstack_1grow (&obstack, 0);
+      string = obstack_finish (&obstack);
+      if (this_is_library_file)
+	string = find_file (string);
+      store_arg (string, delete_this_arg, this_is_output_file);
+      if (this_is_output_file)
+	outfiles[input_file_number] = string;
+      arg_going = 0;
+    }
+
+  return result;
 }
 
 
@@ -4699,8 +4935,56 @@
    of the switches/n_switches array.  */
 
 static void
-do_self_spec (spec)
-     const char *spec;
+do_option_spec (const char *name, const char *spec)
+{
+  unsigned int i, value_count, value_len;
+  const char *p, *q, *value;
+  char *tmp_spec, *tmp_spec_p;
+
+  if (configure_default_options[0].name == NULL)
+    return;
+
+  for (i = 0; i < ARRAY_SIZE (configure_default_options); i++)
+    if (strcmp (configure_default_options[i].name, name) == 0)
+      break;
+  if (i == ARRAY_SIZE (configure_default_options))
+    return;
+
+  value = configure_default_options[i].value;
+  value_len = strlen (value);
+
+  /* Compute the size of the final spec.  */
+  value_count = 0;
+  p = spec;
+  while ((p = strstr (p, "%(VALUE)")) != NULL)
+    {
+      p ++;
+      value_count ++;
+    }
+
+  /* Replace each %(VALUE) by the specified value.  */
+  tmp_spec = alloca (strlen (spec) + 1
+		     + value_count * (value_len - strlen ("%(VALUE)")));
+  tmp_spec_p = tmp_spec;
+  q = spec;
+  while ((p = strstr (q, "%(VALUE)")) != NULL)
+    {
+      memcpy (tmp_spec_p, q, p - q);
+      tmp_spec_p = tmp_spec_p + (p - q);
+      memcpy (tmp_spec_p, value, value_len);
+      tmp_spec_p += value_len;
+      q = p + strlen ("%(VALUE)");
+    }
+  strcpy (tmp_spec_p, q);
+
+  do_self_spec (tmp_spec);
+}
+
+/* Process the given spec string and add any new options to the end
+   of the switches/n_switches array.  */
+
+static void
+do_self_spec (const char *spec)
 {
   do_spec_2 (spec);
   do_spec_1 (" ", 0, NULL);
@@ -4746,10 +5030,7 @@
    and the command on that line reported an error.  */
 
 static int
-do_spec_1 (spec, inswitch, soft_matched_part)
-     const char *spec;
-     int inswitch;
-     const char *soft_matched_part;
+do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
 {
   const char *p = spec;
   int c;
@@ -4779,17 +5060,12 @@
 
         if (argbuf_index > 0 && !strcmp (argbuf[argbuf_index - 1], "|"))
           {
-            for (i = 0; i < n_switches; i++)
-              if (!strcmp (switches[i].part1, "pipe"))
-                break;
-
             /* A `|' before the newline means use a pipe here,
                but only if -pipe was specified.
                Otherwise, execute now and don't pass the `|' as an arg.  */
-            if (i < n_switches)
+	    if (use_pipes)
               {
                 input_from_pipe = 1;
-                switches[i].validated = 1;
                 break;
               }
             else
@@ -4878,7 +5154,7 @@
             {
               struct prefix_list *pl = startfile_prefixes.plist;
               size_t bufsize = 100;
-              char *buffer = (char *) xmalloc (bufsize);
+	      char *buffer = xmalloc (bufsize);
               int idx;
 
               for (; pl; pl = pl->next)
@@ -4889,7 +5165,7 @@
                   /* Relative directories always come from -B,
                      and it is better not to use them for searching
                      at run time.  In particular, stage1 loses.  */
-                  if (!IS_ABSOLUTE_PATHNAME (pl->prefix))
+		  if (!IS_ABSOLUTE_PATH (pl->prefix))
                     continue;
 #endif
                   /* Try subdirectory if there is one.  */
@@ -4906,7 +5182,7 @@
                               >= bufsize)
                             bufsize = (strlen (pl->prefix)
                                        + strlen (machine_suffix)) * 2 + 1;
-                          buffer = (char *) xrealloc (buffer, bufsize);
+			  buffer = xrealloc (buffer, bufsize);
                           strcpy (buffer, pl->prefix);
                           strcat (buffer, machine_suffix);
                           if (is_directory (buffer, multilib_dir, 1))
@@ -4948,7 +5224,7 @@
                           /* Remove slash from machine_suffix.  */
                           if (strlen (machine_suffix) >= bufsize)
                             bufsize = strlen (machine_suffix) * 2 + 1;
-                          buffer = (char *) xrealloc (buffer, bufsize);
+			  buffer = xrealloc (buffer, bufsize);
                           strcpy (buffer, machine_suffix);
                           idx = strlen (buffer);
                           if (IS_DIR_SEPARATOR (buffer[idx - 1]))
@@ -4969,7 +5245,7 @@
                           /* Remove slash from pl->prefix.  */
                           if (strlen (pl->prefix) >= bufsize)
                             bufsize = strlen (pl->prefix) * 2 + 1;
-                          buffer = (char *) xrealloc (buffer, bufsize);
+			  buffer = xrealloc (buffer, bufsize);
                           strcpy (buffer, pl->prefix);
                           idx = strlen (buffer);
                           if (IS_DIR_SEPARATOR (buffer[idx - 1]))
@@ -4992,7 +5268,7 @@
               char *buf;
               while (*p != 0 && *p != '\n')
                 p++;
-              buf = (char *) alloca (p - q + 1);
+	      buf = alloca (p - q + 1);
               strncpy (buf, q, p - q);
               buf[p - q] = 0;
               error ("%s", buf);
@@ -5006,7 +5282,7 @@
               char *buf;
               while (*p != 0 && *p != '\n')
                 p++;
-              buf = (char *) alloca (p - q + 1);
+	      buf = alloca (p - q + 1);
               strncpy (buf, q, p - q);
               buf[p - q] = 0;
               notice ("%s\n", buf);
@@ -5019,10 +5295,10 @@
             {
               struct stat st;
 
-              /* If save_temps_flag is off, and the HOST_BIT_BUCKET is defined,
-                 and it is not a directory, and it is writable, use it.
-                 Otherwise, fall through and treat this like any other
-                 temporary file.  */
+	      /* If save_temps_flag is off, and the HOST_BIT_BUCKET is
+		 defined, and it is not a directory, and it is
+		 writable, use it.  Otherwise, treat this like any
+		 other temporary file.  */
 
               if ((!save_temps_flag)
                   && (stat (HOST_BIT_BUCKET, &st) == 0) && (!S_ISDIR (st.st_mode))
@@ -5035,9 +5311,45 @@
                   break;
                 }
             }
+	    goto create_temp_file;
+	  case '|':
+	    if (use_pipes)
+#ifdef GCC_3_4
+	      {
+		obstack_1grow (&obstack, '-');
+		delete_this_arg = 0;
+		arg_going = 1;
+
+		/* consume suffix */
+		while (*p == '.' || ISALPHA ((unsigned char) *p))
+		  p++;
+		if (p[0] == '%' && p[1] == 'O')
+		  p += 2;
+
+		break;
+	      }
+	    goto create_temp_file;
+#else
+              do_spec_1 ("-", 0, NULL);
+            break;
+#endif
+              
+	  case 'm':
+	    if (use_pipes)
+	      {
+		/* consume suffix */
+		while (*p == '.' || ISALPHA ((unsigned char) *p))
+		  p++;
+		if (p[0] == '%' && p[1] == 'O')
+		  p += 2;
+
+		break;
+	      }
+	    goto create_temp_file;
           case 'g':
           case 'u':
           case 'U':
+	  create_temp_file:
               {
                 struct temp_name *t;
                 int suffix_length;
@@ -5058,7 +5370,7 @@
                     else
                       {
                         saved_suffix
-                          = (char *) xmalloc (suffix_length
+			  = xmalloc (suffix_length
                                               + strlen (TARGET_OBJECT_SUFFIX));
                         strncpy (saved_suffix, suffix, suffix_length);
                         strcpy (saved_suffix + suffix_length,
@@ -5121,7 +5433,7 @@
                 for (t = temp_names; t; t = t->next)
                   if (t->length == suffix_length
                       && strncmp (t->suffix, suffix, suffix_length) == 0
-                      && t->unique == (c != 'g'))
+		      && t->unique == (c == 'u' || c == 'U' || c == 'j'))
                     break;
 
                 /* Make a new association if needed.  %u and %j
@@ -5130,7 +5442,7 @@
                   {
                     if (t == 0)
                       {
-                        t = (struct temp_name *) xmalloc (sizeof (struct temp_name));
+			t = xmalloc (sizeof (struct temp_name));
                         t->next = temp_names;
                         temp_names = t;
                       }
@@ -5142,7 +5454,7 @@
                       }
                     else
                       t->suffix = save_string (suffix, suffix_length);
-                    t->unique = (c != 'g');
+		    t->unique = (c == 'u' || c == 'U' || c == 'j');
                     temp_filename = make_temp_file (t->suffix);
                     temp_filename_length = strlen (temp_filename);
                     t->filename = temp_filename;
@@ -5159,8 +5471,16 @@
             break;
 
           case 'i':
+	    if (combine_inputs)
+	      {
+		for (i = 0; (int) i < n_infiles; i++)
+		  store_arg (infiles[i].name, 0, 0);
+	      }
+	    else
+	      {
             obstack_grow (&obstack, input_filename, input_filename_length);
             arg_going = 1;
+	      }
             break;
 
           case 'I':
@@ -5176,6 +5496,18 @@
                   do_spec_1 (" ", 0, NULL);
                 }
 
+	      if (target_system_root_changed ||
+		  (target_system_root && target_sysroot_hdrs_suffix))
+		{
+		  do_spec_1 ("-isysroot", 1, NULL);
+		  /* Make this a separate argument.  */
+		  do_spec_1 (" ", 0, NULL);
+		  do_spec_1 (target_system_root, 1, NULL);
+		  if (target_sysroot_hdrs_suffix)
+		    do_spec_1 (target_sysroot_hdrs_suffix, 1, NULL);
+		  do_spec_1 (" ", 0, NULL);
+		}
+
               for (; pl; pl = pl->next)
                 {
                   do_spec_1 ("-isystem", 1, NULL);
@@ -5207,6 +5539,10 @@
             this_is_library_file = 1;
             break;
 
+	  case 'V':
+	    outfiles[input_file_number] = NULL;
+	    break;
+
           case 'w':
             this_is_output_file = 1;
             break;
@@ -5247,6 +5583,18 @@
               p = handle_braces (p + 1);
               if (p == 0)
                 return -1;
+	      /* End any pending argument.  */
+	      if (arg_going)
+		{
+		  obstack_1grow (&obstack, 0);
+		  string = obstack_finish (&obstack);
+		  if (this_is_library_file)
+		    string = find_file (string);
+		  store_arg (string, delete_this_arg, this_is_output_file);
+		  if (this_is_output_file)
+		    outfiles[input_file_number] = string;
+		  arg_going = 0;
+		}
               /* If any args were output, mark the last one for deletion
                  on failure.  */
               if (argbuf_index != cur_index)
@@ -5555,6 +5903,19 @@
             }
             break;
 
+	  case 'R':
+	    /* We assume there is a directory
+	       separator at the end of this string.  */
+	    if (target_system_root)
+	      {
+	        obstack_grow (&obstack, target_system_root,
+			      strlen (target_system_root));
+		if (target_sysroot_suffix)
+		  obstack_grow (&obstack, target_sysroot_suffix,
+				strlen (target_sysroot_suffix));
+	      }
+	    break;
+
           case 'S':
             value = do_spec_1 (startfile_spec, 0, NULL);
             if (value != 0)
@@ -5590,6 +5951,32 @@
             }
             break;
 
+	   /* Henceforth ignore the option(s) matching the pattern
+	      after the %<.  */
+	  case '<':
+	    {
+	      unsigned len = 0;
+	      int have_wildcard = 0;
+	      int i;
+
+	      while (p[len] && p[len] != ' ' && p[len] != '\t')
+		len++;
+
+	      if (p[len-1] == '*')
+		have_wildcard = 1;
+
+	      for (i = 0; i < n_switches; i++)
+		if (!strncmp (switches[i].part1, p, len - have_wildcard)
+		    && (have_wildcard || switches[i].part1[len] == '\0'))
+		  {
+		    switches[i].live_cond = SWITCH_IGNORE;
+		    switches[i].validated = 1;
+		  }
+
+	      p += len;
+	    }
+	    break;
+
           case '*':
             if (soft_matched_part)
               {
@@ -5645,7 +6032,7 @@
                     }
                   else
                     {
-                      char *x = (char *) alloca (strlen (name) * 2 + 1);
+		      char *x = alloca (strlen (name) * 2 + 1);
                       char *buf = x;
                       const char *y = name;
                       int flag = 0;
@@ -5748,11 +6135,6 @@
             }
             break;
 
-          case '|':
-            if (input_from_pipe)
-              do_spec_1 ("-", 0, NULL);
-            break;
-
           default:
             error ("spec failure: unrecognized spec option '%c'", c);
             break;
@@ -5763,7 +6145,7 @@
         /* Backslash: treat next character as ordinary.  */
         c = *p++;
 
-        /* fall through */
+	/* Fall through.  */
       default:
         /* Ordinary character: put it into the current argument.  */
         obstack_1grow (&obstack, c);
@@ -5790,8 +6172,7 @@
 /* Look up a spec function.  */
 
 static const struct spec_function *
-lookup_spec_function (name)
-     const char *name;
+lookup_spec_function (const char *name)
 {
   static const struct spec_function * const spec_function_tables[] =
   {
@@ -5814,8 +6195,7 @@
 /* Evaluate a spec function.  */
 
 static const char *
-eval_spec_function (func, args)
-     const char *func, *args;
+eval_spec_function (const char *func, const char *args)
 {
   const struct spec_function *sf;
   const char *funcval;
@@ -5887,8 +6267,7 @@
    NULL if no processing is required.  */
 
 static const char *
-handle_spec_function (p)
-     const char *p;
+handle_spec_function (const char *p)
 {
   char *func, *args;
   const char *endp, *funcval;
@@ -5943,273 +6322,305 @@
   return p;
 }
 
-/* Return 0 if we call do_spec_1 and that returns -1.  */
+/* Inline subroutine of handle_braces.  Returns true if the current
+   input suffix matches the atom bracketed by ATOM and END_ATOM.  */
+static inline bool
+input_suffix_matches (const char *atom, const char *end_atom)
+{
+  return (input_suffix
+	  && !strncmp (input_suffix, atom, end_atom - atom)
+	  && input_suffix[end_atom - atom] == '\0');
+}
 
-static const char *
-handle_braces (p)
-     const char *p;
+/* Inline subroutine of handle_braces.  Returns true if a switch
+   matching the atom bracketed by ATOM and END_ATOM appeared on the
+   command line.  */
+static inline bool
+switch_matches (const char *atom, const char *end_atom, int starred)
 {
-  const char *filter, *body = NULL, *endbody = NULL;
-  int pipe_p = 0;
-  int true_once = 0;    /* If, in %{a|b:d}, at least one of a,b was seen.  */
-  int negate;
-  int suffix;
-  int include_blanks = 1;
-  int elide_switch = 0;
-  int ordered = 0;
-
-  if (*p == '^')
-    {
-      /* A '^' after the open-brace means to not give blanks before args.  */
-      include_blanks = 0;
-      ++p;
-    }
-
-  if (*p == '|')
-    {
-      /* A `|' after the open-brace means,
-         if the test fails, output a single minus sign rather than nothing.
-         This is used in %{|!pipe:...}.  */
-      pipe_p = 1;
-      ++p;
-    }
-
-  if (*p == '<')
-    {
-      /* A `<' after the open-brace means that the switch should be
-         removed from the command-line.  */
-      elide_switch = 1;
-      ++p;
-    }
-
-next_member:
-  negate = suffix = 0;
+  int i;
+  int len = end_atom - atom;
+  int plen = starred ? len : -1;
 
-  if (*p == '!')
-    /* A `!' after the open-brace negates the condition:
-       succeed if the specified switch is not present.  */
-    negate = 1, ++p;
+  for (i = 0; i < n_switches; i++)
+    if (!strncmp (switches[i].part1, atom, len)
+	&& (starred || switches[i].part1[len] == '\0')
+	&& check_live_switch (i, plen))
+      return true;
+
+  return false;
+}
+
+/* Inline subroutine of handle_braces.  Mark all of the switches which
+   match ATOM (extends to END_ATOM; STARRED indicates whether there
+   was a star after the atom) for later processing.  */
+static inline void
+mark_matching_switches (const char *atom, const char *end_atom, int starred)
+{
+  int i;
+  int len = end_atom - atom;
+  int plen = starred ? len : -1;
 
-  if (*p == '.')
-    /* A `.' after the open-brace means test against the current suffix.  */
-    {
-      if (pipe_p)
-        abort ();
+  for (i = 0; i < n_switches; i++)
+    if (!strncmp (switches[i].part1, atom, len)
+	&& (starred || switches[i].part1[len] == '\0')
+	&& check_live_switch (i, plen))
+      switches[i].ordering = 1;
+}
 
-      suffix = 1;
-      ++p;
-    }
+/* Inline subroutine of handle_braces.  Process all the currently
+   marked switches through give_switch, and clear the marks.  */
+static inline void
+process_marked_switches (void)
+{
+  int i;
 
-  if (elide_switch && (negate || pipe_p || suffix))
+  for (i = 0; i < n_switches; i++)
+    if (switches[i].ordering == 1)
     {
-      /* It doesn't make sense to mix elision with other flags.  We
-         could fatal() here, but the standard seems to be to abort.  */
-      abort ();
+	switches[i].ordering = 0;
+	give_switch (i, 0);
     }
+}
 
- next_ampersand:
-  filter = p;
-  while (*p != ':' && *p != '}' && *p != '|' && *p != '&')
-    p++;
-
-  if (*p == '|' && (pipe_p || ordered))
-    abort ();
+/* Handle a %{ ... } construct.  P points just inside the leading {.
+   Returns a pointer one past the end of the brace block, or 0
+   if we call do_spec_1 and that returns -1.  */
 
-  if (!body)
-    {
-      if (*p != '}' && *p != '&')
-        {
-          int count = 1;
-          const char *q = p;
+static const char *
+handle_braces (const char *p)
+{
+  const char *atom, *end_atom;
+  const char *d_atom = NULL, *d_end_atom = NULL;
 
-          while (*q++ != ':')
-            continue;
-          body = q;
+  bool a_is_suffix;
+  bool a_is_starred;
+  bool a_is_negated;
+  bool a_matched;
+
+  bool a_must_be_last = false;
+  bool ordered_set    = false;
+  bool disjunct_set   = false;
+  bool disj_matched   = false;
+  bool disj_starred   = true;
+  bool n_way_choice   = false;
+  bool n_way_matched  = false;
+  bool pipe_p = false;
 
-          while (count > 0)
-            {
-              if (*q == '{')
-                count++;
-              else if (*q == '}')
-                count--;
-              else if (*q == 0)
-                fatal ("mismatched braces in specs");
-              q++;
-            }
-          endbody = q;
-        }
-      else
-        body = p, endbody = p + 1;
-    }
+#define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
 
-  if (suffix)
+  do
     {
-      int found = (input_suffix != 0
-                   && (long) strlen (input_suffix) == (long) (p - filter)
-                   && strncmp (input_suffix, filter, p - filter) == 0);
-
-      if (body[0] == '}')
+      if (a_must_be_last)
+      abort ();
+        if (*p == '|')
+	  {
+            /* A `|' after the open-brace means, if the test fails,
+	       output a single minus sign rather than nothing.
+	       This is used in %{|!pipe:...}.  */
+	    a_must_be_last = pipe_p = true;
+	    p++;
+    }
+
+      /* Scan one "atom" (S in the description above of %{}, possibly
+	 with !, ., or * modifiers).  */
+      a_matched = a_is_suffix = a_is_starred = a_is_negated = false;
+
+      SKIP_WHITE();
+      if (*p == '!')
+	p++, a_is_negated = true;
+
+      SKIP_WHITE();
+      if (*p == '.')
+	p++, a_is_suffix = true;
+
+      atom = p;
+      while (ISIDNUM(*p) || *p == '-' || *p == '+' || *p == '='
+	     || *p == ',' || *p == '.' || *p == '@' || *p == '$')
+	p++;
+      end_atom = p;
+
+      if (*p == '*')
+	p++, a_is_starred = 1;
+
+      SKIP_WHITE();
+      if (*p == '&' || *p == '}')
+    {
+	  /* Substitute the switch(es) indicated by the current atom.  */
+	  ordered_set = true;
+	  if (disjunct_set || n_way_choice || a_is_negated || a_is_suffix
+	      || atom == end_atom)
         abort ();
 
-      if (negate != found
-          && do_spec_1 (save_string (body, endbody-body-1), 0, NULL) < 0)
-        return 0;
+	  mark_matching_switches (atom, end_atom, a_is_starred);
+
+	  if (*p == '}')
+	    process_marked_switches ();
     }
-  else if (p[-1] == '*' && (p[0] == '}' || p[0] == '&'))
+      else if (*p == '|' || *p == ':')
     {
-      /* Substitute all matching switches as separate args.  */
-      int i;
+	  /* Substitute some text if the current atom appears as a switch
+	     or suffix.  */
+	  disjunct_set = true;
+	  if (ordered_set)
+	    abort ();
 
-      for (i = 0; i < n_switches; i++)
-        if (!strncmp (switches[i].part1, filter, p - 1 - filter)
-            && check_live_switch (i, p - 1 - filter))
-          {
-            if (elide_switch)
+	  if (atom == end_atom)
               {
-                switches[i].live_cond = SWITCH_IGNORE;
-                switches[i].validated = 1;
-              }
-            else
-              ordered = 1, switches[i].ordering = 1;
-          }
+	      if (!n_way_choice || disj_matched || *p == '|'
+		  || a_is_negated || a_is_suffix || a_is_starred)
+		abort ();
+
+	      /* An empty term may appear as the last choice of an
+		 N-way choice set; it means "otherwise".  */
+	      a_must_be_last = true;
+	      disj_matched = !n_way_matched;
+	      disj_starred = false;
     }
   else
     {
-      /* Test for presence of the specified switch.  */
-      int i;
-      int present = 0;
+	       if (a_is_suffix && a_is_starred)
+		 abort ();
 
-      /* If name specified ends in *, as in {x*:...},
-         check for %* and handle that case.  */
-      if (p[-1] == '*' && !negate)
-        {
-          int substitution;
-          const char *r = body;
+	       if (!a_is_starred)
+		 disj_starred = false;
 
-          /* First see whether we have %*.  */
-          substitution = 0;
-          while (r < endbody)
-            {
-              if (*r == '%' && r[1] == '*')
-                substitution = 1;
-              r++;
-            }
-          /* If we do, handle that case.  */
-          if (substitution)
-            {
-              /* Substitute all matching switches as separate args.
-                 But do this by substituting for %*
-                 in the text that follows the colon.  */
-
-              unsigned hard_match_len = p - filter - 1;
-              char *string = save_string (body, endbody - body - 1);
+	       /* Don't bother testing this atom if we already have a
+                  match.  */
+	       if (!disj_matched && !n_way_matched)
+            {
+		   if (a_is_suffix)
+		     a_matched = input_suffix_matches (atom, end_atom);
+		   else
+		     a_matched = switch_matches (atom, end_atom, a_is_starred);
 
-              for (i = 0; i < n_switches; i++)
-                if (!strncmp (switches[i].part1, filter, hard_match_len)
-                    && check_live_switch (i, -1))
+		   if (a_matched != a_is_negated)
                   {
-                    do_spec_1 (string, 0, &switches[i].part1[hard_match_len]);
-                    /* Pass any arguments this switch has.  */
-                    give_switch (i, 1, 1);
-                    suffix_subst = NULL;
+		       disj_matched = true;
+		       d_atom = atom;
+		       d_end_atom = end_atom;
                   }
-
-              /* We didn't match.  Try again.  */
-              if (*p++ == '|')
-                goto next_member;
-              return endbody;
             }
         }
 
-      /* If name specified ends in *, as in {x*:...},
-         check for presence of any switch name starting with x.  */
-      if (p[-1] == '*')
+	  if (*p == ':')
         {
-          for (i = 0; i < n_switches; i++)
-            {
-              unsigned hard_match_len = p - filter - 1;
-
-              if (!strncmp (switches[i].part1, filter, hard_match_len)
-                  && check_live_switch (i, hard_match_len))
-                {
-                  present = 1;
-                  break;
+	      /* Found the body, that is, the text to substitute if the
+		 current disjunction matches.  */
+	      p = process_brace_body (p + 1, d_atom, d_end_atom, disj_starred,
+				      disj_matched && !n_way_matched);
+	      if (p == 0)
+		return 0;
+
+	      /* If we have an N-way choice, reset state for the next
+		 disjunction.  */
+	      if (*p == ';')
+		{
+		  n_way_choice = true;
+		  n_way_matched |= disj_matched;
+		  disj_matched = false;
+		  disj_starred = true;
+		  d_atom = d_end_atom = NULL;
                 }
             }
         }
-      /* Otherwise, check for presence of exact name specified.  */
       else
+	abort ();
+      if (pipe_p && /* use_pipes */ ! (n_way_matched || disj_matched) )
         {
-          for (i = 0; i < n_switches; i++)
-            {
-              if (!strncmp (switches[i].part1, filter, p - filter)
-                  && switches[i].part1[p - filter] == 0
-                  && check_live_switch (i, -1))
-                {
-                  present = 1;
-                  break;
-                }
+	  /* Here if a %{|...} conditional fails: output a minus sign,
+	     which means "standard output" or "standard input".  */
+	  do_spec_1 ("-", 0, NULL);
             }
         }
+  while (*p++ != '}');
 
-      /* If it is as desired (present for %{s...}, absent for %{!s...})
-         then substitute either the switch or the specified
-         conditional text.  */
-      if (present != negate)
-        {
-          if (elide_switch)
+  return p;
+
+#undef SKIP_WHITE
+}
+
+/* Subroutine of handle_braces.  Scan and process a brace substitution body
+   (X in the description of %{} syntax).  P points one past the colon;
+   ATOM and END_ATOM bracket the first atom which was found to be true
+   (present) in the current disjunction; STARRED indicates whether all
+   the atoms in the current disjunction were starred (for syntax validation);
+   MATCHED indicates whether the disjunction matched or not, and therefore
+   whether or not the body is to be processed through do_spec_1 or just
+   skipped.  Returns a pointer to the closing } or ;, or 0 if do_spec_1
+   returns -1.  */
+
+static const char *
+process_brace_body (const char *p, const char *atom, const char *end_atom,
+		    int starred, int matched)
+{
+  const char *body, *end_body;
+  unsigned int nesting_level;
+  bool have_subst     = false;
+
+  /* Locate the closing } or ;, honoring nested braces.
+     Trim trailing whitespace.  */
+  body = p;
+  nesting_level = 1;
+  for (;;)
             {
-              switches[i].live_cond = SWITCH_IGNORE;
-              switches[i].validated = 1;
-            }
-          else if (ordered || *p == '&')
-            ordered = 1, switches[i].ordering = 1;
+      if (*p == '{')
+	nesting_level++;
           else if (*p == '}')
-            give_switch (i, 0, include_blanks);
-          else
-            /* Even if many alternatives are matched, only output once.  */
-            true_once = 1;
-        }
-      else if (pipe_p)
         {
-          /* Here if a %{|...} conditional fails: output a minus sign,
-             which means "standard output" or "standard input".  */
-          do_spec_1 ("-", 0, NULL);
-          return endbody;
+	  if (!--nesting_level)
+	    break;
         }
-    }
+      else if (*p == ';' && nesting_level == 1)
+	break;
+      else if (*p == '%' && p[1] == '*' && nesting_level == 1)
+	have_subst = true;
+      else if (*p == '\0')
+	abort ();
+      p++;
+    }
+
+  end_body = p;
+  while (end_body[-1] == ' ' || end_body[-1] == '\t')
+    end_body--;
 
-  /* We didn't match; try again.  */
-  if (*p++ == '|')
-    goto next_member;
+  if (have_subst && !starred)
+    abort ();
 
-  if (p[-1] == '&')
+  if (matched)
+    {
+      /* Copy the substitution body to permanent storage and execute it.
+	 If have_subst is false, this is a simple matter of running the
+	 body through do_spec_1...  */
+      char *string = save_string (body, end_body - body);
+      if (!have_subst)
     {
-      body = 0;
-      goto next_ampersand;
+	  if (do_spec_1 (string, 0, NULL) < 0)
+	    return 0;
     }
-
-  if (ordered)
+      else
     {
+	  /* ... but if have_subst is true, we have to process the
+	     body once for each matching switch, with %* set to the
+	     variant part of the switch.  */
+	  unsigned int hard_match_len = end_atom - atom;
       int i;
-      /* Doing this set of switches later preserves their command-line
-         ordering.  This is needed for e.g. -U, -D and -A.  */
+
       for (i = 0; i < n_switches; i++)
-        if (switches[i].ordering == 1)
+	    if (!strncmp (switches[i].part1, atom, hard_match_len)
+		&& check_live_switch (i, hard_match_len))
           {
-            switches[i].ordering = 0;
-            give_switch (i, 0, include_blanks);
+		if (do_spec_1 (string, 0,
+			       &switches[i].part1[hard_match_len]) < 0)
+		  return 0;
+		/* Pass any arguments this switch has.  */
+		give_switch (i, 1);
+		suffix_subst = NULL;
           }
     }
-  /* Process the spec just once, regardless of match count.  */
-  else if (true_once)
-    {
-      if (do_spec_1 (save_string (body, endbody - body - 1),
-                     0, NULL) < 0)
-        return 0;
     }
 
-  return endbody;
+  return p;
 }
 
 /* Return 0 iff switch number SWITCHNUM is obsoleted by a later switch
@@ -6221,9 +6632,7 @@
    with the "no-", similarly for a switch with the "no-" prefix.  */
 
 static int
-check_live_switch (switchnum, prefix_length)
-     int switchnum;
-     int prefix_length;
+check_live_switch (int switchnum, int prefix_length)
 {
   const char *name = switches[switchnum].part1;
   int i;
@@ -6294,16 +6703,10 @@
    the vector of switches gcc received, which is `switches'.
    This cannot fail since it never finishes a command line.
 
-   If OMIT_FIRST_WORD is nonzero, then we omit .part1 of the argument.
-
-   If INCLUDE_BLANKS is nonzero, then we include blanks before each argument
-   of the switch.  */
+   If OMIT_FIRST_WORD is nonzero, then we omit .part1 of the argument.  */
 
 static void
-give_switch (switchnum, omit_first_word, include_blanks)
-     int switchnum;
-     int omit_first_word;
-     int include_blanks;
+give_switch (int switchnum, int omit_first_word)
 {
   if (switches[switchnum].live_cond == SWITCH_IGNORE)
     return;
@@ -6321,7 +6724,6 @@
         {
           const char *arg = *p;
 
-          if (include_blanks)
             do_spec_1 (" ", 0, NULL);
           if (suffix_subst)
             {
@@ -6354,8 +6756,7 @@
    Return the absolute file name found.  If nothing is found, return NAME.  */
 
 static const char *
-find_file (name)
-     const char *name;
+find_file (const char *name)
 {
   char *newname;
 
@@ -6380,14 +6781,11 @@
    limit.  */
 
 static int
-is_directory (path1, path2, linker)
-     const char *path1;
-     const char *path2;
-     int linker;
+is_directory (const char *path1, const char *path2, int linker)
 {
   int len1 = strlen (path1);
   int len2 = strlen (path2);
-  char *path = (char *) alloca (3 + len1 + len2);
+  char *path = alloca (3 + len1 + len2);
   char *cp;
   struct stat st;
 
@@ -6425,8 +6823,7 @@
    the input file named FILENAME.  */
 
 void
-set_input (filename)
-     const char *filename;
+set_input (const char *filename)
 {
   const char *p;
 
@@ -6467,8 +6864,7 @@
 /* On fatal signals, delete all the temporary files.  */
 
 static void
-fatal_error (signum)
-     int signum;
+fatal_error (int signum)
 {
   signal (signum, SIG_DFL);
   delete_failure_queue ();
@@ -6478,16 +6874,15 @@
   kill (getpid (), signum);
 }
 
-extern int main PARAMS ((int, const char *const *));
+extern int main (int, const char **);
 
 int
-main (argc, argv)
-     int argc;
-     const char *const *argv;
+main (int argc, const char **argv)
 {
   size_t i;
   int value;
   int linker_was_run = 0;
+  int num_linker_inputs = 0;
   char *explicit_link_files;
   char *specs_file;
   const char *p;
@@ -6598,18 +6993,11 @@
 
   process_command (argc, argv);
 
-  /* Process DRIVER_SELF_SPECS, adding any new options to the end
-     of the command line.  */
-
-  for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
-    do_self_spec (driver_self_specs[i]);
-
   /* Initialize the vector of specs to just the default.
      This means one element containing 0s, as a terminator.  */
 
-  compilers = (struct compiler *) xmalloc (sizeof default_compilers);
-  memcpy ((char *) compilers, (char *) default_compilers,
-          sizeof default_compilers);
+  compilers = xmalloc (sizeof default_compilers);
+  memcpy (compilers, default_compilers, sizeof default_compilers);
   n_compilers = n_default_compilers;
 
   /* Read specs from a file if there is one.  */
@@ -6627,9 +7015,8 @@
 
   /* We need to check standard_exec_prefix/just_machine_suffix/specs
      for any override of as, ld and libraries.  */
-  specs_file = (char *) alloca (strlen (standard_exec_prefix)
-                                + strlen (just_machine_suffix)
-                                + sizeof ("specs"));
+  specs_file = alloca (strlen (standard_exec_prefix)
+		       + strlen (just_machine_suffix) + sizeof ("specs"));
 
   strcpy (specs_file, standard_exec_prefix);
   strcat (specs_file, just_machine_suffix);
@@ -6637,40 +7024,92 @@
   if (access (specs_file, R_OK) == 0)
     read_specs (specs_file, TRUE);
 
+  /* Process any configure-time defaults specified for the command line
+     options, via OPTION_DEFAULT_SPECS.  */
+  for (i = 0; i < ARRAY_SIZE (option_default_specs); i++)
+    do_option_spec (option_default_specs[i].name,
+		    option_default_specs[i].spec);
+
+  /* Process DRIVER_SELF_SPECS, adding any new options to the end
+     of the command line.  */
+
+  for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
+    do_self_spec (driver_self_specs[i]);
+
 #ifdef GPC
   init_automake_temp_file (argc, argv);
   check_amtmpfile_switch ();
 #endif
 
-  /* If not cross-compiling, look for startfiles in the standard places.
-     Similarly, don't add the standard prefixes if startfile handling
-     will be under control of startfile_prefix_spec.  */
-  if (*cross_compile == '0' && *startfile_prefix_spec == 0)
+  /* If not cross-compiling, look for executables in the standard
+     places.  */
+  if (*cross_compile == '0')
     {
       if (*md_exec_prefix)
         {
           add_prefix (&exec_prefixes, md_exec_prefix, "GCC",
                       PREFIX_PRIORITY_LAST, 0, NULL, 0);
-          add_prefix (&startfile_prefixes, md_exec_prefix, "GCC",
-                      PREFIX_PRIORITY_LAST, 0, NULL, 0);
+	}
         }
 
-      if (*md_startfile_prefix)
-        add_prefix (&startfile_prefixes, md_startfile_prefix, "GCC",
+  /* Process sysroot_suffix_spec.  */
+  if (*sysroot_suffix_spec != 0
+      && do_spec_2 (sysroot_suffix_spec) == 0)
+    {
+      if (argbuf_index > 1)
+        error ("spec failure: more than one arg to SYSROOT_SUFFIX_SPEC.");
+      else if (argbuf_index == 1)
+        target_sysroot_suffix = xstrdup (argbuf[argbuf_index -1]);
+    }
+
+  /* Process sysroot_hdrs_suffix_spec.  */
+  if (*sysroot_hdrs_suffix_spec != 0
+      && do_spec_2 (sysroot_hdrs_suffix_spec) == 0)
+    {
+      if (argbuf_index > 1)
+        error ("spec failure: more than one arg to SYSROOT_HEADERS_SUFFIX_SPEC.");
+      else if (argbuf_index == 1)
+        target_sysroot_hdrs_suffix = xstrdup (argbuf[argbuf_index -1]);
+    }
+
+  /* Look for startfiles in the standard places.  */
+  if (*startfile_prefix_spec != 0
+      && do_spec_2 (startfile_prefix_spec) == 0
+      && do_spec_1 (" ", 0, NULL) == 0)
+    {
+      int ndx;
+      for (ndx = 0; ndx < argbuf_index; ndx++)
+	add_sysrooted_prefix (&startfile_prefixes, argbuf[ndx], "BINUTILS",
                     PREFIX_PRIORITY_LAST, 0, NULL, 1);
+    }
+  /* We should eventually get rid of all these and stick to
+     startfile_prefix_spec exclusively.  */
+  else if (*cross_compile == '0' || target_system_root)
+    {
+      if (*md_exec_prefix)
+	add_sysrooted_prefix (&startfile_prefixes, md_exec_prefix, "GCC",
+			      PREFIX_PRIORITY_LAST, 0, NULL, 1);
+
+      if (*md_startfile_prefix)
+	add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix,
+			      "GCC", PREFIX_PRIORITY_LAST, 0, NULL, 1);
 
       if (*md_startfile_prefix_1)
-        add_prefix (&startfile_prefixes, md_startfile_prefix_1, "GCC",
-                    PREFIX_PRIORITY_LAST, 0, NULL, 1);
+	add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix_1,
+			      "GCC", PREFIX_PRIORITY_LAST, 0, NULL, 1);
 
       /* If standard_startfile_prefix is relative, base it on
          standard_exec_prefix.  This lets us move the installed tree
          as a unit.  If GCC_EXEC_PREFIX is defined, base
-         standard_startfile_prefix on that as well.  */
-      if (IS_ABSOLUTE_PATHNAME (standard_startfile_prefix))
-        add_prefix (&startfile_prefixes, standard_startfile_prefix, "BINUTILS",
+	 standard_startfile_prefix on that as well.
+
+         If the prefix is relative, only search it for native compilers;
+         otherwise we will search a directory containing host libraries.  */
+      if (IS_ABSOLUTE_PATH (standard_startfile_prefix))
+	add_sysrooted_prefix (&startfile_prefixes,
+			      standard_startfile_prefix, "BINUTILS",
                     PREFIX_PRIORITY_LAST, 0, NULL, 1);
-      else
+      else if (*cross_compile == '0')
         {
           if (gcc_exec_prefix)
             add_prefix (&startfile_prefixes,
@@ -6684,34 +7123,15 @@
                       NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
         }
 
-      add_prefix (&startfile_prefixes, standard_startfile_prefix_1,
+      add_sysrooted_prefix (&startfile_prefixes, standard_startfile_prefix_1,
                   "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
-      add_prefix (&startfile_prefixes, standard_startfile_prefix_2,
+      add_sysrooted_prefix (&startfile_prefixes, standard_startfile_prefix_2,
                   "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
 #if 0 /* Can cause surprises, and one can use -B./ instead.  */
       add_prefix (&startfile_prefixes, "./", NULL,
                   PREFIX_PRIORITY_LAST, 1, NULL, 0);
 #endif
     }
-  else
-    {
-      if (!IS_ABSOLUTE_PATHNAME (standard_startfile_prefix)
-          && gcc_exec_prefix)
-        add_prefix (&startfile_prefixes,
-                    concat (gcc_exec_prefix, machine_suffix,
-                            standard_startfile_prefix, NULL),
-                    "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
-    }
-
-  if (*startfile_prefix_spec != 0
-      && do_spec_2 (startfile_prefix_spec) == 0
-      && do_spec_1 (" ", 0, NULL) == 0)
-    {
-      int ndx;
-      for (ndx = 0; ndx < argbuf_index; ndx++)
-        add_prefix (&startfile_prefixes, argbuf[ndx], "BINUTILS",
-                    PREFIX_PRIORITY_LAST, 0, NULL, 1);
-    }
 
   /* Process any user specified specs in the order given on the command
      line.  */
@@ -6865,14 +7285,35 @@
 
   i = n_infiles;
   i += lang_specific_extra_outfiles;
-  outfiles = (const char **) xcalloc (i, sizeof (char *));
+  outfiles = xcalloc (i, sizeof (char *));
 
   /* Record which files were specified explicitly as link input.  */
 
   explicit_link_files = xcalloc (1, n_infiles);
 
+  if (combine_inputs)
+    {
+       int lang_n_infiles = 0;
   for (i = 0; (int) i < n_infiles; i++)
     {
+	   const char *name = infiles[i].name;
+	   struct compiler *compiler
+	     = lookup_compiler (name, strlen (name), infiles[i].language);
+	   if (compiler == NULL)
+	     error ("%s: linker input file unused because linking not done",
+		    name);
+	   else if (lang_n_infiles > 0 && compiler != input_file_compiler)
+	     fatal ("cannot specify -o with -c or -S and multiple languages");
+	   else
+	     {
+	       lang_n_infiles++;
+	       input_file_compiler = compiler;
+	     }
+	 }
+    }
+  
+  for (i = 0; (int) i < (combine_inputs ? 1 : n_infiles); i++)
+    {
       int this_file_error = 0;
 
       /* Tell do_spec what to substitute for %i.  */
@@ -6886,6 +7327,7 @@
 
       /* Figure out which compiler from the file's suffix.  */
 
+      if (! combine_inputs)
       input_file_compiler
         = lookup_compiler (infiles[i].name, input_filename_length,
                            infiles[i].language);
@@ -6941,9 +7383,15 @@
         error_count++;
     }
 
+  /* Determine if there are any linker input files.  */
+  num_linker_inputs = 0;
+  for (i = 0; (int) i < n_infiles; i++)
+    if (explicit_link_files[i] || outfiles[i] != NULL)
+      num_linker_inputs++;
+
   /* Run ld to link all the compiler output files.  */
 
-  if (error_count == 0)
+  if (num_linker_inputs > 0 && error_count == 0)
     {
       int tmp = execution_count;
 
@@ -7000,10 +7448,7 @@
    or 0 if this file is to be passed to the linker.  */
 
 static struct compiler *
-lookup_compiler (name, length, language)
-     const char *name;
-     size_t length;
-     const char *language;
+lookup_compiler (const char *name, size_t length, const char *language)
 {
   struct compiler *cp;
 
@@ -7069,9 +7514,7 @@
 }
 
 static char *
-save_string (s, len)
-     const char *s;
-     int len;
+save_string (const char *s, int len)
 {
   char *result = xmalloc (len + 1);
 
@@ -7081,8 +7524,7 @@
 }
 
 void
-pfatal_with_name (name)
-     const char *name;
+pfatal_with_name (const char *name)
 {
   perror_with_name (name);
   delete_temp_files ();
@@ -7090,16 +7532,13 @@
 }
 
 static void
-perror_with_name (name)
-     const char *name;
+perror_with_name (const char *name)
 {
   error ("%s: %s", name, xstrerror (errno));
 }
 
 static void
-pfatal_pexecute (errmsg_fmt, errmsg_arg)
-     const char *errmsg_fmt;
-     const char *errmsg_arg;
+pfatal_pexecute (const char *errmsg_fmt, const char *errmsg_arg)
 {
   if (errmsg_arg)
     {
@@ -7116,136 +7555,153 @@
   pfatal_with_name (errmsg_fmt);
 }
 
-/* Output an error message and exit */
+/* Output an error message and exit.  */
 
 void
-fancy_abort ()
+fancy_abort (void)
 {
   fatal ("internal gpc abort");
 }
 
-/* Output an error message and exit */
+/* Output an error message and exit.  */
 
 void
-fatal VPARAMS ((const char *msgid, ...))
+fatal (const char *msgid, ...)
 {
-  VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, const char *, msgid);
+  va_list ap;
+
+  va_start (ap, msgid);
 
   fprintf (stderr, "%s: ", programname);
   vfprintf (stderr, _(msgid), ap);
-  VA_CLOSE (ap);
+  va_end (ap);
   fprintf (stderr, "\n");
   delete_temp_files ();
   safe_exit (1);
 }
 
 void
-error VPARAMS ((const char *msgid, ...))
+error (const char *msgid, ...)
 {
-  VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, const char *, msgid);
+  va_list ap;
 
+  va_start (ap, msgid);
   fprintf (stderr, "%s: ", programname);
   vfprintf (stderr, _(msgid), ap);
-  VA_CLOSE (ap);
+  va_end (ap);
 
   fprintf (stderr, "\n");
 }
 
 static void
-notice VPARAMS ((const char *msgid, ...))
+notice (const char *msgid, ...)
 {
-  VA_OPEN (ap, msgid);
-  VA_FIXEDARG (ap, const char *, msgid);
+  va_list ap;
 
+  va_start (ap, msgid);
   vfprintf (stderr, _(msgid), ap);
-  VA_CLOSE (ap);
+  va_end (ap);
+}
+
+static inline void
+validate_switches_from_spec (const char *spec)
+{
+  const char *p = spec;
+  char c;
+  while ((c = *p++))
+    if (c == '%' && (*p == '{' || *p == '<' || (*p == 'W' && *++p == '{')))
+      /* We have a switch spec.  */
+      p = validate_switches (p + 1);
 }
 
 static void
-validate_all_switches ()
+validate_all_switches (void)
 {
   struct compiler *comp;
-  const char *p;
-  char c;
   struct spec_list *spec;
 
   for (comp = compilers; comp->spec; comp++)
-    {
-      p = comp->spec;
-      while ((c = *p++))
-        if (c == '%' && (*p == '{' || (*p == 'W' && *++p == '{')))
-          /* We have a switch spec.  */
-          validate_switches (p + 1);
-    }
+    validate_switches_from_spec (comp->spec);
 
   /* Look through the linked list of specs read from the specs file.  */
   for (spec = specs; spec; spec = spec->next)
-    {
-      p = *(spec->ptr_spec);
-      while ((c = *p++))
-        if (c == '%' && (*p == '{' || (*p == 'W' && *++p == '{')))
-          /* We have a switch spec.  */
-          validate_switches (p + 1);
-    }
+    validate_switches_from_spec (*spec->ptr_spec);
 
-  p = link_command_spec;
-  while ((c = *p++))
-    if (c == '%' && (*p == '{' || (*p == 'W' && *++p == '{')))
-      /* We have a switch spec.  */
-      validate_switches (p + 1);
+  validate_switches_from_spec (link_command_spec);
 }
 
 /* Look at the switch-name that comes after START
    and mark as valid all supplied switches that match it.  */
 
-static void
-validate_switches (start)
-     const char *start;
+static const char *
+validate_switches (const char *start)
 {
   const char *p = start;
-  const char *filter;
+  const char *atom;
+  size_t len;
   int i;
-  int suffix;
+  bool suffix = false;
+  bool starred = false;
 
-  if (*p == '|')
-    ++p;
+#define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
 
 next_member:
+  SKIP_WHITE ();
+
   if (*p == '!')
-    ++p;
+    p++;
 
-  suffix = 0;
+  SKIP_WHITE ();
   if (*p == '.')
-    suffix = 1, ++p;
+    suffix = true, p++;
 
-  filter = p;
-  while (*p != ':' && *p != '}' && *p != '|' && *p != '&')
+  atom = p;
+  while (ISIDNUM (*p) || *p == '-' || *p == '+' || *p == '='
+	 || *p == ',' || *p == '.' || *p == '@')
     p++;
+  len = p - atom;
 
-  if (suffix)
-    ;
-  else if (p[-1] == '*')
+  if (*p == '*')
+    starred = true, p++;
+
+  SKIP_WHITE ();
+
+  if (!suffix)
     {
       /* Mark all matching switches as valid.  */
       for (i = 0; i < n_switches; i++)
-        if (!strncmp (switches[i].part1, filter, p - filter - 1))
+	if (!strncmp (switches[i].part1, atom, len)
+	    && (starred || switches[i].part1[len] == 0))
           switches[i].validated = 1;
     }
-  else
+
+  if (*p) p++;
+  if (*p && (p[-1] == '|' || p[-1] == '&'))
+    goto next_member;
+
+  if (*p && p[-1] == ':')
     {
-      /* Mark an exact matching switch as valid.  */
-      for (i = 0; i < n_switches; i++)
+      while (*p && *p != ';' && *p != '}')
         {
-          if (!strncmp (switches[i].part1, filter, p - filter)
-              && switches[i].part1[p - filter] == 0)
-            switches[i].validated = 1;
+	  if (*p == '%')
+	    {
+	      p++;
+	      if (*p == '{' || *p == '<')
+		p = validate_switches (p+1);
+	      else if (p[0] == 'W' && p[1] == '{')
+		p = validate_switches (p+2);
         }
+	  else
+	    p++;
     }
 
-  if (*p++ == '|' || p[-1] == '&')
+      if (*p) p++;
+      if (*p && p[-1] == ';')
     goto next_member;
+    }
+
+  return p;
+#undef SKIP_WHITE
 }
 
 struct mdswitchstr
@@ -7261,9 +7717,7 @@
    canonicalize the switches to keep only the ones we care about.  */
 
 static int
-used_arg (p, len)
-     const char *p;
-     int len;
+used_arg (const char *p, int len)
 {
   struct mswitchstr
   {
@@ -7289,8 +7743,7 @@
         if (*q == ';')
           cnt++;
 
-      matches =
-        (struct mswitchstr *) alloca ((sizeof (struct mswitchstr)) * cnt);
+      matches = alloca ((sizeof (struct mswitchstr)) * cnt);
       i = 0;
       q = multilib_matches;
       while (*q != '\0')
@@ -7322,8 +7775,7 @@
          xmalloc from calling fatal, and prevents us from re-executing this
          block of code.  */
       mswitches
-        = (struct mswitchstr *)
-          xmalloc (sizeof (struct mswitchstr)
+	= xmalloc (sizeof (struct mswitchstr)
                    * (n_mdswitches + (n_switches ? n_switches : 1)));
       for (i = 0; i < n_switches; i++)
         {
@@ -7401,9 +7853,7 @@
 }
 
 static int
-default_arg (p, len)
-     const char *p;
-     int len;
+default_arg (const char *p, int len)
 {
   int i;
 
@@ -7426,7 +7876,7 @@
    will be used.  */
 
 static void
-set_multilib_dir ()
+set_multilib_dir (void)
 {
   const char *p;
   unsigned int this_path_len;
@@ -7452,9 +7902,7 @@
     {
       int i = 0;
 
-      mdswitches
-        = (struct mdswitchstr *) xmalloc (sizeof (struct mdswitchstr)
-                                          * n_mdswitches);
+      mdswitches = xmalloc (sizeof (struct mdswitchstr) * n_mdswitches);
       for (start = multilib_defaults; *start != '\0'; start = end + 1)
         {
           while (*start == ' ' || *start == '\t')
@@ -7661,7 +8109,7 @@
    the exclusions.  */
 
 static void
-print_multilib_info ()
+print_multilib_info (void)
 {
   const char *p = multilib_select;
   const char *last_path = 0, *this_path;
@@ -7909,12 +8357,10 @@
    (whose name has been expanded with %s).  */
 
 static const char *
-if_exists_spec_function (argc, argv)
-     int argc;
-     const char **argv;
+if_exists_spec_function (int argc, const char **argv)
 {
   /* Must have only one argument.  */
-  if (argc == 1 && IS_ABSOLUTE_PATHNAME (argv[0]) && ! access (argv[0], R_OK))
+  if (argc == 1 && IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
     return argv[0];
 
   return NULL;
@@ -7926,15 +8372,13 @@
    is returned if the first argument does not exist.  */
 
 static const char *
-if_exists_else_spec_function (argc, argv)
-     int argc;
-     const char **argv;
+if_exists_else_spec_function (int argc, const char **argv)
 {
   /* Must have exactly two arguments.  */
   if (argc != 2)
     return NULL;
 
-  if (IS_ABSOLUTE_PATHNAME (argv[0]) && ! access (argv[0], R_OK))
+  if (IS_ABSOLUTE_PATH (argv[0]) && ! access (argv[0], R_OK))
     return argv[0];
 
   return argv[1];
@@ -7978,7 +8422,7 @@
     }
   if (!new_argc)
     return;
-  argv = (const char **) xmalloc ((argc + new_argc + 1) * sizeof (const char *));
+  argv = (const char **) xmalloc ((argc + new_argc+1) * sizeof (const char *));
   memcpy (argv, *argvp, argc * sizeof (const char *));
   memcpy (argv + argc, new_argv, new_argc * sizeof (const char *));
   argv [argc + new_argc] = NULL;
@@ -8236,7 +8680,7 @@
 {
   printf("\
 GNU Pascal version %s, based on gcc-%s.\n\
-Copyright (C) 1987-2004 Free Software Foundation, Inc.\n\
+Copyright (C) 1987-2003 Free Software Foundation, Inc.\n\
 \n\
 GNU Pascal is free software; you can redistribute it and/or modify\n\
 it under the terms of the GNU General Public License as published by\n\
@@ -8359,6 +8803,7 @@
 }
 #endif
 
+#ifndef GCC_3_4
 #ifndef HAVE_PUTENV
 void
 putenv (str)
@@ -8398,6 +8843,7 @@
          sizeof (char *) * (num_envs+1));
 }
 #endif
+#endif
 
 #ifndef EGCS
 /* We need to provide a type for gcc_uint64_t.  */
diff -ru gpc-20040516.orig/p/gpc.h gpc-20040516/p/gpc.h
--- gpc-20040516.orig/p/gpc.h	2004-05-12 17:05:19.000000000 +0200
+++ gpc-20040516/p/gpc.h	2004-07-06 19:12:30.000000000 +0200
@@ -166,10 +166,16 @@
 };
 #undef DEFTREECODE
 
+#ifndef GCC_3_4
 #define NUMBER_OF_OPERANDS(code) \
   (((code) == SAVE_EXPR || (code) == WITH_CLEANUP_EXPR) ? 1 \
   : ((code) == METHOD_CALL_EXPR) ? 3 \
   : tree_code_length[(int) (code)])
+#else
+#define NUMBER_OF_OPERANDS(code) \
+  (((code) == SAVE_EXPR || (code) == WITH_CLEANUP_EXPR) ? 1 \
+  : tree_code_length[(int) (code)])
+#endif
 
 typedef HOST_WIDE_INT gpi_int;
 
@@ -188,9 +194,12 @@
 #define INTERFACE_TABLE(NODE)    (AS_INTERFACE_NAME_NODE (NODE)->table)
 #define INTERFACE_CHECKSUM(NODE) (AS_INTERFACE_NAME_NODE (NODE)->checksum)
 
+typedef enum {IMPORT_USES, IMPORT_QUALIFIED, IMPORT_ISO} import_type;
+
 struct tree_import GTY(())
 {
   struct tree_common common;
+  gpi_int qualified;
   tree interface;
   tree import_qualifier;
   tree filename;
@@ -198,6 +207,7 @@
 };
 #define AS_IMPORT_NODE(NODE) ((struct tree_import *) IMPORT_NODE_CHECK (NODE))
 #define IMPORT_INTERFACE(NODE) (AS_IMPORT_NODE (NODE)->interface)
+#define PASCAL_TREE_QUALIFIED(NODE) (AS_IMPORT_NODE (NODE)->qualified)
 #define IMPORT_QUALIFIER(NODE) (AS_IMPORT_NODE (NODE)->import_qualifier)
 #define IMPORT_FILENAME(NODE) (AS_IMPORT_NODE (NODE)->filename)
 
@@ -359,7 +369,7 @@
 #define PASCAL_TREE_IGNORABLE(t) TREE_LANG_FLAG_2 (t)
 
 /* `Qualified' import. Used in IMPORT_NODE nodes. */
-#define PASCAL_TREE_QUALIFIED(t) TREE_LANG_FLAG_2 (t)
+/* #define PASCAL_TREE_QUALIFIED(t) TREE_LANG_FLAG_2 (t) */
 
 /* Set if the parameter is a value parameter passed by reference.
    This is necessary for undiscriminated strings/schemata and
@@ -411,9 +421,19 @@
 /* Set for `const' parameters. Used in *_TYPE and some TREE_LIST nodes. */
 #define PASCAL_CONST_PARM(type) TREE_LANG_FLAG_6 (type)
 
+/* Set if identifier is a qualified identifer (only for identifiers) */
+#define PASCAL_QUALIFIED_ID(id) TREE_LANG_FLAG_6 (id)
+
 /* GPC specific decl node extensions. */
 
-/* Decl flags 0, 1, 2 are still available. */
+/* Decl flag 0 is still available. */
+
+/* Set for declarations imported from other modules/units */
+#define PASCAL_DECL_IMPORTED(NODE) DECL_LANG_FLAG_1 (NODE)
+
+/* Set if declaration is imported via `uses' (so it can be 
+   overriden). */
+#define PASCAL_DECL_WEAK(NODE) DECL_LANG_FLAG_2 (NODE)
 
 /* Borland Pascal allows a "typed constant" to be used as an initialized
    variable and does not even warn if a value is written to it (because
@@ -459,6 +479,10 @@
    Used in VAR_DECL nodes. */
 #define PASCAL_FOR_LOOP_COUNTER(decl) DECL_LANG_FLAG_7 (decl)
 
+/* Set if a declaration represents principal identifier of a constant
+   (see EP 6.10.2) */
+#define PASCAL_CST_PRINCIPAL_ID(decl) DECL_LANG_FLAG_7 (decl)
+
 struct lang_decl GTY(())
 {
   tree info;
@@ -1021,7 +1045,11 @@
 extern int is_pascal_option PARAMS ((const char *));
 extern int process_pascal_directive PARAMS ((char *, int));
 extern void activate_options PARAMS ((struct options *, int));
+#ifndef GCC_3_4
 extern void pascal_init_options PARAMS ((void));
+#else
+extern unsigned int pascal_init_options (unsigned int argc, const char **argv);
+#endif
 extern void do_deferred_options PARAMS ((void));
 extern void error_or_warning PARAMS ((int, const char *));
 extern void dialect_msg PARAMS ((int, unsigned long, const char *, const char *, const char *));
@@ -1096,12 +1124,16 @@
 extern void set_block PARAMS ((tree));
 extern void check_duplicate_id PARAMS ((tree));
 extern tree lookup_name PARAMS ((tree));
+extern tree lookup_name_current_level PARAMS ((tree));
 extern void set_identifier_spelling PARAMS ((tree, const char *, const char *, int));
 extern tree make_identifier PARAMS ((const char *, int));
 extern tree get_identifier_with_spelling PARAMS ((const char *, const char *));
 extern tree get_unique_identifier PARAMS ((const char *));
+extern tree build_qualified_id PARAMS ((tree, tree));
+extern tree build_qualified_or_component_acces PARAMS ((tree, tree));
 extern tree check_identifier PARAMS ((tree));
 extern tree de_capitalize PARAMS ((tree));
+extern tree pascal_mangle_names PARAMS ((const char *, const char *));
 extern tree build_formal_param PARAMS ((tree, tree, int, int));
 extern tree build_procedural_type PARAMS ((tree, tree));
 extern tree build_formal_param_list PARAMS ((tree));
@@ -1110,6 +1142,7 @@
 extern void pushlevel_expand PARAMS ((void));
 extern tree poplevel_expand PARAMS ((int, int));
 extern tree pushdecl PARAMS ((tree));
+extern tree pushdecl_import PARAMS ((tree, int));
 extern tree pushdecl_nocheck PARAMS ((tree));
 extern void pushlevel PARAMS ((int));
 extern tree start_struct PARAMS ((enum tree_code));
@@ -1233,6 +1266,7 @@
 extern tree check_set_bounds PARAMS ((tree, tree));
 extern tree build_set_type PARAMS ((tree, int));
 extern tree pascal_build_set_type PARAMS ((tree));
+extern tree build_pascal_pointer_type PARAMS ((tree));
 extern tree convert_to_cstring PARAMS ((tree));
 extern tree string_may_be_char PARAMS ((tree, int));
 extern tree char_may_be_string PARAMS ((tree));
@@ -1369,7 +1403,7 @@
 extern void start_module_interface PARAMS ((void));
 extern void start_unit_implementation PARAMS ((void));
 extern void finalize_module PARAMS ((int));
-extern void import_interface PARAMS ((tree, tree, int, tree));
+extern void import_interface PARAMS ((tree, tree, import_type, tree));
 extern void export_interface PARAMS ((tree, tree));
 extern void do_extra_import PARAMS ((void));
 extern int is_gpi_special_node PARAMS ((tree));
@@ -1394,9 +1428,13 @@
 extern void yyerror PARAMS ((const char *));
 extern void yyerror_id PARAMS ((tree, const YYLTYPE *));
 extern int peek_token PARAMS ((int));
+extern void set_old_input_filename PARAMS ((const char *));
 extern int yylex PARAMS ((void));
-extern void init_lex PARAMS ((void));
+extern void pascal_init_lex PARAMS ((const char *));
 extern void discard_input PARAMS ((void));
+#ifdef GCC_3_4
+extern FILE * finput;
+#endif
 
 /* Put all global tree node variables here (don't use static ones) */
 
@@ -1405,7 +1443,9 @@
 /* Types */
 #define byte_integer_type_node PGT(0)
 #define byte_unsigned_type_node PGT(1)
+#ifndef GCC_3_4
 #define boolean_type_node PGT(2)
+#endif
 #define cboolean_type_node PGT(3)
 #define byte_boolean_type_node PGT(4)
 #define short_boolean_type_node PGT(5)
@@ -1418,7 +1458,9 @@
 #define pascal_size_type_node PGT(12)
 #define ptrsize_unsigned_type_node PGT(13)
 #define ptrsize_integer_type_node PGT(14)
+#ifndef GCC_3_4
 #define integer_ptr_type_node PGT(15)
+#endif
 #define untyped_file_type_node PGT(16)
 #define text_type_node PGT(17)
 #define any_file_type_node PGT(18)
@@ -1437,8 +1479,10 @@
 
 /* Constants */
 #define integer_maxint_node PGT(31)
+#ifndef GCC_3_4
 #define boolean_false_node PGT(32)
 #define boolean_true_node PGT(33)
+#endif
 #define char_max_node PGT(34)
 #define real_max_node PGT(35)
 #define real_min_node PGT(36)
diff -ru gpc-20040516.orig/p/gpc-lex.c gpc-20040516/p/gpc-lex.c
--- gpc-20040516.orig/p/gpc-lex.c	2004-05-15 01:43:11.000000000 +0200
+++ gpc-20040516/p/gpc-lex.c	2004-07-06 19:08:51.000000000 +0200
@@ -27,10 +27,6 @@
 #include "gpc.h"
 #undef FLEX_SCANNER
 
-#ifdef MULTIBYTE_CHARS
-#include <locale.h>
-#endif
-
 #define LEX_SEMANTIC_VALUES 1
 #define LEX_INVALID (-1)
 #define LEX_WHITESPACE (-1)
@@ -211,28 +207,23 @@
   while (getc (finput) != EOF) ;
 }
 
-/* Initialize the lexical analyzer. */
+#ifndef EGCS 
 void
 init_lex ()
 {
-#ifndef EGCS  /* otherwise done in lang_init */
-  add_pascal_tree_codes ();
-#endif
-
-#ifndef EGCS97
-  /* Make identifier nodes long enough for the language-specific slots. */
-  set_identifier_size (sizeof (struct lang_identifier));
+  /* Empty, required by 2.8.1 */
+}
 #endif
 
+/* Initialize the lexical analyzer. */
+void
+pascal_init_lex (filename)
+     const char * filename;
+{
   /* Start it at 0, because check_newline is called at the very beginning
      and will increment it to 1. */
   lineno = 0;
 
-#ifdef MULTIBYTE_CHARS
-  /* Change to the native locale for multibyte conversions. */
-  setlocale (LC_CTYPE, "");
-#endif
-
 #ifdef HAVE_SIGALRM
   /* Periodically trigger the output of progress messages. */
   if (flag_progress_messages || flag_progress_bar)
@@ -247,7 +238,7 @@
     }
 #endif
 
-  InitLex ("???", finput, 0);
+  InitLex (filename, finput, 0);
 }
 
 static void
@@ -301,23 +292,40 @@
   process_pascal_directive (s, q - s);
 }
 
+char * old_input_filename;
+
+void set_old_input_filename (s)
+     const char * s;
+{
+  old_input_filename = save_string(s);
+}
+
 void
 SetFileName (v)
      int v;
 {
   input_filename = NewPos.SrcName;
+#ifndef EGCS97
   if (!main_input_filename)
     main_input_filename = input_filename;
+#endif
   if (v == 1)
     {
       /* Pushing to a new file. */
       struct file_stack *p = (struct file_stack *) xmalloc (sizeof (struct file_stack));
+#ifndef GCC_3_4
       input_file_stack->line = LexPos.Line;
-      p->next = input_file_stack;
       p->name = input_filename;
+#else
+      p->location.line = LexPos.Line;
+      p->location.file = old_input_filename;
+#endif
+      p->next = input_file_stack;
       input_file_stack = p;
       input_file_stack_tick++;
 #ifdef EGCS97
+      /* Can use backend only afer initialization (see err1.pas) */
+      if (main_input_filename)
       (*debug_hooks->start_source_file) (LexPos.Line, input_filename);
 #else
       debug_start_source_file (input_filename);
@@ -326,26 +334,41 @@
   else if (v == 2)
     {
       /* Popping out of a file. */
+#ifndef GCC_3_4
       if (input_file_stack->next)
+#else
+      if (input_file_stack)
+#endif
         {
           struct file_stack *p = input_file_stack;
           input_file_stack = p->next;
-          free (p);
           input_file_stack_tick++;
 #ifdef EGCS97
+#ifndef GCC_3_4
           (*debug_hooks->end_source_file) (input_file_stack->line);
 #else
+          (*debug_hooks->end_source_file) (p->location.line);
+#endif
+#else
           debug_end_source_file (input_file_stack->line);
 #endif
+          free (p);
         }
       else
         error ("#-lines for entering and leaving files don't match");
     }
-
+#ifdef EGCS97
+  if (!main_input_filename)
+    main_input_filename = input_filename;
+#endif
   /* Now that we've pushed or popped the input stack,
      update the name in the top element. */
+#ifndef GCC_3_4
   if (input_file_stack)
     input_file_stack->name = input_filename;
+#else
+  old_input_filename = input_filename;
+#endif
 }
 
 /* Hooks for parse.y: error handling. */
@@ -356,14 +379,28 @@
   const char *s = LexSem.TokenString;
   char buf[200];
   syntax_errors++;
+#ifndef GCC_3_4
   strcpy (buf, string);
+#else
+  strcpy (buf, "%H");
+  strcat (buf, string);
+#endif
   if (!s)
     strcat (buf, " at end of input");
   else if (s[0] < 0x20 || (unsigned char) s[0] >= 0x7f)
     sprintf (buf + strlen (buf), " before character #%i", (unsigned char) s[0]);
   else
     strcat (buf, " before `%s'");
+#ifndef GCC_3_4
   error_with_file_and_line (lexer_filename, lexer_lineno, buf, s);
+#else
+  {
+    location_t loc_aux;
+    loc_aux.file = lexer_filename;
+    loc_aux.line = lexer_lineno;
+    error (buf, &loc_aux, s);
+  }
+#endif
 }
 
 void
@@ -372,8 +409,17 @@
      const YYLTYPE *location;
 {
   syntax_errors++;
+#ifndef GCC_3_4
   error_with_file_and_line (location->last_file, location->last_line,
                             "syntax error before `%s'", IDENTIFIER_NAME (id));
+#else
+  {
+    location_t loc_aux;
+    loc_aux.file = location->last_file;
+    loc_aux.line = location->last_line;
+    error ("%Hsyntax error before `%s'", &loc_aux, IDENTIFIER_NAME (id));
+  }
+#endif
 }
 
 static int get_token PARAMS ((void));
diff -ru gpc-20040516.orig/p/gpcpp.c gpc-20040516/p/gpcpp.c
--- gpc-20040516.orig/p/gpcpp.c	2004-01-01 00:07:10.000000000 +0100
+++ gpc-20040516/p/gpcpp.c	2004-07-06 19:08:51.000000000 +0200
@@ -5763,16 +5763,10 @@
 
 /* Print error message and increment count of errors. */
 static void
-error VPARAMS ((const char *msg, ...))
+error (const char *msg, ...)
 {
-#ifndef ANSI_PROTOTYPES
-  const char *msg;
-#endif
   va_list args;
-  VA_START (args, msg);
-#ifndef ANSI_PROTOTYPES
-  msg = va_arg (ap, const char *);
-#endif
+  va_start (args, msg);
   verror (msg, args);
   va_end (args);
 }
@@ -5818,16 +5812,10 @@
 
 /* Print warning. */
 static void
-warning VPARAMS ((const char *msg, ...))
+warning (const char *msg, ...)
 {
-#ifndef ANSI_PROTOTYPES
-  const char *msgid;
-#endif
   va_list args;
-  VA_START (args, msg);
-#ifndef ANSI_PROTOTYPES
-  msg = va_arg (ap, const char *);
-#endif
+  va_start (args, msg);
   vwarning (msg, args);
   va_end (args);
 }
@@ -5857,20 +5845,12 @@
 }
 
 static void
-error_with_line VPARAMS ((int line, const char *msg, ...))
+error_with_line (int line, const char *msg, ...)
 {
   int i;
   FILE_BUF *ip = NULL;
-#ifndef ANSI_PROTOTYPES
-  int line;
-  const char *msgid;
-#endif
   va_list args;
-  VA_START (args, msg);
-#ifndef ANSI_PROTOTYPES
-  line = va_arg (ap, int);
-  msg = va_arg (ap, const char *);
-#endif
+  va_start (args, msg);
   print_containing_files ();
   for (i = indepth; i >= 0; i--)
     if (instack[i].fname != NULL) {
@@ -5887,16 +5867,10 @@
 
 /* Print an error or warning message. */
 static void
-pedwarn VPARAMS ((const char *msg, ...))
+pedwarn (const char *msg, ...)
 {
-#ifndef ANSI_PROTOTYPES
-  const char *msgid;
-#endif
   va_list args;
-  VA_START (args, msg);
-#ifndef ANSI_PROTOTYPES
-  msg = va_arg (ap, const char *);
-#endif
+  va_start (args, msg);
   if (pedantic_errors)
     verror (msg, args);
   else
@@ -5907,13 +5881,8 @@
 /* Report a warning (or an error if pedantic_errors)
    giving specified file name and line number, not current. */
 static void
-pedwarn_with_file_and_line VPARAMS ((const char *file, int line, const char *msg, ...))
+pedwarn_with_file_and_line (const char *file, int line, const char *msg, ...)
 {
-#ifndef ANSI_PROTOTYPES
-  const char *file;
-  int line;
-  const char *msgid;
-#endif
   va_list args;
   if (!pedantic_errors && inhibit_warnings)
     return;
@@ -5923,12 +5892,7 @@
     errors++;
   if (!pedantic_errors)
     fprintf (stderr, "warning: ");
-  VA_START (args, msg);
-#ifndef ANSI_PROTOTYPES
-  file = va_arg (ap, const char *);
-  line = va_arg (ap, int);
-  msg = va_arg (ap, const char *);
-#endif
+  va_start (args, msg);
   vfprintf (stderr, msg, args);
   va_end (args);
   fprintf (stderr, "\n");
@@ -6368,17 +6332,11 @@
 static
 #endif
 void
-fatal VPARAMS ((const char *msg, ...))
+fatal (const char *msg, ...)
 {
   va_list args;
-#ifndef ANSI_PROTOTYPES
-  const char *msgid;
-#endif
   fprintf (stderr, "%s: ", progname);
-  VA_START (args, msg);
-#ifndef ANSI_PROTOTYPES
-  msgid = va_arg (ap, const char *);
-#endif
+  va_start (args, msg);
   vfprintf (stderr, msg, args);
   va_end (args);
   fprintf (stderr, "\n");
diff -ru gpc-20040516.orig/p/lang.c gpc-20040516/p/lang.c
--- gpc-20040516.orig/p/lang.c	2004-05-15 01:37:50.000000000 +0200
+++ gpc-20040516/p/lang.c	2004-07-06 22:55:02.000000000 +0200
@@ -201,32 +201,7 @@
     }
 }
 
-#ifdef GCC_3_3
-#define error_function_changed() (last_error_function != current_function_decl)
-#define record_last_error_function() (last_error_function = current_function_decl)
-static tree last_error_function = NULL;
-#endif
-
 /* Our function to print out name of current routine that caused an error. */
-#ifdef EGCS97
-
-/* @@ Why is this function static in ../diagnostic.c? */
-static void output_buffer_to_stream PARAMS ((output_buffer *));
-static void
-output_buffer_to_stream (buffer)
-     output_buffer *buffer;
-{
-  const char *text = output_finalize_message (buffer);
-  fputs (text, output_buffer_attached_stream (buffer));
-  output_clear_message_text (buffer);
-}
-
-static void pascal_print_error_function PARAMS ((diagnostic_context *, const char *));
-static void
-pascal_print_error_function (context, file)
-     diagnostic_context *context;
-     const char *file;
-#else
 #define error_function_changed() (last_error_function != current_function_decl)
 #define record_last_error_function() (last_error_function = current_function_decl)
 #define output_add_string(X, S) fprintf (stderr, S)
@@ -236,6 +211,13 @@
 #define _(S) S
 #endif
 static tree last_error_function = NULL;
+#ifdef EGCS97
+static void pascal_print_error_function PARAMS ((diagnostic_context *, const char *));
+static void
+pascal_print_error_function (context, file)
+     diagnostic_context *context;
+     const char *file;
+#else
 static void pascal_print_error_function PARAMS ((const char *));
 static void
 pascal_print_error_function (file)
@@ -244,17 +226,8 @@
 {
   if (error_function_changed ())
     {
-#ifdef EGCS97
-      char *prefix = file ? ACONCAT ((file, ": ", NULL)) : NULL;
-#ifndef GCC_3_3
-      output_state os;
-      os = output_buffer_state (context);
-#endif
-      output_set_prefix ((output_buffer *) context, prefix);
-#else
       if (file)
         fprintf (stderr, "%s: ", file);
-#endif
       if (!current_function_decl || EM (current_function_decl))
         output_add_string ((output_buffer *) context, _("At top level:"));
       else
@@ -297,20 +270,16 @@
         }
       output_add_newline ((output_buffer *) context);
       record_last_error_function ();
-#ifdef EGCS97
-      output_buffer_to_stream ((output_buffer *) context);
-#ifndef GCC_3_3
-      output_buffer_state (context) = os;
-#endif
-#endif
     }
 }
 
+#ifndef EGCS97
 void
 lang_init_options ()
 {
   pascal_init_options ();
 }
+#endif
 
 #ifndef GCC_3_3
 /* Tree code classes. */
@@ -433,6 +402,29 @@
   fprintf (stderr, "-D%s -D__%s -D__%s__ ", s, s, s);
 }
 
+int 
+c_lex (t)
+    tree * t;
+{
+     return 0;
+}
+
+void
+cpp_define (r, s)
+     void * r;
+     const char * s;
+{
+  builtin_define_std (s);
+} 
+
+void
+cpp_assert (pfile, str)
+     void *pfile;
+     const char *str;
+{
+}
+
+
 #define preprocessing_asm_p() 0
 #define preprocessing_trad_p() 0
 #define c_language (-1)
@@ -442,6 +434,80 @@
 #define flag_isoc99 0
 #endif
 
+#ifdef GCC_3_4
+#include "options.h"
+#include "opts.h"
+
+static int saved_lineno;
+static char * saved_filename = 0;
+
+bool
+pascal_post_options (const char **pfilename)
+{
+  char * filename = num_in_fnames>0?in_fnames[0]: 0 /* "-" */;
+#if 1
+  filename = init_parse (filename);
+  /* The beginning of the file is a new line; check for `#'.
+     With luck, we discover the real source file's name from that
+     and put it in input_filename. */
+  main_input_filename = 0;
+  lineno = 1;
+  /* With luck, we discover the real source file name from a line directive
+     at the beginning of the file and put it in input_filename. */
+  set_old_input_filename (filename?filename:"???");
+  peek_token (0);
+  saved_lineno = lineno;
+
+  lineno = 0;
+  *pfilename = main_input_filename?main_input_filename:filename;
+#else
+  *pfilename = dump_base_name?dump_base_name:filename;
+#endif
+  saved_filename = filename;
+  return false;
+}
+
+pascal_handle_option (size_t scode, const char *arg, int value)
+{
+  enum opt_code code = (enum opt_code) scode;
+  const char * pp[2];
+  switch (code)
+    {
+    default:
+      break;
+      assert (0);
+#include "handle-opts.c"
+    }
+  return 1;
+}
+
+static size_t pascal_tree_size (enum tree_code);
+static size_t
+pascal_tree_size (enum tree_code code)
+{
+  switch (code)
+    {
+    case INTERFACE_NAME_NODE: return sizeof (struct tree_inn);
+    case IMPORT_NODE: return sizeof (struct tree_import);
+    default:
+      assert (0);
+    }
+  /* NOTREACHED */
+}
+
+
+bool
+lang_init_3_4 (void)
+{
+  if (saved_filename) {
+    lang_init (saved_filename);
+  } else {
+    lang_init (main_input_filename);
+  }
+  return true;
+}
+#endif
+
 #ifdef EGCS97
 const char *
 lang_init (filename)
@@ -459,9 +525,17 @@
      So we just turn it off here. */
   debug_no_type_hash = 1;
 
+#ifndef EGCS
+  pascal_init_lex (input_filename);
+#endif
+
 #ifdef EGCS97
   init_decl_processing ();
+
+#ifndef GCC_3_4
   filename = init_parse (filename);
+#endif
+
 #ifndef GCC_3_3
   decl_printable_name = pascal_decl_name;
 #endif
@@ -507,9 +581,12 @@
 /* @@ Backend bug: TARGET_OS_CPP_BUILTINS on some targets uses it
       though it's a C specific flag. */
 #define flag_iso 1
-
-      TARGET_CPU_CPP_BUILTINS ();
-      TARGET_OS_CPP_BUILTINS ();
+      {
+        extern void rs6000_cpu_cpp_builtins PARAMS ((void *));
+        void * pfile = 0;
+        TARGET_CPU_CPP_BUILTINS ();
+        TARGET_OS_CPP_BUILTINS ();
+      }
 #endif
       /* The following is no joke! The difference between what the
          preprocessor and the compiler think of BYTES_BIG_ENDIAN is
@@ -543,17 +620,15 @@
     }
 #endif
 
-#ifdef EGCS
-  /* In gcc-2.8.1, init_tree_codes() has not been called yet.
-     Do it in init_lex instead. */
 #ifndef GCC_3_3
   add_pascal_tree_codes ();
 #endif
-#endif
 
+#ifndef GCC_3_4
   /* With luck, we discover the real source file name from a line directive
      at the beginning of the file and put it in input_filename. */
   peek_token (0);
+#endif
 
 #ifdef EGCS97
   if (main_input_filename)
@@ -678,7 +753,7 @@
   setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
 #endif
 #endif
-  init_lex ();
+  pascal_init_lex (filename);
 #if USE_CPPLIB
   yy_cur = "\n";
   yy_lim = yy_cur + 1;
@@ -1115,7 +1190,17 @@
 #undef LANG_HOOKS_NAME
 #define LANG_HOOKS_NAME "GNU Pascal"
 #undef LANG_HOOKS_INIT
+#ifndef GCC_3_4
 #define LANG_HOOKS_INIT lang_init
+#else
+#define LANG_HOOKS_INIT lang_init_3_4
+#undef LANG_HOOKS_TREE_SIZE
+#define LANG_HOOKS_TREE_SIZE pascal_tree_size
+#undef LANG_HOOKS_HANDLE_OPTION
+#define LANG_HOOKS_HANDLE_OPTION pascal_handle_option
+#undef LANG_HOOKS_POST_OPTIONS
+#define LANG_HOOKS_POST_OPTIONS pascal_post_options
+#endif
 #undef LANG_HOOKS_DECODE_OPTION
 #define LANG_HOOKS_DECODE_OPTION lang_decode_option
 #undef LANG_HOOKS_INIT_OPTIONS
@@ -1157,6 +1242,9 @@
 #undef LANG_HOOKS_COMMON_ATTRIBUTE_TABLE
 #define LANG_HOOKS_COMMON_ATTRIBUTE_TABLE gpc_attribute_table
 
+#undef LANG_HOOKS_HASH_TYPES
+#define LANG_HOOKS_HASH_TYPES false
+
 static void
 pascal_parse (debug)
      int debug;
Only in gpc-20040516/p: lang.c.orig
diff -ru gpc-20040516.orig/p/lang.opt gpc-20040516/p/lang.opt
--- gpc-20040516.orig/p/lang.opt	2004-07-06 19:20:23.000000000 +0200
+++ gpc-20040516/p/lang.opt	2004-07-06 19:08:51.000000000 +0200
@@ -0,0 +1,474 @@
+; Options for the Pascal front end.
+; Copyright (C) 2003 Free Software Foundation, Inc.
+;
+; This file is part of GCC.
+;
+; GCC is free software; you can redistribute it and/or modify it under
+; the terms of the GNU General Public License as published by the Free
+; Software Foundation; either version 2, or (at your option) any later
+; version.
+; 
+; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+; for more details.
+; 
+; You should have received a copy of the GNU General Public License
+; along with GCC; see the file COPYING.  If not, write to the Free
+; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+; 02111-1307, USA.
+
+; See c.opt for a description of this file's format.
+
+; Please try to keep this file in ASCII collating order.
+
+Language
+Pascal
+
+famtmpfile=
+Pascal Joined RejectNegative
+(Internal switch used for automake)
+
+fassertions
+Pascal
+Enable assertion checking (default)
+
+fautobuild
+Pascal
+Automatically compile all units/modules/`{$L ...}' files and link the object files provided
+
+fautolink
+Pascal
+Automatically link object files provided by units/modules or `{$L ...}' (default)
+
+fautomake-gcc=
+Pascal Joined RejectNegative
+Set the C compiler invoked by automake
+
+fautomake-g++=
+Pascal Joined RejectNegative
+Set the C++ compiler invoked by automake
+
+fautomake-gpc=
+Pascal Joined RejectNegative
+Set the Pascal compiler invoked by automake
+
+fautomake
+Pascal
+Automatically compile changed units/modules/`{$L ...}' files and link the object files provided
+
+fbig-endian
+Pascal RejectNegative
+Tell GPC that the system is big-endian (for those targets where it can vary)
+
+fborland-pascal
+Pascal RejectNegative
+Try to emulate Borland Pascal, version 7.0
+
+fcidefine=
+Pascal Joined RejectNegative
+Define a case-insensitive macro
+
+fclassic-pascal-level-0
+Pascal RejectNegative
+Reject conformant arrays and anything besides ISO 7185 Pascal
+
+fclassic-pascal
+Pascal RejectNegative
+Reject anything besides ISO 7185 Pascal
+
+fcsdefine=
+Pascal Joined RejectNegative
+Define a case-sensitive macro
+
+fcstrings-as-strings
+Pascal
+Treat CStrings as strings
+
+fdebug-automake
+Pascal RejectNegative
+(For GPC developers.) Give additional information about the actions of automake
+
+fdebug-gpi
+Pascal RejectNegative
+(For GPC developers.) Show what is written to and read from GPI files (huge output!)
+
+fdebug-info
+Pascal
+Inhibit `-g' options (temporary work-around, this option may disappear in the future)
+
+fdebug-source
+Pascal RejectNegative
+Output the source while it is processed
+
+fdebug-tree=
+Pascal Joined RejectNegative
+(For GPC developers.) Show the internal representation of a given tree node (name or address)
+
+fdefault-paths
+Pascal
+Do not add a default path to the unit and object path
+
+fdelphi-comments
+Pascal
+Allow Delphi style `//' comments (default)
+
+fdelphi
+Pascal RejectNegative
+Try to emulate Borland Pascal, version 7.0, with some Delphi extensions
+
+fdisable-keyword=
+Pascal Joined RejectNegative
+Disable a keyword, independently of dialect defaults
+
+fdouble-quoted-strings
+Pascal
+Allow strings enclosed in \"\" (default)
+
+fenable-keyword=
+Pascal Joined RejectNegative
+Enable a keyword, independently of dialect defaults
+
+fexact-compare-strings
+Pascal
+Do not blank-pad strings for comparisons
+
+fexecutable-file-name=
+Pascal Joined RejectNegative
+
+
+fexecutable-file-name
+Pascal RejectNegative
+Name for the output file, if specified; otherwise derive from main source file name
+
+fexecutable-path
+Pascal
+Create the executable file in the directory where the main source is (default)
+
+fexecutable-path=
+Pascal Joined RejectNegative
+Path where to create the executable file
+
+fextended-pascal
+Pascal RejectNegative
+Reject anything besides ISO 10206 Extended Pascal
+
+fextended-syntax
+Pascal
+same as `--ignore-function-results --pointer-arithmetic --cstrings-as-strings -Wno-absolute' (same as `{$X+}')
+
+ffield-widths=
+Pascal Joined RejectNegative
+
+
+ffield-widths
+Pascal
+Optional colon-separated list of default field widths for Integer, Real, Boolean, LongInt, LongReal
+
+fgnu-pascal
+Pascal RejectNegative
+Undo the effect of previous dialect options, allow all features again
+
+fgpc-main=
+Pascal Joined RejectNegative
+External name for the program's entry point (default
+ `main')
+
+fgpi-destination-path=
+Pascal Joined RejectNegative
+(Internal switch used for automake)
+
+fignore-function-results
+Pascal
+Do not complain when a function is called like a procedure
+
+fignore-garbage-after-dot
+Pascal
+Ignore anything after the terminating `.' (default in `--borland-pascal')
+
+fignore-packed
+Pascal
+Ignore `packed' in the source code (default in `--borland-pascal')
+
+fimplementation-only
+Pascal RejectNegative
+Do not produce a GPI file; only compile the implementation part
+
+finit-modules=
+Pascal Joined RejectNegative
+Initialize the named modules in addition to those imported regularly; kind of a kludge
+
+finterface-only
+Pascal RejectNegative
+Compile only the interface part of a unit/module and exit (creates `.gpi' file, no `.o' file)
+
+fio-checking
+Pascal
+Check I/O operations automatically (same as `{$I+}') (default)
+
+flittle-endian
+Pascal RejectNegative
+Tell GPC that the system is little-endian (for those targets where it can vary)
+
+flongjmp-all-nonlocal-labels
+Pascal
+Use `longjmp' for all nonlocal labels
+
+fmac-pascal
+Pascal RejectNegative
+Support (some features of) traditional Macintosh Pascal compilers
+
+fmacros
+Pascal
+Expand macros (default)
+
+fmaximum-field-alignment=
+Pascal Joined RejectNegative
+Set the maximum field alignment in bits if `pack-struct' is in effect
+
+fmethods-always-virtual
+Pascal
+Make all methods virtual (default in `--mac-pascal')
+
+fmixed-comments
+Pascal
+Allow comments like `{ ... *)' as required in ISO Pascal (default in ISO 7185/10206 Pascal mode)
+
+fnested-comments
+Pascal
+Allow nested comments like `{ { } }' and `(* (* *) *)'
+
+fobject-destination-path
+Pascal
+Create additional object files (e.g. of C files, not Pascal units) in the current directory (default)
+
+fobject-destination-path=
+Pascal Joined RejectNegative
+Path where to create additional object files (e.g. of C files, not Pascal units)
+
+fobject-pascal
+Pascal RejectNegative
+Reject anything besides (the implemented parts of) ANSI draft Object Pascal
+
+fobject-path
+Pascal
+Forget about directories where to look for additional object (and source) files
+
+fobject-path=
+Pascal Joined RejectNegative
+Directories where to look for additional object (and source) files
+
+fpascal-sc
+Pascal RejectNegative
+Be strict about the implemented Pascal-SC extensions
+
+fpedantic
+Pascal
+Reject everything not allowed in some dialect, e.g. redefinition of its keywords
+
+fpointer-arithmetic
+Pascal
+Enable pointer arithmetic
+
+fprint-needed-options
+Pascal RejectNegative
+Print the needed options
+
+fprogress-bar
+Pascal
+Output number of processed lines while compiling
+
+fprogress-messages
+Pascal
+Output source file names and line numbers while compiling
+
+frange-checking
+Pascal
+Do automatic range checks (same as `{$R+}') (default)
+
+fread-base-specifier
+Pascal
+In read statements, allow input base specifier `n#' (default)
+
+fread-hex
+Pascal
+In read statements, allow hexadecimal input with `$' (default)
+
+fread-white-space
+Pascal
+In read statements, require whitespace after numbers
+
+fsetlimit=
+Pascal Joined RejectNegative
+Define the range for `set of Integer' etc.
+
+fshort-circuit
+Pascal
+Guarantee short-circuit Boolean evaluation (default; same as `{$B-}')
+
+fstack-checking
+Pascal
+Enable stack checking (same as `{$S+}')
+
+fstandard-pascal-level-0
+Pascal RejectNegative
+Synonym for `--classic-pascal-level-0'
+
+fstandard-pascal
+Pascal RejectNegative
+Synonym for `--classic-pascal'
+
+fsun-pascal
+Pascal RejectNegative
+Support (a few features of) Sun Pascal
+
+ftransparent-file-names
+Pascal
+Derive external file names from variable names
+
+ftruncate-strings
+Pascal
+Truncate strings being assigned to other strings of too short capacity.
+
+ftyped-address
+Pascal
+Make the result of the address operator typed (same as `{$T+}', default)
+
+fucsd-pascal
+Pascal RejectNegative
+Try to emulate UCSD Pascal
+
+funit-destination-path
+Pascal
+Create object and GPI files of Pascal units in the current directory (default)
+
+funit-destination-path=
+Pascal Joined RejectNegative
+Path where to create object and GPI files of Pascal units
+
+funit-path
+Pascal
+Forget about directories where to look for unit/module sources
+
+funit-path=
+Pascal Joined RejectNegative
+Directories where to look for unit/module sources
+
+fuses=
+Pascal Joined RejectNegative
+Add an implicit `uses' clause
+
+fvax-pascal
+Pascal RejectNegative
+Support (a few features of) VAX Pascal
+
+fwrite-capital-exponent
+Pascal
+Write real exponents with a capital `E'
+
+fwrite-clip-strings
+Pascal
+In write statements, truncate strings exceeding their field width (`Write (SomeLongString 
+ 3)')
+
+fwrite-real-blank
+Pascal
+Output a blank in front of positive reals in exponential form (default)
+
+Wabsolute
+Pascal
+Warn about variables at absolute adresses and `absolute' variable with non-constant addresses (default)
+
+Wall
+Pascal
+
+
+Wcomment
+Pascal
+
+
+Wfloat-equal
+Pascal
+Warn about `=' and `<>' comparisons of real numbers
+
+Widentifier-case-local
+Pascal
+Warn about an identifier written with varying case within one program/module/unit
+
+Widentifier-case
+Pascal
+Warn about an identifier written with varying case
+
+Wimplicit-abstract
+Pascal
+Warn when an object type not declared `abstract' contains an abstract method (default)
+
+Wimplicit-io
+Pascal
+Warn when `Input' or `Output' are used implicitly
+
+Winherited-abstract
+Pascal
+Warn when an abstract object type inherits from a non-abstract one (default)
+
+Winterface-file-name
+Pascal
+Warn when a unit/module interface differs from the file name
+
+Wlocal-external
+Pascal
+Warn about local `external' declarations
+
+Wmissing-declarations
+Pascal
+
+
+Wmissing-prototypes
+Pascal
+
+
+Wmixed-comments
+Pascal
+Warn about mixed comments like `{ ... *)'
+
+Wnear-far
+Pascal
+Warn about use of useless `near' or `far' directives (default)
+
+Wnested-comments
+Pascal
+Warn about nested comments like `{ { } }'
+
+Wobject-assignment
+Pascal
+Warn when when assigning objects or declaring them as value parameters or function results (default)
+
+Wpointer-arith
+Pascal
+
+
+Wsemicolon
+Pascal
+Warn about a semicolon after `then', `else' or `do' (default)
+
+Wtyped-const
+Pascal
+Warn about misuse of typed constants as initialized variables (default)
+
+Wundef
+Pascal
+
+
+Wunderscore
+Pascal
+Warn about double/leading/trailing underscores in identifiers
+
+Wwarnings
+Pascal
+Enable warnings (same as `{$W+}')
+
+Wwrite-strings
+Pascal
+
+
+; This comment is to ensure we retain the blank line above.
diff -ru gpc-20040516.orig/p/Make-lang.in gpc-20040516/p/Make-lang.in
--- gpc-20040516.orig/p/Make-lang.in	2004-05-14 23:51:21.000000000 +0200
+++ gpc-20040516/p/Make-lang.in	2004-07-06 22:55:02.000000000 +0200
@@ -52,7 +52,12 @@
 # `'   for gcc-3.x
 GPC_GCC_2_=2
 GPC_GCC_28_=8
+GPC_GCC_34_PPQ_=foo
+GPC_GCC_34_PPP=$(GPC_GCC_34_PPQ_$(target_noncanonical))
+GPC_GCC_34_PP_=34
+GPC_GCC_34_=$(GPC_GCC_34_PP_$(GPC_GCC_34_PPP))
 GCC_VERSION_FOR_GPC=$(GPC_GCC_2_$(BACKEND))$(GPC_GCC_28_$(gcc_version))
+GCC_VERSION_FOR_GPC34=$(GPC_GCC_34_)$(GCC_VERSION_FOR_GPC)
 GPC_GCC_VERSION_28=$(version)
 GPC_GCC_VERSION_2=$(gcc_version)
 GPC_GCC_VERSION_=$(gcc_version)
@@ -91,11 +96,14 @@
 GPC_HOST_28=$(host)
 GPC_HOST_2=$(host_canonical)
 GPC_HOST_=$(host_canonical)
-GPC_HOST=$(GPC_HOST_$(GCC_VERSION_FOR_GPC))
+GPC_HOST_34=$(host)
+GPC_HOST=$(GPC_HOST_$(GCC_VERSION_FOR_GPC34))
+
 GPC_BUILD_28=$(build)
 GPC_BUILD_2=$(build_canonical)
 GPC_BUILD_=$(build_canonical)
-GPC_BUILD=$(GPC_BUILD_$(GCC_VERSION_FOR_GPC))
+GPC_BUILD_34=$(build)
+GPC_BUILD=$(GPC_BUILD_$(GCC_VERSION_FOR_GPC34))
 
 # gcc<3 doesn't set $(STAMP) and $(man1ext).
 # gcc-3 does, but it should not matter to set them here again.
@@ -161,7 +169,11 @@
 GPC_INSTALL_NAME=`t='$(program_transform_name)'; echo gpc | sed $$t`
 
 # Actual names to use when installing a cross-compiler.
-GPC_CROSS_NAME=`t='$(program_transform_cross_name)'; echo gpc | sed $$t`
+GPC_CROSS_NAME_=`t='$(program_transform_cross_name)'; echo gpc | sed $$t`
+
+GPC_CROSS_NAME_34=$(target_noncanonical)`t='$(program_transform_name)'; echo gpc | sed $$t`
+
+GPC_CROSS_NAME=$(GPC_CROSS_NAME_$(GPC_GCC_34_))
 
 # The GPC to use for compiling libgpc.a
 # Usually the one we just built.
@@ -205,18 +217,32 @@
 	HOST="$(GPC_HOST)"
 
 # Flags to pass when building the RTS.
-RTS_FLAGS_TO_PASS=\
+RTS_FLAGS_TO_PASS_ALL=\
 	GCC_VERSION="$(GPC_GCC_VERSION)" \
 	SHELL="$(SHELL)" \
 	CFLAGS="$(CFLAGS)" \
 	PFLAGS="$(PFLAGS)" \
-	AR="$(AR_FOR_TARGET)" \
 	AR_FLAGS="$(AR_FLAGS)" \
-	RANLIB="$(RANLIB_FOR_TARGET)" \
-	RANLIB_TEST="$(RANLIB_TEST_FOR_TARGET)" \
 	RTSFLAGS="$(RTSFLAGS)" \
 	DESTDIR="../.."
 
+RTS_FLAGS_TO_PASS_28=\
+        AR="$(AR)" \
+        RANLIB="$(RANLIB)" \
+        RANLIB_TEST="$(RANLIB_TEST)"
+
+RTS_FLAGS_TO_PASS_=\
+        AR="$(AR_FOR_TARGET)" \
+        RANLIB="$(RANLIB_FOR_TARGET)" \
+        RANLIB_TEST="$(RANLIB_TEST_FOR_TARGET)"
+
+RTS_FLAGS_TO_PASS_2=$(RTS_FLAGS_TO_PASS_)
+
+RTS_FLAGS_TO_PASS_34=$(RTS_FLAGS_TO_PASS_)
+
+RTS_FLAGS_TO_PASS=$(RTS_FLAGS_TO_PASS_ALL) \
+             $(RTS_FLAGS_TO_PASS_$(GCC_VERSION_FOR_GPC))
+
 # Flags to pass when running the test suite.
 TEST_FLAGS_TO_PASS=\
 	MASK="$(MASK)" \
@@ -377,8 +403,8 @@
 MAKEINFO_ES=LANG=es_ES LC_ALL=es_ES $(MAKEINFO) $(MAKEINFOFLAGS) $(GPC_DOC_DIRS_ES)
 
 # Define the names for selecting Pascal in LANGUAGES.
-Pascal pascal: xgpc$(exeext) gpc1$(exeext) gpcpp$(exeext) gpc-run pascal.utils \
-               pascal.rts specs pascal.generated-files pascal.docdemos
+Pascal pascal: xgpc$(exeext) gpc1$(exeext) gpcpp$(exeext) gpc-run \
+               specs pascal.generated-files pascal.docdemos
 
 # Tell GNU make to ignore these if they exist.
 .PHONY: Pascal pascal
@@ -511,6 +537,10 @@
 
 pascal.generated-manpages:
 
+pascal.man:
+
+pascal.srcman:
+
 pascal.docdemos: p/stamp-docdemos
 p/stamp-docdemos: $(GPC_TEXI_EN)
 	rm -rf p/docdemos
@@ -546,7 +576,9 @@
 GPC_GBE_H=$(CONFIG_H) system.h tree.h input.h rtl.h flags.h output.h expr.h \
           except.h function.h convert.h toplev.h $(GPC_GCC_VERSION_H)
 P_H=$(GPC_GBE_H) p/gpc.h p/p-tree.def p/predef.h $(srcdir)/p/parse.h p/gbe.h
-ALL_GPC_FLAGS=$(ALL_CFLAGS) $(ALL_CPPFLAGS) $(GPC_ALL_WARNINGS) $(INCLUDES) -DGPC -I$(srcdir)/p
+ALL_GPC_FLAGS=$(ALL_CFLAGS) $(ALL_CPPFLAGS) $(GPC_ALL_WARNINGS) $(INCLUDES) \
+  -DGPC -DGPC_UNITS_DIR=\"$(libsubdir)/units\" -I$(srcdir)/p
+
 
 # Headers and flags for patched backend files.
 GPC_BE_H=$(GPC_GBE_H) defaults.h machmode.h machmode.def real.h recog.h \
@@ -569,7 +601,7 @@
 	p/typecheck.o p/types.o p/convert.o p/dbxout.o p/dwarf2out.o \
 	p/expr.o p/fold-const.o p/function.o p/integrate.o p/optabs.o \
 	p/stor-layout.o p/toplev.o p/tree.o p/stmt.o p/emit-rtl.o \
-	p/version.o
+	p/version.o $(C_TARGET_OBJS)
 
 # Exclude patched files from language-independent object file list.
 # Not necessary for gcc-3 since for a library (libbackend.a), the linker does this automatically.
@@ -607,9 +639,15 @@
 p/gpc-lex.o: p/gpc-lex.c $(srcdir)/p/pascal-lex.c $(P_H)
 	$(CC) -o $@ -c $(ALL_GPC_FLAGS) $<
 
-p/lang.o: p/lang.c $(P_H)
+p/handle-opts.c: $(srcdir)/p/opts.sum $(srcdir)/p/mkopts2.pl
+	perl $(srcdir)/p/mkopts2.pl $(srcdir)/p/opts.sum > "$@"
+
+p/lang.o: p/lang.c $(P_H) p/handle-opts.c
 	$(CC) -o $@ -c $(ALL_GPC_FLAGS) $<
 
+$(srcdir)/p/lang.opt: $(srcdir)/p/opts.sum $(srcdir)/p/mk_lang_opt
+	$(srcdir)/p/mk_lang_opt < $(srcdir)/p/opts.sum > "$@"
+
 p/module.o: p/module.c $(P_H) p/version.h
 	$(CC) -o $@ -c $(ALL_GPC_FLAGS) -DTARGET_NAME=\"$(target_alias)\" $<
 
@@ -683,6 +721,9 @@
 $(srcdir)/p/pascal-lex.c: $(srcdir)/p/pascal-lex.l
 	cd $(srcdir)/p && $(GPC_LEX) $(GPC_LEXFLAGS) -opascal-lex.c pascal-lex.l
 
+p/version.o: version.c $(GPC_BE_H)
+	$(CC) -o $@ -c $(ALL_GPC_GBE_FLAGS) $<
+
 $(srcdir)/p/parse.c $(srcdir)/p/parse.h: $(srcdir)/p/parse.y
 	echo "expect 16 shift/reduce and 30 reduce/reduce conflicts" >&2
 	cd $(srcdir)/p && $(BISON) $(BISONFLAGS) -o parse.c parse.y
@@ -728,9 +769,9 @@
 # Build hooks:
 
 pascal.all.build: xgpc$(exeext)
-pascal.all.cross: gpc-cross$(exeext)
+pascal.all.cross: gpc-cross$(exeext) pascal.rts pascal.utils
 pascal.start.encap:
-pascal.rest.encap:
+pascal.rest.encap: pascal.rts pascal.utils
 
 pascal.info: $(srcdir)/p/doc/info/gpc.info \
              $(srcdir)/p/doc/info/gpcs.info \
@@ -870,6 +911,10 @@
 	rm -f $(DESTDIR)$(libsubdir)/gpcpp$(exeext)
 	$(INSTALL_PROGRAM) gpcpp$(exeext) $(DESTDIR)$(libsubdir)/gpcpp$(exeext)
 
+install-gpcpp34: pascal.install-dir gpcpp$(exeext)
+	rm -f $(DESTDIR)$(libexecsubdir)/gpcpp$(exeext)
+	$(INSTALL_PROGRAM) gpcpp$(exeext) $(DESTDIR)$(libexecsubdir)/gpcpp$(exeext)
+
 # Install the driver program as $(target)-gpc
 # and also as either gpc (if native) or $(tooldir)/bin/gpc.
 pascal.install-common: pascal.install-dir xgpc$(exeext) gpc-run
@@ -897,9 +942,7 @@
 	  rm -f $(DESTDIR)$(libsubdir)/libgpc.a; \
 	  $(INSTALL_DATA) libgpc.a $(DESTDIR)$(libsubdir)/libgpc.a && \
 	  chmod a-x $(DESTDIR)$(libsubdir)/libgpc.a || exit 1; \
-	  if $(RANLIB_TEST_FOR_TARGET); then \
-	    $(RANLIB_FOR_TARGET) $(DESTDIR)$(libsubdir)/libgpc.a || exit 1; \
-	  fi; \
+	  $(RANLIB_FOR_TARGET) $(DESTDIR)$(libsubdir)/libgpc.a; \
 	fi
 	for f in .. $(GPC_EXTRA_INSTALL_LIBS); do \
 	  if [ x"$$f" != x.. ]; then \
@@ -1020,6 +1063,8 @@
 	done
 	chmod a-x $(DESTDIR)$(infodir)/gpc-es.info* $(DESTDIR)$(infodir)/gpcs-es.info*
 
+pascal.install-compiler34: 
+
 # Install gpc1 et.al.
 # Do *not* overwrite files if they exist.
 pascal.install-compiler: pascal.install-dir pascal
@@ -1046,8 +1091,8 @@
 	  chmod a-x $(DESTDIR)$(libsubdir)/specs || exit 1; \
 	fi; exit 0
 
-pascal.install-normal: pascal.install-common pascal.install-compiler \
- install-gpcpp pascal.install-utils pascal.install-lib pascal.install-man \
+pascal.install-normal: pascal.install-common pascal.install-compiler$(GPC_GCC_34_) \
+ install-gpcpp$(GPC_GCC_34_) pascal.install-utils pascal.install-lib pascal.install-man \
  pascal.install-info pascal.install-units pascal.install-doc
 
 # This target will install GPC into an existing GCC installation,
@@ -1166,7 +1211,8 @@
 
 RTSSTAGESTUFF=p/rts/*.o p/rts/*.lo p/rts/*.gpi p/rts/*.gpd \
   p/rts/config.cache p/rts/config.log p/rts/config.status p/rts/Makefile \
-  p/rts/rts-config.h p/rts/rts-config.inc p/rts/needed-options
+  p/rts/rts-config.h p/rts/rts-config.inc p/rts/needed-options \
+  p/rts/stamp-error-gpi
 
 pascal.stage1:
 	$(srcdir)/p/script/mkdir-p stage1/p/rts
Only in gpc-20040516/p: Make-lang.in.orig
diff -ru gpc-20040516.orig/p/mk_lang_opt gpc-20040516/p/mk_lang_opt
--- gpc-20040516.orig/p/mk_lang_opt	2004-07-06 19:20:15.000000000 +0200
+++ gpc-20040516/p/mk_lang_opt	2004-07-06 19:08:51.000000000 +0200
@@ -0,0 +1,34 @@
+#!/bin/sh
+cat <<'EOF'
+; Options for the Pascal front end.
+; Copyright (C) 2003 Free Software Foundation, Inc.
+;
+; This file is part of GCC.
+;
+; GCC is free software; you can redistribute it and/or modify it under
+; the terms of the GNU General Public License as published by the Free
+; Software Foundation; either version 2, or (at your option) any later
+; version.
+; 
+; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+; for more details.
+; 
+; You should have received a copy of the GNU General Public License
+; along with GCC; see the file COPYING.  If not, write to the Free
+; Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+; 02111-1307, USA.
+
+; See c.opt for a description of this file's format.
+
+; Please try to keep this file in ASCII collating order.
+
+Language
+Pascal
+
+EOF
+
+sed 's,:,:Pascal ,' | tr : '\001' | sort | tr '\001' : | sed 's, :,:,;s,$,:,' | tr : '\n' 
+
+echo "; This comment is to ensure we retain the blank line above."
diff -ru gpc-20040516.orig/p/mkopts2.pl gpc-20040516/p/mkopts2.pl
--- gpc-20040516.orig/p/mkopts2.pl	2004-07-06 19:20:07.000000000 +0200
+++ gpc-20040516/p/mkopts2.pl	2004-07-06 19:08:51.000000000 +0200
@@ -0,0 +1,22 @@
+#!/usr/bin/perl
+
+while(<>) {
+        chop;
+        s/:.*//;
+        $pl = $_;
+        $ol = $_;
+        $nl = $ol;
+        $nl =~ s/^(.)/\1no-/;
+        $pl =~ tr/+=-/___/;
+        print "    case OPT_$pl:\n";
+	if(/=$/) {
+	    print "       pp[0] = ACONCAT ((\"-$ol\", arg, NULL));\n";
+        } else {
+            print "       if (value)\n"; 
+            print "         pp[0] = \"-$ol\";\n";
+            print "       else\n";
+            print "         pp[0] = \"-$nl\";\n";
+        }
+        print "       pascal_decode_option(1, pp);\n";
+	print "       break;\n\n";
+}
diff -ru gpc-20040516.orig/p/module.c gpc-20040516/p/module.c
--- gpc-20040516.orig/p/module.c	2004-05-12 02:42:02.000000000 +0200
+++ gpc-20040516/p/module.c	2004-07-06 19:12:30.000000000 +0200
@@ -114,7 +114,7 @@
 static char *locate_interface_source PARAMS ((const char *, const char *, const char *));
 static MEMFILE *gpi_open PARAMS ((tree, const char *, const char *, int, gpi_int *, gpi_int *, gpi_int *));
 static tree load_gpi_file PARAMS ((tree, const char *, int));
-static void import_node PARAMS ((tree, tree));
+static void import_node PARAMS ((tree, tree, tree, import_type));
 static void load_own_interface PARAMS ((int));
 static module_t find_module PARAMS ((tree, int));
 static void module_expand_exported_ranges PARAMS ((tree));
@@ -124,6 +124,7 @@
 static void start_chunk PARAMS ((FILE *, int, gpi_int));
 static void store_string_chunk PARAMS ((FILE *, int, const char *));
 static inline void store_string PARAMS ((const char *));
+static tree dequalify_id PARAMS ((tree));
 static void store_tree PARAMS ((tree, FILE *, tree, int));
 static int get_node_id PARAMS ((tree));
 static void store_node PARAMS ((tree));
@@ -453,6 +454,7 @@
      int kind;
 {
   const char *n;
+  const char * current_module_name = 0;
   if (kind == 1)
     chk_dialect ("units are", U_B_D_M_PASCAL);
   else if (kind == 2 || kind == 3)
@@ -468,20 +470,16 @@
       id = get_identifier ("noname");
     }
   current_module = find_module (id, 1);
+  current_module->assembler_name = NULL; 
   if (kind == 0)
     {
       string_list *link_file;
       for (link_file = current_module->link_files; link_file; link_file = link_file->next)
         add_to_automake_temp_file (link_file->string);
-      n = "init_pascal_main_program";
       current_module->main_program = current_module->implementation = 1;
+      current_module_name = "_p__M0";
+      current_module->assembler_name = get_identifier (current_module_name);
     }
-  else
-    n = ACONCAT (("init_", IDENTIFIER_POINTER (current_module->name), NULL));
-  current_module->initializers = build_tree_list (NULL_TREE, get_identifier (n));
-  n = ACONCAT (("fini_", IDENTIFIER_POINTER (current_module->name), NULL));
-  current_module->finalizer = build_implicit_routine_decl (get_identifier (n),
-    void_type_node, build_tree_list (NULL_TREE, void_type_node), ER_STATIC);
   if (par)
     {
       tree t;
@@ -496,13 +494,25 @@
             && TREE_VALUE (t) && list_length (TREE_VALUE (t)) == 1)
           {
             current_module->assembler_name = check_assembler_name (TREE_VALUE (TREE_VALUE (t)));
-            n = ACONCAT (("init_", IDENTIFIER_POINTER (current_module->assembler_name),
-                          "_", IDENTIFIER_POINTER (current_module->name), NULL));
-            current_module->initializers = build_tree_list (NULL_TREE, get_identifier (n));
+            current_module_name = IDENTIFIER_POINTER (current_module->assembler_name);
           }
         else
           error ("unknown module attribute `%s'", IDENTIFIER_NAME (TREE_PURPOSE (t)));
     }
+  if (!current_module->assembler_name)
+    {
+      char name_len[23];
+      const char * mname = IDENTIFIER_POINTER (current_module->name);
+      sprintf (name_len, "%ld_", (long)strlen (mname));
+      current_module_name = ACONCAT (("_p__M", name_len, mname, NULL));
+      current_module->assembler_name = get_identifier (current_module_name);
+    }
+  n = ACONCAT ((current_module_name, "_init", NULL));
+  current_module->initializers = build_tree_list (NULL_TREE, get_identifier (n)); 
+  n = ACONCAT ((current_module_name, "_fini", NULL));
+  current_module->finalizer = build_implicit_routine_decl (get_identifier (n),
+    void_type_node, build_tree_list (NULL_TREE, void_type_node), ER_STATIC);
+
   if (kind != 0)
     pushlevel (0);
   /* Unit autoexport */
@@ -637,12 +647,22 @@
 
    NAME is an IDENTIFIER_NODE of the exported interface name.
 
-   EXPORT_LIST is a TREE_LIST:
+   EXPORT_LIST is a TREE_LIST containig:
+     export "all" marker (TREE_PURPOSE == NULL_TREE, TREE_VALUE == NULL_TREE)
+     explicit exports
+     end of explictit exports marker (TREE_PURPOSE == integer_zero_node,
+                 TREE_VALUE == NULL_TREE)
+     implicit ("all") exports
+  
+   normal export entries:
    TREE_READONLY: protected
    TREE_PURPOSE: Export renaming (new name) or NULL_TREE.
    TREE_VALUE: IDENTIFIER_NODE of the exported name
      or TREE_LIST if exporting a range (TREE_PURPOSE..TREE_VALUE)
-     or NULL_TREE for "all" */
+
+   Later in `module_expand_exported_ranges' we replace TREE_LIST 
+   representing range by NULL_TREE and we add entries for values. */
+
 void
 export_interface (name, export_list)
      tree name, export_list;
@@ -666,8 +686,14 @@
      So the explicit exports take precendence. This is a bit fragile. */
   for (t = export_list; t && TREE_VALUE (t); t = TREE_CHAIN (t)) ;
   if (t)
-    current_module->autoexport = chainon (current_module->autoexport,
-      build_tree_list (tree_last (export_list), build_tree_list (export_list, name)));
+    {
+      tree last = tree_last (export_list);
+      /* Mark end of explicit exports */
+      TREE_CHAIN (last) = build_tree_list (integer_zero_node , NULL_TREE);
+      last = TREE_CHAIN (last);
+      current_module->autoexport = chainon (current_module->autoexport,
+             build_tree_list (last, build_tree_list (export_list, name)));
+    }
 }
 
 /* Import module/unit interfaces specified on the command line via `--uses=...'. */
@@ -715,7 +741,7 @@
         }
       else
         file_name = NULL_TREE;
-      import_interface (interface_name, NULL_TREE, 0, file_name);
+      import_interface (interface_name, NULL_TREE, IMPORT_USES, file_name);
       while (*p
              && !((*p >= 'A' && *p <= 'Z')
                   || (*p >= 'a' && *p <= 'z')
@@ -1612,6 +1638,16 @@
   return 0;
 }
 
+static tree
+dequalify_id (id)
+     tree id;
+{
+  char * str = IDENTIFIER_POINTER (id);
+  assert (str = strchr (str, '.'));
+  str++;
+  return get_identifier (str);
+}
+
 static void
 store_tree (name, s, main_node, autoexport_flag)
      tree name;
@@ -1623,6 +1659,7 @@
   gpi_int main_node_id, checksum;
   tree main_node_end, t, *tt;
   char *main_exported;
+  int autoexporting = 0;
 
   /* How many nodes will be stored (approx.; will be extended when necessary) */
   wb.size = list_length (main_node) + 1024 + NUM_SPECIAL_NODES;
@@ -1684,8 +1721,8 @@
       t = TREE_CHAIN (t);
     }
 
-  /* Due to the autoexporting of enum type values, the main list may
-     contain duplicates. Remove them here. */
+  /* Due to the autoexporting of enum type values and operators, the main
+     list may contain duplicates. Remove them here. */
   main_exported = alloca (wb.size * sizeof (char));
   memset (main_exported, 0, wb.size * sizeof (char));
   tt = &TREE_CHAIN (main_node);
@@ -1694,12 +1731,17 @@
       int flag = 1;
       tree id = TREE_VALUE (*tt), rename = TREE_PURPOSE (*tt);
       if (!id)
-        flag = 0;
+        {
+          flag = 0;
+          if (rename == integer_zero_node)
+            autoexporting = 1;
+        }
       else if (TREE_CODE (id) != IMPORT_NODE)
         {
           int c1 = get_node_id (id);
           int c2 = get_node_id (rename);
           assert (TREE_CODE (id) == IDENTIFIER_NODE);
+          assert (!rename || !autoexporting);
           if (id)
             {
               tree value = IDENTIFIER_VALUE (id);
@@ -1712,17 +1754,40 @@
                     error ("exporting unknown identifier `%s'", IDENTIFIER_NAME (id));
                 }
               if (rename)
-                TREE_VALUE (*tt) = rename;
+                {
+                  TREE_VALUE (*tt) = rename;
+                  if (value && TREE_CODE (value) == CONST_DECL 
+                       && PASCAL_CST_PRINCIPAL_ID (value))
+                    {
+                      tree nd = build_decl (CONST_DECL, rename, 
+                                             TREE_TYPE (value));
+                      DECL_INITIAL (nd) = DECL_INITIAL (value);
+                      value = nd;
+                      get_node_id (value);
+                      FLUSH_NODES;
+                    }
+                }
+              else if (PASCAL_QUALIFIED_ID (id))
+                {
+                  id = dequalify_id (id);
+                  c1 = get_node_id (id);
+                  while (wb.count > n)
+                    FLUSH_NODES;
+                  TREE_VALUE (*tt) = id;
+                }
               TREE_PURPOSE (*tt) = value;
             }
-          if (rename && main_exported[c2])
+          if (rename && main_exported[c2] == 1)
             {
               error ("duplicate exported identifier `%s' due to renaming", IDENTIFIER_NAME (rename));
               TREE_VALUE (*tt) = NULL_TREE;
             }
-          if (!TREE_VALUE (*tt) || !TREE_PURPOSE (*tt) || main_exported[c1])
+          if (id && !rename && !autoexporting && main_exported[c1] == 1)
+            error ("duplicate exported identifier `%s'", IDENTIFIER_NAME (id));
+          if (!TREE_VALUE (*tt) || !TREE_PURPOSE (*tt) || 
+               (main_exported[c1] && autoexporting))
             flag = 0;
-          main_exported[c1] = 1;
+          main_exported[c1] = rename ? 2 : 1;
           main_exported[c2] = 1;
         }
       if (flag)
@@ -1888,6 +1953,8 @@
               else
                 DECL_EXTERNAL (t) = 1;  /* not for module interface so init_any won't ignore it */
             }
+          PASCAL_DECL_WEAK (t) = 0;
+          PASCAL_DECL_IMPORTED (t) = 1;
           rest_of_decl_compilation (t, NULL, 1, 1);
         }
       /* Support `private' for object fields/methods */
@@ -2082,7 +2149,11 @@
       {
         int i, l = NUMBER_OF_OPERANDS (code);
         store_node (TREE_TYPE (t));
+#ifndef GCC_3_4
         for (i = (code == CONSTRUCTOR) ? 1 : 0; i < l; i++)
+#else
+        for (i = 0; i < l; i++)
+#endif
           store_node (TREE_OPERAND (t, i));
         class_done = 1;
         break;
@@ -2113,10 +2184,14 @@
       break;
 
     case IMPORT_NODE:
+      { 
+        gpi_int q = PASCAL_TREE_QUALIFIED (t);
       store_node (IMPORT_INTERFACE (t));
       store_node (IMPORT_QUALIFIER (t));
       store_node (IMPORT_FILENAME (t));
+        STORE_ANY (q);
       break;
+      }
 
     case TREE_LIST:
       {
@@ -2133,23 +2208,6 @@
       }
 
     case ENUMERAL_TYPE:
-      /* For directly or indirectly exported enumerated types, mark their
-         values here for exporting in the main list(!), but only in
-         autoexported interfaces (EP, 6.11.2, note 2).
-         Not storing TYPE_VALUES (t) directly causes the values not be
-         connected with the type in an importing interface. Therefore, it
-         will not automatically re-export the values again (BP behaves
-         the same way). (fjf628.pas) */
-      if (wb.autoexport_flag)
-        {
-          tree item;
-          for (item = TYPE_VALUES (t); item; item = TREE_CHAIN (item))
-            wb.append_additional_globals_to_export =
-              TREE_CHAIN (wb.append_additional_globals_to_export) =
-                build_tree_list (NULL_TREE, TREE_PURPOSE (item));
-        }
-      /* FALLTHROUGH */
-    case VOID_TYPE:
     case REAL_TYPE:
     case COMPLEX_TYPE:
     case BOOLEAN_TYPE:
@@ -2158,6 +2216,12 @@
       store_node (TREE_TYPE (t));
       store_node (TYPE_MIN_VALUE (t));
       store_node (TYPE_MAX_VALUE (t));
+      if (code == ENUMERAL_TYPE)
+        store_node (TYPE_VALUES (t));
+      break;
+
+    case VOID_TYPE:
+      store_node (TREE_TYPE (t));
       break;
 
     case SET_TYPE:
@@ -2580,7 +2644,11 @@
       {
         int i, l = NUMBER_OF_OPERANDS (code);
         TREE_TYPE (t) = load_node ();
+#ifndef GCC_3_4
         for (i = (code == CONSTRUCTOR) ? 1 : 0; i < l; i++)
+#else
+        for (i = 0; i < l; i++)
+#endif
           TREE_OPERAND (t, i) = load_node ();
         break;
       }
@@ -2631,10 +2699,15 @@
       }
 
     case IMPORT_NODE:
+      {
+        gpi_int q;
       IMPORT_INTERFACE (t) = load_node ();
       IMPORT_QUALIFIER (t) = load_node ();
       IMPORT_FILENAME (t) = load_node ();
+        LOAD_ANY (q);
+        PASCAL_TREE_QUALIFIED (t) = q;
       break;
+      }
 
     case TREE_LIST:
       {
@@ -2652,7 +2725,6 @@
         break;
       }
 
-    case VOID_TYPE:
     case REAL_TYPE:
     case COMPLEX_TYPE:
     case BOOLEAN_TYPE:
@@ -2663,7 +2735,14 @@
       TYPE_MIN_VALUE (t) = load_node ();
       TYPE_MAX_VALUE (t) = load_node ();
       if (code == ENUMERAL_TYPE)
-        TYPE_STUB_DECL (t) = build_decl (TYPE_DECL, NULL_TREE, t);
+        {
+          TYPE_VALUES (t) = load_node ();
+          TYPE_STUB_DECL (t) = build_decl (TYPE_DECL, NULL_TREE, t);
+        }
+      break;
+
+    case VOID_TYPE:
+      TREE_TYPE (t) = load_node ();
       break;
 
     case SET_TYPE:
@@ -2853,6 +2932,10 @@
       TREE_TYPE (t) = load_node ();
       break;
 
+    case OPERATOR_DECL:
+      TREE_TYPE (t) = void_type_node;
+      break;
+
     default:
       break;
   }
@@ -3458,19 +3541,49 @@
   return temp;
 }
 
+
 /* Activate a node during import */
 static void
-import_node (item, rename)
+import_node (item, rename, interface, qualified)
      tree item, rename;
+     tree interface;
+     import_type qualified;
 {
   tree value = TREE_PURPOSE (item);
+  int no_principal = (rename && TREE_CODE (value) == CONST_DECL);
+  rename = rename ? rename : TREE_VALUE (item);
   if (TREE_CODE (TREE_VALUE (item)) == IMPORT_NODE)
     return;
   TREE_READONLY (value) |= TREE_READONLY (item);
   if (TREE_CODE (value) == FUNCTION_DECL && DECL_LANG_OPERATOR_DECL (value))
     operators_defined = 1;
-  pushdecl_nocheck (value);
-  IDENTIFIER_VALUE (rename ? rename : TREE_VALUE (item)) = value;
+  if (qualified == IMPORT_ISO || qualified == IMPORT_USES)
+    { 
+      tree decl1 = interface ? copy_node (value) : value;
+      DECL_NAME (decl1) = rename;
+      PASCAL_DECL_WEAK (decl1) = 0;
+      PASCAL_DECL_IMPORTED (decl1) = 1;
+      if (no_principal)
+        PASCAL_CST_PRINCIPAL_ID (decl1) = 0;
+      IDENTIFIER_VALUE (rename) = pushdecl_import (decl1,
+         qualified == IMPORT_USES);
+    }
+  if (interface) 
+    {
+        tree qdecl = copy_node(value);
+        tree qid = get_identifier (ACONCAT ((
+		IDENTIFIER_POINTER (interface),
+		".",
+		IDENTIFIER_POINTER (rename),
+		NULL)));
+        PASCAL_DECL_WEAK (qdecl) = 0;
+        PASCAL_DECL_IMPORTED (qdecl) = 1;
+        DECL_NAME (qdecl) = qid;
+        if (no_principal)
+          PASCAL_CST_PRINCIPAL_ID (qdecl) = 0;
+        pushdecl_import (qdecl, 0);
+        IDENTIFIER_VALUE (qid) = qdecl;
+    }
   TREE_USED (item) = 1;
 }
 
@@ -3500,7 +3613,7 @@
         t = TREE_PURPOSE (ename);
         if (TREE_CODE (t) == FUNCTION_DECL && PASCAL_FORWARD_DECLARATION (t))
           set_forward_decl (t, 1);
-        import_node (ename, NULL_TREE);
+        import_node (ename, NULL_TREE, NULL_TREE, IMPORT_ISO);
       }
   current_module->initializers = itab_get_initializers (interface_name);  /* @@ use any interface name */
 }
@@ -3528,11 +3641,16 @@
 void
 import_interface (interface, import_qualifier, qualified, filename)
      tree interface, import_qualifier;
-     int qualified;
+     import_type qualified;
      tree filename;
 {
   tree exported_name_list, imported, exported, ename, iname;
+  tree import_decl;
   struct predef *pd;
+#ifndef EGCS97
+  struct obstack *ambient_obstack = current_obstack;
+  current_obstack = &permanent_obstack;
+#endif
 
   if (filename && TREE_CODE (filename) != STRING_CST)
     {
@@ -3549,20 +3667,25 @@
         error ("self-dependent module or unit");
       return;
     }
-
-  for (imported = current_module->imports; imported; imported = TREE_CHAIN (imported))
-    if (interface == IMPORT_INTERFACE (TREE_VALUE (imported)))
+  import_decl = lookup_name_current_level (interface);
+  if (import_decl && TREE_CODE (import_decl) == NAMESPACE_DECL)
       {
-        error ("interface `%s' has already been imported", IDENTIFIER_NAME (interface));
+      error ("interface `%s' has already been imported",
+               IDENTIFIER_NAME (interface));
         return;
       }
+  import_decl = build_decl(NAMESPACE_DECL, interface, void_type_node);
+  pushdecl (import_decl); 
+  for (imported = current_module->imports; imported; imported = TREE_CHAIN (imported))
+    if (interface == IMPORT_INTERFACE (TREE_VALUE (imported)))
+      break;
 
   if (!imported)
     {
       tree t = make_node (IMPORT_NODE);
       IMPORT_INTERFACE (t) = interface;
       IMPORT_QUALIFIER (t) = import_qualifier;
-      PASCAL_TREE_QUALIFIED (t) = !!qualified;
+      PASCAL_TREE_QUALIFIED (t) = qualified;
       IMPORT_FILENAME (t) = filename;
       imported = build_tree_list (NULL_TREE, t);
       current_module->imports = chainon (current_module->imports, imported);
@@ -3590,6 +3713,7 @@
       for (exported = exported_interface_list; exported; exported = TREE_CHAIN (exported))
         if (TREE_VALUE (exported) == interface)
           break;
+      
       if (!exported)
         {
           const char *gpi_source;
@@ -3598,14 +3722,11 @@
           else
             gpi_source = NULL;
           exported = load_gpi_file (interface, gpi_source, 0);
-          exported_interface_list = tree_cons (NULL_TREE, interface, exported_interface_list);
+          exported_interface_list = tree_cons (TREE_PURPOSE (exported), interface, exported_interface_list);
         }
       exported_name_list = TREE_PURPOSE (exported);
     }
 
-  if (qualified)
-    warning ("`qualified' not yet supported -- ignored");
-
   for (ename = exported_name_list; ename; ename = TREE_CHAIN (ename))
     TREE_USED (ename) = 0;
   if (import_qualifier)
@@ -3616,7 +3737,7 @@
           ename = TREE_CHAIN (ename);
         /* Activate this name and resolve possible import renaming. */
         if (ename)
-          import_node (ename, TREE_VALUE (iname));
+          import_node (ename, TREE_VALUE (iname), interface, qualified);
         else
           error ("interface `%s' does not export `%s'",
                  IDENTIFIER_NAME (interface), IDENTIFIER_NAME (TREE_PURPOSE (iname)));
@@ -3626,7 +3747,10 @@
   if (!(import_qualifier && TREE_PURPOSE (import_qualifier)))
     for (ename = exported_name_list; ename; ename = TREE_CHAIN (ename))
       if (!TREE_USED (ename))
-        import_node (ename, NULL_TREE);
+        import_node (ename, NULL_TREE, interface, qualified);
+#ifndef EGCS97
+    current_obstack = ambient_obstack;
+#endif
 }
 
 /* Replace the exported TREE_LISTs denoting ranges by the actual identifier
@@ -3658,8 +3782,21 @@
             {
               if (tree_int_cst_equal (TREE_VALUE (item), DECL_INITIAL (tlow)))
                 export_it = 1;
-              if (export_it)
-                exported = tree_cons (NULL_TREE, TREE_PURPOSE (item), exported);
+              if (export_it) 
+                {
+                  tree id = TREE_PURPOSE (item);
+                  tree tid = lookup_name (id);
+                  if ( !tid || TREE_CODE (tid) != CONST_DECL 
+                       || DECL_INITIAL (tid) != TREE_VALUE (item)
+                       || !PASCAL_CST_PRINCIPAL_ID (tid))
+                    {
+                      error ("Can not export range value %s", 
+                               IDENTIFIER_POINTER (id));
+                      error (" principal identifier not in scope");
+                    }
+                   else
+                     exported = tree_cons (NULL_TREE, id, exported);
+                }
               if (tree_int_cst_equal (TREE_VALUE (item), DECL_INITIAL (thigh)))
                 {
                   if (!export_it)
diff -ru gpc-20040516.orig/p/objects.c gpc-20040516/p/objects.c
--- gpc-20040516.orig/p/objects.c	2004-05-12 17:08:07.000000000 +0200
+++ gpc-20040516/p/objects.c	2004-07-06 19:08:51.000000000 +0200
@@ -385,7 +385,12 @@
         PASCAL_METHOD (method) = 1;
         TREE_PROTECTED (method) = protected_private == 1;
         TREE_PRIVATE (method) = protected_private == 2;
-        SET_DECL_ASSEMBLER_NAME (method, assembler_name ? check_assembler_name (assembler_name) : method_name);
+        if (assembler_name)
+          assembler_name = check_assembler_name (assembler_name);
+        else
+          assembler_name = pascal_mangle_names (object_name,
+                              IDENTIFIER_POINTER (name));
+        SET_DECL_ASSEMBLER_NAME (method, assembler_name);
         DECL_LANG_SPECIFIC (method) = allocate_decl_lang_specific ();
         DECL_LANG_PARMS (method) = TREE_PURPOSE (TREE_OPERAND (h, 1));
         DECL_LANG_RESULT_VARIABLE (method) = (TREE_CHAIN (heading) && TREE_PRIVATE (TREE_CHAIN (heading))) ? NULL_TREE : TREE_CHAIN (heading);
diff -ru gpc-20040516.orig/p/options.c gpc-20040516/p/options.c
--- gpc-20040516.orig/p/options.c	2004-05-14 16:38:19.000000000 +0200
+++ gpc-20040516/p/options.c	2004-07-06 19:08:51.000000000 +0200
@@ -27,6 +27,10 @@
 #include "gpc-options.h"
 #include "p/version.h"
 
+#ifdef GCC_3_4
+#include "options.h"
+#endif
+
 /* An array with all long Pascal command-line switches. */
 static const struct
 {
@@ -890,8 +894,13 @@
 
 /* This initialization is run once per compilation just before command-line
    options are processed. */
+#ifndef GCC_3_4
 void
 pascal_init_options ()
+#else
+unsigned int
+pascal_init_options (unsigned int argc, const char * * argv)
+#endif
 {
   const char *const *option;
   char *p, *q, *r;
@@ -901,10 +910,14 @@
      version number there, let's at least output it here ... */
   /* Great! toplev.h doesn't even export version_flag, so check for
      it again. :-/ At least it exports save_arg[cv] ... */
+#ifndef GCC_3_4
   int version_flag = 0, i;
   for (i = 1; i < save_argc; i++)
     if (!strcmp (save_argv[i], "-version"))
       version_flag = 1;
+#else
+  const char * * save_argv = argv;
+#endif
   if (version_flag)
     fprintf (stderr, "GNU Pascal version is actually %s, based on gcc-%s\n", GPC_RELEASE_STRING, version_string);
 
@@ -920,6 +933,7 @@
   /* Initialize the default paths, using the directory we are living in. */
   string_append (&default_unit_path, getenv ("GPC_UNIT_PATH"), path_separator_str);
   string_append (&default_object_path, getenv ("GPC_OBJECT_PATH"), path_separator_str);
+#ifndef GCC_3_4
   p = save_string (save_argv[0]);
   q = p + strlen (p) - 1;
   while (q >= p && !IS_DIR_SEPARATOR (*q))
@@ -933,6 +947,10 @@
       string_append (&default_unit_path, p, path_separator_str);
     }
   free (p);
+#else
+  string_append (&default_unit_path, GPC_UNITS_DIR, path_separator_str);
+  return CL_Pascal;
+#endif
 }
 
 void
diff -ru gpc-20040516.orig/p/opts.sum gpc-20040516/p/opts.sum
--- gpc-20040516.orig/p/opts.sum	2004-07-06 19:20:03.000000000 +0200
+++ gpc-20040516/p/opts.sum	2004-07-06 19:08:51.000000000 +0200
@@ -0,0 +1,111 @@
+Wall::
+Wcomment::
+Wmissing-declarations::
+Wmissing-prototypes::
+Wpointer-arith::
+Wundef::
+Wwrite-strings::
+fexecutable-file-name=:Joined RejectNegative:
+ffield-widths=:Joined RejectNegative:
+Wabsolute::Warn about variables at absolute adresses and `absolute' variable with non-constant addresses (default)
+Wfloat-equal::Warn about `=' and `<>' comparisons of real numbers
+Widentifier-case-local::Warn about an identifier written with varying case within one program/module/unit
+Widentifier-case::Warn about an identifier written with varying case
+Wimplicit-abstract::Warn when an object type not declared `abstract' contains an abstract method (default)
+Wimplicit-io::Warn when `Input' or `Output' are used implicitly
+Winherited-abstract::Warn when an abstract object type inherits from a non-abstract one (default)
+Winterface-file-name::Warn when a unit/module interface differs from the file name
+Wlocal-external::Warn about local `external' declarations
+Wmixed-comments::Warn about mixed comments like `{ ... *)'
+Wnear-far::Warn about use of useless `near' or `far' directives (default)
+Wnested-comments::Warn about nested comments like `{ { } }'
+Wobject-assignment::Warn when when assigning objects or declaring them as value parameters or function results (default)
+Wsemicolon::Warn about a semicolon after `then', `else' or `do' (default)
+Wtyped-const::Warn about misuse of typed constants as initialized variables (default)
+Wunderscore::Warn about double/leading/trailing underscores in identifiers
+Wwarnings::Enable warnings (same as `{$W+}')
+fassertions::Enable assertion checking (default)
+fautobuild::Automatically compile all units/modules/`{$L ...}' files and link the object files provided
+fautolink::Automatically link object files provided by units/modules or `{$L ...}' (default)
+fautomake::Automatically compile changed units/modules/`{$L ...}' files and link the object files provided
+fcstrings-as-strings::Treat CStrings as strings
+fdelphi-comments::Allow Delphi style `//' comments (default)
+fdouble-quoted-strings::Allow strings enclosed in \"\" (default)
+fexact-compare-strings::Do not blank-pad strings for comparisons
+fextended-syntax::same as `--ignore-function-results --pointer-arithmetic --cstrings-as-strings -Wno-absolute' (same as `{$X+}')
+ffield-widths::Optional colon-separated list of default field widths for Integer, Real, Boolean, LongInt, LongReal
+fignore-function-results::Do not complain when a function is called like a procedure
+fignore-garbage-after-dot::Ignore anything after the terminating `.' (default in `--borland-pascal')
+fignore-packed::Ignore `packed' in the source code (default in `--borland-pascal')
+fio-checking::Check I/O operations automatically (same as `{$I+}') (default)
+flongjmp-all-nonlocal-labels::Use `longjmp' for all nonlocal labels
+fmacros::Expand macros (default)
+fmethods-always-virtual::Make all methods virtual (default in `--mac-pascal')
+fmixed-comments::Allow comments like `{ ... *)' as required in ISO Pascal (default in ISO 7185/10206 Pascal mode)
+fnested-comments::Allow nested comments like `{ { } }' and `(* (* *) *)'
+fpedantic::Reject everything not allowed in some dialect, e.g. redefinition of its keywords
+fpointer-arithmetic::Enable pointer arithmetic
+fprogress-bar::Output number of processed lines while compiling
+fprogress-messages::Output source file names and line numbers while compiling
+frange-checking::Do automatic range checks (same as `{$R+}') (default)
+fread-base-specifier::In read statements, allow input base specifier `n#' (default)
+fread-hex::In read statements, allow hexadecimal input with `$' (default)
+fread-white-space::In read statements, require whitespace after numbers
+fshort-circuit::Guarantee short-circuit Boolean evaluation (default; same as `{$B-}')
+fstack-checking::Enable stack checking (same as `{$S+}')
+ftransparent-file-names::Derive external file names from variable names
+ftruncate-strings::Truncate strings being assigned to other strings of too short capacity.
+ftyped-address::Make the result of the address operator typed (same as `{$T+}', default)
+fwrite-capital-exponent::Write real exponents with a capital `E'
+fwrite-clip-strings::In write statements, truncate strings exceeding their field width (`Write (SomeLongString : 3)')
+fwrite-real-blank::Output a blank in front of positive reals in exponential form (default)
+fbig-endian:RejectNegative:Tell GPC that the system is big-endian (for those targets where it can vary)
+fborland-pascal:RejectNegative:Try to emulate Borland Pascal, version 7.0
+fclassic-pascal-level-0:RejectNegative:Reject conformant arrays and anything besides ISO 7185 Pascal
+fclassic-pascal:RejectNegative:Reject anything besides ISO 7185 Pascal
+fdebug-automake:RejectNegative:(For GPC developers.) Give additional information about the actions of automake
+fdebug-gpi:RejectNegative:(For GPC developers.) Show what is written to and read from GPI files (huge output!)
+fdebug-source:RejectNegative:Output the source while it is processed
+fdelphi:RejectNegative:Try to emulate Borland Pascal, version 7.0, with some Delphi extensions
+fexecutable-file-name:RejectNegative:Name for the output file, if specified; otherwise derive from main source file name
+fextended-pascal:RejectNegative:Reject anything besides ISO 10206 Extended Pascal
+fgnu-pascal:RejectNegative:Undo the effect of previous dialect options, allow all features again
+fimplementation-only:RejectNegative:Do not produce a GPI file; only compile the implementation part
+finterface-only:RejectNegative:Compile only the interface part of a unit/module and exit (creates `.gpi' file, no `.o' file)
+flittle-endian:RejectNegative:Tell GPC that the system is little-endian (for those targets where it can vary)
+fmac-pascal:RejectNegative:Support (some features of) traditional Macintosh Pascal compilers
+fdebug-info::Inhibit `-g' options (temporary work-around, this option may disappear in the future)
+fdefault-paths::Do not add a default path to the unit and object path
+fexecutable-path::Create the executable file in the directory where the main source is (default)
+fobject-destination-path::Create additional object files (e.g. of C files, not Pascal units) in the current directory (default)
+fobject-path::Forget about directories where to look for additional object (and source) files
+funit-destination-path::Create object and GPI files of Pascal units in the current directory (default)
+funit-path::Forget about directories where to look for unit/module sources
+fobject-pascal:RejectNegative:Reject anything besides (the implemented parts of) ANSI draft Object Pascal
+fpascal-sc:RejectNegative:Be strict about the implemented Pascal-SC extensions
+fprint-needed-options:RejectNegative:Print the needed options
+fstandard-pascal-level-0:RejectNegative:Synonym for `--classic-pascal-level-0'
+fstandard-pascal:RejectNegative:Synonym for `--classic-pascal'
+fsun-pascal:RejectNegative:Support (a few features of) Sun Pascal
+fucsd-pascal:RejectNegative:Try to emulate UCSD Pascal
+fvax-pascal:RejectNegative:Support (a few features of) VAX Pascal
+famtmpfile=:Joined RejectNegative:(Internal switch used for automake)
+fautomake-g++=:Joined RejectNegative:Set the C++ compiler invoked by automake
+fautomake-gcc=:Joined RejectNegative:Set the C compiler invoked by automake
+fautomake-gpc=:Joined RejectNegative:Set the Pascal compiler invoked by automake
+fcidefine=:Joined RejectNegative:Define a case-insensitive macro
+fcsdefine=:Joined RejectNegative:Define a case-sensitive macro
+fdebug-tree=:Joined RejectNegative:(For GPC developers.) Show the internal representation of a given tree node (name or address)
+fdisable-keyword=:Joined RejectNegative:Disable a keyword, independently of dialect defaults
+fenable-keyword=:Joined RejectNegative:Enable a keyword, independently of dialect defaults
+fexecutable-path=:Joined RejectNegative:Path where to create the executable file
+fgpc-main=:Joined RejectNegative:External name for the program's entry point (default: `main')
+fgpi-destination-path=:Joined RejectNegative:(Internal switch used for automake)
+finit-modules=:Joined RejectNegative:Initialize the named modules in addition to those imported regularly; kind of a kludge
+fmaximum-field-alignment=:Joined RejectNegative:Set the maximum field alignment in bits if `pack-struct' is in effect
+fobject-destination-path=:Joined RejectNegative:Path where to create additional object files (e.g. of C files, not Pascal units)
+fobject-path=:Joined RejectNegative:Directories where to look for additional object (and source) files
+fsetlimit=:Joined RejectNegative:Define the range for `set of Integer' etc.
+funit-destination-path=:Joined RejectNegative:Path where to create object and GPI files of Pascal units
+funit-path=:Joined RejectNegative:Directories where to look for unit/module sources
+fuses=:Joined RejectNegative:Add an implicit `uses' clause
diff -ru gpc-20040516.orig/p/parse.y gpc-20040516/p/parse.y
--- gpc-20040516.orig/p/parse.y	2004-05-12 17:04:56.000000000 +0200
+++ gpc-20040516/p/parse.y	2004-07-06 19:12:30.000000000 +0200
@@ -77,6 +77,8 @@
 static int parentheses_count = 0;
 static tree iso_no_parentheses PARAMS ((tree));
 
+static int in_uses = 0;
+
 enum { od_none, od_uses, od_label, od_const, od_type, od_var, od_routine };
 static int check_decl_order PARAMS ((int, int));
 
@@ -86,7 +88,17 @@
 union yyGLRStackItem;
 static void locations PARAMS ((YYLTYPE *, const union yyGLRStackItem*, int));
 #define YYLLOC_DEFAULT(DEST, SRC, N) locations (&DEST, SRC, N)
+#ifndef GCC_3_4
 #define LOCATION_NOTE(LOC) if (current_function_decl) emit_line_note ((LOC).first_file, (LOC).first_line)
+#else
+#define LOCATION_NOTE(LOC) if (current_function_decl) \
+  { \
+    location_t loc_aux; \
+    loc_aux.file = (LOC).first_file; \
+    loc_aux.line = (LOC).first_line; \
+    emit_line_note (loc_aux); \
+  }
+#endif
 #define COPYLOC(D, S) (* (YYLTYPE *) memcpy (&(D), &(S), sizeof (YYLTYPE)))
 
 #define YYASSERT assert
@@ -113,6 +125,9 @@
    - put all the look-ahead tokens needed in the precedence in one single
      `%nonassoc' declaration. */
 
+%nonassoc prec_id
+%nonassoc '.'
+
 /* Dangling else */
 %nonassoc prec_if
 
@@ -127,7 +142,8 @@
   p_else
 
   /* higher than prec_import */
-  p_uses p_implementation p_constructor p_destructor p_operator
+  p_uses p_initialization p_implementation p_constructor p_destructor
+  p_operator
 
   /* higher than prec_lower_than_error */
   error
@@ -216,6 +232,7 @@
   optional_variable_directive_list subrange_type object_section conformant_array
   operator_symbol initializer_expression typename_or_string255 asm_clobbers term
   id_list factor attrib id_list_limited id_list1 intconst caret_letter id null
+  qualified_id_access typename_1 new_quid
   err
 
 /* Unimplemented ISO initializers
@@ -368,7 +385,7 @@
 
 optional_unit_implementation:
       { chk_dialect ("units without `implementation' part are", U_M_PASCAL); }
-  | p_implementation declarations_and_uses optional_unit_init_and_final_part { }
+  | p_implementation optional_import_part1 declarations_and_uses optional_unit_init_and_final_part { }
   ;
 
 module:
@@ -543,25 +560,40 @@
   ;
 
 export_list_item:
-    new_identifier optional_rename
+    new_quid optional_rename
       { $$ = build_tree_list ($2, $1); }
-  | new_identifier LEX_RANGE new_identifier
+  | new_quid LEX_RANGE new_quid
       { $$ = build_tree_list (NULL_TREE, build_tree_list ($1, $3)); }
-  | i_protected new_identifier optional_rename
+  | i_protected new_quid optional_rename
       { $$ = build_tree_list ($3, $2); TREE_READONLY ($$) = 1; }
   ;
 
+new_quid:
+    new_identifier
+  | new_identifier '.' new_identifier
+     { $$ = build_qualified_id ($1,$3);}
+  ;
+
 optional_rename:
     null
   | LEX_RENAME new_identifier
       { $$ = $2; }
   ;
 
-optional_import_part:
+
+extra_import_part:
     /* empty */
       { do_extra_import (); }
-  |   { do_extra_import (); }
-    p_import import_specification_list ';' %prec prec_import
+  ;
+
+optional_import_part1:
+    /* empty */
+  |  
+    p_import { in_uses = 0 } import_specification_list ';' %prec prec_import
+  ;
+
+optional_import_part:
+  extra_import_part optional_import_part1
   ;
 
 import_specification_list:
@@ -572,7 +604,7 @@
   ;
 
 uses_part:
-    p_uses uses_list ';'
+    p_uses { in_uses = 1 } uses_list ';'
       { $$ = od_uses; }
   ;
 
@@ -585,7 +617,8 @@
 
 import_specification:
     new_identifier optional_access_qualifier optional_import_qualifier optional_unit_filename
-      { import_interface ($1, $3, $2, $4); }
+      { import_interface ($1, $3, ($2 == 1) ? IMPORT_QUALIFIED : 
+                           (in_uses ? IMPORT_USES : IMPORT_ISO), $4); }
   ;
 
 optional_access_qualifier:
@@ -829,7 +862,7 @@
   ;
 
 typename:
-    id
+    typename_1
       {
         tree decl = lookup_name ($1);
         $$ = error_mark_node;
@@ -842,6 +875,12 @@
       }
   ;
 
+typename_1:
+    id
+  | id '.' id
+     { $$ = build_qualified_id ($1,$3);}
+  ;
+
 actual_schema_discriminants:
     '(' discriminant_expression_list ')'
       { chk_dialect ("schema/string discriminants are", E_O_PASCAL); $$ = $2; }
@@ -916,15 +955,15 @@
 /* Pointers */
 new_pointer_type:
     '@' pointer_domain_type
-      { $$ = EM ($2) ? error_mark_node : build_pointer_type ($2); }
+      { $$ = EM ($2) ? error_mark_node : build_pascal_pointer_type ($2); }
   | '^' pointer_domain_type
-      { $$ = EM ($2) ? error_mark_node : build_pointer_type ($2); }
+      { $$ = EM ($2) ? error_mark_node : build_pascal_pointer_type ($2); }
   | LEX_CARET_WHITE pointer_domain_type
-      { $$ = EM ($2) ? error_mark_node : build_pointer_type ($2); }
+      { $$ = EM ($2) ? error_mark_node : build_pascal_pointer_type ($2); }
   | pointer_char p_const pointer_domain_type
       {
         chk_dialect ("pointers to `const' types are", GNU_PASCAL);
-        $$ = EM ($3) ? error_mark_node : build_pointer_type (p_build_type_variant ($3, 1, TYPE_VOLATILE ($3)));
+        $$ = EM ($3) ? error_mark_node : build_pascal_pointer_type (p_build_type_variant ($3, 1, TYPE_VOLATILE ($3)));
       }
   ;
 
@@ -1551,6 +1590,7 @@
       { declare_routine ($1, $3, 0); }
   | routine_or_method_heading ';' optional_routine_directive_list
       { $<ttype>$ = start_routine ($1, $3); }
+    optional_import_part1
     any_declaration_part
       {
         do_setjmp ();
@@ -2330,8 +2370,14 @@
   | variable_or_routine_access_no_builtin_function
   ;
 
-variable_or_routine_access_no_builtin_function:
+qualified_id_access:
     identifier
+  | id '.' new_identifier
+      { $$ = build_qualified_or_component_acces ($1, $3); }
+  ;
+
+variable_or_routine_access_no_builtin_function:
+    qualified_id_access
   | p_inherited new_identifier
       { $$ = build_inherited_method ($2); }
   | variable_or_routine_access_no_parentheses '.' new_identifier
@@ -2638,7 +2684,7 @@
 
 identifier:
     id
-      { $$ = check_identifier ($1); }
+      { $$ = check_identifier ($1); } %prec prec_id 
   ;
 
 id:
@@ -2809,7 +2855,16 @@
          parser in the right places causes some conflicts (especially assignments
          with nontrivial expressions on their left side are problematic). */
       if (current_function_decl)
+#ifndef GCC_3_4
         emit_line_note (dest->first_file, dest->first_line);
+#else
+        {
+          location_t loc_aux;
+	  loc_aux.file = dest->first_file;
+	  loc_aux.line = dest->first_line;
+          emit_line_note (loc_aux);
+        }
+#endif
     }
   dest->option_id = 0;
   for (i = 1; i <= n; i++)
diff -ru gpc-20040516.orig/p/p-tree.def gpc-20040516/p/p-tree.def
--- gpc-20040516.orig/p/p-tree.def	2004-01-01 00:11:33.000000000 +0100
+++ gpc-20040516/p/p-tree.def	2004-07-06 19:08:51.000000000 +0200
@@ -38,4 +38,5 @@
 DEFTREECODE (POWER_EXPR, "power_expr", "2", 2)
 DEFTREECODE (POW_EXPR, "pow_expr", "2", 2)
 DEFTREECODE (SYMDIFF_EXPR, "symdiff_expr", "2", 2)
+DEFTREECODE (NAMESPACE_DECL, "namespace_decl", "d", 0)
 #endif
diff -ru gpc-20040516.orig/p/rts/endian.pas gpc-20040516/p/rts/endian.pas
--- gpc-20040516.orig/p/rts/endian.pas	2004-01-01 00:23:28.000000000 +0100
+++ gpc-20040516/p/rts/endian.pas	2004-07-06 19:08:51.000000000 +0200
@@ -30,7 +30,7 @@
 
 {$gnu-pascal,I-}
 
-unit Endian; attribute (name = 'GPC');
+unit Endian; attribute (name = '_p__rts_Endian');
 
 interface
 
diff -ru gpc-20040516.orig/p/rts/error.pas gpc-20040516/p/rts/error.pas
--- gpc-20040516.orig/p/rts/error.pas	2004-05-12 16:31:05.000000000 +0200
+++ gpc-20040516/p/rts/error.pas	2004-07-06 19:08:51.000000000 +0200
@@ -31,7 +31,7 @@
 
 {$gnu-pascal,I-}
 
-unit Error; attribute (name = 'GPC');
+unit Error; attribute (name = '_p__rts_Error');
 
 interface
 
diff -ru gpc-20040516.orig/p/rts/filename.pas gpc-20040516/p/rts/filename.pas
--- gpc-20040516.orig/p/rts/filename.pas	2004-05-07 16:48:07.000000000 +0200
+++ gpc-20040516/p/rts/filename.pas	2004-07-06 19:08:51.000000000 +0200
@@ -31,7 +31,7 @@
 
 {$gnu-pascal,I-}
 
-unit FileName; attribute (name = 'GPC');
+unit FileName; attribute (name = '_p__rts_FileName');
 
 interface
 
diff -ru gpc-20040516.orig/p/rts/files.pas gpc-20040516/p/rts/files.pas
--- gpc-20040516.orig/p/rts/files.pas	2004-05-07 16:48:09.000000000 +0200
+++ gpc-20040516/p/rts/files.pas	2004-07-06 19:08:51.000000000 +0200
@@ -31,7 +31,7 @@
 
 {$gnu-pascal,I-}
 
-unit Files; attribute (name = 'GPC');
+unit Files; attribute (name = '_p__rts_Files');
 
 interface
 
diff -ru gpc-20040516.orig/p/rts/getopt.pas gpc-20040516/p/rts/getopt.pas
--- gpc-20040516.orig/p/rts/getopt.pas	2004-05-07 16:48:11.000000000 +0200
+++ gpc-20040516/p/rts/getopt.pas	2004-07-06 19:08:51.000000000 +0200
@@ -30,7 +30,7 @@
 
 {$gnu-pascal,I-}
 
-unit GetOpt; attribute (name = 'GPC');
+unit GetOpt; attribute (name = '_p__rts_GetOpt');
 
 interface
 
diff -ru gpc-20040516.orig/p/rts/heap.pas gpc-20040516/p/rts/heap.pas
--- gpc-20040516.orig/p/rts/heap.pas	2004-04-08 14:34:05.000000000 +0200
+++ gpc-20040516/p/rts/heap.pas	2004-07-06 19:08:51.000000000 +0200
@@ -31,7 +31,7 @@
 
 {$gnu-pascal,I-}
 
-unit Heap; attribute (name = 'GPC');
+unit Heap; attribute (name = '_p__rts_Heap');
 
 interface
 
diff -ru gpc-20040516.orig/p/rts/init.pas gpc-20040516/p/rts/init.pas
--- gpc-20040516.orig/p/rts/init.pas	2004-05-07 16:48:14.000000000 +0200
+++ gpc-20040516/p/rts/init.pas	2004-07-06 19:08:51.000000000 +0200
@@ -30,7 +30,7 @@
 
 {$gnu-pascal,I-}
 
-unit Init; attribute (name = 'GPC');
+unit Init; attribute (name = '_p__rts_Init');
 
 interface
 
@@ -264,7 +264,7 @@
   if InitProc <> nil then InitProc^
 end;
 
-procedure InitInit; external name 'init_GPC_Init';
+procedure InitInit; external name '_p__rts_Init_init';
 
 procedure GPC_Initialize (ArgumentCount: Integer; Arguments, StartEnvironment: PCStrings; Options: Integer);
 begin
diff -ru gpc-20040516.orig/p/rts/Makefile.in gpc-20040516/p/rts/Makefile.in
--- gpc-20040516.orig/p/rts/Makefile.in	2004-05-13 15:56:28.000000000 +0200
+++ gpc-20040516/p/rts/Makefile.in	2004-07-06 19:08:51.000000000 +0200
@@ -190,7 +190,7 @@
 $(GPCLIB): $(OBJS)
 	-rm -f $(GPCLIB)
 	$(AR) $(AR_FLAGS) $(GPCLIB) $(OBJS)
-	if $(RANLIB_TEST); then $(RANLIB) $(GPCLIB); else true; fi
+	-$(RANLIB) $(GPCLIB)
 
 # That's a way to do an `if' that even a stupid make understands ...
 sharedlib. sharedlib.no sharedlib.@with_shared$(DUMMY)@:
diff -ru gpc-20040516.orig/p/rts/math.pas gpc-20040516/p/rts/math.pas
--- gpc-20040516.orig/p/rts/math.pas	2004-05-12 16:47:11.000000000 +0200
+++ gpc-20040516/p/rts/math.pas	2004-07-06 19:08:51.000000000 +0200
@@ -33,7 +33,7 @@
 
 {$gnu-pascal,I-}
 
-unit Math; attribute (name = 'GPC');
+unit Math; attribute (name = '_p__rts_Math');
 
 interface
 
diff -ru gpc-20040516.orig/p/rts/move.pas gpc-20040516/p/rts/move.pas
--- gpc-20040516.orig/p/rts/move.pas	2004-01-01 00:23:08.000000000 +0100
+++ gpc-20040516/p/rts/move.pas	2004-07-06 19:08:51.000000000 +0200
@@ -31,7 +31,7 @@
 
 {$gnu-pascal,I-}
 
-unit Move; attribute (name = 'GPC');
+unit Move; attribute (name = '_p__rts_Move');
 
 interface
 
diff -ru gpc-20040516.orig/p/rts/numtodec.pas gpc-20040516/p/rts/numtodec.pas
--- gpc-20040516.orig/p/rts/numtodec.pas	2004-01-01 00:23:06.000000000 +0100
+++ gpc-20040516/p/rts/numtodec.pas	2004-07-06 19:08:51.000000000 +0200
@@ -33,7 +33,7 @@
 
 {$gnu-pascal,I-}
 
-unit NumToDec; attribute (name = 'GPC');
+unit NumToDec; attribute (name = '_p__rts_NumToDec');
 
 interface
 
diff -ru gpc-20040516.orig/p/rts/random.pas gpc-20040516/p/rts/random.pas
--- gpc-20040516.orig/p/rts/random.pas	2004-05-08 14:34:20.000000000 +0200
+++ gpc-20040516/p/rts/random.pas	2004-07-06 19:08:51.000000000 +0200
@@ -31,7 +31,7 @@
 
 {$gnu-pascal,I-}
 
-unit Random; attribute (name = 'GPC');
+unit Random; attribute (name = '_p__rts_Random');
 
 interface
 
diff -ru gpc-20040516.orig/p/rts/rtsc.pas gpc-20040516/p/rts/rtsc.pas
--- gpc-20040516.orig/p/rts/rtsc.pas	2004-05-15 21:54:02.000000000 +0200
+++ gpc-20040516/p/rts/rtsc.pas	2004-07-06 19:08:51.000000000 +0200
@@ -40,7 +40,7 @@
 
 {$gnu-pascal,I-}
 
-unit RTSC; attribute (name = 'GPC');
+unit RTSC; attribute (name = '_p__rts_RTSC');
 
 interface
 
diff -ru gpc-20040516.orig/p/rts/sets.pas gpc-20040516/p/rts/sets.pas
--- gpc-20040516.orig/p/rts/sets.pas	2004-01-01 00:22:52.000000000 +0100
+++ gpc-20040516/p/rts/sets.pas	2004-07-06 19:08:51.000000000 +0200
@@ -40,7 +40,7 @@
 
 {$gnu-pascal,I-} { @@ $R- }
 
-unit Sets; attribute (name = 'GPC');
+unit Sets; attribute (name = '_p__rts_Sets');
 
 interface
 
diff -ru gpc-20040516.orig/p/rts/string1.pas gpc-20040516/p/rts/string1.pas
--- gpc-20040516.orig/p/rts/string1.pas	2004-05-07 16:47:39.000000000 +0200
+++ gpc-20040516/p/rts/string1.pas	2004-07-06 19:08:51.000000000 +0200
@@ -32,7 +32,7 @@
 
 {$gnu-pascal,I-}
 
-unit String1; attribute (name = 'GPC');
+unit String1; attribute (name = '_p__rts_String1');
 
 interface
 
diff -ru gpc-20040516.orig/p/rts/string2.pas gpc-20040516/p/rts/string2.pas
--- gpc-20040516.orig/p/rts/string2.pas	2004-05-07 16:48:19.000000000 +0200
+++ gpc-20040516/p/rts/string2.pas	2004-07-06 19:08:51.000000000 +0200
@@ -31,7 +31,7 @@
 
 {$gnu-pascal,I-}
 
-unit String2; attribute (name = 'GPC');
+unit String2; attribute (name = '_p__rts_String2');
 
 interface
 
diff -ru gpc-20040516.orig/p/rts/time.pas gpc-20040516/p/rts/time.pas
--- gpc-20040516.orig/p/rts/time.pas	2004-05-07 16:48:27.000000000 +0200
+++ gpc-20040516/p/rts/time.pas	2004-07-06 19:08:51.000000000 +0200
@@ -31,7 +31,7 @@
 
 {$gnu-pascal,I-}
 
-unit Time; attribute (name = 'GPC');
+unit Time; attribute (name = '_p__rts_Time');
 
 interface
 
diff -ru gpc-20040516.orig/p/statements.c gpc-20040516/p/statements.c
--- gpc-20040516.orig/p/statements.c	2004-05-12 02:43:34.000000000 +0200
+++ gpc-20040516/p/statements.c	2004-07-06 19:08:51.000000000 +0200
@@ -89,7 +89,16 @@
   /* Generate the ASM_OPERANDS insn; store into the TREE_VALUEs of OUTPUTS
      some trees for where the values were actually stored. */
   if (outputs || inputs || clobbers)
+#ifndef GCC_3_4
     expand_asm_operands (string, outputs, inputs, clobbers, vol, input_filename, lineno);
+#else
+    {
+      location_t loc_aux;
+      loc_aux.file = input_filename;
+      loc_aux.line = lineno;
+      expand_asm_operands (string, outputs, inputs, clobbers, vol, loc_aux);
+    }
+#endif
   else
     /* @@ GCC since 20021213 wants:
          expand_asm (string, vol);
@@ -103,7 +112,7 @@
   for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++)
     if (o[i] != TREE_VALUE (tail))
       {
-        expand_expr (build_modify_expr (o[i], NOP_EXPR, TREE_VALUE (tail)), 0, VOIDmode, 0);
+        expand_expr_stmt (build_modify_expr (o[i], NOP_EXPR, TREE_VALUE (tail)));
         free_temp_slots ();
       }
 
@@ -814,7 +823,11 @@
     }
 
   if (TREE_CODE (thing) == VAR_DECL && !DECL_ARTIFICIAL (thing))
+#ifndef GCC_3_4
     emit_line_note (DECL_SOURCE_FILE (thing), DECL_SOURCE_LINE (thing));
+#else
+    emit_line_note (DECL_SOURCE_LOCATION (thing));
+#endif
   switch (TREE_CODE (type))
   {
     case ARRAY_TYPE:
@@ -1392,9 +1405,19 @@
   check_forward_decls (1);
   check_external_objects (current_module->parms);
   /* According to the standard the program name is in a separate name
-     space, so we use the special name `pascal_main_program'. */
+     space, so we build a special name for main program. */
+  /* Does not work when compiled by 2.95.3
   start_implicit_routine (NULL_TREE, get_identifier_with_spelling
-    ("pascal_main_program", "main program"), void_type_node, NULL_TREE);
+        (ACONCAT ((IDENTIFIER_POINTER (current_module->assembler_name),
+          "_main_program", NULL)),
+     "main program"), void_type_node, NULL_TREE);
+*/
+  {
+    char * n = ACONCAT ((IDENTIFIER_POINTER (current_module->assembler_name),
+                            "_main_program", NULL));
+    start_implicit_routine (NULL_TREE, get_identifier_with_spelling
+                    (n, "main program"), void_type_node, NULL_TREE);
+  }
   do_setjmp ();
 }
 
@@ -1475,7 +1498,9 @@
   call_no_args (TREE_VALUE (current_module->initializers), 1);
 
   /* Call the Pascal main program. */
-  call_no_args (get_identifier ("pascal_main_program"), 0);
+  call_no_args (get_identifier ( ACONCAT ((
+       IDENTIFIER_POINTER (current_module->assembler_name),
+       "_main_program" , NULL))), 0);
 
   /* Call the RTS finalization routine. */
   call_no_args (get_identifier ("_p_finalize"), 1);
@@ -1521,20 +1546,69 @@
          initializers; initializers = TREE_CHAIN (initializers))
       call_no_args (TREE_VALUE (initializers), 1);
 
+#define SKIP_WHITE() do { while (*p == ' ' || *p == '\t') p++; } while (0)
+
+#ifndef EGCS97
+#define ISIDNUM(c) (isalnum(c)||(c) == '_')
+#endif
+
   if (extra_inits)
     {
       char *buffer = alloca (strlen (extra_inits) + 1), *p = extra_inits;
+      char module_name_len[23];
       while (*p)
         {
           char *q = buffer, *name;
           tree t;
-          while (*p && *p != ',' && *p != ':')
+          SKIP_WHITE();
+          if (*p == '\'')
+            {
+              p++;
+              while (*p)
+                {
+                  if (*p == '\'')
+                    {
+                       if (*(p+1) == '\'')
+                         p++;
+                       else
+                         break;
+                    }
+                    *q++ = *p++;
+                }
+              *q = 0;
+              if (*p != '\'')
+                error ("unterminated string in `--init-modules'");
+              else
+                {
+                  p++;
+                }
+              name = ACONCAT ((buffer, "_init", NULL));
+            }   
+          else
+            {
+              while (*p && ISIDNUM (*p))
+                {
             if (q == buffer)
+                    {
+                      if (*p <= '9' && *p >= '0')
+                        error("invalid char in name in `--init-modules'");
               *q++ = TOUPPER (*p++);
+                    }
             else
               *q++ = TOLOWER (*p++);
+                }
           *q = 0;
-          name = ACONCAT (("init_", buffer, NULL));
+              sprintf(module_name_len, "%ld_", (long)strlen(buffer));
+              name = ACONCAT (("_p__M", module_name_len, buffer, "_init", NULL));
+            }
+            SKIP_WHITE ();
+            if (*p && *p != ',' && *p != ':')
+              {
+                error ("invalid char in name in `--init-modules'");
+                while (*p && *p != ',' && *p != ':') p++;
+              }
+            if (*p)
+              p++;
           /* Don't call our own constructor recursively. This check
              is redundant currently, since the run_condition flag
              prevents the recursion, anyway, but relying on this
@@ -1545,8 +1619,6 @@
             t = TREE_CHAIN (t);
           if (!t)
             call_no_args (get_identifier (name), 1);
-          if (*p)
-            p++;
         }
     }
   extra_inits_used = 1;
diff -ru gpc-20040516.orig/p/test/chief18.pas gpc-20040516/p/test/chief18.pas
--- gpc-20040516.orig/p/test/chief18.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/chief18.pas	2002-11-16 21:36:27.000000000 +0100
@@ -0,0 +1,14 @@
+{ Qualified identifiers }
+
+Program Chief18;
+
+uses
+  one in 'chief18u.pas',
+  two in 'chief18v.pas';
+
+begin
+  if positive ( 42 ) and neutral ( 0 ) and negative ( -137 ) then
+    writeln ( 'OK' )
+  else
+    writeln ( 'failed' )
+end.
diff -ru gpc-20040516.orig/p/test/dialec5.pas gpc-20040516/p/test/dialec5.pas
--- gpc-20040516.orig/p/test/dialec5.pas	2004-05-14 23:56:16.000000000 +0200
+++ gpc-20040516/p/test/dialec5.pas	2004-07-06 19:08:51.000000000 +0200
@@ -8,7 +8,8 @@
   GPC;
   {$ifdef HAVE_CRT}
   CRT;
-  Turbo3;  { uses CRT }
+  Turbo3(LowVideo  => Turbo3_LowVideo, 
+         HighVideo => Turbo3_HighVideo);  { uses CRT }
   {$endif}
   Dos;
   DosUnix;
@@ -33,10 +34,14 @@
   {$endif}
   Strings;
   StringUtils;
-  System;
+  System (MaxLongInt => System_MaxLongInt,
+          MemAvail   => System_MemAvail,  { Memavail is in Turbo3 }
+          MaxAvail   => System_MaxAvail); { ditto }
   TFDD;
   Trap;
-  WinDos;
+  WinDos (FindFirst => WinDos_FindFirst,
+          FindNext  => WinDos_FindNext,
+          FindClose => WinDos_FindClose);
   Dialec5u;
 
 begin
diff -ru gpc-20040516.orig/p/test/err1.pas gpc-20040516/p/test/err1.pas
--- gpc-20040516.orig/p/test/err1.pas	2004-07-06 19:19:33.000000000 +0200
+++ gpc-20040516/p/test/err1.pas	2004-07-06 19:08:51.000000000 +0200
@@ -0,0 +1,3 @@
+# 1  "error1.pas" 1
+{ FLAG -x Preprocessed-Pascal }
+{ WRONG }
diff -ru gpc-20040516.orig/p/test/fjf260a.pas gpc-20040516/p/test/fjf260a.pas
--- gpc-20040516.orig/p/test/fjf260a.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf260a.pas	2002-11-16 21:32:20.000000000 +0100
@@ -0,0 +1,14 @@
+{ Qualified identifiers }
+
+program fjf260a;
+
+uses fjf260u;
+
+procedure foo;
+begin
+  writeln ('OK')
+end;
+
+begin
+  foo
+end.
diff -ru gpc-20040516.orig/p/test/fjf260b.pas gpc-20040516/p/test/fjf260b.pas
--- gpc-20040516.orig/p/test/fjf260b.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf260b.pas	2002-11-16 21:32:17.000000000 +0100
@@ -0,0 +1,9 @@
+{ Qualified identifiers }
+
+program fjf260b;
+
+uses fjf260v, fjf260w;
+
+begin
+  foo
+end.
diff -ru gpc-20040516.orig/p/test/fjf561.pas gpc-20040516/p/test/fjf561.pas
--- gpc-20040516.orig/p/test/fjf561.pas	2002-09-23 09:39:12.000000000 +0200
+++ gpc-20040516/p/test/fjf561.pas	2004-07-06 19:08:51.000000000 +0200
@@ -3,5 +3,5 @@
 uses fjf561u;
 
 begin
-  WriteLn (fjf561u)
+  WriteLn (fjf561u) { WRONG }
 end.
diff -ru gpc-20040516.orig/p/test/fjf561u.pas gpc-20040516/p/test/fjf561u.pas
--- gpc-20040516.orig/p/test/fjf561u.pas	2002-09-23 09:39:12.000000000 +0200
+++ gpc-20040516/p/test/fjf561u.pas	2004-07-06 19:08:51.000000000 +0200
@@ -3,7 +3,7 @@
 interface
 
 const
-  fjf561u = 'OK';
+  fjf561u = 'failed';
 
 implementation
 
diff -ru gpc-20040516.orig/p/test/fjf921a.pas gpc-20040516/p/test/fjf921a.pas
--- gpc-20040516.orig/p/test/fjf921a.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf921a.pas	2004-04-07 20:14:29.000000000 +0200
@@ -0,0 +1,7 @@
+program fjf921a;
+
+import fjf921m;  { WRONG }
+
+begin
+
+end.
diff -ru gpc-20040516.orig/p/test/fjf921b.pas gpc-20040516/p/test/fjf921b.pas
--- gpc-20040516.orig/p/test/fjf921b.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf921b.pas	2004-04-07 20:41:25.000000000 +0200
@@ -0,0 +1,7 @@
+program fjf921b;
+
+import fjf921n;
+
+begin
+  WriteLn (a)
+end.
diff -ru gpc-20040516.orig/p/test/fjf921c2.pas gpc-20040516/p/test/fjf921c2.pas
--- gpc-20040516.orig/p/test/fjf921c2.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf921c2.pas	2004-04-07 20:39:00.000000000 +0200
@@ -0,0 +1,7 @@
+program fjf921c2;
+
+import fjf921o;
+
+begin
+  WriteLn ('failed ', a)  { WRONG }
+end.
diff -ru gpc-20040516.orig/p/test/fjf921c.pas gpc-20040516/p/test/fjf921c.pas
--- gpc-20040516.orig/p/test/fjf921c.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf921c.pas	2004-04-07 20:38:36.000000000 +0200
@@ -0,0 +1,7 @@
+program fjf921c;
+
+import fjf921o;
+
+begin
+  if b = c then WriteLn (b) else WriteLn ('failed')
+end.
diff -ru gpc-20040516.orig/p/test/fjf921d.pas gpc-20040516/p/test/fjf921d.pas
--- gpc-20040516.orig/p/test/fjf921d.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf921d.pas	2004-04-13 19:26:42.000000000 +0200
@@ -0,0 +1,7 @@
+program fjf921d;
+
+import fjf921p;
+
+begin
+  if b = a then WriteLn (b) else WriteLn ('failed')
+end.
diff -ru gpc-20040516.orig/p/test/fjf921e2.pas gpc-20040516/p/test/fjf921e2.pas
--- gpc-20040516.orig/p/test/fjf921e2.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf921e2.pas	2004-04-15 03:23:38.000000000 +0200
@@ -0,0 +1,7 @@
+program fjf921e2;
+
+import fjf921q;
+
+begin
+  WriteLn ('failed ', a)  { WRONG }
+end.
diff -ru gpc-20040516.orig/p/test/fjf921e.pas gpc-20040516/p/test/fjf921e.pas
--- gpc-20040516.orig/p/test/fjf921e.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf921e.pas	2004-04-15 03:23:26.000000000 +0200
@@ -0,0 +1,7 @@
+program fjf921e;
+
+import fjf921q;
+
+begin
+  WriteLn (b)
+end.
diff -ru gpc-20040516.orig/p/test/fjf921f.pas gpc-20040516/p/test/fjf921f.pas
--- gpc-20040516.orig/p/test/fjf921f.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf921f.pas	2004-05-05 11:36:35.000000000 +0200
@@ -0,0 +1,7 @@
+program fjf921f;
+
+import fjf921r2;
+
+begin
+  if b = Succ (a) then WriteLn ('OK') else WriteLn ('failed')
+end.
diff -ru gpc-20040516.orig/p/test/fjf921g2.pas gpc-20040516/p/test/fjf921g2.pas
--- gpc-20040516.orig/p/test/fjf921g2.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf921g2.pas	2004-05-05 11:29:44.000000000 +0200
@@ -0,0 +1,7 @@
+program fjf921g2;
+
+import fjf921s2;
+
+begin
+  WriteLn ('failed ', Ord (c))  { WRONG }
+end.
diff -ru gpc-20040516.orig/p/test/fjf921g.pas gpc-20040516/p/test/fjf921g.pas
--- gpc-20040516.orig/p/test/fjf921g.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf921g.pas	2004-05-05 11:29:28.000000000 +0200
@@ -0,0 +1,7 @@
+program fjf921g;
+
+import fjf921s2;
+
+begin
+  if b = Succ (a) then WriteLn ('OK') else WriteLn ('failed')
+end.
diff -ru gpc-20040516.orig/p/test/fjf921h.pas gpc-20040516/p/test/fjf921h.pas
--- gpc-20040516.orig/p/test/fjf921h.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf921h.pas	2004-05-05 11:31:16.000000000 +0200
@@ -0,0 +1,6 @@
+program fjf921h;
+
+import fjf921t2;  { WRONG }
+
+begin
+end.
diff -ru gpc-20040516.orig/p/test/fjf921i2.pas gpc-20040516/p/test/fjf921i2.pas
--- gpc-20040516.orig/p/test/fjf921i2.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf921i2.pas	2004-07-06 19:59:23.000000000 +0200
@@ -0,0 +1,8 @@
+{ FLAG --extended-pascal }
+program fjf921i2;
+
+import fjf921u;
+
+begin
+  WriteLn ('failed')  { WRONG since `Output' is not implicitly accessble }
+end.
Only in gpc-20040516/p/test: fjf921i2.pas~
diff -ru gpc-20040516.orig/p/test/fjf921i.pas gpc-20040516/p/test/fjf921i.pas
--- gpc-20040516.orig/p/test/fjf921i.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf921i.pas	2004-05-05 11:32:32.000000000 +0200
@@ -0,0 +1,7 @@
+program fjf921i;
+
+import fjf921u;
+
+begin
+  WriteLn (Output, 'OK')
+end.
diff -ru gpc-20040516.orig/p/test/fjf921j2.pas gpc-20040516/p/test/fjf921j2.pas
--- gpc-20040516.orig/p/test/fjf921j2.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf921j2.pas	2004-07-06 20:11:03.000000000 +0200
@@ -0,0 +1,8 @@
+{ FLAG --extended-pascal }
+program fjf921j2;
+
+import fjf921v;
+
+begin
+  WriteLn (Output, 'failed') { WRONG }
+end.
Only in gpc-20040516/p/test: fjf921j2.pas~
diff -ru gpc-20040516.orig/p/test/fjf921j3.pas gpc-20040516/p/test/fjf921j3.pas
--- gpc-20040516.orig/p/test/fjf921j3.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf921j3.pas	2004-07-06 20:00:03.000000000 +0200
@@ -0,0 +1,8 @@
+{ FLAG --extended-pascal }
+program fjf921j3;
+
+import fjf921v;
+
+begin
+  WriteLn ('failed')  { WRONG since `Output' is not implicitly accessble }
+end.
Only in gpc-20040516/p/test: fjf921j3.pas~
diff -ru gpc-20040516.orig/p/test/fjf921j.pas gpc-20040516/p/test/fjf921j.pas
--- gpc-20040516.orig/p/test/fjf921j.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf921j.pas	2004-05-05 11:33:32.000000000 +0200
@@ -0,0 +1,7 @@
+program fjf921j;
+
+import fjf921v;
+
+begin
+  WriteLn (Foo, 'OK')
+end.
diff -ru gpc-20040516.orig/p/test/fjf921k.pas gpc-20040516/p/test/fjf921k.pas
--- gpc-20040516.orig/p/test/fjf921k.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/fjf921k.pas	2004-05-05 11:35:00.000000000 +0200
@@ -0,0 +1,6 @@
+program fjf921k;
+
+import fjf921w;  { WRONG }
+
+begin
+end.
diff -ru gpc-20040516.orig/p/test/gpcu_c_c.c gpc-20040516/p/test/gpcu_c_c.c
--- gpc-20040516.orig/p/test/gpcu_c_c.c	2004-03-23 09:04:32.000000000 +0100
+++ gpc-20040516/p/test/gpcu_c_c.c	2004-07-06 19:08:51.000000000 +0200
@@ -32,7 +32,7 @@
 
 /* External declarations we use from the Pascal code */
 
-extern void init_Gpcu_c_unit ();
+extern void _p__M11_Gpcu_c_unit_init ();
 
 extern int pascal_unit_variable;
 extern void pascal_unit_routine ();
@@ -56,7 +56,7 @@
 
   printf ("Calling the Pascal initializers.\n");
   fflush (stdout);
-  init_Gpcu_c_unit ();
+  _p__M11_Gpcu_c_unit_init ();
 
   printf ("Back in C `main'.\n");
   printf ("Incrementing pascal_unit_variable.\n");
diff -ru gpc-20040516.orig/p/test/grp1.pas gpc-20040516/p/test/grp1.pas
--- gpc-20040516.orig/p/test/grp1.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/grp1.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,12 @@
+{$extended-pascal}
+program grp1(input, output);
+
+{Undetected import error.  Type identifer 't1' imported through grp1b
+does not denote the same type as type identifier 't1' imported through
+grp1a.}
+
+import grp1a; grp1b; { WRONG }
+
+begin
+writeln('FAIL');
+end.
diff -ru gpc-20040516.orig/p/test/kurzw1.pas gpc-20040516/p/test/kurzw1.pas
--- gpc-20040516.orig/p/test/kurzw1.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/kurzw1.pas	2002-11-16 21:31:15.000000000 +0100
@@ -0,0 +1,19 @@
+{ Qualified identifiers }
+
+program kurzw1;
+
+uses kurzw1u;
+
+procedure foo (i : integer);
+begin
+  if i = 42 then WriteLn ('OK') else WriteLn ('failed')
+end;
+
+procedure bar;
+begin
+  foo (42)
+end;
+
+begin
+  bar
+end.
diff -ru gpc-20040516.orig/p/test/mod10.pas gpc-20040516/p/test/mod10.pas
--- gpc-20040516.orig/p/test/mod10.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/mod10.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,10 @@
+program Test(output);
+
+import
+  ModT10A qualified in 'mod10a.pas';
+  ModT10B qualified in 'mod10b.pas';  { `qualified' not yet supported }
+
+begin
+  i := -9;  { WRONG }
+  writeln('failed');
+end.
diff -ru gpc-20040516.orig/p/test/mod13.pas gpc-20040516/p/test/mod13.pas
--- gpc-20040516.orig/p/test/mod13.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod13.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,16 @@
+program qualid1(Output);
+import mod13u; mod13v;
+var fail : boolean;
+begin
+	fail := false;
+	if (v1 <> 1) or (v2 <> 2) then begin
+		writeln('failed1');
+		fail := true;
+        end;
+	if f1 or f2 then begin
+		writeln('failed2');
+		fail := true;
+	end;
+	if not fail then writeln('OK')
+end
+.
diff -ru gpc-20040516.orig/p/test/mod13u1.pas gpc-20040516/p/test/mod13u1.pas
--- gpc-20040516.orig/p/test/mod13u1.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod13u1.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,13 @@
+module mod13u1;
+export mod13u1=(v2, f2);
+var v2 : integer;
+function f2: boolean;
+end;
+function f2: boolean;
+begin
+  f2 := true
+end;
+to begin do
+  v2 := 12;
+end.
+
diff -ru gpc-20040516.orig/p/test/mod13u.pas gpc-20040516/p/test/mod13u.pas
--- gpc-20040516.orig/p/test/mod13u.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod13u.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,14 @@
+module mod13u;
+export mod13u=(v1, f1);
+var v1 : integer;
+function f1: boolean;
+end;
+import mod13u1;
+function f1: boolean;
+begin
+	f1 := (not f2) or (v2<>12)
+end;
+to begin do
+  v1 := 1;
+end.
+
diff -ru gpc-20040516.orig/p/test/mod13v1.pas gpc-20040516/p/test/mod13v1.pas
--- gpc-20040516.orig/p/test/mod13v1.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod13v1.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,13 @@
+module mod13v1;
+export mod13v1=(v1, f1);
+var v1 : integer;
+function f1: boolean;
+end;
+function f1: boolean;
+begin
+	f1:= true
+end;
+to begin do
+ v1:=11;
+end.
+
diff -ru gpc-20040516.orig/p/test/mod13v.pas gpc-20040516/p/test/mod13v.pas
--- gpc-20040516.orig/p/test/mod13v.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod13v.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,14 @@
+module mod13v;
+export mod13v=(v2, f2);
+var v2 : integer;
+function f2: boolean;
+end;
+import mod13v1;
+function f2: boolean;
+begin
+	f2:= (not f1) or (v1<>11)
+end;
+to begin do
+  v2:=2;
+end.
+
diff -ru gpc-20040516.orig/p/test/mod14.pas gpc-20040516/p/test/mod14.pas
--- gpc-20040516.orig/p/test/mod14.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod14.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,64 @@
+program mod14(Output);
+{ FLAG -Wno-warnings }
+import mod14u;
+procedure p0; external name '_p__M6_Mod14v_S0_Pf';
+procedure p1; external name '_p__M6_Mod14v_S1_myob1_Pb';
+procedure p2; external name '_p__M6_Mod14v_S2_myob1_P';
+procedure p3; external name '_p__M6_Mod14v_S3_myob1_Q';
+function f5 (u, v: integer): integer; 
+         external name '_p__M6_Mod14v_S5_Foo_op_Integer_Integer';
+function f6 (u: integer; v: integer): integer;
+         external name '_p__M6_Mod14v_S6_Foo_op_Myob1_Integer';
+var
+v7: integer; external name '_p__M6_Mod14v_S7_Ob1a';
+v8: integer; external name '_p__M6_Mod14v_S8_Ob1b';
+v9: integer; external name '_p__M6_Mod14v_S9_Ob1c';
+v10: integer; external name '_p__M6_Mod14v_S10_Va';
+v11: integer; external name '_p__M6_Mod14v_S11_Vb';
+v12: integer; external name '_p__M6_Mod14v_S12_Vc';
+
+procedure p14; external name '_p__M6_Mod14v_S14_myob2_R';
+procedure p15; external name '_p__M6_Mod14v_S15_myob2_Q';
+procedure p16; external name '_p__M6_Mod14v_S16_myob2_P';
+procedure p17; external name '_p__M6_Mod14v_S17_myob2_S';
+
+procedure p19; external name '_p__M6_Mod14v_S19_myob3_P0';
+procedure p20; external name '_p__M6_Mod14v_S20_myob3_P';
+procedure p21; external name '_p__M6_Mod14v_S21_myob3_Q';
+procedure p22; external name '_p__M6_Mod14v_S22_myob3_R';
+procedure p23; external name '_p__M6_Mod14v_S23_myob3_S';
+
+function f25 (u, v: integer): integer;
+         external name '_p__M6_Mod14v_S25_Foo_op_Myob2_Myob3';
+
+procedure p26 (function f(u, v: integer): integer);
+         external name '_p__M6_Mod14v_S26_Take';
+
+begin
+p26(f25); 
+p26(f6);
+p26(f5);
+p23;
+p22;
+p21;
+p20;
+p19;
+p17;
+p16;
+p15;
+p14;
+p3;
+p2;
+p1;
+p0;
+v10 := 5;
+v11 := f5 (v7, v10);
+v12 := f5 (v8, v11);
+v10 := f5 (v9, 7);
+if (v10 = 7) and (v12 = 5) then
+  writeln('OK')
+else
+  writeln('failed')
+end
+.
+
diff -ru gpc-20040516.orig/p/test/mod14u.pas gpc-20040516/p/test/mod14u.pas
--- gpc-20040516.orig/p/test/mod14u.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod14u.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,7 @@
+module mod14u;
+export mod14u=(dummy);
+const dummy = 'dummy';
+end;
+import mod14v;
+end
+.
diff -ru gpc-20040516.orig/p/test/mod14v.pas gpc-20040516/p/test/mod14v.pas
--- gpc-20040516.orig/p/test/mod14v.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod14v.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,102 @@
+module mod14v;
+export mod14v=(dummy2);
+const dummy2='dummy2';
+procedure pf; forward;
+type
+myob1 = object
+  procedure pb;
+  procedure p; virtual;
+  procedure q; virtual;
+end;
+
+operator foo_op (u, v: integer) w : integer;
+
+operator foo_op (u: myob1; v: integer) w : integer;
+
+var ob1a, ob1b, ob1c : myob1;
+
+var va, vb , vc : integer;
+
+type
+myob2 = object (myob1)
+  ptr : ^myob3;
+  procedure p0;
+  procedure r; virtual;
+  procedure q; virtual;
+  procedure p; virtual;
+  procedure s;
+end;
+myob3 = object (myob2)
+  procedure p0;
+  procedure p; virtual;
+  procedure q; virtual;
+  procedure r; virtual;
+  procedure s;
+end;
+
+operator foo_op (u: myob2; v: myob3) w : myob3;
+
+procedure take(procedure p);
+end;
+{ implementation }
+procedure take(procedure p);
+begin
+end;
+operator foo_op (u: myob2; v : myob3) w : myob3;
+begin
+  w := u.ptr^
+end;
+operator foo_op (u: myob1; v: integer) w : integer;
+begin
+  w := v
+end;
+operator foo_op (u, v: integer) w : integer;
+begin
+  w := v
+end;
+procedure pf;
+begin
+end;
+procedure myob1.pb;
+begin
+end;
+procedure myob1.p;
+begin
+end;
+procedure myob1.q;
+begin
+end;
+procedure myob2.p0;
+begin
+end;
+procedure myob2.p;
+begin
+end;
+procedure myob2.q;
+begin
+end;
+procedure myob2.s;
+begin
+end;
+procedure myob2.r;
+begin
+end;
+
+procedure myob3.p0;
+begin
+end;
+procedure myob3.p;
+begin
+end;
+procedure myob3.q;
+begin
+end;
+procedure myob3.s;
+begin
+end;
+procedure myob3.r;
+begin
+end;
+
+end
+.
diff -ru gpc-20040516.orig/p/test/mod15a.pas gpc-20040516/p/test/mod15a.pas
--- gpc-20040516.orig/p/test/mod15a.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod15a.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,8 @@
+program mod15a;
+ import e1 qualified in 'mod15m.pas';
+var x : integer;
+begin
+ x := 1;
+ writeln('OK')
+end
+.
diff -ru gpc-20040516.orig/p/test/mod15b.pas gpc-20040516/p/test/mod15b.pas
--- gpc-20040516.orig/p/test/mod15b.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod15b.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,7 @@
+program mod15b;
+ import e1 qualified in 'mod15m.pas';
+begin
+ e1.x := 1;
+ e1.f(1)
+end
+.
diff -ru gpc-20040516.orig/p/test/mod15c.pas gpc-20040516/p/test/mod15c.pas
--- gpc-20040516.orig/p/test/mod15c.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod15c.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,13 @@
+program mod15c;
+const x = 'OK';
+procedure p1;
+ import e1 in 'mod15m.pas';
+begin
+ x := 1;
+ f(1)
+end;
+begin
+  writeln(x)
+end
+.
+
diff -ru gpc-20040516.orig/p/test/mod15d.pas gpc-20040516/p/test/mod15d.pas
--- gpc-20040516.orig/p/test/mod15d.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod15d.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,14 @@
+program mod15d;
+const x = 'OK';
+procedure p1;
+ import e1 in 'mod15m.pas';
+begin
+ x := 1;
+ f(2)
+end;
+begin
+  p1;
+  e1.x := 3; { WRONG }
+end
+.
+
diff -ru gpc-20040516.orig/p/test/mod15e.pas gpc-20040516/p/test/mod15e.pas
--- gpc-20040516.orig/p/test/mod15e.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod15e.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,18 @@
+program mod15e;
+const x = 'Dummy';
+procedure p1;
+ import e1 in 'mod15m.pas';
+begin
+ x := 1;
+end;
+procedure p2;
+ import e1 in 'mod15m.pas';
+begin
+ f(1)
+end;
+begin
+ p1;
+ p2
+end
+.
+
diff -ru gpc-20040516.orig/p/test/mod15f.pas gpc-20040516/p/test/mod15f.pas
--- gpc-20040516.orig/p/test/mod15f.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod15f.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,8 @@
+program mod15f;
+ import e1 qualified in 'mod15m.pas';
+var e1 : integer; { WRONG }
+begin
+  writeln('failed')
+end
+.
+
diff -ru gpc-20040516.orig/p/test/mod15g.pas gpc-20040516/p/test/mod15g.pas
--- gpc-20040516.orig/p/test/mod15g.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod15g.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,8 @@
+program mod15g;
+ import e1 qualified in 'mod15m.pas';
+begin
+  e1 := 1; { WRONG }
+  writeln('failed')
+end
+.
+
diff -ru gpc-20040516.orig/p/test/mod15h.pas gpc-20040516/p/test/mod15h.pas
--- gpc-20040516.orig/p/test/mod15h.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod15h.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,8 @@
+program mod1;
+ import e1 only(x) in 'mod15m.pas';
+begin
+ x := 1;
+ e1.f(2) { WRONG }
+end
+.
+
diff -ru gpc-20040516.orig/p/test/mod15m.pas gpc-20040516/p/test/mod15m.pas
--- gpc-20040516.orig/p/test/mod15m.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod15m.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,15 @@
+module m15m;
+  export e1 = (x, f);
+  var x : integer;
+  procedure f(y : integer);
+end;
+procedure f(y : integer);
+begin
+  if x = y then
+    writeln('OK')
+  else
+    writeln('failed')
+end;
+end
+.
+
diff -ru gpc-20040516.orig/p/test/mod16a.pas gpc-20040516/p/test/mod16a.pas
--- gpc-20040516.orig/p/test/mod16a.pas	2004-07-06 19:17:58.000000000 +0200
+++ gpc-20040516/p/test/mod16a.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,6 @@
+program mod16a(output);
+import mod16m; mod16m1;
+begin
+  writeln('OK')
+end
+.
diff -ru gpc-20040516.orig/p/test/mod16b.pas gpc-20040516/p/test/mod16b.pas
--- gpc-20040516.orig/p/test/mod16b.pas	2004-07-06 19:18:40.000000000 +0200
+++ gpc-20040516/p/test/mod16b.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,6 @@
+program mod16b(output);
+import mod16m; mod16m1 only (ci => ce); { WRONG }
+begin
+  writeln('failed')
+end
+.
diff -ru gpc-20040516.orig/p/test/mod16c.pas gpc-20040516/p/test/mod16c.pas
--- gpc-20040516.orig/p/test/mod16c.pas	2004-07-06 19:18:40.000000000 +0200
+++ gpc-20040516/p/test/mod16c.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,6 @@
+program mod16c(output);
+import mod16m; mod16m1 only (te => ts); { WRONG }
+begin
+  writeln('failed')
+end
+.
diff -ru gpc-20040516.orig/p/test/mod16d.pas gpc-20040516/p/test/mod16d.pas
--- gpc-20040516.orig/p/test/mod16d.pas	2004-07-06 19:18:40.000000000 +0200
+++ gpc-20040516/p/test/mod16d.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,6 @@
+program mod16d(output);
+import mod16m; mod16m1 only (ve => vs); { WRONG }
+begin
+  writeln('failed')
+end
+.
diff -ru gpc-20040516.orig/p/test/mod16e.pas gpc-20040516/p/test/mod16e.pas
--- gpc-20040516.orig/p/test/mod16e.pas	2004-07-06 19:18:40.000000000 +0200
+++ gpc-20040516/p/test/mod16e.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,6 @@
+program mod16e(output);
+import mod16m; mod16m1 only (pe => ps); { WRONG }
+begin
+  writeln('failed')
+end
+.
diff -ru gpc-20040516.orig/p/test/mod16m1.pas gpc-20040516/p/test/mod16m1.pas
--- gpc-20040516.orig/p/test/mod16m1.pas	2004-07-06 19:18:40.000000000 +0200
+++ gpc-20040516/p/test/mod16m1.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,6 @@
+module mod16m1;
+  export mod16m1 = (ci, ce, te, ts, ve, vs, pe, ps);
+  import mod16m;
+end;
+end
+.
diff -ru gpc-20040516.orig/p/test/mod16m.pas gpc-20040516/p/test/mod16m.pas
--- gpc-20040516.orig/p/test/mod16m.pas	2004-07-06 19:18:40.000000000 +0200
+++ gpc-20040516/p/test/mod16m.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,19 @@
+module mod16m;
+  export mod16m = (ci, ce, te, ts, ve, vs, pe, ps);
+type te = (a, b, c, d);
+     tc = (ca, ce, cf);
+     ts = set of tc;
+const ci = 15;
+var ve : te;
+    vs : ts;
+procedure pe (x : te);
+procedure ps (x : ts);
+end;
+procedure pe;
+begin
+end;
+procedure ps;
+begin
+end;
+end
+.
diff -ru gpc-20040516.orig/p/test/mod17a.pas gpc-20040516/p/test/mod17a.pas
--- gpc-20040516.orig/p/test/mod17a.pas	2004-07-06 23:01:29.000000000 +0200
+++ gpc-20040516/p/test/mod17a.pas	2004-05-24 18:07:41.000000000 +0200
@@ -0,0 +1,5 @@
+program mod17a;
+  import mod17v2; {WRONG}
+begin
+end
+.
diff -ru gpc-20040516.orig/p/test/mod17b.pas gpc-20040516/p/test/mod17b.pas
--- gpc-20040516.orig/p/test/mod17b.pas	2004-07-06 23:01:29.000000000 +0200
+++ gpc-20040516/p/test/mod17b.pas	2004-05-24 19:29:05.000000000 +0200
@@ -0,0 +1,5 @@
+program mod17b;
+  import mod17v4; {WRONG}
+begin
+end
+.
diff -ru gpc-20040516.orig/p/test/mod17c.pas gpc-20040516/p/test/mod17c.pas
--- gpc-20040516.orig/p/test/mod17c.pas	2004-07-06 23:01:29.000000000 +0200
+++ gpc-20040516/p/test/mod17c.pas	2004-05-24 19:28:55.000000000 +0200
@@ -0,0 +1,5 @@
+program mod17c;
+  import mod17v6; {WRONG}
+begin
+end
+.
diff -ru gpc-20040516.orig/p/test/mod17d.pas gpc-20040516/p/test/mod17d.pas
--- gpc-20040516.orig/p/test/mod17d.pas	2004-07-06 23:01:29.000000000 +0200
+++ gpc-20040516/p/test/mod17d.pas	2004-05-24 20:09:57.000000000 +0200
@@ -0,0 +1,6 @@
+program mod17c (Output);
+  import mod17w3; 
+begin
+  writeln ('OK')
+end
+.
diff -ru gpc-20040516.orig/p/test/mod17v1.pas gpc-20040516/p/test/mod17v1.pas
--- gpc-20040516.orig/p/test/mod17v1.pas	2004-07-06 23:01:29.000000000 +0200
+++ gpc-20040516/p/test/mod17v1.pas	2004-05-24 18:35:32.000000000 +0200
@@ -0,0 +1,6 @@
+module mod17v1;
+  export mod17v1 = (a => a, b);
+  type t = (a, b);
+end;
+end
+.
diff -ru gpc-20040516.orig/p/test/mod17v2.pas gpc-20040516/p/test/mod17v2.pas
--- gpc-20040516.orig/p/test/mod17v2.pas	2004-07-06 23:01:29.000000000 +0200
+++ gpc-20040516/p/test/mod17v2.pas	2004-05-24 18:35:16.000000000 +0200
@@ -0,0 +1,6 @@
+module mod17v2;
+  export mod17v2 = (a ..  b); { WRONG }
+  import mod17v1;
+end;
+end
+.
diff -ru gpc-20040516.orig/p/test/mod17v3.pas gpc-20040516/p/test/mod17v3.pas
--- gpc-20040516.orig/p/test/mod17v3.pas	2004-07-06 23:01:29.000000000 +0200
+++ gpc-20040516/p/test/mod17v3.pas	2004-05-24 18:39:14.000000000 +0200
@@ -0,0 +1,6 @@
+module mod17v3;
+  export mod17v3 = (a => c, b => d);
+  type t = (a, b);
+end;
+end
+.
diff -ru gpc-20040516.orig/p/test/mod17v4.pas gpc-20040516/p/test/mod17v4.pas
--- gpc-20040516.orig/p/test/mod17v4.pas	2004-07-06 23:01:29.000000000 +0200
+++ gpc-20040516/p/test/mod17v4.pas	2004-05-24 18:38:54.000000000 +0200
@@ -0,0 +1,8 @@
+module mod17v2;
+  export mod17v4 = (a ..  b); { WRONG }
+  import mod17v3;
+  const a = c;
+        b = d;
+end;
+end
+.
diff -ru gpc-20040516.orig/p/test/mod17v5.pas gpc-20040516/p/test/mod17v5.pas
--- gpc-20040516.orig/p/test/mod17v5.pas	2004-07-06 23:01:29.000000000 +0200
+++ gpc-20040516/p/test/mod17v5.pas	2004-05-24 19:27:30.000000000 +0200
@@ -0,0 +1,6 @@
+module mod17v5;
+  export mod17v5 = (a, b);
+  type t = (a, b);
+end;
+end
+.
diff -ru gpc-20040516.orig/p/test/mod17v6.pas gpc-20040516/p/test/mod17v6.pas
--- gpc-20040516.orig/p/test/mod17v6.pas	2004-07-06 23:01:29.000000000 +0200
+++ gpc-20040516/p/test/mod17v6.pas	2004-05-24 19:28:17.000000000 +0200
@@ -0,0 +1,6 @@
+module mod17v6;
+  export mod17v6 = (mod17v5.a ..  mod17v5.b); { WRONG }
+  import qualified mod17v5;
+end;
+end
+.
diff -ru gpc-20040516.orig/p/test/mod17w1.pas gpc-20040516/p/test/mod17w1.pas
--- gpc-20040516.orig/p/test/mod17w1.pas	2004-07-06 23:01:29.000000000 +0200
+++ gpc-20040516/p/test/mod17w1.pas	2004-05-24 20:26:24.000000000 +0200
@@ -0,0 +1,10 @@
+module mod17w1;
+  export mod17w1 = (wa => wa, wb);
+         w1i2 = (mod17v5.a, mod17v5.b); 
+         w1i3 = (wa);
+         w1i4 = (wb => bb);
+  import mod17v5 qualified;
+  type t = (wa, wb);
+end;
+end
+.
diff -ru gpc-20040516.orig/p/test/mod17w2.pas gpc-20040516/p/test/mod17w2.pas
--- gpc-20040516.orig/p/test/mod17w2.pas	2004-07-06 23:01:29.000000000 +0200
+++ gpc-20040516/p/test/mod17w2.pas	2004-05-24 20:08:58.000000000 +0200
@@ -0,0 +1,9 @@
+module mod17w2;
+  export mod17w2 = (wa .. wb);
+         w2i2 = (a .. b); 
+         w2i3 = (wb);
+         w2i4 = (wa => a, wb => b);
+  import mod17w1; w1i2 in 'mod17w1.pas'; w1i3 in 'mod17w1.pas';
+end;
+end
+.
diff -ru gpc-20040516.orig/p/test/mod17w3.pas gpc-20040516/p/test/mod17w3.pas
--- gpc-20040516.orig/p/test/mod17w3.pas	2004-07-06 23:01:29.000000000 +0200
+++ gpc-20040516/p/test/mod17w3.pas	2004-05-24 20:08:38.000000000 +0200
@@ -0,0 +1,8 @@
+module mod17w3;
+  export mod17w3 = (wa => foo);
+         w3i2 = (a .. b); 
+  import w1i3 in 'mod17w1.pas'; w2i3 in 'mod17w2.pas';
+         w2i4 in 'mod17w2.pas';
+end;
+end
+.
diff -ru gpc-20040516.orig/p/test/mod9.pas gpc-20040516/p/test/mod9.pas
--- gpc-20040516.orig/p/test/mod9.pas	2004-07-06 19:16:15.000000000 +0200
+++ gpc-20040516/p/test/mod9.pas	2004-07-06 19:11:13.000000000 +0200
@@ -0,0 +1,9 @@
+program Test(output);
+
+import
+  ModT9A in 'mod9a.pas';
+  ModT9B in 'mod9b.pas';  { WRONG: `i' declared two times. }
+
+begin
+  writeln('failed');
+end.
diff -ru gpc-20040516.orig/p/test/pipetes2.pas gpc-20040516/p/test/pipetes2.pas
--- gpc-20040516.orig/p/test/pipetes2.pas	2004-05-14 23:56:23.000000000 +0200
+++ gpc-20040516/p/test/pipetes2.pas	2004-07-06 19:11:13.000000000 +0200
@@ -28,7 +28,7 @@
   if Copy (s, Length (s) - 3) = '.out' then s := Copy (s, 1, Length (s) - 4) + '.exe';
   {$endif}
   {$local I-}
-  Pipe (ToInput, f, f, s, Parameters, GetCEnvironment, Process, nil);
+  MakePipe (ToInput, f, f, s, Parameters, GetCEnvironment, Process, nil);
   {$endlocal}
   if InOutRes <> 0 then
     begin
diff -ru gpc-20040516.orig/p/test/pipetest.pas gpc-20040516/p/test/pipetest.pas
--- gpc-20040516.orig/p/test/pipetest.pas	2004-05-14 23:56:32.000000000 +0200
+++ gpc-20040516/p/test/pipetest.pas	2004-07-06 19:11:13.000000000 +0200
@@ -67,7 +67,7 @@
   {$endif}
 
   {$local I-}
-  Pipe (ToInput, FromOutput, FromStdErr, '', Null, GetCEnvironment, Process, DemoProcedure);
+  MakePipe (ToInput, FromOutput, FromStdErr, '', Null, GetCEnvironment, Process, DemoProcedure);
   {$endlocal}
   if InOutRes <> 0 then
     begin
diff -ru gpc-20040516.orig/p/test/test_run gpc-20040516/p/test/test_run
--- gpc-20040516.orig/p/test/test_run	2004-05-15 20:44:11.000000000 +0200
+++ gpc-20040516/p/test/test_run	2004-07-06 19:11:13.000000000 +0200
@@ -89,7 +89,7 @@
   exit 1
 fi
 
-echo "program Dummy; begin WriteLn ('1723') end." > dummy.pas
+echo "program Dummy(Output); begin WriteLn ('1723') end." > dummy.pas
 NEEDED_OPTIONS="`$PC $PFLAGS --print-needed-options dummy.pas 3>&2 2>&1 1>&3`"
 if $echon "$NEEDED_OPTIONS" | grep '^[^-]' > /dev/null; then
   echo "$0: fatal: \`--print-needed-options' yields:" >&2
Only in gpc-20040516.orig/p/test/todo: chief18.pas
diff -ru gpc-20040516.orig/p/test/todo/contourbug.pas gpc-20040516/p/test/todo/contourbug.pas
--- gpc-20040516.orig/p/test/todo/contourbug.pas	2002-11-16 21:35:42.000000000 +0100
+++ gpc-20040516/p/test/todo/contourbug.pas	2004-07-06 19:11:13.000000000 +0200
@@ -4,7 +4,7 @@
 
 program CountourBug;
 
-{ Running this program with the command line:
+(* Running this program with the command line:
 
     gpc --gnu-pascal --stack-checking -S contourbug.pas
 
@@ -41,7 +41,7 @@
   to the `goto' and to what GPC does internally with strings. It can
   be reproduced in C, using local variables of variable size and a
   certain way of using `{ ... }' groups.
-}
+*)
 
 
 procedure p (str: string);
Only in gpc-20040516.orig/p/test/todo: fjf260a.pas
Only in gpc-20040516.orig/p/test/todo: fjf260b.pas
Only in gpc-20040516.orig/p/test/todo: fjf921a.pas
Only in gpc-20040516.orig/p/test/todo: fjf921b.pas
Only in gpc-20040516.orig/p/test/todo: fjf921c2.pas
Only in gpc-20040516.orig/p/test/todo: fjf921c.pas
Only in gpc-20040516.orig/p/test/todo: fjf921d.pas
Only in gpc-20040516.orig/p/test/todo: fjf921e2.pas
Only in gpc-20040516.orig/p/test/todo: fjf921e.pas
Only in gpc-20040516.orig/p/test/todo: fjf921f.pas
Only in gpc-20040516.orig/p/test/todo: fjf921g2.pas
Only in gpc-20040516.orig/p/test/todo: fjf921g.pas
Only in gpc-20040516.orig/p/test/todo: fjf921h.pas
Only in gpc-20040516.orig/p/test/todo: fjf921i2.pas
Only in gpc-20040516.orig/p/test/todo: fjf921i.pas
Only in gpc-20040516.orig/p/test/todo: fjf921j2.pas
Only in gpc-20040516.orig/p/test/todo: fjf921j3.pas
Only in gpc-20040516.orig/p/test/todo: fjf921j.pas
Only in gpc-20040516.orig/p/test/todo: fjf921k.pas
Only in gpc-20040516.orig/p/test/todo: grp1.pas
Only in gpc-20040516.orig/p/test/todo: kurzw1.pas
Only in gpc-20040516.orig/p/test/todo: mod10.pas
Only in gpc-20040516.orig/p/test/todo: mod9.pas
diff -ru gpc-20040516.orig/p/typecheck.c gpc-20040516/p/typecheck.c
--- gpc-20040516.orig/p/typecheck.c	2004-05-12 01:50:17.000000000 +0200
+++ gpc-20040516/p/typecheck.c	2004-07-06 19:11:13.000000000 +0200
@@ -1595,8 +1595,9 @@
               && PASCAL_TYPE_DISCRIMINATED_STRING (TREE_TYPE (TREE_OPERAND (TREE_VALUE (init), 0))))
             {
               int constant = TREE_CONSTANT (TREE_VALUE (init));
-              TREE_VALUE (init) = build1 (ADDR_EXPR, cstring_type_node, TREE_VALUE (
-                TREE_CHAIN (TREE_CHAIN (TREE_OPERAND (TREE_OPERAND (TREE_VALUE (init), 0), 1)))));
+              tree t = CONSTRUCTOR_ELTS (TREE_OPERAND (TREE_VALUE (init), 0));
+              TREE_VALUE (init) = build1 (ADDR_EXPR, cstring_type_node,
+                TREE_VALUE ( TREE_CHAIN (TREE_CHAIN (t))));
               TREE_CONSTANT (TREE_VALUE (init)) = constant;
               return 0;
             }
@@ -1742,7 +1743,11 @@
     {
       int i = 0, l = NUMBER_OF_OPERANDS (code);
       if (code == CONSTRUCTOR)
+#ifndef GCC_3_4
         i = 1 + !TREE_OPERAND (type_or_expr, 1);
+#else
+        i = !TREE_OPERAND (type_or_expr, 0);
+#endif
       for (; i < l; i++)
         if (contains_discriminant (TREE_OPERAND (type_or_expr, i), fields))
           return 1;
@@ -1819,7 +1824,7 @@
       tree t;
       expr = copy_node (expr);
       TREE_OPERAND (expr, 0) = re_fold (TREE_OPERAND (expr, 0), fields, &foreign_discr);
-      for (t = TREE_OPERAND (expr, 0); t; t = TREE_CHAIN (t))
+      for (t = TREE_OPERAND (expr, 1); t; t = TREE_CHAIN (t))
         TREE_VALUE (t) = re_fold (TREE_VALUE (t), fields, &foreign_discr);
       if (!foreign_discr)
         return fold (expr);
@@ -1834,10 +1839,15 @@
     {
       int i = 0, l = tree_code_length[(int) code];
       expr = copy_node (expr);
+#ifndef GCC_3_4
       if (code == METHOD_CALL_EXPR)
         l = 3;
       else if (code == CONSTRUCTOR)
         i = 1 + !TREE_OPERAND (expr, 1);
+#else
+      if (code == CONSTRUCTOR)
+        i = !TREE_OPERAND (expr, 0);
+#endif
       for (; i < l; i++)
         TREE_OPERAND (expr, i) = re_fold (TREE_OPERAND (expr, i), fields, &foreign_discr);
       if (!foreign_discr)
@@ -3289,7 +3299,11 @@
               && TREE_CODE (constructor_max_index) == INTEGER_CST
               && !tree_int_cst_lt (constructor_max_index, constructor_unfilled_index))
             error_or_warning (co->pascal_dialect & E_O_PASCAL, "too few initializers for array");
+#ifndef GCC_3_4
           constructor = build (CONSTRUCTOR, constructor_type, NULL_TREE, nreverse (constructor_elements));
+#else
+          constructor = build_constructor (constructor_type, nreverse (constructor_elements));
+#endif
           if (constructor_constant)
             TREE_CONSTANT (constructor) = 1;
           if (constructor_constant && constructor_simple)
diff -ru gpc-20040516.orig/p/types.c gpc-20040516/p/types.c
--- gpc-20040516.orig/p/types.c	2004-05-16 15:52:02.000000000 +0200
+++ gpc-20040516/p/types.c	2004-07-06 19:11:13.000000000 +0200
@@ -764,6 +764,18 @@
   return expr;
 }
 
+/* Since pascal declaration gives a new type we have to defeat 
+   caching in `build_pointer_type' */
+
+tree
+build_pascal_pointer_type (to_type)
+    tree to_type;
+{
+  if (TYPE_POINTER_TO (to_type))
+    to_type = build_type_copy (to_type);
+  return build_pointer_type (to_type);
+}
+ 
 /* Each variable length string looks like:
 
    String = record
@@ -950,7 +962,11 @@
     {
       int i = 0, l = NUMBER_OF_OPERANDS (code);
       if (code == CONSTRUCTOR)
+#ifndef GCC_3_4
         i = 1 + !TREE_OPERAND (expr, 1);
+#else
+        i = !TREE_OPERAND (expr, 0);
+#endif
       for (; i < l; i++)
         TREE_OPERAND (expr, i) = maybe_schema_discriminant (TREE_OPERAND (expr, i));
     }
diff -ru gpc-20040516.orig/p/units/dos.pas gpc-20040516/p/units/dos.pas
--- gpc-20040516.orig/p/units/dos.pas	2004-01-01 00:09:21.000000000 +0100
+++ gpc-20040516/p/units/dos.pas	2004-07-06 19:11:13.000000000 +0200
@@ -62,7 +62,7 @@
   get the built-in meaning by using `GPC_AnyFile'. }
 export Dos = all (DosAnyFile => AnyFile, FSearch, FExpand, FSplit, GetEnv);
 
-import GPC; System;
+import GPC (MaxLongInt => Orig_GPC_Maxlongint); System;
 
 type
   GPC_AnyFile = AnyFile;
diff -ru gpc-20040516.orig/p/units/gpc-in-c.h gpc-20040516/p/units/gpc-in-c.h
--- gpc-20040516.orig/p/units/gpc-in-c.h	2004-03-23 09:05:25.000000000 +0100
+++ gpc-20040516/p/units/gpc-in-c.h	2004-07-06 19:11:13.000000000 +0200
@@ -66,7 +66,8 @@
   and run the constructors of the mentioned unit/module and all
   units/modules used by it.
 */
-extern void init_pascal_main_program ();
+#define init_pascal_main_program() _p__M0_init ()
+extern void _p__M0_init ();
 
 /*
   _p_finalize() (also part of GPC's Run Time System) should be
diff -ru gpc-20040516.orig/p/units/pipes.pas gpc-20040516/p/units/pipes.pas
--- gpc-20040516.orig/p/units/pipes.pas	2004-05-14 23:54:25.000000000 +0200
+++ gpc-20040516/p/units/pipes.pas	2004-07-06 19:11:13.000000000 +0200
@@ -142,7 +142,7 @@
   IOSelectRead) while writing the Input data (under Dos, there
   simply won't be any data then, but checking for data doesn't do
   any harm). Please see pipedemo.pas for an example. }
-procedure Pipe (var ToInputFile, FromOutputFile, FromStdErrFile: AnyFile; const ProcessName: String; protected var Parameters: TPStrings; ProcessEnvironment: PCStrings; var Process: PPipeProcess; ChildProc: TProcedure); attribute (iocritical);
+procedure MakePipe (var ToInputFile, FromOutputFile, FromStdErrFile: AnyFile; const ProcessName: String; protected var Parameters: TPStrings; ProcessEnvironment: PCStrings; var Process: PPipeProcess; ChildProc: TProcedure); attribute (iocritical);
 
 { Waits for a process created by Pipe as determined in the Process
   record. (Process is Dispose'd of afterwards.) Returns True if
@@ -317,7 +317,7 @@
   SetTFDD (f, OpenProc, SelectFunc, SelectProc, ReadFunc, WriteFunc, FlushProc, PipeTFDDClose, DoneProc, p)
 end;
 
-procedure Pipe (var ToInputFile, FromOutputFile, FromStdErrFile: AnyFile; const ProcessName: String; protected var Parameters: TPStrings; ProcessEnvironment: PCStrings; var Process: PPipeProcess; ChildProc: TProcedure);
+procedure MakePipe (var ToInputFile, FromOutputFile, FromStdErrFile: AnyFile; const ProcessName: String; protected var Parameters: TPStrings; ProcessEnvironment: PCStrings; var Process: PPipeProcess; ChildProc: TProcedure);
 var
   ParameterCount, i: Cardinal;
   PipeStdIn, PipeStdOut, PipeStdErr: Integer;
@@ -542,7 +542,7 @@
   Reset (f)
 end;
 
-procedure Pipe (var ToInputFile, FromOutputFile, FromStdErrFile: AnyFile; const ProcessName: String; protected var Parameters: TPStrings; ProcessEnvironment: PCStrings; var Process: PPipeProcess; ChildProc: TProcedure);
+procedure MakePipe (var ToInputFile, FromOutputFile, FromStdErrFile: AnyFile; const ProcessName: String; protected var Parameters: TPStrings; ProcessEnvironment: PCStrings; var Process: PPipeProcess; ChildProc: TProcedure);
 var
   i: Cardinal;
   PipeData: PPipeData;
diff -ru gpc-20040516.orig/p/units/printer.pas gpc-20040516/p/units/printer.pas
--- gpc-20040516.orig/p/units/printer.pas	2004-05-14 23:55:01.000000000 +0200
+++ gpc-20040516/p/units/printer.pas	2004-07-06 19:11:13.000000000 +0200
@@ -126,7 +126,7 @@
 begin
   { @@ Check status in Close }
   WritePrinter := 0;
-  Pipe (Data.f^, Data.SpoolerOutput^, Data.SpoolerOutput^, PrinterCommand^, PrinterArguments^, GetCEnvironment, Process, nil);  { this also makes sure this function won't be called again for this file }
+  MakePipe (Data.f^, Data.SpoolerOutput^, Data.SpoolerOutput^, PrinterCommand^, PrinterArguments^, GetCEnvironment, Process, nil);  { this also makes sure this function won't be called again for this file }
   if InOutRes <> 0 then Exit;
   Process^.Signal  := PrinterPipeSignal;
   Process^.Seconds := PrinterPipeSeconds;
diff -ru gpc-20040516.orig/p/units/turbo3.pas gpc-20040516/p/units/turbo3.pas
--- gpc-20040516.orig/p/units/turbo3.pas	2004-01-01 00:08:10.000000000 +0100
+++ gpc-20040516/p/units/turbo3.pas	2004-07-06 19:11:13.000000000 +0200
@@ -43,8 +43,7 @@
 
 interface
 
-import GPC;
-       System (MemAvail => System_MemAvail,
+import System (MemAvail => System_MemAvail,
                MaxAvail => System_MaxAvail);
        CRT (LowVideo  => CRT_LowVideo,
             HighVideo => CRT_HighVideo);
@@ -63,6 +62,7 @@
 procedure HighVideo; attribute (name = '_p_HighVideo3');
 
 implementation
+import GPC only (AssignTFDD);
 
 function Kbd_Read (var PrivateData; var Buffer; Size: SizeType) = BytesRead: SizeType;
 var
diff -ru gpc-20040516.orig/p/units/windos.pas gpc-20040516/p/units/windos.pas
--- gpc-20040516.orig/p/units/windos.pas	2004-01-01 00:08:07.000000000 +0100
+++ gpc-20040516/p/units/windos.pas	2004-07-06 19:11:13.000000000 +0200
@@ -74,10 +74,10 @@
                      {$endif}
                      CStringGetEnv => GetEnvVar);
 
-import GPC; System; Dos (FindFirst  => Dos_FindFirst,
+import GPC(MaxLongInt => Orig_GPC_Maxlongint); System; 
+                    Dos (FindFirst  => Dos_FindFirst,
                          FindNext   => Dos_FindNext,
                          FindClose  => Dos_FindClose);
-
 const
   { File attribute constants }
   faReadOnly  = ReadOnly;
diff -ru gpc-20040516.orig/p/utils/gpidump.pas gpc-20040516/p/utils/gpidump.pas
--- gpc-20040516.orig/p/utils/gpidump.pas	2004-05-12 12:03:06.000000000 +0200
+++ gpc-20040516/p/utils/gpidump.pas	2004-07-06 19:11:13.000000000 +0200
@@ -26,7 +26,7 @@
 
 program GPIDump;
 
-uses GPC, StringUtils;
+import GPC; StringUtils;
 
 var
   Verbose, Hex: Boolean;
@@ -752,7 +752,9 @@
              case TreeCode of
                SAVE_EXPR,
                WITH_CLEANUP_EXPR: a := 1;
+	       {$ifndef GCC_3_4}
                METHOD_CALL_EXPR:  a := 3;
+	       {$endif}
                else               a := TreeCodes[TreeCode].Arguments
              end;
              for i := 1 + Ord (TreeCode = CONSTRUCTOR) to a do
@@ -779,7 +781,8 @@
       IMPORT_NODE:      begin
                           Ref ('interface');
                           OptRef ('qualifier');
-                          OptRef ('filename')
+                          OptRef ('filename');
+                          var qualifued : Integer = GetNumber (Pos1);
                         end;
       TREE_LIST:        for i := 1 to GetNumber (Pos1) do
                           begin
diff -ru gpc-20040516.orig/p/utils/mk-t-inc gpc-20040516/p/utils/mk-t-inc
--- gpc-20040516.orig/p/utils/mk-t-inc	2004-01-01 00:07:59.000000000 +0100
+++ gpc-20040516/p/utils/mk-t-inc	2004-07-06 19:11:13.000000000 +0200
@@ -71,6 +71,9 @@
     echo '{$define EGCS97}'
     if echo $version | grep '3\.[3-9]' > /dev/null; then
       echo '{$define GCC_3_3}'
+      if echo $version | grep '3\.[4-9]' > /dev/null; then
+        echo '{$define GCC_3_4}'
+      fi
     fi
   fi
 fi
