diff options
author | Nick Clifton <nickc@redhat.com> | 2009-09-30 07:27:28 +0000 |
---|---|---|
committer | Nick Clifton <nickc@gcc.gnu.org> | 2009-09-30 07:27:28 +0000 |
commit | 3c8348d376afad91fb9f89f14960af14e8cd5e77 (patch) | |
tree | a07773b7f99167050e2f054029c205c70e6e0dec /gcc | |
parent | 08a4a761ebe388e1b231eabd6f8e7e155d10b222 (diff) | |
download | gcc-3c8348d376afad91fb9f89f14960af14e8cd5e77.zip gcc-3c8348d376afad91fb9f89f14960af14e8cd5e77.tar.gz gcc-3c8348d376afad91fb9f89f14960af14e8cd5e77.tar.bz2 |
config.gcc (sh-symbianelf): Replace definition of extra_objs with separate definitions of c_target_objs and...
* config.gcc (sh-symbianelf): Replace definition of extra_objs
with separate definitions of c_target_objs and cxx_target_objs.
* config/sh/t-sh: Add rules to build symbian-cxx.o, symbian-c.o
and symbian-base.o.
* config/sh/sh.c (TARGET_CXX_INPUT_EXPORT_CLASS): Use
sh_symbian_import_export_class.
* config/sh/sh-protos.h: Fix names of exported symbian functions.
* config/sh/symbian.c: Delete, moving code into...
* config/sh/symbian-base.c: ... here
* config/sh/symbian-c.c: ... and here
* config/sh/symbian-cxx.c: ... and here.
From-SVN: r152323
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/config.gcc | 3 | ||||
-rw-r--r-- | gcc/config/sh/sh-protos.h | 8 | ||||
-rw-r--r-- | gcc/config/sh/sh-symbian.h | 42 | ||||
-rw-r--r-- | gcc/config/sh/sh.c | 2 | ||||
-rw-r--r-- | gcc/config/sh/symbian-base.c | 244 | ||||
-rw-r--r-- | gcc/config/sh/symbian-c.c | 181 | ||||
-rw-r--r-- | gcc/config/sh/symbian-cxx.c (renamed from gcc/config/sh/symbian.c) | 744 | ||||
-rw-r--r-- | gcc/config/sh/symbian-post.h | 4 | ||||
-rw-r--r-- | gcc/config/sh/t-symbian | 22 |
10 files changed, 768 insertions, 496 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a14b81c..0c6ebdc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2009-09-30 Nick Clifton <nickc@redhat.com> + + * config.gcc (sh-symbianelf): Replace definition of extra_objs + with separate definitions of c_target_objs and cxx_target_objs. + * config/sh/t-sh: Add rules to build symbian-cxx.o, symbian-c.o + and symbian-base.o. + * config/sh/sh.c (TARGET_CXX_INPUT_EXPORT_CLASS): Use + sh_symbian_import_export_class. + * config/sh/sh-protos.h: Fix names of exported symbian functions. + * config/sh/symbian.c: Delete, moving code into... + * config/sh/symbian-base.c: ... here + * config/sh/symbian-c.c: ... and here + * config/sh/symbian-cxx.c: ... and here. + 2009-09-30 Uros Bizjak <ubizjak@gmail.com> PR target/22093 diff --git a/gcc/config.gcc b/gcc/config.gcc index 6351aa5..1b0194b 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -2184,7 +2184,8 @@ sh-*-symbianelf* | sh[12346l]*-*-symbianelf* | \ *-*-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" + c_target_objs="symbian-base.o symbian-c.o" + cxx_target_objs="symbian-base.o symbian-cxx.o" extra_parts="crt1.o crti.o crtn.o crtbegin.o crtend.o crtbeginS.o crtendS.o" ;; *-*-elf*) diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h index f61c5d5..8157221 100644 --- a/gcc/config/sh/sh-protos.h +++ b/gcc/config/sh/sh-protos.h @@ -183,15 +183,15 @@ extern bool sh_hard_regno_mode_ok (unsigned int, enum machine_mode); #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); +extern bool sh_symbian_is_dllexported_name (const char *); #ifdef TREE_CODE -extern bool sh_symbian_dllexport_p (tree); +extern bool sh_symbian_is_dllexported (tree); +extern int sh_symbian_import_export_class (tree, int); 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 */ + diff --git a/gcc/config/sh/sh-symbian.h b/gcc/config/sh/sh-symbian.h new file mode 100644 index 0000000..2e37d2b --- /dev/null +++ b/gcc/config/sh/sh-symbian.h @@ -0,0 +1,42 @@ +/* header file for GCC for a Symbian OS targeted SH backend. + Copyright (C) 2004, 2005, 2007, 2009 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 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/>. */ + +/* 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." + +/* 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 */ + +/* Functions exported from symbian-base.c. */ +extern tree sh_symbian_associated_type (tree); + +/* Functions exported from symbian-[c|c++].c. */ +extern bool sh_symbian_is_dllimported (tree); + diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index df03c14..679cf11 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -503,7 +503,7 @@ static const struct attribute_spec sh_attribute_table[] = #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 +#define TARGET_CXX_IMPORT_EXPORT_CLASS sh_symbian_import_export_class #endif /* SYMBIAN */ diff --git a/gcc/config/sh/symbian-base.c b/gcc/config/sh/symbian-base.c new file mode 100644 index 0000000..624c6fc --- /dev/null +++ b/gcc/config/sh/symbian-base.c @@ -0,0 +1,244 @@ +/* Routines for GCC for a Symbian OS targeted SH backend, shared by + both the C and C++ compilers. + Copyright (C) 2004, 2005, 2007, 2009 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 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 "tm.h" +#include "rtl.h" +#include "output.h" +#include "flags.h" +#include "tree.h" +#include "expr.h" +#include "tm_p.h" +#include "toplev.h" +#include "sh-symbian.h" + +/* Return nonzero if SYMBOL is marked as being dllexport'd. */ + +bool +sh_symbian_is_dllexported_name (const char *symbol) +{ + return strncmp (DLL_EXPORT_PREFIX, symbol, + strlen (DLL_EXPORT_PREFIX)) == 0; +} + +/* Return nonzero if SYMBOL is marked as being dllimport'd. */ + +static bool +sh_symbian_is_dllimported_name (const char *symbol) +{ + return strncmp (DLL_IMPORT_PREFIX, symbol, + strlen (DLL_IMPORT_PREFIX)) == 0; +} + +/* Return nonzero if DECL is a dllexport'd object. */ + +bool +sh_symbian_is_dllexported (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; +} + +/* 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 (MEM_P (rtlname)) + rtlname = XEXP (rtlname, 0); + gcc_assert (GET_CODE (rtlname) == SYMBOL_REF); + oldname = XSTR (rtlname, 0); + + if (sh_symbian_is_dllexported_name (oldname)) + { + error ("%qE declared as both exported to and imported from a DLL", + DECL_NAME (decl)); + } + else if (sh_symbian_is_dllimported_name (oldname)) + { + /* Already done, but do a sanity check to prevent assembler errors. */ + if (!DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl)) + error ("failure in redeclaration of %q+D: dllimport'd symbol lacks external linkage", + decl); + } + else + { + newname = (char *) 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; + } +} + +/* Mark a DECL as being dllexport'd. + Note that we override the previous setting (e.g.: 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 (MEM_P (rtlname)) + rtlname = XEXP (rtlname, 0); + gcc_assert (GET_CODE (rtlname) == SYMBOL_REF); + oldname = XSTR (rtlname, 0); + + if (sh_symbian_is_dllimported_name (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 definition to be marked as dllexport. The prototypes + are in headers used everywhere and the definition is in a translation + unit which has included the header in order to ensure argument + correctness. */ + oldname += strlen (DLL_IMPORT_PREFIX); + DECL_DLLIMPORT_P (decl) = 0; + } + else if (sh_symbian_is_dllexported_name (oldname)) + return; /* Already done. */ + + newname = (char *) 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)); +} + +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_is_dllexported (decl)) + sh_symbian_mark_dllexport (decl); + else if (sh_symbian_is_dllimported (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_DLLIMPORT_P flag. */ + else if ( (TREE_CODE (decl) == FUNCTION_DECL + || TREE_CODE (decl) == VAR_DECL) + && DECL_RTL (decl) != NULL_RTX + && MEM_P (DECL_RTL (decl)) + && MEM_P (XEXP (DECL_RTL (decl), 0)) + && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF + && sh_symbian_is_dllimported_name (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 (0, "%s %q+D %s after being referenced with dllimport linkage", + 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_DLLIMPORT_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; +} + diff --git a/gcc/config/sh/symbian-c.c b/gcc/config/sh/symbian-c.c new file mode 100644 index 0000000..4fda0ae --- /dev/null +++ b/gcc/config/sh/symbian-c.c @@ -0,0 +1,181 @@ +/* Routines for C compiler part of GCC for a Symbian OS targeted SH backend. + Copyright (C) 2004, 2005, 2007, 2009 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 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 "tm.h" +#include "rtl.h" +#include "output.h" +#include "flags.h" +#include "tree.h" +#include "expr.h" +#include "tm_p.h" +#include "toplev.h" +#include "sh-symbian.h" + + +/* Return the type that we should use to determine if DECL is + imported or exported. */ + +tree +sh_symbian_associated_type (tree decl) +{ + tree t = NULL_TREE; + + /* 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 dllimport'd object. */ + +bool +sh_symbian_is_dllimported (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_DECLARED_INLINE_P (decl)) + { + warning (OPT_Wattributes, "function %q+D is defined after prior " + "declaration as dllimport: attribute ignored", + 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)) + { + error ("definition of static data member %q+D of dllimport'd class", + decl); + return false; + } + + return true; +} + +/* 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 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 (OPT_Wattributes, "%qs 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 (OPT_Wattributes, "%qs 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 ("variable %q+D definition is marked dllimport", + 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; + } + } + + /* 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 ("external linkage required for symbol %q+D because of %qE attribute", + node, 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; +} + +int +sh_symbian_import_export_class (tree ctype ATTRIBUTE_UNUSED, int import_export) +{ + return import_export; +} diff --git a/gcc/config/sh/symbian.c b/gcc/config/sh/symbian-cxx.c index b4dbc3f..0a45765 100644 --- a/gcc/config/sh/symbian.c +++ b/gcc/config/sh/symbian-cxx.c @@ -1,4 +1,4 @@ -/* Routines for GCC for a Symbian OS targeted SH backend. +/* Routines for C++ support for GCC for a Symbian OS targeted SH backend. Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. Contributed by RedHat. Most of this code is stolen from i386/winnt.c. @@ -31,27 +31,13 @@ #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 */ - -/* 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." +#include "sh-symbian.h" /* Return the type that we should use to determine if DECL is imported or exported. */ -static tree +tree sh_symbian_associated_type (tree decl) { tree t = NULL_TREE; @@ -70,49 +56,11 @@ sh_symbian_associated_type (tree 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) +bool +sh_symbian_is_dllimported (tree decl) { tree imp; @@ -186,335 +134,7 @@ sh_symbian_dllimport_p (tree decl) 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 (e.g.: 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 (MEM_P (rtlname)) - rtlname = XEXP (rtlname, 0); - gcc_assert (GET_CODE (rtlname) == SYMBOL_REF); - oldname = XSTR (rtlname, 0); - - 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 definition to be marked as dllexport. The prototypes - are in headers used everywhere and the definition is in a translation - unit which has included the header in order to ensure argument - correctness. */ - oldname += strlen (DLL_IMPORT_PREFIX); - DECL_DLLIMPORT_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 (MEM_P (rtlname)) - rtlname = XEXP (rtlname, 0); - gcc_assert (GET_CODE (rtlname) == SYMBOL_REF); - oldname = XSTR (rtlname, 0); - - if (sh_symbian_dllexport_name_p (oldname)) - { - error ("%qE declared as both exported to and imported from a DLL", - 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 ("failure in redeclaration of %q+D: dllimport'd symbol lacks external linkage", - 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_DLLIMPORT_P flag. */ - else if ( (TREE_CODE (decl) == FUNCTION_DECL - || TREE_CODE (decl) == VAR_DECL) - && DECL_RTL (decl) != NULL_RTX - && MEM_P (DECL_RTL (decl)) - && MEM_P (XEXP (DECL_RTL (decl), 0)) - && 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 (0, "%s %q+D %s after being referenced with dllimport linkage", - 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_DLLIMPORT_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); - - if (DECL_P (node)) - DECL_ATTRIBUTES (node) = tree_cons (attr, NULL_TREE, attrs); - else - TYPE_ATTRIBUTES (node) = tree_cons (attr, NULL_TREE, attrs); - -#if SYMBIAN_DEBUG - fprintf (stderr, "propagate %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 (OPT_Wattributes, "%qs 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 (OPT_Wattributes, "%qs 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 ("variable %q+D definition is marked dllimport", - 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 destructor, then we must - make sure that the attribute is propagated 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); - - /* Propagate 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)) - { - /* Propagate 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 ("external linkage required for symbol %q+D because of %qE attribute", - node, 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: @@ -543,12 +163,12 @@ sh_symbian_handle_dll_attribute (tree *pnode, tree name, tree args, + 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) +sh_symbian_possibly_export_base_class (tree base_class) { VEC(tree,gc) *method_vec; int len; @@ -603,6 +223,119 @@ symbian_possibly_export_base_class (tree base_class) #endif } +/* 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 +sh_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); + + if (DECL_P (node)) + DECL_ATTRIBUTES (node) = tree_cons (attr, NULL_TREE, attrs); + else + TYPE_ATTRIBUTES (node) = tree_cons (attr, NULL_TREE, attrs); + +#if SYMBIAN_DEBUG + fprintf (stderr, "propagate %s attribute", attr_name); + print_node_brief (stderr, " to", node, 0); + fprintf (stderr, "\n"); +#endif +} + +/* Add the named attribute to a class and its vtable and rtti. */ + +static void +sh_symbian_add_attribute_to_class_vtable_and_rtti (tree ctype, const char *attr_name) +{ + sh_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 ? */ + sh_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))) + sh_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 +sh_symbian_class_needs_attribute (tree ctype, const char *attribute_name) +{ + VEC(tree,gc) *method_vec; + + method_vec = CLASSTYPE_METHOD_VEC (ctype); + + /* If the key function has the attribute then the class needs it too. */ + if (TYPE_POLYMORPHIC_P (ctype) + && method_vec + && tree_contains_struct [TREE_CODE (ctype), TS_DECL_COMMON] == 1 + && lookup_attribute (attribute_name, + DECL_ATTRIBUTES (VEC_index (tree, method_vec, 0)))) + return true; + + /* Check the class's member functions. */ + if (TREE_CODE (ctype) == RECORD_TYPE) + { + unsigned int len; + + len = method_vec ? VEC_length (tree, method_vec) : 0; + + for (;len --;) + { + tree member = VEC_index (tree, method_vec, 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; +} + /* Decide if a class needs its vtable and rtti exporting. */ static bool @@ -725,97 +458,19 @@ symbian_export_vtable_and_rtti_p (tree ctype) /* Now we must check and possibly export the base classes. */ for (i = 0, binfo = TYPE_BINFO (ctype); BINFO_BASE_ITERATE (binfo, i, base_binfo); i++) - symbian_possibly_export_base_class (BINFO_TYPE (base_binfo)); + sh_symbian_possibly_export_base_class (BINFO_TYPE (base_binfo)); 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) -{ - VEC(tree,gc) *method_vec; - - method_vec = CLASSTYPE_METHOD_VEC (ctype); - - /* If the key function has the attribute then the class needs it too. */ - if (TYPE_POLYMORPHIC_P (ctype) - && method_vec - && lookup_attribute (attribute_name, - DECL_ATTRIBUTES (VEC_index (tree, method_vec, 0)))) - return true; - - /* Check the class's member functions. */ - if (TREE_CODE (ctype) == RECORD_TYPE) - { - unsigned int len; - - len = method_vec ? VEC_length (tree, method_vec) : 0; - - for (;len --;) - { - tree member = VEC_index (tree, method_vec, 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; -} +/* Possibly override the decision to export class TYPE. Upon entry + IMPORT_EXPORT will contain 1 if the class is going to be exported, + -1 if it is going to be imported and 0 otherwise. This function + should return the modified value and perform any other actions + necessary to support the backend's targeted operating system. */ int -symbian_import_export_class (tree ctype, int import_export) +sh_symbian_import_export_class (tree ctype, int import_export) { const char *attr_name = NULL; @@ -832,14 +487,14 @@ symbian_import_export_class (tree ctype, int import_export) 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); + if (sh_symbian_class_needs_attribute (ctype, attr_name)) + sh_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"); + sh_symbian_add_attribute_to_class_vtable_and_rtti (ctype, "dllexport"); /* Make sure that the class and its vtable are exported. */ import_export = 1; @@ -877,18 +532,131 @@ symbian_import_export_class (tree ctype, int import_export) return import_export; } -/* Dummy definition of this array for cc1 building purposes. */ -tree cp_global_trees[CPTI_MAX] __attribute__((weak)); +/* 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 (OPT_Wattributes, "%qs 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 (OPT_Wattributes, "%qs attribute ignored", attr); + *no_add_attrs = true; + } -#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007) + 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 ("variable %q+D definition is marked dllimport", + node); + *no_add_attrs = true; + } -/* Dummy version of this G++ function for building cc1. */ -void lang_check_failed (const char *, int, const char *) __attribute__((weak)); + /* `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; + } + } -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); + /* If the node is an overloaded constructor or destructor, then we must + make sure that the attribute is propagated 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; + } + + sh_symbian_add_attribute (function, attr); + + /* Propagate the attribute to any function thunks as well. */ + for (thunk = DECL_THUNKS (function); thunk; thunk = TREE_CHAIN (thunk)) + if (TREE_CODE (thunk) == FUNCTION_DECL) + sh_symbian_add_attribute (thunk, attr); + } + } + + if (TREE_CODE (node) == FUNCTION_DECL && DECL_VIRTUAL_P (node)) + { + /* Propagate the attribute to any thunks of this function. */ + for (thunk = DECL_THUNKS (node); thunk; thunk = TREE_CHAIN (thunk)) + if (TREE_CODE (thunk) == FUNCTION_DECL) + sh_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 ("external linkage required for symbol %q+D because of %qE attribute", + node, 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; } -#endif /* ENABLE_TREE_CHECKING */ diff --git a/gcc/config/sh/symbian-post.h b/gcc/config/sh/symbian-post.h index d8d56b1..a4497b9 100644 --- a/gcc/config/sh/symbian-post.h +++ b/gcc/config/sh/symbian-post.h @@ -31,8 +31,8 @@ #define SYMBIAN_EXPORT_NAME(NAME,FILE,DECL) \ do \ { \ - if ((DECL && sh_symbian_dllexport_p (DECL)) \ - || sh_symbian_dllexport_name_p (NAME)) \ + if ((DECL && sh_symbian_is_dllexported (DECL)) \ + || sh_symbian_is_dllexported_name (NAME)) \ { \ fprintf ((FILE), "\t.pushsection .directive\n"); \ fprintf ((FILE), "\t.asciz \"EXPORT %s\\n\"\n", \ diff --git a/gcc/config/sh/t-symbian b/gcc/config/sh/t-symbian index 1698b72..f0b7dab 100644 --- a/gcc/config/sh/t-symbian +++ b/gcc/config/sh/t-symbian @@ -21,6 +21,28 @@ sh-c.o: $(srcdir)/config/sh/sh-c.c \ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ $(srcdir)/config/sh/sh-c.c +symbian-cxx.o: \ + $(srcdir)/config/sh/symbian-cxx.c \ + $(srcdir)/config/sh/sh-symbian.h \ + $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) $(RTL_H) \ + toplev.h output.h coretypes.h flags.h expr.h + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< + +symbian-c.o: \ + $(srcdir)/config/sh/symbian-c.c \ + $(srcdir)/config/sh/sh-symbian.h \ + $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) $(RTL_H) \ + toplev.h output.h coretypes.h flags.h expr.h + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< + +symbian-base.o: \ + $(srcdir)/config/sh/symbian-base.c \ + $(srcdir)/config/sh/sh-symbian.h \ + $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) $(RTL_H) \ + toplev.h output.h coretypes.h flags.h expr.h + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< + + LIB1ASMSRC = sh/lib1funcs.asm LIB1ASMFUNCS = _ashiftrt _ashiftrt_n _ashiftlt _lshiftrt _movstr \ _movstr_i4 _mulsi3 _sdivsi3 _sdivsi3_i4 _udivsi3 _udivsi3_i4 _set_fpscr \ |