OSDN Git Service

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