OSDN Git Service

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