Index: gcc/gcc.c
===================================================================
--- gcc/gcc.c	(.../trunk)	(revision 231059)
+++ gcc/gcc.c	(.../branches/gupc)	(revision 231080)
@@ -1016,16 +1016,20 @@ proper position among the other output f
     %{flto} %{fno-lto} %{flto=*} %l " LINK_PIE_SPEC \
    "%{fuse-ld=*:-fuse-ld=%*} " LINK_COMPRESS_DEBUG_SPEC \
    "%X %{o*} %{e*} %{N} %{n} %{r}\
-    %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}} \
+    %{s} %{t} %{u*} %{z} %{Z}\
+    %{!nostdlib:%{!nostartfiles:%{fupc:%:include(upc-crtbegin.spec)%(upc_crtbegin)}}}\
+    %{!nostdlib:%{!nostartfiles:%S}} \
     %{static:} %{L*} %(mfwrap) %(link_libgcc) " \
     VTABLE_VERIFICATION_SPEC " " SANITIZER_EARLY_SPEC " %o " CHKP_SPEC " \
     %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*} 1):\
 	%:include(libgomp.spec)%(link_gomp)}\
     %{fcilkplus:%:include(libcilkrts.spec)%(link_cilkrts)}\
     %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\
+    %{fupc:%:include(libgupc.spec)%(link_upc)}\
     %(mflib) " STACK_SPLIT_SPEC "\
     %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} " SANITIZER_SPEC " \
     %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\
+    %{!nostdlib:%{!nostartfiles:%{fupc:%:include(upc-crtend.spec)%(upc_crtend)}}}\
     %{!nostdlib:%{!nostartfiles:%E}} %{T*}  \n%(post_link) }}}}}}"
 #endif
 
@@ -1061,6 +1065,9 @@ static const char *asm_final_spec = ASM_
 static const char *link_spec = LINK_SPEC;
 static const char *lib_spec = LIB_SPEC;
 static const char *link_gomp_spec = "";
+static const char *upc_crtbegin_spec = "";
+static const char *link_upc_spec = "";
+static const char *upc_crtend_spec = "";
 static const char *libgcc_spec = LIBGCC_SPEC;
 static const char *endfile_spec = ENDFILE_SPEC;
 static const char *startfile_spec = STARTFILE_SPEC;
@@ -1134,6 +1141,9 @@ static const char *cc1_options =
  %{fsyntax-only:-o %j} %{-param*}\
  %{coverage:-fprofile-arcs -ftest-coverage}";
 
+static const char *upc_options =
+ "-fupc %{!fno-upc-pre-include:-include gcc-upc.h}";
+
 static const char *asm_options =
 "%{-target-help:%:print-asm-header()} "
 #if HAVE_GNU_AS
@@ -1345,6 +1355,21 @@ static const struct compiler default_com
        as %(asm_debug) %(asm_options) %m.s %A }}}}"
 #endif
    , 0, 0, 0},
+  {".upc", "@upc", 0, 0, 0},
+  {"@upc",
+     /* Same as "@c" above, with the addition of %(upc_options).  */
+     "%{E|M|MM:cc1 -E %(upc_options) %(cpp_options) %(cpp_debug_options)}\
+      %{!E:%{!M:%{!MM:\
+	%{traditional|ftraditional|traditional-cpp:\
+              %e UPC does not support traditional compilation}\
+	%{save-temps|no-integrated-cpp:\
+	      cc1 -E %(upc_options) %(cpp_options)\
+	  %{save-temps:%b.mi} %{!save-temps:%g.mi} \n\
+	      cc1 -fpreprocessed %{save-temps:%b.mi} %{!save-temps:%g.mi}\
+	             %(upc_options) %(cc1_options)}\
+	%{!save-temps:%{!no-integrated-cpp:\
+	    cc1 %(cpp_unique_options) %(upc_options) %(cc1_options)}}\
+        %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
 
 #include "specs.h"
   /* Mark end of table.  */
@@ -1555,6 +1580,7 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("trad_capable_cpp",		&trad_capable_cpp),
   INIT_STATIC_SPEC ("cc1",			&cc1_spec),
   INIT_STATIC_SPEC ("cc1_options",		&cc1_options),
+  INIT_STATIC_SPEC ("upc_options",		&upc_options),
   INIT_STATIC_SPEC ("cc1plus",			&cc1plus_spec),
   INIT_STATIC_SPEC ("link_gcc_c_sequence",	&link_gcc_c_sequence_spec),
   INIT_STATIC_SPEC ("link_ssp",			&link_ssp_spec),
@@ -1562,6 +1588,9 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("link",			&link_spec),
   INIT_STATIC_SPEC ("lib",			&lib_spec),
   INIT_STATIC_SPEC ("link_gomp",		&link_gomp_spec),
+  INIT_STATIC_SPEC ("upc_crtbegin",		&upc_crtbegin_spec),
+  INIT_STATIC_SPEC ("link_upc",			&link_upc_spec),
+  INIT_STATIC_SPEC ("upc_crtend",		&upc_crtend_spec),
   INIT_STATIC_SPEC ("libgcc",			&libgcc_spec),
   INIT_STATIC_SPEC ("startfile",		&startfile_spec),
   INIT_STATIC_SPEC ("cross_compile",		&cross_compile),
Index: gcc/timevar.def
===================================================================
--- gcc/timevar.def	(.../trunk)	(revision 231059)
+++ gcc/timevar.def	(.../branches/gupc)	(revision 231080)
@@ -143,6 +143,7 @@ DEFTIMEVAR (TV_EARLY_INLINING        , "
 DEFTIMEVAR (TV_INLINE_PARAMETERS     , "inline parameters")
 DEFTIMEVAR (TV_INTEGRATION           , "integration")
 DEFTIMEVAR (TV_TREE_GIMPLIFY	     , "tree gimplify")
+DEFTIMEVAR (TV_TREE_UPC_GENERICIZE   , "tree UPC genericize")
 DEFTIMEVAR (TV_TREE_EH		     , "tree eh")
 DEFTIMEVAR (TV_TREE_CFG		     , "tree CFG construction")
 DEFTIMEVAR (TV_TREE_CLEANUP_CFG	     , "tree CFG cleanup")
Index: gcc/c-family/c-opts.c
===================================================================
--- gcc/c-family/c-opts.c	(.../trunk)	(revision 231059)
+++ gcc/c-family/c-opts.c	(.../branches/gupc)	(revision 231080)
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3.
 #include "tm_p.h"		/* For C_COMMON_OVERRIDE_OPTIONS.  */
 #include "diagnostic.h"
 #include "c-pragma.h"
+#include "c-upc-pts.h"
 #include "flags.h"
 #include "toplev.h"
 #include "langhooks.h"
@@ -208,6 +209,46 @@ c_common_init_options_struct (struct gcc
   opts->x_flag_complex_method = 2;
 }
 
+/* Initialize UPC-specific options.  */
+static void
+upc_init_options ()
+{
+  struct cl_option_handlers handlers;
+
+  /* UPC is based upon the C99 dialect.  Assert it here.
+   * We'll let the user override these options as he/she
+   * sees fit.  For example, -traditional will disable
+   * prototype checking.  */
+  set_std_c99 ( 0 /* iso=0 */ );
+
+  /* The consensus of the UPC community seems to be that
+     arithmetic on (void *) pointers and sizeof (void)
+     are compilation errors.  Enable this warning-as-error
+     mode by default.  */
+  warn_pointer_arith = 1;
+  set_default_handlers (&handlers);
+  control_warning_option (OPT_Wpointer_arith, (int) DK_ERROR, true,
+			  UNKNOWN_LOCATION, CL_C,
+			  &handlers, &global_options, &global_options_set,
+			  global_dc);
+
+  /* By default, don't generate UPC's DWARF2 extensions.  */
+  use_upc_dwarf2_extensions = 0;
+  flag_upc = 1;
+  flag_upc_threads = 0;
+  flag_upc_pthreads = 0;
+  /* By default, don't map UPC threads to POSIX threads.  */
+  flag_upc_pthreads = 0;
+  upc_pthreads_model = upc_pthreads_no_model;
+  /* By default, GASP profiling is off.  */
+  flag_upc_instrument = 0;
+  flag_upc_instrument_functions = 0;
+  /* By default, optimization level > 0 defines shared access routines
+     inlining, otherwise use the user specified flag to unconditionally
+     enable/disable inlining of the UPC shared memory access routines.  */
+  flag_upc_inline_lib = -1;
+}
+
 /* Common initialization before calling option handlers.  */
 void
 c_common_init_options (unsigned int decoded_options_count,
@@ -235,20 +276,94 @@ c_common_init_options (unsigned int deco
     {
       /* The default for C is gnu11.  */
       set_std_c11 (false /* ISO */);
-
-      /* If preprocessing assembly language, accept any of the C-family
-	 front end options since the driver may pass them through.  */
       for (i = 1; i < decoded_options_count; i++)
-	if (decoded_options[i].opt_index == OPT_lang_asm)
-	  {
-	    accept_all_c_family_options = true;
-	    break;
-	  }
+        {
+          /* If preprocessing assembly language, accept any of the C-family
+	     front end options since the driver may pass them through.  */
+	  if (decoded_options[i].opt_index == OPT_lang_asm)
+	    {
+	      accept_all_c_family_options = true;
+	      break;
+	    }
+	  /* If compiling UPC, initialize appropriate default options.  */
+	  if (decoded_options[i].opt_index == OPT_fupc)
+	    {
+	      upc_init_options ();
+	      break;
+	    }
+        }
     }
 
   global_dc->colorize_source_p = true;
 }
 
+/* Process UPC specific command line switches */
+
+static bool
+upc_handle_option (const enum opt_code code, const char *arg, const int value)
+{
+  int result = 1;
+  if (!flag_upc)
+    {
+      error ("%s is supported only when -fupc is also present", arg);
+      return false;
+    }
+  switch (code)
+    {
+    default:
+      gcc_unreachable ();
+      break;
+    case OPT_fupc:
+      flag_upc = value;
+      break;
+    case OPT_dwarf_2_upc:
+      use_upc_dwarf2_extensions = value;
+      break;
+    case OPT_fupc_debug:
+      if ((value == 1) && (flag_upc_inline_lib == 1))
+	error ("-fupc-debug is incompatible with -fupc-inline-lib");
+      flag_upc_debug = value;
+      break;
+    case OPT_fupc_inline_lib:
+      if ((value == 1) && (flag_upc_instrument == 1))
+	error ("-fupc-inline-lib is incompatible with -fupc-instrument");
+      if ((value == 1) && (flag_upc_debug == 1))
+	error ("-fupc-inline-lib is incompatible with -fupc-debug");
+      flag_upc_inline_lib = value;
+      break;
+    case OPT_fupc_instrument:
+      if ((value == 1) && (flag_upc_inline_lib == 1))
+	error ("-fupc-instrument is incompatible with -fupc-inline-lib");
+      flag_upc_instrument = value;
+      break;
+    case OPT_fupc_instrument_functions:
+      if ((value == 1) && (flag_upc_inline_lib == 1))
+	error
+	  ("-fupc-instrument-functions is incompatible "
+	   "with -fupc-inline-lib");
+      flag_upc_instrument = value;
+      flag_upc_instrument_functions = value;
+      break;
+    case OPT_fupc_pthreads_model_tls:
+      flag_upc_pthreads = 1;
+      upc_pthreads_model = upc_pthreads_tls_model;
+      break;
+    case OPT_fupc_threads_:
+      {
+        int num_threads = value;
+	if (num_threads > UPC_MAX_THREADS)
+	  {
+	    error ("THREADS value exceeds UPC implementation limit of %d",
+		   UPC_MAX_THREADS);
+	    num_threads = 1;
+	  }
+        flag_upc_threads = num_threads;
+      }
+      break;
+    }
+  return result;
+}
+
 /* Handle switch SCODE with argument ARG.  VALUE is true, unless no-
    form of an -f or -W option was given.  Returns false if the switch was
    invalid, true if valid.  Use HANDLERS in recursive handle_option calls.  */
@@ -532,6 +647,17 @@ c_common_handle_option (size_t scode, co
       cpp_opts->ext_numeric_literals = value;
       break;
 
+    case OPT_fupc:
+    case OPT_dwarf_2_upc:
+    case OPT_fupc_debug:
+    case OPT_fupc_inline_lib:
+    case OPT_fupc_instrument:
+    case OPT_fupc_instrument_functions:
+    case OPT_fupc_pthreads_model_tls:
+    case OPT_fupc_threads_:
+      result = upc_handle_option (code, arg, value);
+      break;
+
     case OPT_idirafter:
       add_path (xstrdup (arg), AFTER, 0, true);
       break;
@@ -1062,6 +1188,9 @@ c_common_parse_file (void)
       pch_init ();
       push_file_scope ();
       c_parse_file ();
+      /* Generate UPC global initialization code, if required.  */
+      if (flag_upc)
+        (*lang_hooks.upc.write_global_declarations) ();
       pop_file_scope ();
       /* And end the main input file, if the debug writer wants it  */
       if (debug_hooks->start_end_main_source_file)
Index: gcc/c-family/c.opt
===================================================================
--- gcc/c-family/c.opt	(.../trunk)	(revision 231059)
+++ gcc/c-family/c.opt	(.../branches/gupc)	(revision 231080)
@@ -992,6 +992,10 @@ d
 C ObjC C++ ObjC++ Joined
 ; Documented in common.opt.  FIXME - what about -dI, -dD, -dN and -dD?
 
+dwarf-2-upc
+C Report Var(use_upc_dwarf2_extensions) Init(0)
+Generate DWARF-2 debug info with UPC extensions.
+
 fabi-compat-version=
 C++ ObjC++ Joined RejectNegative UInteger Var(flag_abi_compat_version) Init(-1)
 The version of the C++ ABI used for -Wabi warnings and link compatibility aliases.
@@ -1512,6 +1516,46 @@ funsigned-char
 C ObjC C++ ObjC++ LTO Var(flag_signed_char, 0)
 Make \"char\" unsigned by default.
 
+fupc
+C Report Var(flag_upc) Init(0)
+Enable UPC.
+
+fupc-debug
+C Var(flag_upc_debug)
+Generate code that provides the UPC runtime with
+the file and line number where the runtime was called.
+
+fupc-inline-lib
+C Var(flag_upc_inline_lib)
+Generate code for inlined UPC runtime library routines.
+Default, at optimization levels greater than 0.
+
+fupc-pre-include
+C Init(1)
+Pre-include UPC runtime header file.
+
+fupc-pthreads-model-tls
+C
+Generate code for a POSIX threads based UPC runtime environment
+with TLS (Thread Local Storage) support.
+
+fupc-threads=
+C Joined RejectNegative UInteger
+Specify the compile-time value of THREADS.
+
+fupc-threads-
+C Joined RejectNegative UInteger Alias(fupc-threads=)
+Deprecated in favor of -fupc-threads=.
+
+fupc-instrument
+C Var(flag_upc_instrument)
+Instrument UPC shared accesses and library calls, using GASP tool support.
+
+fupc-instrument-functions
+C Var(flag_upc_instrument_functions)
+Instrument functions calls, using GASP tool support
+(implies -fupc-instrument).
+
 fuse-cxa-atexit
 C++ ObjC++ Var(flag_use_cxa_atexit) Init(DEFAULT_USE_CXA_ATEXIT)
 Use __cxa_atexit to register destructors.
Index: gcc/c/gupcspec.c
===================================================================
--- gcc/c/gupcspec.c	(.../trunk)	(revision 0)
+++ gcc/c/gupcspec.c	(.../branches/gupc)	(revision 231080)
@@ -0,0 +1,303 @@
+/* gupcspec.c: the UPC compiler driver program
+   Copyright (C) 2001-2015 Free Software Foundation, Inc.
+   Contributed by Gary Funck <gary@intrepid.com>
+     and Nenad Vukicevic <nenad@intrepid.com>.
+
+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 3, 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 COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "gcc.h"
+#include "opts.h"
+
+#include "tm.h"
+
+
+/* GUPC driver - derived from fortran/gfortranspec.c.  */
+
+/* The original argument list and related info is copied here.  */
+static unsigned int gupc_xargc;
+static const struct cl_decoded_option *gupc_x_decoded_options;
+static void append_arg (const struct cl_decoded_option *);
+
+/* The new argument list will be built here.  */
+static unsigned int gupc_newargc;
+static struct cl_decoded_option *gupc_new_decoded_options;
+
+static const char *const standard_bindir_prefix = STANDARD_BINDIR_PREFIX;
+static const char *const standard_exec_prefix = STANDARD_EXEC_PREFIX;
+
+/* By default the linker is always invoked.  */
+static int invoke_linker = 1;
+
+static int match_suffix (const char *s, const char *suffix);
+
+#define END_ARGS ((char *) 0)
+
+/* Return true if the strings S1 and S2 are either both NULL
+ * or both the same string.  */
+
+static bool
+strings_same (const char *s1, const char *s2)
+{
+  return s1 == s2 || (s1 != NULL && s2 != NULL && strcmp (s1, s2) == 0);
+}
+
+/* Return whether decoded option structures OPT1 and OPT2 are the
+   same.  */
+
+static bool
+options_same (const struct cl_decoded_option *opt1,
+	      const struct cl_decoded_option *opt2)
+{
+  return (opt1->opt_index == opt2->opt_index
+	  && strings_same (opt1->arg, opt2->arg)
+	  && strings_same (opt1->orig_option_with_args_text,
+			   opt2->orig_option_with_args_text)
+	  && strings_same (opt1->canonical_option[0],
+			   opt2->canonical_option[0])
+	  && strings_same (opt1->canonical_option[1],
+			   opt2->canonical_option[1])
+	  && strings_same (opt1->canonical_option[2],
+			   opt2->canonical_option[2])
+	  && strings_same (opt1->canonical_option[3],
+			   opt2->canonical_option[3])
+	  && (opt1->canonical_option_num_elements
+	      == opt2->canonical_option_num_elements)
+	  && opt1->value == opt2->value && opt1->errors == opt2->errors);
+}
+
+/* Append another argument to the list being built.  As long as it is
+   identical to the corresponding arg in the original list, just increment
+   the new arg count.  Otherwise allocate a new list, etc.  */
+
+static void
+append_arg (const struct cl_decoded_option *arg)
+{
+  static unsigned int newargsize;
+
+  if (gupc_new_decoded_options == gupc_x_decoded_options
+      && gupc_newargc < gupc_xargc
+      && options_same (arg, &gupc_x_decoded_options[gupc_newargc]))
+    {
+      ++gupc_newargc;
+      return;			/* Nothing new here.  */
+    }
+
+  if (gupc_new_decoded_options == gupc_x_decoded_options)
+    {				/* Make new arglist.  */
+      unsigned int i;
+
+      newargsize = (gupc_xargc << 2) + 20;	/* This should handle all.  */
+      gupc_new_decoded_options =
+	XNEWVEC (struct cl_decoded_option, newargsize);
+
+      /* Copy what has been done so far.  */
+      for (i = 0; i < gupc_newargc; ++i)
+	gupc_new_decoded_options[i] = gupc_x_decoded_options[i];
+    }
+
+  if (gupc_newargc == newargsize)
+    fatal_error (input_location, "overflowed output arg list for %qs",
+		 arg->orig_option_with_args_text);
+
+  gupc_new_decoded_options[gupc_newargc++] = *arg;
+}
+
+/* Append an option described by OPT_INDEX, ARG and VALUE to the list
+   being built.  */
+static void
+append_option (size_t opt_index, const char *arg, int value)
+{
+  struct cl_decoded_option decoded;
+
+  generate_option (opt_index, arg, value, CL_DRIVER, &decoded);
+  append_arg (&decoded);
+}
+
+static int
+match_suffix (const char *s, const char *suffix)
+{
+  int slen = strlen (s);
+  int xlen = strlen (suffix);
+  const char *start = (xlen <= slen) ? s + slen - xlen : 0;
+  return start && !strncmp (start, suffix, xlen);
+}
+
+void
+lang_specific_driver (struct cl_decoded_option **in_decoded_options,
+		      unsigned int *in_decoded_options_count,
+		      int *in_added_libraries ATTRIBUTE_UNUSED)
+{
+  struct cl_decoded_option *decoded_options = *in_decoded_options;
+  unsigned int i;
+  int is_x_in_effect = 0;
+  int is_x_upc_in_effect = 0;
+  int verbose = 0;
+  int n_infiles = 0;
+  int n_outfiles = 0;
+  int pre_processed = 0;
+
+  gupc_xargc = *in_decoded_options_count;
+  gupc_x_decoded_options = decoded_options;
+  gupc_newargc = 0;
+  gupc_new_decoded_options = decoded_options;
+
+  /* First pass through the argument list.  */
+
+  /* Check to see if any switches are asserted that inhibit linking
+     and record the presence of other switches that may require
+     special handling.  */
+  for (i = 1; i < gupc_xargc; ++i)
+    {
+      if (decoded_options[i].errors & CL_ERR_MISSING_ARG)
+	continue;
+
+      switch (decoded_options[i].opt_index)
+	{
+
+	case OPT_SPECIAL_input_file:
+	  ++n_infiles;
+	  continue;
+
+	case OPT_nostdlib:
+	case OPT_nodefaultlibs:
+	case OPT_c:
+	case OPT_S:
+	case OPT_fsyntax_only:
+	case OPT_E:
+	  /* These options disable linking entirely or linking of the
+	     standard libraries.  */
+	  invoke_linker = 0;
+	  break;
+
+	case OPT_fpreprocessed:
+	  pre_processed = 1;
+	  break;
+
+	case OPT_l:
+	  ++n_infiles;
+	  break;
+
+	case OPT_o:
+	  ++n_outfiles;
+	  break;
+
+	case OPT_v:
+	  verbose = 1;
+	  break;
+
+	case OPT__version:
+	  /* Optional GUPC version string. Let GCC handle it for now.  */
+	  break;
+
+	case OPT__help:
+	  /* Let gcc.c handle this, as it has a really
+	     cool facility for handling --help and --verbose --help.  */
+	  return;
+
+	default:
+	  break;
+	}
+    }
+
+  /* Create the new argument list.  */
+
+  /* Start with the compiler itself.  */
+  append_arg (&decoded_options[0]);
+
+  /* Always assert -fupc.  */
+  append_option (OPT_fupc, NULL, 1);
+
+  /* If there are no input files, no need for the library.  */
+  if (n_infiles == 0)
+    invoke_linker = 0;
+
+  /* Copy in the arguments as passed to 'upc' */
+  is_x_in_effect = 0;
+  is_x_upc_in_effect = 0;
+  for (i = 1; i < gupc_xargc; ++i)
+    {
+      /* Skip -fupc, we asserted it above.  */
+      if (decoded_options[i].opt_index == OPT_fupc)
+        continue;
+
+      /* Check for "-x [c,upc,..]".  */
+      if (decoded_options[i].opt_index == OPT_x)
+	{
+	  /* Go to default if "none" found.  */
+	  if (!strcmp (decoded_options[i].arg, "none"))
+	    {
+	      is_x_in_effect = 0;
+	      is_x_upc_in_effect = 0;
+	    }
+	  else
+	    is_x_in_effect = 1;
+	}
+
+      /* By default, driver accepts C files as UPC files.  Unless there
+         is "-x" option in affect.  */
+      if (decoded_options[i].opt_index == OPT_SPECIAL_input_file)
+	{
+	  const int is_c_file = match_suffix (decoded_options[i].arg, ".c")
+	    || match_suffix (decoded_options[i].arg, ".h")
+	    || (pre_processed && match_suffix (decoded_options[i].arg, ".i"));
+	  if (is_c_file)
+	    {
+              if ( !(is_x_in_effect || is_x_upc_in_effect))
+		{
+		  append_option (OPT_x, "upc", 1);
+	   	  is_x_upc_in_effect = 1;
+		}
+	      append_arg (&decoded_options[i]);
+	      continue;
+	    }
+	  else
+	    {
+	      if (is_x_upc_in_effect)
+	        {
+	          is_x_upc_in_effect = 0;
+		  append_option (OPT_x, "none", 1);
+	        }
+	    }
+	}
+      append_arg (&decoded_options[i]);
+    }
+
+  if (verbose)
+    {
+      fprintf (stderr, "Driving:");
+      for (i = 0; i < gupc_newargc; i++)
+	fprintf (stderr, " %s",
+		 gupc_new_decoded_options[i].orig_option_with_args_text);
+      fprintf (stderr, "\n");
+    }
+
+  *in_decoded_options_count = gupc_newargc;
+  *in_decoded_options = gupc_new_decoded_options;
+}
+
+/* Called before linking.  Returns 0 on success and -1 on failure.  */
+int
+lang_specific_pre_link (void)
+{
+  return 0;
+}
+
+/* Number of extra output files that lang_specific_pre_link may generate.  */
+int lang_specific_extra_outfiles = 0;	/* Not used for GUPC.  */
