OSDN Git Service

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