OSDN Git Service

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