OSDN Git Service

* calls.c (expand_call): Convert structure_value_addr to Pmode if
[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   static const enum tree_code stmt_codes[] = {
248     c_common_stmt_codes
249   };
250
251   INIT_STATEMENT_CODES (stmt_codes);
252
253   c_init_decl_processing ();
254
255   if (c_common_init () == false)
256     return false;
257
258   lang_expand_decl_stmt = c_expand_decl_stmt;
259
260   /* These were not defined in the Objective-C front end, but I'm
261      putting them here anyway.  The diagnostic format decoder might
262      want an enhanced ObjC implementation.  */
263   diagnostic_format_decoder (global_dc) = &c_tree_printer;
264   lang_missing_noreturn_ok_p = &c_missing_noreturn_ok_p;
265
266   /* If still unspecified, make it match -std=c99
267      (allowing for -pedantic-errors).  */
268   if (mesg_implicit_function_declaration < 0)
269     {
270       if (flag_isoc99)
271         mesg_implicit_function_declaration = flag_pedantic_errors ? 2 : 1;
272       else
273         mesg_implicit_function_declaration = 0;
274     }
275
276   VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
277
278   return true;
279 }
280
281 /* Register a function tree, so that its optimization and conversion
282    to RTL is only done at the end of the compilation.  */
283
284 int
285 defer_fn (fn)
286      tree fn;
287 {
288   VARRAY_PUSH_TREE (deferred_fns, fn);
289
290   return 1;
291 }
292
293 /* Expand deferred functions for C and ObjC.  */
294
295 static void
296 expand_deferred_fns ()
297 {
298   unsigned int i;
299
300   for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_fns); i++)
301     {
302       tree decl = VARRAY_TREE (deferred_fns, i);
303
304       if (! TREE_ASM_WRITTEN (decl))
305         {
306           /* For static inline functions, delay the decision whether to
307              emit them or not until wrapup_global_declarations.  */
308           if (! TREE_PUBLIC (decl))
309             DECL_DEFER_OUTPUT (decl) = 1;
310           c_expand_deferred_function (decl);
311         }
312     }
313
314   deferred_fns = 0;
315 }
316
317 static tree
318 start_cdtor (method_type)
319      int method_type;
320 {
321   tree fnname = get_file_function_name (method_type);
322   tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
323   tree body;
324
325   start_function (void_list_node_1,
326                   build_nt (CALL_EXPR, fnname,
327                             tree_cons (NULL_TREE, NULL_TREE, void_list_node_1),
328                             NULL_TREE),
329                   NULL_TREE);
330   store_parm_decls ();
331
332   current_function_cannot_inline
333     = "static constructors and destructors cannot be inlined";
334
335   body = c_begin_compound_stmt ();
336
337   pushlevel (0);
338   clear_last_expr ();
339   add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
340
341   return body;
342 }
343
344 static void
345 finish_cdtor (body)
346      tree body;
347 {
348   tree scope;
349   tree block;
350
351   scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
352   block = poplevel (0, 0, 0);
353   SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
354   SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
355
356   RECHAIN_STMTS (body, COMPOUND_BODY (body));
357
358   finish_function (0, 0);
359 }
360
361 /* Called at end of parsing, but before end-of-file processing.  */
362
363 void
364 c_objc_common_finish_file ()
365 {
366   if (pch_file)
367     c_common_write_pch ();
368
369   if (flag_unit_at_a_time)
370     {
371       cgraph_finalize_compilation_unit ();
372       cgraph_optimize ();
373     }
374   else
375     expand_deferred_fns ();
376
377   if (static_ctors)
378     {
379       tree body = start_cdtor ('I');
380
381       for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
382         c_expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
383                                                  NULL_TREE));
384
385       finish_cdtor (body);
386     }
387
388   if (static_dtors)
389     {
390       tree body = start_cdtor ('D');
391
392       for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
393         c_expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
394                                                  NULL_TREE));
395
396       finish_cdtor (body);
397     }
398
399   {
400     int flags;
401     FILE *stream = dump_begin (TDI_all, &flags);
402
403     if (stream)
404       {
405         dump_node (getdecls (), flags & ~TDF_SLIM, stream);
406         dump_end (TDI_all, stream);
407       }
408   }
409 }
410
411 /* Called during diagnostic message formatting process to print a
412    source-level entity onto BUFFER.  The meaning of the format specifiers
413    is as follows:
414    %D: a general decl,
415    %F: a function declaration,
416    %T: a type.
417
418    These format specifiers form a subset of the format specifiers set used
419    by the C++ front-end.
420    Please notice when called, the `%' part was already skipped by the
421    diagnostic machinery.  */
422 static bool
423 c_tree_printer (buffer, text)
424      output_buffer *buffer;
425      text_info *text;
426 {
427   tree t = va_arg (*text->args_ptr, tree);
428
429   switch (*text->format_spec)
430     {
431     case 'D':
432     case 'F':
433     case 'T':
434       {
435         const char *n = DECL_NAME (t)
436           ? (*lang_hooks.decl_printable_name) (t, 2)
437           : "({anonymous})";
438         output_add_string (buffer, n);
439       }
440       return true;
441
442     default:
443       return false;
444     }
445 }
446
447 #include "gt-c-objc-common.h"