comparison gcc/config/sh/symbian-base.c @ 55:77e2b8dfacca gcc-4.4.5

update it from 4.4.3 to 4.5.0
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Fri, 12 Feb 2010 23:39:51 +0900
parents
children f6334be47118
comparison
equal deleted inserted replaced
52:c156f1bd5cd9 55:77e2b8dfacca
1 /* Routines for GCC for a Symbian OS targeted SH backend, shared by
2 both the C and C++ compilers.
3 Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
4 Contributed by RedHat.
5 Most of this code is stolen from i386/winnt.c.
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "output.h"
29 #include "flags.h"
30 #include "tree.h"
31 #include "expr.h"
32 #include "tm_p.h"
33 #include "toplev.h"
34 #include "sh-symbian.h"
35
36 /* Return nonzero if SYMBOL is marked as being dllexport'd. */
37
38 bool
39 sh_symbian_is_dllexported_name (const char *symbol)
40 {
41 return strncmp (DLL_EXPORT_PREFIX, symbol,
42 strlen (DLL_EXPORT_PREFIX)) == 0;
43 }
44
45 /* Return nonzero if SYMBOL is marked as being dllimport'd. */
46
47 static bool
48 sh_symbian_is_dllimported_name (const char *symbol)
49 {
50 return strncmp (DLL_IMPORT_PREFIX, symbol,
51 strlen (DLL_IMPORT_PREFIX)) == 0;
52 }
53
54 /* Return nonzero if DECL is a dllexport'd object. */
55
56 bool
57 sh_symbian_is_dllexported (tree decl)
58 {
59 tree exp;
60
61 if ( TREE_CODE (decl) != VAR_DECL
62 && TREE_CODE (decl) != FUNCTION_DECL)
63 return false;
64
65 exp = lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl));
66
67 /* Class members get the dllexport status of their class. */
68 if (exp == NULL)
69 {
70 tree class = sh_symbian_associated_type (decl);
71
72 if (class)
73 exp = lookup_attribute ("dllexport", TYPE_ATTRIBUTES (class));
74 }
75 #if SYMBIAN_DEBUG
76 if (exp)
77 {
78 print_node_brief (stderr, "dllexport:", decl, 0);
79 fprintf (stderr, "\n");
80 }
81 else
82 #if SYMBIAN_DEBUG < 2
83 if (TREE_CODE (decl) != FUNCTION_DECL)
84 #endif
85 {
86 print_node_brief (stderr, "no dllexport:", decl, 0);
87 fprintf (stderr, "\n");
88 }
89 #endif
90 return exp ? true : false;
91 }
92
93 /* Mark a DECL as being dllimport'd. */
94
95 static void
96 sh_symbian_mark_dllimport (tree decl)
97 {
98 const char *oldname;
99 char *newname;
100 tree idp;
101 rtx rtlname;
102 rtx newrtl;
103
104 rtlname = XEXP (DECL_RTL (decl), 0);
105 if (MEM_P (rtlname))
106 rtlname = XEXP (rtlname, 0);
107 gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
108 oldname = XSTR (rtlname, 0);
109
110 if (sh_symbian_is_dllexported_name (oldname))
111 {
112 error ("%qE declared as both exported to and imported from a DLL",
113 DECL_NAME (decl));
114 }
115 else if (sh_symbian_is_dllimported_name (oldname))
116 {
117 /* Already done, but do a sanity check to prevent assembler errors. */
118 if (!DECL_EXTERNAL (decl) || !TREE_PUBLIC (decl))
119 error ("failure in redeclaration of %q+D: dllimport'd symbol lacks external linkage",
120 decl);
121 }
122 else
123 {
124 newname = (char *) alloca (strlen (DLL_IMPORT_PREFIX) + strlen (oldname) + 1);
125 sprintf (newname, "%s%s", DLL_IMPORT_PREFIX, oldname);
126
127 /* We pass newname through get_identifier to ensure it has a unique
128 address. RTL processing can sometimes peek inside the symbol ref
129 and compare the string's addresses to see if two symbols are
130 identical. */
131 idp = get_identifier (newname);
132 newrtl = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
133 XEXP (DECL_RTL (decl), 0) = newrtl;
134 }
135 }
136
137 /* Mark a DECL as being dllexport'd.
138 Note that we override the previous setting (e.g.: dllimport). */
139
140 static void
141 sh_symbian_mark_dllexport (tree decl)
142 {
143 const char *oldname;
144 char *newname;
145 rtx rtlname;
146 tree idp;
147
148 rtlname = XEXP (DECL_RTL (decl), 0);
149 if (MEM_P (rtlname))
150 rtlname = XEXP (rtlname, 0);
151 gcc_assert (GET_CODE (rtlname) == SYMBOL_REF);
152 oldname = XSTR (rtlname, 0);
153
154 if (sh_symbian_is_dllimported_name (oldname))
155 {
156 /* Remove DLL_IMPORT_PREFIX.
157 Note - we do not issue a warning here. In Symbian's environment it
158 is legitimate for a prototype to be marked as dllimport and the
159 corresponding definition to be marked as dllexport. The prototypes
160 are in headers used everywhere and the definition is in a translation
161 unit which has included the header in order to ensure argument
162 correctness. */
163 oldname += strlen (DLL_IMPORT_PREFIX);
164 DECL_DLLIMPORT_P (decl) = 0;
165 }
166 else if (sh_symbian_is_dllexported_name (oldname))
167 return; /* Already done. */
168
169 newname = (char *) alloca (strlen (DLL_EXPORT_PREFIX) + strlen (oldname) + 1);
170 sprintf (newname, "%s%s", DLL_EXPORT_PREFIX, oldname);
171
172 /* We pass newname through get_identifier to ensure it has a unique
173 address. RTL processing can sometimes peek inside the symbol ref
174 and compare the string's addresses to see if two symbols are
175 identical. */
176 idp = get_identifier (newname);
177
178 XEXP (DECL_RTL (decl), 0) =
179 gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
180 }
181
182 void
183 sh_symbian_encode_section_info (tree decl, rtx rtl, int first)
184 {
185 default_encode_section_info (decl, rtl, first);
186
187 /* Mark the decl so we can tell from the rtl whether
188 the object is dllexport'd or dllimport'd. */
189 if (sh_symbian_is_dllexported (decl))
190 sh_symbian_mark_dllexport (decl);
191 else if (sh_symbian_is_dllimported (decl))
192 sh_symbian_mark_dllimport (decl);
193 /* It might be that DECL has already been marked as dllimport, but a
194 subsequent definition nullified that. The attribute is gone but
195 DECL_RTL still has (DLL_IMPORT_PREFIX) prefixed. We need to remove
196 that. Ditto for the DECL_DLLIMPORT_P flag. */
197 else if ( (TREE_CODE (decl) == FUNCTION_DECL
198 || TREE_CODE (decl) == VAR_DECL)
199 && DECL_RTL (decl) != NULL_RTX
200 && MEM_P (DECL_RTL (decl))
201 && MEM_P (XEXP (DECL_RTL (decl), 0))
202 && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 0)) == SYMBOL_REF
203 && sh_symbian_is_dllimported_name (XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0)))
204 {
205 const char * oldname = XSTR (XEXP (XEXP (DECL_RTL (decl), 0), 0), 0);
206 /* Remove DLL_IMPORT_PREFIX. */
207 tree idp = get_identifier (oldname + strlen (DLL_IMPORT_PREFIX));
208 rtx newrtl = gen_rtx_SYMBOL_REF (Pmode, IDENTIFIER_POINTER (idp));
209
210 warning (0, "%s %q+D %s after being referenced with dllimport linkage",
211 TREE_CODE (decl) == VAR_DECL ? "variable" : "function",
212 decl, (DECL_INITIAL (decl) || !DECL_EXTERNAL (decl))
213 ? "defined locally" : "redeclared without dllimport attribute");
214
215 XEXP (DECL_RTL (decl), 0) = newrtl;
216
217 DECL_DLLIMPORT_P (decl) = 0;
218 }
219 }
220
221 /* Return the length of a function name prefix
222 that starts with the character 'c'. */
223
224 static int
225 sh_symbian_get_strip_length (int c)
226 {
227 /* XXX Assumes strlen (DLL_EXPORT_PREFIX) == strlen (DLL_IMPORT_PREFIX). */
228 return (c == SH_SYMBIAN_FLAG_CHAR[0]) ? strlen (DLL_EXPORT_PREFIX) : 0;
229 }
230
231 /* Return a pointer to a function's name with any
232 and all prefix encodings stripped from it. */
233
234 const char *
235 sh_symbian_strip_name_encoding (const char *name)
236 {
237 int skip;
238
239 while ((skip = sh_symbian_get_strip_length (*name)))
240 name += skip;
241
242 return name;
243 }
244