re PR rtl-optimization/4330 (Optimizer generates illegal assembly code)
[platform/upstream/gcc.git] / gcc / c-objc-common.c
1 /* Some code common to C and ObjC front ends.
2    Copyright (C) 2001 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING.  If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "tree.h"
24 #include "rtl.h"
25 #include "insn-config.h"
26 #include "integrate.h"
27 #include "expr.h"
28 #include "c-tree.h"
29 #include "function.h"
30 #include "flags.h"
31 #include "toplev.h"
32 #include "diagnostic.h"
33 #include "tree-inline.h"
34 #include "varray.h"
35 #include "ggc.h"
36 #include "langhooks.h"
37
38 static int c_tree_printer PARAMS ((output_buffer *));
39 static tree inline_forbidden_p PARAMS ((tree *, int *, void *));
40 static void expand_deferred_fns PARAMS ((void));
41 static tree start_cdtor PARAMS ((int));
42 static void finish_cdtor PARAMS ((tree));
43
44 static varray_type deferred_fns;
45
46 int
47 c_missing_noreturn_ok_p (decl)
48      tree decl;
49 {
50   /* A missing noreturn is not ok for freestanding implementations and
51      ok for the `main' function in hosted implementations.  */
52   return flag_hosted && MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl));
53 }
54
55 /* We want to inline `extern inline' functions even if this would
56    violate inlining limits.  Some glibc and linux constructs depend on
57    such functions always being inlined when optimizing.  */
58
59 int
60 c_disregard_inline_limits (fn)
61      tree fn;
62 {
63   if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
64     return 1;
65
66   return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
67 }
68
69 static tree
70 inline_forbidden_p (nodep, walk_subtrees, fn)
71      tree *nodep;
72      int *walk_subtrees ATTRIBUTE_UNUSED;
73      void *fn;
74 {
75   tree node = *nodep;
76   tree t;
77
78   switch (TREE_CODE (node))
79     {
80     case CALL_EXPR:
81       t = get_callee_fndecl (node);
82
83       if (! t)
84         break;
85
86       /* We cannot inline functions that call setjmp.  */
87       if (setjmp_call_p (t))
88         return node;
89
90       switch (DECL_FUNCTION_CODE (t))
91         {
92           /* We cannot inline functions that take a variable number of
93              arguments.  */
94         case BUILT_IN_VARARGS_START:
95         case BUILT_IN_STDARG_START:
96 #if 0
97           /* Functions that need information about the address of the
98              caller can't (shouldn't?) be inlined.  */
99         case BUILT_IN_RETURN_ADDRESS:
100 #endif
101           return node;
102
103         default:
104           break;
105         }
106
107       break;
108
109     case DECL_STMT:
110       /* We cannot inline functions that contain other functions.  */
111       if (TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
112           && DECL_INITIAL (TREE_OPERAND (node, 0)))
113         return node;
114       break;
115
116     case GOTO_STMT:
117     case GOTO_EXPR:
118       t = TREE_OPERAND (node, 0);
119
120       /* We will not inline a function which uses computed goto.  The
121          addresses of its local labels, which may be tucked into
122          global storage, are of course not constant across
123          instantiations, which causes unexpected behaviour.  */
124       if (TREE_CODE (t) != LABEL_DECL)
125         return node;
126
127       /* We cannot inline a nested function that jumps to a nonlocal
128          label.  */
129       if (TREE_CODE (t) == LABEL_DECL
130           && DECL_CONTEXT (t) && DECL_CONTEXT (t) != fn)
131         return node;
132
133       break;
134
135     default:
136       break;
137     }
138
139   return NULL_TREE;
140 }
141
142 int
143 c_cannot_inline_tree_fn (fnp)
144      tree *fnp;
145 {
146   tree fn = *fnp;
147   tree t;
148
149   if (flag_really_no_inline
150       && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
151     return 1;
152
153   if (! function_attribute_inlinable_p (fn))
154     {
155       DECL_UNINLINABLE (fn) = 1;
156       return 1;
157     }
158
159   /* If a function has pending sizes, we must not defer its
160      compilation, and we can't inline it as a tree.  */
161   if (fn == current_function_decl)
162     {
163       t = get_pending_sizes ();
164       put_pending_sizes (t);
165
166       if (t)
167         {
168           DECL_UNINLINABLE (fn) = 1;
169           return 1;
170         }
171     }
172
173   if (DECL_CONTEXT (fn))
174     {
175       /* If a nested function has pending sizes, we may have already
176          saved them.  */
177       if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
178         {
179           DECL_UNINLINABLE (fn) = 1;
180           return 1;
181         }
182     }
183   else
184     {
185       /* We rely on the fact that this function is called upfront,
186          just before we start expanding a function.  If FN is active
187          (i.e., it's the current_function_decl or a parent thereof),
188          we have to walk FN's saved tree.  Otherwise, we can safely
189          assume we have done it before and, if we didn't mark it as
190          uninlinable (in which case we wouldn't have been called), it
191          is inlinable.  Unfortunately, this strategy doesn't work for
192          nested functions, because they're only expanded as part of
193          their enclosing functions, so the inlinability test comes in
194          late.  */
195       t = current_function_decl;
196
197       while (t && t != fn)
198         t = DECL_CONTEXT (t);
199       if (! t)
200         return 0;
201     }
202     
203   if (walk_tree (&DECL_SAVED_TREE (fn), inline_forbidden_p, fn, NULL))
204     {
205       DECL_UNINLINABLE (fn) = 1;
206       return 1;
207     }
208
209   return 0;
210 }
211
212 /* Called from check_global_declarations.  */
213
214 bool
215 c_warn_unused_global_decl (decl)
216      tree decl;
217 {
218   if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
219     return false;
220   if (DECL_IN_SYSTEM_HEADER (decl))
221     return false;
222
223   return true;
224 }
225
226 /* Initialization common to C and Objective-C front ends.  */
227 const char *
228 c_objc_common_init (filename)
229      const char *filename;
230 {
231   c_init_decl_processing ();
232
233   filename = c_common_init (filename);
234   if (filename == NULL)
235     return NULL;
236
237   save_lang_status = &push_c_function_context;
238   restore_lang_status = &pop_c_function_context;
239   mark_lang_status = &mark_c_function_context;
240   lang_expand_decl_stmt = c_expand_decl_stmt;
241
242   /* These were not defined in the Objective-C front end, but I'm
243      putting them here anyway.  The diagnostic format decoder might
244      want an enhanced ObjC implementation.  */
245   diagnostic_format_decoder (global_dc) = &c_tree_printer;
246   lang_missing_noreturn_ok_p = &c_missing_noreturn_ok_p;
247
248   /* If still unspecified, make it match -std=c99
249      (allowing for -pedantic-errors).  */
250   if (mesg_implicit_function_declaration < 0)
251     {
252       if (flag_isoc99)
253         mesg_implicit_function_declaration = flag_pedantic_errors ? 2 : 1;
254       else
255         mesg_implicit_function_declaration = 0;
256     }
257
258   VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
259   ggc_add_tree_varray_root (&deferred_fns, 1);
260
261   return filename;
262 }
263
264 /* Register a function tree, so that its optimization and conversion
265    to RTL is only done at the end of the compilation.  */
266
267 int
268 defer_fn (fn)
269      tree fn;
270 {
271   VARRAY_PUSH_TREE (deferred_fns, fn);
272
273   return 1;
274 }
275
276 /* Expand deferred functions for C and ObjC.  */
277
278 static void
279 expand_deferred_fns ()
280 {
281   unsigned int i;
282
283   for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_fns); i++)
284     {
285       tree decl = VARRAY_TREE (deferred_fns, i);
286
287       if (! TREE_ASM_WRITTEN (decl))
288         {
289           /* For static inline functions, delay the decision whether to
290              emit them or not until wrapup_global_declarations.  */
291           if (! TREE_PUBLIC (decl))
292             DECL_DEFER_OUTPUT (decl) = 1;
293           c_expand_deferred_function (decl);
294         }
295     }
296
297   VARRAY_FREE (deferred_fns);
298 }
299
300 static tree
301 start_cdtor (method_type)
302      int method_type;
303 {
304   tree fnname = get_file_function_name (method_type);
305   tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
306   tree body;
307
308   start_function (void_list_node_1,
309                   build_nt (CALL_EXPR, fnname,
310                             tree_cons (NULL_TREE, NULL_TREE, void_list_node_1),
311                             NULL_TREE),
312                   NULL_TREE);
313   store_parm_decls ();
314
315   current_function_cannot_inline
316     = "static constructors and destructors cannot be inlined";
317
318   body = c_begin_compound_stmt ();
319
320   pushlevel (0);
321   clear_last_expr ();
322   add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
323
324   return body;
325 }
326
327 static void
328 finish_cdtor (body)
329      tree body;
330 {
331   tree scope;
332   tree block;
333
334   scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
335   block = poplevel (0, 0, 0);
336   SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
337   SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
338
339   RECHAIN_STMTS (body, COMPOUND_BODY (body));
340
341   finish_function (0, 0);
342 }
343
344 /* Called at end of parsing, but before end-of-file processing.  */
345
346 void
347 c_objc_common_finish_file ()
348 {
349   expand_deferred_fns ();
350
351   if (static_ctors)
352     {
353       tree body = start_cdtor ('I');
354
355       for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
356         c_expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
357                                                  NULL_TREE));
358
359       finish_cdtor (body);
360     }
361
362   if (static_dtors)
363     {
364       tree body = start_cdtor ('D');
365
366       for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
367         c_expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
368                                                  NULL_TREE));
369
370       finish_cdtor (body);
371     }
372
373   {
374     int flags;
375     FILE *stream = dump_begin (TDI_all, &flags);
376
377     if (stream)
378       {
379         dump_node (getdecls (), flags & ~TDF_SLIM, stream);
380         dump_end (TDI_all, stream);
381       }
382   }
383 }
384
385 /* Called during diagnostic message formatting process to print a
386    source-level entity onto BUFFER.  The meaning of the format specifiers
387    is as follows:
388    %D: a general decl,
389    %F: a function declaration,
390    %T: a type.
391
392    These format specifiers form a subset of the format specifiers set used
393    by the C++ front-end.
394    Please notice when called, the `%' part was already skipped by the
395    diagnostic machinery.  */
396 static int
397 c_tree_printer (buffer)
398      output_buffer *buffer;
399 {
400   tree t = va_arg (output_buffer_format_args (buffer), tree);
401
402   switch (*output_buffer_text_cursor (buffer))
403     {
404     case 'D':
405     case 'F':
406     case 'T':
407       {
408         const char *n = DECL_NAME (t)
409           ? (*lang_hooks.decl_printable_name) (t, 2)
410           : "({anonymous})";
411         output_add_string (buffer, n);
412       }
413       return 1;
414
415     default:
416       return 0;
417     }
418 }