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