OSDN Git Service

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