OSDN Git Service

* c-common.h (c_common_init, c_common_post_options): Update.
[pf3gnuchains/gcc-fork.git] / gcc / c-objc-common.c
1 /* Some code common to C and ObjC front ends.
2    Copyright (C) 2001, 2002 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 PARAMS ((output_buffer *, text_info *));
43 static tree inline_forbidden_p PARAMS ((tree *, int *, void *));
44 static void expand_deferred_fns PARAMS ((void));
45 static tree start_cdtor PARAMS ((int));
46 static void finish_cdtor PARAMS ((tree));
47
48 static GTY(()) varray_type deferred_fns;
49
50 int
51 c_missing_noreturn_ok_p (decl)
52      tree decl;
53 {
54   /* A missing noreturn is not ok for freestanding implementations and
55      ok for the `main' function in hosted implementations.  */
56   return flag_hosted && MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl));
57 }
58
59 /* We want to inline `extern inline' functions even if this would
60    violate inlining limits.  Some glibc and linux constructs depend on
61    such functions always being inlined when optimizing.  */
62
63 int
64 c_disregard_inline_limits (fn)
65      tree fn;
66 {
67   if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
68     return 1;
69
70   return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
71 }
72
73 static tree
74 inline_forbidden_p (nodep, walk_subtrees, fn)
75      tree *nodep;
76      int *walk_subtrees ATTRIBUTE_UNUSED;
77      void *fn;
78 {
79   tree node = *nodep;
80   tree t;
81
82   switch (TREE_CODE (node))
83     {
84     case CALL_EXPR:
85       t = get_callee_fndecl (node);
86
87       if (! t)
88         break;
89
90       /* We cannot inline functions that call setjmp.  */
91       if (setjmp_call_p (t))
92         return node;
93
94       switch (DECL_FUNCTION_CODE (t))
95         {
96           /* We cannot inline functions that take a variable number of
97              arguments.  */
98         case BUILT_IN_VA_START:
99         case BUILT_IN_STDARG_START:
100 #if 0
101           /* Functions that need information about the address of the
102              caller can't (shouldn't?) be inlined.  */
103         case BUILT_IN_RETURN_ADDRESS:
104 #endif
105           return node;
106
107         default:
108           break;
109         }
110
111       break;
112
113     case DECL_STMT:
114       /* We cannot inline functions that contain other functions.  */
115       if (TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
116           && DECL_INITIAL (TREE_OPERAND (node, 0)))
117         return node;
118       break;
119
120     case GOTO_STMT:
121     case GOTO_EXPR:
122       t = TREE_OPERAND (node, 0);
123
124       /* We will not inline a function which uses computed goto.  The
125          addresses of its local labels, which may be tucked into
126          global storage, are of course not constant across
127          instantiations, which causes unexpected behavior.  */
128       if (TREE_CODE (t) != LABEL_DECL)
129         return node;
130
131       /* We cannot inline a nested function that jumps to a nonlocal
132          label.  */
133       if (TREE_CODE (t) == LABEL_DECL
134           && DECL_CONTEXT (t) && DECL_CONTEXT (t) != fn)
135         return node;
136
137       break;
138
139     case RECORD_TYPE:
140     case UNION_TYPE:
141       /* We cannot inline a function of the form
142
143            void F (int i) { struct S { int ar[i]; } s; }
144
145          Attempting to do so produces a catch-22 in tree-inline.c.
146          If walk_tree examines the TYPE_FIELDS chain of RECORD_TYPE/
147          UNION_TYPE nodes, then it goes into infinite recursion on a
148          structure containing a pointer to its own type.  If it doesn't,
149          then the type node for S doesn't get adjusted properly when
150          F is inlined, and we abort in find_function_data.  */
151       for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
152         if (variably_modified_type_p (TREE_TYPE (t)))
153           return node;
154
155     default:
156       break;
157     }
158
159   return NULL_TREE;
160 }
161
162 int
163 c_cannot_inline_tree_fn (fnp)
164      tree *fnp;
165 {
166   tree fn = *fnp;
167   tree t;
168
169   if (flag_really_no_inline
170       && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
171     return 1;
172
173   /* Don't auto-inline anything that might not be bound within 
174      this unit of translation.  */
175   if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
176     goto cannot_inline;
177
178   if (! function_attribute_inlinable_p (fn))
179     goto cannot_inline;
180
181   /* If a function has pending sizes, we must not defer its
182      compilation, and we can't inline it as a tree.  */
183   if (fn == current_function_decl)
184     {
185       t = get_pending_sizes ();
186       put_pending_sizes (t);
187
188       if (t)
189         goto cannot_inline;
190     }
191
192   if (DECL_CONTEXT (fn))
193     {
194       /* If a nested function has pending sizes, we may have already
195          saved them.  */
196       if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
197         goto cannot_inline;
198     }
199   else
200     {
201       /* We rely on the fact that this function is called upfront,
202          just before we start expanding a function.  If FN is active
203          (i.e., it's the current_function_decl or a parent thereof),
204          we have to walk FN's saved tree.  Otherwise, we can safely
205          assume we have done it before and, if we didn't mark it as
206          uninlinable (in which case we wouldn't have been called), it
207          is inlinable.  Unfortunately, this strategy doesn't work for
208          nested functions, because they're only expanded as part of
209          their enclosing functions, so the inlinability test comes in
210          late.  */
211       t = current_function_decl;
212
213       while (t && t != fn)
214         t = DECL_CONTEXT (t);
215       if (! t)
216         return 0;
217     }
218     
219   if (walk_tree (&DECL_SAVED_TREE (fn), inline_forbidden_p, fn, NULL))
220     goto cannot_inline;
221
222   return 0;
223
224  cannot_inline:
225   DECL_UNINLINABLE (fn) = 1;
226   return 1;
227 }
228
229 /* Called from check_global_declarations.  */
230
231 bool
232 c_warn_unused_global_decl (decl)
233      tree decl;
234 {
235   if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
236     return false;
237   if (DECL_IN_SYSTEM_HEADER (decl))
238     return false;
239
240   return true;
241 }
242
243 /* Initialization common to C and Objective-C front ends.  */
244 bool
245 c_objc_common_init ()
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 (fn)
280      tree fn;
281 {
282   VARRAY_PUSH_TREE (deferred_fns, fn);
283
284   return 1;
285 }
286
287 /* Expand deferred functions for C and ObjC.  */
288
289 static void
290 expand_deferred_fns ()
291 {
292   unsigned int i;
293
294   for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_fns); i++)
295     {
296       tree decl = VARRAY_TREE (deferred_fns, i);
297
298       if (! TREE_ASM_WRITTEN (decl))
299         {
300           /* For static inline functions, delay the decision whether to
301              emit them or not until wrapup_global_declarations.  */
302           if (! TREE_PUBLIC (decl))
303             DECL_DEFER_OUTPUT (decl) = 1;
304           c_expand_deferred_function (decl);
305         }
306     }
307
308   deferred_fns = 0;
309 }
310
311 static tree
312 start_cdtor (method_type)
313      int method_type;
314 {
315   tree fnname = get_file_function_name (method_type);
316   tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
317   tree body;
318
319   start_function (void_list_node_1,
320                   build_nt (CALL_EXPR, fnname,
321                             tree_cons (NULL_TREE, NULL_TREE, void_list_node_1),
322                             NULL_TREE),
323                   NULL_TREE);
324   store_parm_decls ();
325
326   current_function_cannot_inline
327     = "static constructors and destructors cannot be inlined";
328
329   body = c_begin_compound_stmt ();
330
331   pushlevel (0);
332   clear_last_expr ();
333   add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
334
335   return body;
336 }
337
338 static void
339 finish_cdtor (body)
340      tree body;
341 {
342   tree scope;
343   tree block;
344
345   scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
346   block = poplevel (0, 0, 0);
347   SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
348   SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
349
350   RECHAIN_STMTS (body, COMPOUND_BODY (body));
351
352   finish_function (0, 0);
353 }
354
355 /* Called at end of parsing, but before end-of-file processing.  */
356
357 void
358 c_objc_common_finish_file ()
359 {
360   if (pch_file)
361     c_common_write_pch ();
362
363   if (flag_unit_at_a_time)
364     {
365       cgraph_finalize_compilation_unit ();
366       cgraph_optimize ();
367     }
368   else
369     expand_deferred_fns ();
370
371   if (static_ctors)
372     {
373       tree body = start_cdtor ('I');
374
375       for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
376         c_expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
377                                                  NULL_TREE));
378
379       finish_cdtor (body);
380     }
381
382   if (static_dtors)
383     {
384       tree body = start_cdtor ('D');
385
386       for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
387         c_expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
388                                                  NULL_TREE));
389
390       finish_cdtor (body);
391     }
392
393   {
394     int flags;
395     FILE *stream = dump_begin (TDI_all, &flags);
396
397     if (stream)
398       {
399         dump_node (getdecls (), flags & ~TDF_SLIM, stream);
400         dump_end (TDI_all, stream);
401       }
402   }
403 }
404
405 /* Called during diagnostic message formatting process to print a
406    source-level entity onto BUFFER.  The meaning of the format specifiers
407    is as follows:
408    %D: a general decl,
409    %F: a function declaration,
410    %T: a type.
411
412    These format specifiers form a subset of the format specifiers set used
413    by the C++ front-end.
414    Please notice when called, the `%' part was already skipped by the
415    diagnostic machinery.  */
416 static bool
417 c_tree_printer (buffer, text)
418      output_buffer *buffer;
419      text_info *text;
420 {
421   tree t = va_arg (*text->args_ptr, tree);
422
423   switch (*text->format_spec)
424     {
425     case 'D':
426     case 'F':
427     case 'T':
428       {
429         const char *n = DECL_NAME (t)
430           ? (*lang_hooks.decl_printable_name) (t, 2)
431           : "({anonymous})";
432         output_add_string (buffer, n);
433       }
434       return true;
435
436     default:
437       return false;
438     }
439 }
440
441 #include "gt-c-objc-common.h"