OSDN Git Service

* java-tree.h (DECL_NUM_STMTS): Rename to...
[pf3gnuchains/gcc-fork.git] / gcc / c-objc-common.c
1 /* Some code common to C and ObjC front ends.
2    Copyright (C) 2001, 2002, 2003 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 "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "rtl.h"
27 #include "insn-config.h"
28 #include "integrate.h"
29 #include "expr.h"
30 #include "c-tree.h"
31 #include "function.h"
32 #include "flags.h"
33 #include "toplev.h"
34 #include "diagnostic.h"
35 #include "tree-inline.h"
36 #include "varray.h"
37 #include "ggc.h"
38 #include "langhooks.h"
39 #include "target.h"
40 #include "cgraph.h"
41
42 static bool c_tree_printer (output_buffer *, text_info *);
43 static tree inline_forbidden_p (tree *, int *, void *);
44 static void expand_deferred_fns (void);
45 static tree start_cdtor (int);
46 static void finish_cdtor (tree);
47
48 static GTY(()) varray_type deferred_fns;
49
50 int
51 c_missing_noreturn_ok_p (tree decl)
52 {
53   /* A missing noreturn is not ok for freestanding implementations and
54      ok for the `main' function in hosted implementations.  */
55   return flag_hosted && MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl));
56 }
57
58 /* We want to inline `extern inline' functions even if this would
59    violate inlining limits.  Some glibc and linux constructs depend on
60    such functions always being inlined when optimizing.  */
61
62 int
63 c_disregard_inline_limits (tree fn)
64 {
65   if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
66     return 1;
67
68   return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
69 }
70
71 static tree
72 inline_forbidden_p (tree *nodep, 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_VA_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 behavior.  */
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     case RECORD_TYPE:
136     case UNION_TYPE:
137       /* We cannot inline a function of the form
138
139            void F (int i) { struct S { int ar[i]; } s; }
140
141          Attempting to do so produces a catch-22 in tree-inline.c.
142          If walk_tree examines the TYPE_FIELDS chain of RECORD_TYPE/
143          UNION_TYPE nodes, then it goes into infinite recursion on a
144          structure containing a pointer to its own type.  If it doesn't,
145          then the type node for S doesn't get adjusted properly when
146          F is inlined, and we abort in find_function_data.  */
147       for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
148         if (variably_modified_type_p (TREE_TYPE (t)))
149           return node;
150
151     default:
152       break;
153     }
154
155   return NULL_TREE;
156 }
157
158 int
159 c_cannot_inline_tree_fn (tree *fnp)
160 {
161   tree fn = *fnp;
162   tree t;
163
164   if (flag_really_no_inline
165       && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
166     return 1;
167
168   /* Don't auto-inline anything that might not be bound within
169      this unit of translation.  */
170   if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
171     goto cannot_inline;
172
173   if (! function_attribute_inlinable_p (fn))
174     goto cannot_inline;
175
176   /* If a function has pending sizes, we must not defer its
177      compilation, and we can't inline it as a tree.  */
178   if (fn == current_function_decl)
179     {
180       t = get_pending_sizes ();
181       put_pending_sizes (t);
182
183       if (t)
184         goto cannot_inline;
185     }
186
187   if (DECL_CONTEXT (fn))
188     {
189       /* If a nested function has pending sizes, we may have already
190          saved them.  */
191       if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
192         goto cannot_inline;
193     }
194   else
195     {
196       /* We rely on the fact that this function is called upfront,
197          just before we start expanding a function.  If FN is active
198          (i.e., it's the current_function_decl or a parent thereof),
199          we have to walk FN's saved tree.  Otherwise, we can safely
200          assume we have done it before and, if we didn't mark it as
201          uninlinable (in which case we wouldn't have been called), it
202          is inlinable.  Unfortunately, this strategy doesn't work for
203          nested functions, because they're only expanded as part of
204          their enclosing functions, so the inlinability test comes in
205          late.  */
206       t = current_function_decl;
207
208       while (t && t != fn)
209         t = DECL_CONTEXT (t);
210       if (! t)
211         return 0;
212     }
213
214   if (walk_tree (&DECL_SAVED_TREE (fn), inline_forbidden_p, fn, NULL))
215     goto cannot_inline;
216
217   return 0;
218
219  cannot_inline:
220   DECL_UNINLINABLE (fn) = 1;
221   return 1;
222 }
223
224 /* Called from check_global_declarations.  */
225
226 bool
227 c_warn_unused_global_decl (tree decl)
228 {
229   if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
230     return false;
231   if (DECL_IN_SYSTEM_HEADER (decl))
232     return false;
233
234   return true;
235 }
236
237 /* Initialization common to C and Objective-C front ends.  */
238 bool
239 c_objc_common_init (void)
240 {
241   static const enum tree_code stmt_codes[] = {
242     c_common_stmt_codes
243   };
244
245   INIT_STATEMENT_CODES (stmt_codes);
246
247   c_init_decl_processing ();
248
249   if (c_common_init () == false)
250     return false;
251
252   lang_expand_decl_stmt = c_expand_decl_stmt;
253
254   /* These were not defined in the Objective-C front end, but I'm
255      putting them here anyway.  The diagnostic format decoder might
256      want an enhanced ObjC implementation.  */
257   diagnostic_format_decoder (global_dc) = &c_tree_printer;
258   lang_missing_noreturn_ok_p = &c_missing_noreturn_ok_p;
259
260   /* If still unspecified, make it match -std=c99
261      (allowing for -pedantic-errors).  */
262   if (mesg_implicit_function_declaration < 0)
263     {
264       if (flag_isoc99)
265         mesg_implicit_function_declaration = flag_pedantic_errors ? 2 : 1;
266       else
267         mesg_implicit_function_declaration = 0;
268     }
269
270   VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
271
272   return true;
273 }
274
275 /* Register a function tree, so that its optimization and conversion
276    to RTL is only done at the end of the compilation.  */
277
278 int
279 defer_fn (tree fn)
280 {
281   VARRAY_PUSH_TREE (deferred_fns, fn);
282
283   return 1;
284 }
285
286 /* Expand deferred functions for C and ObjC.  */
287
288 static void
289 expand_deferred_fns (void)
290 {
291   unsigned int i;
292
293   for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_fns); i++)
294     {
295       tree decl = VARRAY_TREE (deferred_fns, i);
296
297       if (! TREE_ASM_WRITTEN (decl))
298         {
299           /* For static inline functions, delay the decision whether to
300              emit them or not until wrapup_global_declarations.  */
301           if (! TREE_PUBLIC (decl))
302             DECL_DEFER_OUTPUT (decl) = 1;
303           c_expand_deferred_function (decl);
304         }
305     }
306
307   deferred_fns = 0;
308 }
309
310 static tree
311 start_cdtor (int method_type)
312 {
313   tree fnname = get_file_function_name (method_type);
314   tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
315   tree body;
316
317   start_function (void_list_node_1,
318                   build_nt (CALL_EXPR, fnname,
319                             tree_cons (NULL_TREE, NULL_TREE, void_list_node_1),
320                             NULL_TREE),
321                   NULL_TREE);
322   store_parm_decls ();
323
324   current_function_cannot_inline
325     = "static constructors and destructors cannot be inlined";
326
327   body = c_begin_compound_stmt ();
328
329   pushlevel (0);
330   clear_last_expr ();
331   add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
332
333   return body;
334 }
335
336 static void
337 finish_cdtor (tree body)
338 {
339   tree scope;
340   tree block;
341
342   scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
343   block = poplevel (0, 0, 0);
344   SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
345   SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
346
347   RECHAIN_STMTS (body, COMPOUND_BODY (body));
348
349   finish_function (0, 0);
350 }
351
352 /* Called at end of parsing, but before end-of-file processing.  */
353
354 void
355 c_objc_common_finish_file (void)
356 {
357   if (pch_file)
358     c_common_write_pch ();
359
360   if (flag_unit_at_a_time)
361     {
362       cgraph_finalize_compilation_unit ();
363       cgraph_optimize ();
364     }
365   else
366     expand_deferred_fns ();
367
368   if (static_ctors)
369     {
370       tree body = start_cdtor ('I');
371
372       for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
373         c_expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
374                                                  NULL_TREE));
375
376       finish_cdtor (body);
377     }
378
379   if (static_dtors)
380     {
381       tree body = start_cdtor ('D');
382
383       for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
384         c_expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
385                                                  NULL_TREE));
386
387       finish_cdtor (body);
388     }
389
390   {
391     int flags;
392     FILE *stream = dump_begin (TDI_all, &flags);
393
394     if (stream)
395       {
396         dump_node (getdecls (), flags & ~TDF_SLIM, stream);
397         dump_end (TDI_all, stream);
398       }
399   }
400 }
401
402 /* Called during diagnostic message formatting process to print a
403    source-level entity onto BUFFER.  The meaning of the format specifiers
404    is as follows:
405    %D: a general decl,
406    %F: a function declaration,
407    %T: a type.
408
409    These format specifiers form a subset of the format specifiers set used
410    by the C++ front-end.
411    Please notice when called, the `%' part was already skipped by the
412    diagnostic machinery.  */
413 static bool
414 c_tree_printer (output_buffer *buffer, text_info *text)
415 {
416   tree t = va_arg (*text->args_ptr, tree);
417
418   switch (*text->format_spec)
419     {
420     case 'D':
421     case 'F':
422     case 'T':
423       {
424         const char *n = DECL_NAME (t)
425           ? (*lang_hooks.decl_printable_name) (t, 2)
426           : "({anonymous})";
427         output_add_string (buffer, n);
428       }
429       return true;
430
431     default:
432       return false;
433     }
434 }
435
436 #include "gt-c-objc-common.h"