This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFA: Add SH Symbian port


Hi Joern,

OK - will you accept this revised patch with the use/support of naked functions removed ? (The patch also renames the target to sh-*-symbianelf in line with the change made to the binutils sources).

Cheers Nick

gcc/ChangeLog

2004-07-09 Nick Clifton <nickc@redhat.com>

	* config.gcc: Add sh-*-symbianelf target.
	* config/sh/sh.c: Add new target macros:
	TARGET_ENCODE_SECTION_INFO, TARGET_STRIP_NAME_ENCODING,
	TARGET_CXX_IMPORT_EXPORT_CLASS.
	(sh_file_start): Create a definition of the .directive section.
	(sh_attribute): Add dllimport and dllexport attributes.
	* config/sh/symbian-pre.h: New file.
	* config/sh/symbian-post.h: New file.
	* config/sh/symbian.c: New file. Contains Symbian specific
	functions.
	* config/sh/sh-protos.h: Add prototypes for new functions
	provided by symbian.c.
	* config/sh/t-symbian: New file.

Index: gcc/config.gcc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config.gcc,v
retrieving revision 1.465
diff -c -3 -p -r1.465 config.gcc
*** gcc/config.gcc	8 Jul 2004 01:28:53 -0000	1.465
--- gcc/config.gcc	9 Jul 2004 12:42:41 -0000
*************** s390x-ibm-tpf*)
*** 1671,1676 ****
--- 1671,1677 ----
  	tmake_file="t-slibgcc-elf-ver s390/t-crtstuff s390/t-tpf"
  	;;
  sh-*-elf* | sh[12346l]*-*-elf* | sh*-*-kaos* | \
+ sh-*-symbianelf* | sh[12346l]*-*-symbianelf* | \
    sh-*-linux* | sh[346lbe]*-*-linux* | \
    sh-*-netbsdelf* | shl*-*-netbsdelf* | sh5-*-netbsd* | sh5l*-*-netbsd* | \
     sh64-*-netbsd* | sh64l*-*-netbsd*)
*************** sh-*-elf* | sh[12346l]*-*-elf* | sh*-*-k
*** 1730,1735 ****
--- 1731,1742 ----
  		tm_file="${tm_file} sh/sh64.h"
  		extra_headers="shmedia.h ushmedia.h sshmedia.h"
  		;;
+ 	*-*-symbianelf*)
+ 		tmake_file="sh/t-symbian"
+ 		tm_file="sh/symbian-pre.h sh/little.h ${tm_file} sh/symbian-post.h"
+ 		extra_objs="symbian.o"
+ 		extra_parts="crt1.o crti.o crtn.o crtbegin.o crtend.o crtbeginS.o crtendS.o"
+ 		;;	
  	esac
  	# sed el/eb endian suffixes away to avoid confusion with sh[23]e
  	case `echo ${target} | sed 's/e[lb]-/-/'` in
Index: gcc/config/sh/sh-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh-protos.h,v
retrieving revision 1.55
diff -c -3 -p -r1.55 sh-protos.h
*** gcc/config/sh/sh-protos.h	10 May 2004 23:25:13 -0000	1.55
--- gcc/config/sh/sh-protos.h	9 Jul 2004 12:42:47 -0000
*************** extern const char *sh_pch_valid_p (const
*** 144,146 ****
--- 144,160 ----
  extern bool sh_promote_prototypes (tree);
  
  #endif /* ! GCC_SH_PROTOS_H */
+ 
+ #ifdef SYMBIAN
+ extern bool         sh_symbian_dllimport_name_p       (const char *);
+ extern const char * sh_symbian_strip_name_encoding    (const char *);
+ extern bool         sh_symbian_dllexport_name_p       (const char *);
+ extern int          symbian_import_export_class       (tree, int);
+ #ifdef TREE_CODE
+ extern bool         sh_symbian_dllexport_p            (tree);
+ extern tree         sh_symbian_handle_dll_attribute   (tree *, tree, tree, int, bool *);
+ #ifdef RTX_CODE
+ extern void         sh_symbian_encode_section_info    (tree, rtx, int);
+ #endif
+ #endif
+ #endif /* SYMBIAN */
Index: gcc/config/sh/sh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.c,v
retrieving revision 1.277
diff -c -3 -p -r1.277 sh.c
*** gcc/config/sh/sh.c	9 Jul 2004 00:47:46 -0000	1.277
--- gcc/config/sh/sh.c	9 Jul 2004 12:42:57 -0000
*************** static tree sh_build_builtin_va_list (vo
*** 446,451 ****
--- 446,462 ----
  /* Return current register pressure for regmode.  */
  #define CURR_REGMODE_PRESSURE(MODE) 	curr_regmode_pressure[((MODE) == SImode) ? 0 : 1]
  
+ #ifdef SYMBIAN
+ 
+ #undef  TARGET_ENCODE_SECTION_INFO
+ #define TARGET_ENCODE_SECTION_INFO	sh_symbian_encode_section_info
+ #undef  TARGET_STRIP_NAME_ENCODING
+ #define TARGET_STRIP_NAME_ENCODING	sh_symbian_strip_name_encoding
+ #undef  TARGET_CXX_IMPORT_EXPORT_CLASS
+ #define TARGET_CXX_IMPORT_EXPORT_CLASS  symbian_import_export_class
+ 
+ #endif /* SYMBIAN */
+ 
  struct gcc_target targetm = TARGET_INITIALIZER;
  
  /* Print the operand address in x to the stream.  */
*************** sh_file_start (void)
*** 1426,1431 ****
--- 1437,1448 ----
  {
    default_file_start ();
  
+ #ifdef SYMBIAN
+   /* Declare the .directive section before it is used.  */
+   fputs ("\t.section .directive, \"SM\", @progbits, 1\n", asm_out_file);
+   fputs ("\t.asciz \"#<SYMEDIT>#\\n\"\n", asm_out_file);
+ #endif
+   
    if (TARGET_ELF)
      /* We need to show the text section with the proper
         attributes as in TEXT_SECTION_ASM_OP, before dwarf2out
*************** const struct attribute_spec sh_attribute
*** 6965,6970 ****
--- 6982,6998 ----
    { "sp_switch",         1, 1, true,  false, false, sh_handle_sp_switch_attribute },
    { "trap_exit",         1, 1, true,  false, false, sh_handle_trap_exit_attribute },
    { "renesas",           0, 0, false, true, false, sh_handle_renesas_attribute },
+ #ifdef SYMBIAN
+   /* Symbian support adds three new attributes:
+      dllexport - for exporting a function/variable that will live in a dll
+      dllimport - for importing a function/variable from a dll
+      
+      Microsoft allows multiple declspecs in one __declspec, separating
+      them with spaces.  We do NOT support this.  Instead, use __declspec
+      multiple times.  */
+   { "dllimport",         0, 0, true,  false, false, sh_symbian_handle_dll_attribute },
+   { "dllexport",         0, 0, true,  false, false, sh_symbian_handle_dll_attribute },
+ #endif
    { NULL,                0, 0, false, false, false, NULL }
  };
  
*** /dev/null	2004-02-18 15:26:44.000000000 +0000
--- gcc/config/sh/symbian-pre.h	2004-07-02 13:00:33.000000000 +0100
***************
*** 0 ****
--- 1,48 ----
+ /* Definitions for the Symbian OS running on an SH part.
+    This file is included before any other target specific headers.
+ 
+    Copyright (C) 2004 Free Software Foundation, Inc.
+    Contributed by Red Hat.
+ 
+    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.  */
+ 
+ /* Enable Symbian specific code.  */
+ #define SYMBIAN		1
+ 
+ /* Default to using the Renesas ABI.  */
+ #define TARGET_ABI_DEFAULT	RENESAS_BIT
+ 
+ /* Support the __declspec keyword by turning them into attributes.
+    We currently only support: naked, dllimport, and dllexport.
+    Note that the current way we do this may result in a collision with
+    predefined attributes later on.  This can be solved by using one attribute,
+    say __declspec__, and passing args to it.  The problem with that approach
+    is that args are not accumulated: each new appearance would clobber any
+    existing args.  */
+ #define SUBTARGET_CPP_SPEC "-D__declspec(x)=__attribute__((x))"
+ 
+ /* Get tree.c to declare merge_dllimport_decl_attributes().  */
+ #define TARGET_DLLIMPORT_DECL_ATTRIBUTES
+ 
+ /* The Symbian OS currently does not support exception handling.  */
+ #define SUBTARGET_CC1PLUS_SPEC "-fno-exceptions"
+ 
+ /* Create constructor/destructor sections without the writable flag.
+    Symbian puts them into the text segment and munges them later on.  */
+ #define CTORS_SECTION_ASM_OP	"\t.section\t.ctors,\"ax\",@progbits"
+ #define DTORS_SECTION_ASM_OP	"\t.section\t.dtors,\"ax\",@progbits"
*** /dev/null	2004-02-18 15:26:44.000000000 +0000
--- gcc/config/sh/symbian-post.h	2004-07-06 12:46:35.000000000 +0100
***************
*** 0 ****
--- 1,89 ----
+ /* Definitions for the Symbian OS running on an SH part.
+    This file is included after all the other target specific headers.
+ 
+    Copyright (C) 2004 Free Software Foundation, Inc.
+    Contributed by Red Hat.
+ 
+    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.  */
+ 
+ #undef  TARGET_VERSION
+ #define TARGET_VERSION \
+   fputs (" (Renesas SH for Symbian OS)", stderr);
+ 
+ #undef  LINK_EMUL_PREFIX
+ #define LINK_EMUL_PREFIX "shlsymbian"
+ 
+ 
+ #define SYMBIAN_EXPORT_NAME(NAME,FILE,DECL)			\
+   do								\
+     {								\
+       if ((DECL && sh_symbian_dllexport_p (DECL))		\
+          || sh_symbian_dllexport_name_p (NAME))			\
+         {							\
+           fprintf ((FILE), "\t.pushsection .directive\n");	\
+           fprintf ((FILE), "\t.asciz \"EXPORT %s\\n\"\n",	\
+ 	           sh_symbian_strip_name_encoding (NAME));	\
+           fprintf ((FILE), "\t.popsection\n");			\
+        }							\
+     }								\
+   while (0)
+ 
+ /* Output a function definition label.  */
+ #undef  ASM_DECLARE_FUNCTION_NAME
+ #define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL)		\
+   do								\
+     {								\
+       SYMBIAN_EXPORT_NAME ((NAME), (FILE), (DECL));		\
+       ASM_OUTPUT_TYPE_DIRECTIVE ((FILE), (NAME), "function");	\
+       ASM_DECLARE_RESULT ((FILE), DECL_RESULT (DECL));		\
+       ASM_OUTPUT_LABEL ((FILE), (NAME));			\
+     }								\
+   while (0)
+ 
+ /* Output the label for an initialized variable.  */
+ #undef  ASM_DECLARE_OBJECT_NAME
+ #define ASM_DECLARE_OBJECT_NAME(FILE, NAME, DECL)		\
+   do								\
+     {								\
+       HOST_WIDE_INT size;					\
+ 								\
+       SYMBIAN_EXPORT_NAME ((NAME), (FILE), (DECL));		\
+       ASM_OUTPUT_TYPE_DIRECTIVE ((FILE), (NAME), "object");	\
+ 								\
+       size_directive_output = 0;				\
+       if (!flag_inhibit_size_directive				\
+ 	  && (DECL)						\
+           && DECL_SIZE (DECL))					\
+ 	{							\
+ 	  size_directive_output = 1;				\
+ 	  size = int_size_in_bytes (TREE_TYPE (DECL));		\
+ 	  ASM_OUTPUT_SIZE_DIRECTIVE ((FILE), (NAME), size);	\
+ 	}							\
+ 								\
+       ASM_OUTPUT_LABEL ((FILE), (NAME));			\
+     }								\
+   while (0)
+ 
+ #undef  ASM_OUTPUT_LABELREF
+ #define ASM_OUTPUT_LABELREF(FILE, NAME)				\
+   do								\
+     {								\
+       asm_fprintf ((FILE), "%U%s",				\
+ 		   sh_symbian_strip_name_encoding (NAME));	\
+     }								\
+   while (0)
*** /dev/null	2004-02-18 15:26:44.000000000 +0000
--- gcc/config/sh/symbian.c	2004-07-09 13:49:38.000000000 +0100
***************
*** 0 ****
--- 1,908 ----
+ /* Routines for GCC for a Symbian OS targeted SH backend.
+    Copyright (C) 2004 Free Software Foundation, Inc.
+    Contributed by RedHat.
+    Most of this code is stolen from i386/winnt.c.
+ 
+    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.  */
+ 
+ #include "config.h"
+ #include "system.h"
+ #include "coretypes.h"
+ #include "tm.h"
+ #include "rtl.h"
+ #include "output.h"
+ #include "flags.h"
+ #include "tree.h"
+ #include "expr.h"
+ #include "tm_p.h"
+ #include "cp/cp-tree.h"	/* We need access to the OVL_... macros.  */
+ #include "toplev.h"
+ 
+ /* Select the level of debugging information to display.
+    0 for no debugging.
+    1 for informative messages about decisions to add attributes
+    2 for verbose information about what is being done.  */
+ #define SYMBIAN_DEBUG 0
+ //#define SYMBIAN_DEBUG 1
+ //#define SYMBIAN_DEBUG 2
+ 
+ extern int current_function_anonymous_args;
+ 
+ /* A unique character to encode declspec encoded objects.  */
+ #define SH_SYMBIAN_FLAG_CHAR "$"
+ 
+ /* Unique strings to prefix exported and imported objects.  */
+ #define DLL_IMPORT_PREFIX SH_SYMBIAN_FLAG_CHAR "i."
+ #define DLL_EXPORT_PREFIX SH_SYMBIAN_FLAG_CHAR "e."
+ 
+ 
+ /* Return the type that we should use to determine if DECL is
+    imported or exported.  */
+ 
+ static tree
+ sh_symbian_associated_type (tree decl)
+ {
+   tree t = NULL_TREE;
+ 
+   if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
+   /* Methods now inherit their dllimport/dllexport attributes correctly
+      so there is no need to check their class.  In fact it is wrong to
+      check their class since a method can remain unexported from an
+      exported class.  */
+     return t;
+ 
+   /* Otherwise we can just take the DECL_CONTEXT as normal.  */
+   if (DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl)))
+     t = DECL_CONTEXT (decl);
+ 
+   return t;
+ }
+ 
+ /* Return nonzero if DECL is a dllexport'd object.  */
+ 
+ bool
+ sh_symbian_dllexport_p (tree decl)
+ {
+   tree exp;
+ 
+   if (   TREE_CODE (decl) != VAR_DECL
+       && TREE_CODE (decl) != FUNCTION_DECL)
+     return false;
+ 
+   exp = lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl));
+ 
+   /* Class members get the dllexport status of their class.  */
+   if (exp == NULL)
+     {
+       tree class = sh_symbian_associated_type (decl);
+ 
+       if (class)
+ 	exp = lookup_attribute ("dllexport", TYPE_ATTRIBUTES (class));
+     }
+ #if SYMBIAN_DEBUG
+   if (exp)
+     {
+       print_node_brief (stderr, "dllexport:", decl, 0);
+       fprintf (stderr, "\n");
+     }
+   else
+ #if SYMBIAN_DEBUG < 2
+     if (TREE_CODE (decl) != FUNCTION_DECL)
+ #endif
+     {
+       print_node_brief (stderr, "no dllexport:", decl, 0);
+       fprintf (stderr, "\n");
+     }
+ #endif
+   return exp ? true : false;
+ }
+ 
+ /* Return nonzero if DECL is a dllimport'd object.  */
+ 
+ static bool
+ sh_symbian_dllimport_p (tree decl)
+ {
+   tree imp;
+ 
+   if (   TREE_CODE (decl) != VAR_DECL
+       && TREE_CODE (decl) != FUNCTION_DECL)
+     return false;
+ 
+   imp = lookup_attribute ("dllimport", DECL_ATTRIBUTES (decl));
+   if (imp)
+     return true;
+ 
+   /* Class members get the dllimport status of their class.  */
+   imp = sh_symbian_associated_type (decl);
+   if (! imp)
+     return false;
+ 
+   imp = lookup_attribute ("dllimport", TYPE_ATTRIBUTES (imp));
+   if (!imp)
+     return false;
+ 
+   /* Don't mark defined functions as dllimport.  If the definition itself
+      was marked with dllimport, then sh_symbian_handle_dll_attribute reports
+      an error. This handles the case when the definition overrides an
+      earlier declaration.  */
+   if (TREE_CODE (decl) ==  FUNCTION_DECL
+       && DECL_INITIAL (decl)
+       && !DECL_INLINE (decl))
+     {
+       /* Don't warn about artificial methods.  */
+       if (!DECL_ARTIFICIAL (decl))
+ 	warning ("%H function '%D' is defined after prior declaration as dllimport: attribute ignored",
+ 		 & DECL_SOURCE_LOCATION (decl), decl);
+       return false;
+     }
+ 
+   /* We ignore the dllimport attribute for inline member functions.
+      This differs from MSVC behavior which treats it like GNUC
+      'extern inline' extension.   */
+   else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl))
+     {
+       if (extra_warnings)
+ 	warning ("%Hinline function '%D' is declared as dllimport: attribute ignored.",
+ 		 & DECL_SOURCE_LOCATION (decl), decl);
+       return false;
+     }
+ 
+   /*  Don't allow definitions of static data members in dllimport
+       class.  Just ignore the attribute for vtable data.  */
+   else if (TREE_CODE (decl) == VAR_DECL
+ 	   && TREE_STATIC (decl)
+ 	   && TREE_PUBLIC (decl)
+ 	   && !DECL_EXTERNAL (decl))
+     {
+       if (!DECL_VIRTUAL_P (decl))
+ 	error ("%Hdefinition of static data member '%D' of dllimport'd class.",
+ 	       & DECL_SOURCE_LOCATION (decl), decl);
+       return false;
+     }
+ 
+   /* Since we can't treat a pointer to a dllimport'd symbol as a
+      constant address, we turn off the attribute on C++ virtual
+      methods to allow creation of vtables using thunks.  Don't mark
+      artificial methods either (in sh_symbian_associated_type, only
+      COMDAT artificial method get import status from class context).  */
+   else if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
+ 	   && (DECL_VIRTUAL_P (decl) || DECL_ARTIFICIAL (decl)))
+     return false;
+ 
+   return true;
+ }
+ 
+ /* Return nonzero if SYMBOL is marked as being dllexport'd.  */
+ 
+ bool
+ sh_symbian_dllexport_name_p (const char *symbol)
+ {
+   return strncmp (DLL_EXPORT_PREFIX, symbol,
+ 		  strlen (DLL_EXPORT_PREFIX)) == 0;
+ }
+ 
+ /* Return nonzero if SYMBOL is marked as being dllimport'd.  */
+ 
+ 
+ bool
+ sh_symbian_dllimport_name_p (const char *symbol)
+ {
+   return strncmp (DLL_IMPORT_PREFIX, symbol,
+ 		  strlen (DLL_IMPORT_PREFIX)) == 0;
+ }
+ 
+ /* Mark a DECL as being dllexport'd.
+    Note that we override the previous setting (eg: dllimport).  */
+ 
+ static void
+ sh_symbian_mark_dllexport (tree decl)
+ {
+   const char *oldname;
+   char *newname;
+   rtx rtlname;
+   tree idp;
+ 
+   rtlname = XEXP (DECL_RTL (decl), 0);
+ 
+   if (GET_CODE (rtlname) == SYMBOL_REF)
+     oldname = XSTR (rtlname, 0);
+   else if (GET_CODE (rtlname) == MEM
+ 	   && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
+     oldname = XSTR (XEXP (rtlname, 0), 0);
+   else
+     abort ();
+ 
+   if (sh_symbian_dllimport_name_p (oldname))
+     {
+      /* Remove DLL_IMPORT_PREFIX.
+ 	Note - we do not issue a warning here.  In Symbian's environment it
+ 	is legitimate for a prototype to be marked as dllimport and the
+ 	corresponding defintion to be marked as dllexport.  The prototypes
+ 	are in headers used everywhere and the defintion is in a translation
+ 	unit which has included the header in order to ensure argument
+ 	correctness.  */
+       oldname += strlen (DLL_IMPORT_PREFIX);
+       DECL_NON_ADDR_CONST_P (decl) = 0;
+     }
+   else if (sh_symbian_dllexport_name_p (oldname))
+     return; /* Already done.  */
+ 
+   newname = alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1);
+   sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname);
+ 
+   /* We pass newname through get_identifier to ensure it has a unique
+      address.  RTL processing can sometimes peek inside the symbol ref
+      and compare the string's addresses to see if two symbols are
+      identical.  */
+   idp = get_identifier (newname);
+ 
+   XEXP (DECL_RTL (decl), 0) =
+     gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
+ }
+ 
+ /* Mark a DECL as being dllimport'd.  */
+ 
+ static void
+ sh_symbian_mark_dllimport (tree decl)
+ {
+   const char *oldname;
+   char *newname;
+   tree idp;
+   rtx rtlname;
+   rtx newrtl;
+ 
+   rtlname = XEXP (DECL_RTL (decl), 0);
+ 
+   if (GET_CODE (rtlname) == SYMBOL_REF)
+     oldname = XSTR (rtlname, 0);
+   else if (GET_CODE (rtlname) == MEM
+ 	   && GET_CODE (XEXP (rtlname, 0)) == SYMBOL_REF)
+     oldname = XSTR (XEXP (rtlname, 0), 0);
+   else
+     abort ();
+ 
+   if (sh_symbian_dllexport_name_p (oldname))
+     {
+       error ("`%s' declared as both exported to and imported from a DLL",
+              IDENTIFIER_POINTER (DECL_NAME (decl)));
+     }
+   else if (sh_symbian_dllimport_name_p (oldname))
+     {
+       /* Already done, but do a sanity check to prevent assembler errors.  */
+       if (!DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
+ 	error ("%Hfailure in redeclaration of '%D': dllimport'd symbol lacks external linkage.",
+ 	       &DECL_SOURCE_LOCATION (decl), decl);
+     }
+   else
+     {
+       newname = alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
+       sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
+ 
+       /* We pass newname through get_identifier to ensure it has a unique
+ 	 address.  RTL processing can sometimes peek inside the symbol ref
+ 	 and compare the string's addresses to see if two symbols are
+ 	 identical.  */
+       idp = get_identifier (newname);
+       newrtl = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
+       XEXP (DECL_RTL (decl), 0) = newrtl;
+     }
+ }
+ 
+ void
+ sh_symbian_encode_section_info (tree decl, rtx rtl, int first)
+ {
+   default_encode_section_info (decl, rtl, first);
+ 
+   /* Mark the decl so we can tell from the rtl whether
+      the object is dllexport'd or dllimport'd.  */
+   if (sh_symbian_dllexport_p (decl))
+     sh_symbian_mark_dllexport (decl);
+   else if (sh_symbian_dllimport_p (decl))
+     sh_symbian_mark_dllimport (decl);
+   /* It might be that DECL has already been marked as dllimport, but a
+      subsequent definition nullified that.  The attribute is gone but
+      DECL_RTL still has (DLL_IMPORT_PREFIX) prefixed. We need to remove
+      that. Ditto for the DECL_NON_ADDR_CONST_P flag.  */
+   else if (  (TREE_CODE (decl) == FUNCTION_DECL
+ 	   || TREE_CODE (decl) == VAR_DECL)
+ 	   && DECL_RTL (decl) != NULL_RTX
+ 	   && GET_CODE (DECL_RTL (decl)) == MEM
+ 	   && GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM
+ 	   && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
+ 	   && sh_symbian_dllimport_name_p (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
+     {
+       const char * oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
+       /* Remove DLL_IMPORT_PREFIX.  */
+       tree idp = get_identifier (oldname + strlen (DLL_IMPORT_PREFIX));
+       rtx newrtl = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
+ 
+       warning ("%H%s '%D' %s after being referenced with dllimport linkage.",
+ 	       & DECL_SOURCE_LOCATION (decl),
+ 	       TREE_CODE (decl) == VAR_DECL ? "variable" : "function",
+ 	       decl, (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
+ 	       ? "defined locally" : "redeclared without dllimport attribute");
+ 
+       XEXP (DECL_RTL (decl), 0) = newrtl;
+ 
+       DECL_NON_ADDR_CONST_P (decl) = 0;
+     }
+ }
+ 
+ 
+ /* Return the length of a function name prefix
+     that starts with the character 'c'.  */
+ 
+ static int
+ sh_symbian_get_strip_length (int c)
+ {
+   /* XXX Assumes strlen (DLL_EXPORT_PREFIX) == strlen (DLL_IMPORT_PREFIX).  */
+   return (c == SH_SYMBIAN_FLAG_CHAR[0]) ? strlen (DLL_EXPORT_PREFIX) : 0;
+ }
+ 
+ /* Return a pointer to a function's name with any
+    and all prefix encodings stripped from it.  */
+ 
+ const char *
+ sh_symbian_strip_name_encoding (const char *name)
+ {
+   int skip;
+ 
+   while ((skip = sh_symbian_get_strip_length (*name)))
+     name += skip;
+ 
+   return name;
+ }
+ 
+ /* Add the named attribute to the given node.  Copes with both DECLs and
+    TYPEs.  Will only add the attribute if it is not already present.  */
+ 
+ static void
+ symbian_add_attribute (tree node, const char *attr_name)
+ {
+   tree attrs;
+   tree attr;
+ 
+   attrs = DECL_P (node) ? DECL_ATTRIBUTES (node) : TYPE_ATTRIBUTES (node);
+ 
+   if (lookup_attribute (attr_name, attrs) != NULL_TREE)
+     return;
+ 
+   attr = get_identifier (attr_name);
+ 
+   (DECL_P (node) ? DECL_ATTRIBUTES (node) : TYPE_ATTRIBUTES (node))
+     = tree_cons (attr, NULL_TREE, attrs);
+ 
+ #if SYMBIAN_DEBUG
+   fprintf (stderr, "propogate %s attribute", attr_name);
+   print_node_brief (stderr, " to", node, 0);
+   fprintf (stderr, "\n");
+ #endif
+ }
+ 
+ /* Handle a "dllimport" or "dllexport" attribute;
+    arguments as in struct attribute_spec.handler.  */
+ 
+ tree
+ sh_symbian_handle_dll_attribute (tree *pnode, tree name, tree args,
+ 				 int flags, bool *no_add_attrs)
+ {
+   tree thunk;
+   tree node = *pnode;
+   const char *attr = IDENTIFIER_POINTER (name);
+ 
+   /* These attributes may apply to structure and union types being
+      created, but otherwise should pass to the declaration involved.  */
+   if (!DECL_P (node))
+     {
+       if (flags & ((int) ATTR_FLAG_DECL_NEXT
+ 		   | (int) ATTR_FLAG_FUNCTION_NEXT
+ 		   | (int) ATTR_FLAG_ARRAY_NEXT))
+ 	{
+ 	  warning ("`%s' attribute ignored", attr);
+ 	  *no_add_attrs = true;
+ 	  return tree_cons (name, args, NULL_TREE);
+ 	}
+ 
+       if (TREE_CODE (node) != RECORD_TYPE && TREE_CODE (node) != UNION_TYPE)
+ 	{
+ 	  warning ("`%s' attribute ignored", attr);
+ 	  *no_add_attrs = true;
+ 	}
+ 
+       return NULL_TREE;
+     }
+ 
+   /* Report error on dllimport ambiguities
+      seen now before they cause any damage.  */
+   else if (is_attribute_p ("dllimport", name))
+     {
+       if (TREE_CODE (node) == VAR_DECL)
+ 	{
+ 	  if (DECL_INITIAL (node))
+ 	    {
+ 	      error ("%Hvariable `%D' definition is marked dllimport.",
+ 		     & DECL_SOURCE_LOCATION (node), node);
+ 	      *no_add_attrs = true;
+ 	    }
+ 
+ 	  /* `extern' needn't be specified with dllimport.
+ 	     Specify `extern' now and hope for the best.  Sigh.  */
+ 	  DECL_EXTERNAL (node) = 1;
+ 	  /* Also, implicitly give dllimport'd variables declared within
+ 	     a function global scope, unless declared static.  */
+ 	  if (current_function_decl != NULL_TREE && ! TREE_STATIC (node))
+   	    TREE_PUBLIC (node) = 1;
+ 	}
+     }
+ 
+   /* If the node is an overloaded constructor or desctructor, then we must
+      make sure that the attribute is propogated along the overload chain,
+      as it is these overloaded functions which will be emitted, rather than
+      the user declared constructor itself.  */
+   if (TREE_CODE (TREE_TYPE (node)) == METHOD_TYPE
+       && (DECL_CONSTRUCTOR_P (node) || DECL_DESTRUCTOR_P (node)))
+     {
+       tree overload;
+ 
+       for (overload = OVL_CHAIN (node); overload; overload = OVL_CHAIN (overload))
+ 	{
+ 	  tree node_args;
+ 	  tree func_args;
+ 	  tree function = OVL_CURRENT (overload);
+ 
+ 	  if (! function
+ 	      || ! DECL_P (function)
+ 	      || (DECL_CONSTRUCTOR_P (node) && ! DECL_CONSTRUCTOR_P (function))
+ 	      || (DECL_DESTRUCTOR_P (node)  && ! DECL_DESTRUCTOR_P (function)))
+ 	    continue;
+ 
+ 	  /* The arguments must match as well.  */
+ 	  for (node_args = DECL_ARGUMENTS (node), func_args = DECL_ARGUMENTS (function);
+ 	       node_args && func_args;
+ 	       node_args = TREE_CHAIN (node_args), func_args = TREE_CHAIN (func_args))
+ 	    if (TREE_TYPE (node_args) != TREE_TYPE (func_args))
+ 	      break;
+ 
+ 	  if (node_args || func_args)
+ 	    {
+ 	      /* We can ignore an extraneous __in_chrg arguments in the node.
+ 		 GCC generated destructors, for example, will have this.  */
+ 	      if ((node_args == NULL_TREE
+ 		   || func_args != NULL_TREE)
+ 		  && strcmp (IDENTIFIER_POINTER (DECL_NAME (node)), "__in_chrg") != 0)
+ 		continue;
+ 	    }
+ 
+ 	  symbian_add_attribute (function, attr);
+ 
+ 	  /* Propogate the attribute to any function thunks as well.  */
+ 	  for (thunk = DECL_THUNKS (function); thunk; thunk = TREE_CHAIN (thunk))
+ 	    if (TREE_CODE (thunk) == FUNCTION_DECL)
+ 	      symbian_add_attribute (thunk, attr);
+ 	}
+     }
+ 
+   if (TREE_CODE (node) == FUNCTION_DECL && DECL_VIRTUAL_P (node))
+     {
+       /* Propogate the attribute to any thunks of this function.  */
+       for (thunk = DECL_THUNKS (node); thunk; thunk = TREE_CHAIN (thunk))
+ 	if (TREE_CODE (thunk) == FUNCTION_DECL)
+ 	  symbian_add_attribute (thunk, attr);
+     }
+ 
+   /*  Report error if symbol is not accessible at global scope.  */
+   if (!TREE_PUBLIC (node)
+       && (   TREE_CODE (node) == VAR_DECL
+ 	  || TREE_CODE (node) == FUNCTION_DECL))
+     {
+       error ("%Hexternal linkage required for symbol '%D' because of '%s' attribute.",
+ 	       & DECL_SOURCE_LOCATION (node), node, IDENTIFIER_POINTER (name));
+       *no_add_attrs = true;
+     }
+ 
+ #if SYMBIAN_DEBUG
+   print_node_brief (stderr, "mark node", node, 0);
+   fprintf (stderr, " as %s\n", attr);
+ #endif
+ 
+   return NULL_TREE;
+ }
+ 
+ /* This code implements a specification for exporting the vtable and rtti of
+    classes that have members with the dllexport or dllexport attributes.
+    This specification is defined here:
+ 
+      http://www.armdevzone.com/EABI/exported_class.txt
+ 
+    Basically it says that a class's vtable and rtti should be exported if
+    the following rules apply:
+ 
+    - If it has any non-inline non-pure virtual functions,
+      at least one of these need to be declared dllimport
+      OR any of the constructors is declared dllimport.
+ 
+    AND
+ 
+    - The class has an inline constructor/destructor and
+      a key-function (placement of vtable uniquely defined) that
+      is defined in this translation unit.
+ 
+    The specification also says that for classes which will have their
+    vtables and rtti exported that their base class(es) might also need a
+    similar exporting if:
+ 
+    - Every base class needs to have its vtable & rtti exported
+      as well, if the following the conditions hold true:
+      + The base class has a non-inline declared non-pure virtual function
+      + The base class is polymorphic (has or inherits any virtual functions)
+        or the base class has any virtual base classes.  */
+ 
+ /* Decide if a base class of a class should
+    also have its vtable and rtti exported.  */
+ 
+ static void
+ symbian_possibly_export_base_class (tree base_class)
+ {
+   tree methods;
+   int len;
+ 
+   if (! (TYPE_POLYMORPHIC_P (base_class)
+ 	 || TYPE_USES_VIRTUAL_BASECLASSES (base_class)))
+     return;
+ 
+   methods = CLASSTYPE_METHOD_VEC (base_class);
+   len = methods ? TREE_VEC_LENGTH (methods) : 0;
+ 
+   for (;len --;)
+     {
+       tree member = TREE_VEC_ELT (methods, len);
+ 
+       if (! member)
+ 	continue;
+ 
+       for (member = OVL_CURRENT (member); member; member = OVL_NEXT (member))
+ 	{
+ 	  if (TREE_CODE (member) != FUNCTION_DECL)
+ 	    continue;
+ 
+ 	  if (DECL_CONSTRUCTOR_P (member) || DECL_DESTRUCTOR_P (member))
+ 	    continue;
+ 
+ 	  if (! DECL_VIRTUAL_P (member))
+ 	    continue;
+ 
+ 	  if (DECL_PURE_VIRTUAL_P (member))
+ 	    continue;
+ 
+ 	  if (DECL_INLINE (member))
+ 	    continue;
+ 
+ 	  break;
+ 	}
+ 
+       if (member)
+ 	break;
+     }
+ 
+   if (len < 0)
+     return;
+ 
+   /* FIXME: According to the spec this base class should be exported, but
+      a) how do we do this ? and
+      b) it does not appear to be necessary for compliance with the Symbian
+         OS which so far is the only consumer of this code.  */
+ #if SYMBIAN_DEBUG
+   print_node_brief (stderr, "", base_class, 0);
+   fprintf (stderr, " EXPORTed [base class of exported class]\n");
+ #endif
+ }
+ 
+ /* Decide if a class needs its vtable and rtti exporting.  */
+ 
+ static bool
+ symbian_export_vtable_and_rtti_p (tree ctype)
+ {
+   bool inline_ctor_dtor;
+   bool dllimport_ctor_dtor;
+   bool dllimport_member;
+   tree binfos;
+   tree methods;
+   tree key;
+   int len;
+ 
+   /* Make sure that we are examining a class...  */
+   if (TREE_CODE (ctype) != RECORD_TYPE)
+     {
+ #if SYMBIAN_DEBUG
+       print_node_brief (stderr, "", ctype, 0);
+       fprintf (stderr, " does NOT need to be EXPORTed [not a class]\n");
+ #endif
+       return false;
+     }
+ 
+   /* If the class does not have a key function it
+      does not need to have its vtable exported.  */
+   if ((key = CLASSTYPE_KEY_METHOD (ctype)) == NULL_TREE)
+     {
+ #if SYMBIAN_DEBUG
+       print_node_brief (stderr, "", ctype, 0);
+       fprintf (stderr, " does NOT need to be EXPORTed [no key function]\n");
+ #endif
+       return false;
+     }
+ 
+   /* If the key fn has not been defined
+      then the class should not be exported.  */
+   if (! TREE_ASM_WRITTEN (key))
+     {
+ #if SYMBIAN_DEBUG
+       print_node_brief (stderr, "", ctype, 0);
+       fprintf (stderr, " does NOT need to be EXPORTed [key function not defined]\n");
+ #endif
+       return false;
+     }
+ 
+   /* Check the class's member functions.  */
+   inline_ctor_dtor = false;
+   dllimport_ctor_dtor = false;
+   dllimport_member = false;
+ 
+   methods = CLASSTYPE_METHOD_VEC (ctype);
+   len = methods ? TREE_VEC_LENGTH (methods) : 0;
+ 
+   for (;len --;)
+     {
+       tree member = TREE_VEC_ELT (methods, len);
+ 
+       if (! member)
+ 	continue;
+ 
+       for (member = OVL_CURRENT (member); member; member = OVL_NEXT (member))
+ 	{
+ 	  if (TREE_CODE (member) != FUNCTION_DECL)
+ 	    continue;
+ 
+ 	  if (DECL_CONSTRUCTOR_P (member) || DECL_DESTRUCTOR_P (member))
+ 	    {
+ 	      if (DECL_INLINE (member)
+ 		  /* Ignore C++ backend created inline ctors/dtors.  */
+ 		  && (   DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (member)
+ 		      || DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (member)))
+ 		inline_ctor_dtor = true;
+ 
+ 	      if (lookup_attribute ("dllimport", DECL_ATTRIBUTES (member)))
+ 		dllimport_ctor_dtor = true;
+ 	    }
+ 	  else
+ 	    {
+ 	      if (DECL_PURE_VIRTUAL_P (member))
+ 		continue;
+ 
+ 	      if (! DECL_VIRTUAL_P (member))
+ 		continue;
+ 
+ 	      if (DECL_INLINE (member))
+ 		continue;
+ 
+ 	      if (lookup_attribute ("dllimport", DECL_ATTRIBUTES (member)))
+ 		dllimport_member = true;
+ 	    }
+ 	}
+     }
+ 
+   if (! dllimport_member && ! dllimport_ctor_dtor)
+     {
+ #if SYMBIAN_DEBUG
+       print_node_brief (stderr, "", ctype, 0);
+       fprintf (stderr,
+ 	       " does NOT need to be EXPORTed [no non-pure virtuals or ctors/dtors with dllimport]\n");
+ #endif
+       return false;
+     }
+ 
+   if (! inline_ctor_dtor)
+     {
+ #if SYMBIAN_DEBUG
+       print_node_brief (stderr, "", ctype, 0);
+       fprintf (stderr,
+ 	       " does NOT need to be EXPORTed [no inline ctor/dtor]\n");
+ #endif
+       return false;
+     }
+ 
+ #if SYMBIAN_DEBUG
+   print_node_brief (stderr, "", ctype, 0);
+   fprintf (stderr, " DOES need to be EXPORTed\n");
+ #endif
+ 
+   /* Now we must check and possibly export the base classes.  */
+   binfos = BINFO_BASE_BINFOS (TYPE_BINFO (ctype));
+   len = BINFO_N_BASE_BINFOS (TYPE_BINFO (ctype));
+ 
+   for (; len --;)
+     {
+       tree base_binfo;
+       tree basetype;
+ 
+       /* Figure out which base we're looking at.  */
+       base_binfo = TREE_VEC_ELT (binfos, len);
+       basetype = TREE_TYPE (base_binfo);
+ 
+       symbian_possibly_export_base_class (basetype);
+     }
+ 
+   return true;
+ }
+ 
+ /* Add the named attribute to a class and its vtable and rtti.  */
+ 
+ static void
+ symbian_add_attribute_to_class_vtable_and_rtti (tree ctype, const char *attr_name)
+ {
+   symbian_add_attribute (ctype, attr_name);
+ 
+   /* If the vtable exists then they need annotating as well.  */
+   if (CLASSTYPE_VTABLES (ctype))
+     /* XXX - Do we need to annotate any vtables other than the primary ?  */
+     symbian_add_attribute (CLASSTYPE_VTABLES (ctype), attr_name);
+ 
+   /* If the rtti exists then it needs annotating as well.  */
+   if (TYPE_MAIN_VARIANT (ctype)
+       && CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (ctype)))
+     symbian_add_attribute (CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (ctype)),
+ 			   attr_name);
+ }
+ 
+ /* Decide if a class needs to have an attribute because
+    one of its member functions has the attribute.  */
+ 
+ static bool
+ symbian_class_needs_attribute_p (tree ctype, const char *attribute_name)
+ {
+   /* If the key function has the attribute then the class needs it too.  */
+   if (TYPE_POLYMORPHIC_P (ctype)
+       && CLASSTYPE_KEY_METHOD (ctype)
+       && lookup_attribute (attribute_name,
+ 			   DECL_ATTRIBUTES (CLASSTYPE_KEY_METHOD (ctype))))
+     return true;
+ 
+   /* Check the class's member functions.  */
+   if (TREE_CODE (ctype) == RECORD_TYPE)
+     {
+       tree methods = CLASSTYPE_METHOD_VEC (ctype);
+       unsigned int len = methods ? TREE_VEC_LENGTH (methods) : 0;
+ 
+       for (;len --;)
+ 	{
+ 	  tree member = TREE_VEC_ELT (methods, len);
+ 
+ 	  if (! member)
+ 	    continue;
+ 
+ 	  for (member = OVL_CURRENT (member);
+ 	       member;
+ 	       member = OVL_NEXT (member))
+ 	    {
+ 	      if (TREE_CODE (member) != FUNCTION_DECL)
+ 		continue;
+ 
+ 	      if (DECL_PURE_VIRTUAL_P (member))
+ 		continue;
+ 
+ 	      if (! DECL_VIRTUAL_P (member))
+ 		continue;
+ 
+ 	      if (lookup_attribute (attribute_name, DECL_ATTRIBUTES (member)))
+ 		{
+ #if SYMBIAN_DEBUG
+ 		  print_node_brief (stderr, "", ctype, 0);
+ 		  fprintf (stderr, " inherits %s because", attribute_name);
+ 		  print_node_brief (stderr, "", member, 0);
+ 		  fprintf (stderr, " has it.\n");
+ #endif
+ 		  return true;
+ 		}
+ 	    }
+ 	}
+     }
+ 
+ #if SYMBIAN_DEBUG
+   print_node_brief (stderr, "", ctype, 0);
+   fprintf (stderr, " does not inherit %s\n", attribute_name);
+ #endif
+   return false;
+ }
+ 
+ int
+ symbian_import_export_class (tree ctype, int import_export)
+ {
+   const char *attr_name = NULL;
+ 
+   /* If we are exporting the class but it does not have the dllexport
+      attribute then we may need to add it.  Similarly imported classes
+      may need the dllimport attribute.  */
+   switch (import_export)
+     {
+     case  1: attr_name = "dllexport"; break;
+     case -1: attr_name = "dllimport"; break;
+     default: break;
+     }
+ 
+   if (attr_name
+       && ! lookup_attribute (attr_name, TYPE_ATTRIBUTES (ctype)))
+     {
+       if (symbian_class_needs_attribute_p (ctype, attr_name))
+ 	symbian_add_attribute_to_class_vtable_and_rtti (ctype, attr_name);
+ 
+       /* Classes can be forced to export their
+ 	 vtable and rtti under certain conditions.  */
+       if (symbian_export_vtable_and_rtti_p (ctype))
+ 	{
+ 	  symbian_add_attribute_to_class_vtable_and_rtti (ctype, "dllexport");
+ 
+ 	  /* Make sure that the class and its vtable are exported.  */
+ 	  import_export = 1;
+ 
+ 	  if (CLASSTYPE_VTABLES (ctype))
+ 	    DECL_EXTERNAL (CLASSTYPE_VTABLES (ctype)) = 1;
+ 
+ 	  /* Check to make sure that if the class has a key method that
+ 	     it is now on the list of keyed classes.  That way its vtable
+ 	     will be emitted.  */
+ 	  if (CLASSTYPE_KEY_METHOD (ctype))
+ 	    {
+ 	      tree class;
+ 
+ 	      for (class = keyed_classes; class; class = TREE_CHAIN (class))
+ 		if (class == ctype)
+ 		  break;
+ 
+ 	      if (class == NULL_TREE)
+ 		{
+ #if SYMBIAN_DEBUG
+ 		  print_node_brief (stderr, "Add node", ctype, 0);
+ 		  fprintf (stderr, " to the keyed classes list\n");
+ #endif
+ 		  keyed_classes = tree_cons (NULL_TREE, ctype, keyed_classes);
+ 		}
+ 	    }
+ 
+ 	  /* Make sure that the typeinfo will be emitted as well.  */
+ 	  if (CLASS_TYPE_P (ctype))
+ 	    TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (CLASSTYPE_TYPEINFO_VAR (TYPE_MAIN_VARIANT (ctype)))) = 1;
+ 	}
+     }
+ 
+   return import_export;
+ }
+ 
+ /* Dummy defintion of this array for cc1 building purposes.  */
+ tree cp_global_trees[CPTI_MAX] __attribute__((weak));
+ 
+ #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
+ 
+ /* Dummy version of this G++ function for building cc1.  */
+ void lang_check_failed (const char *, int, const char *) __attribute__((weak));
+ 
+ void
+ lang_check_failed (const char *file, int line, const char *function)
+ {
+   internal_error ("lang_* check: failed in %s, at %s:%d",
+ 		  function, trim_filename (file), line);
+ }
+ #endif /* ENABLE_TREE_CHECKING */
*** /dev/null	2004-02-18 15:26:44.000000000 +0000
--- gcc/config/sh/t-symbian	2004-07-02 12:40:10.000000000 +0100
***************
*** 0 ****
--- 1,35 ----
+ LIB1ASMSRC = sh/lib1funcs.asm
+ LIB1ASMFUNCS = _ashiftrt _ashiftrt_n _ashiftlt _lshiftrt _movstr \
+   _movstr_i4 _mulsi3 _sdivsi3 _sdivsi3_i4 _udivsi3 _udivsi3_i4 _set_fpscr \
+   $(LIB1ASMFUNCS_CACHE)
+ 
+ # We want fine grained libraries, so use the new code to build the
+ # floating point emulation libraries.
+ FPBIT = fp-bit.c
+ DPBIT = dp-bit.c
+ 
+ dp-bit.c: $(srcdir)/config/fp-bit.c
+ 	cat $(srcdir)/config/fp-bit.c >> dp-bit.c
+ 
+ fp-bit.c: $(srcdir)/config/fp-bit.c
+ 	echo '#define FLOAT' > fp-bit.c
+ 	cat $(srcdir)/config/fp-bit.c >> fp-bit.c
+ 
+ $(T)crt1.o: $(srcdir)/config/sh/crt1.asm $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)crt1.o -x assembler-with-cpp $(srcdir)/config/sh/crt1.asm
+ $(T)crti.o: $(srcdir)/config/sh/crti.asm $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/sh/crti.asm
+ $(T)crtn.o: $(srcdir)/config/sh/crtn.asm $(GCC_PASSES)
+ 	$(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/sh/crtn.asm
+ 
+ $(out_object_file): gt-sh.h
+ gt-sh.h : s-gtype ; @true
+ 
+ symbian.o: $(srcdir)/config/sh/symbian.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+   $(RTL_H) output.h flags.h $(TREE_H) expr.h toplev.h $(TM_P_H)
+ 	$(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/config/sh/symbian.c
+ 
+ 
+ # Local Variables:
+ # mode: Makefile
+ # End:

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]