2002-06-06 James Clark <jjc@jclark.com>
[official-gcc.git] / gcc / c-objc-common.c
blob32b894b4552a582f56666c5aecb11767692fb16e
1 /* Some code common to C and ObjC front ends.
2 Copyright (C) 2001, 2002 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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. */
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"
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));
48 static GTY(()) varray_type deferred_fns;
50 int
51 c_missing_noreturn_ok_p (decl)
52 tree decl;
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));
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. */
63 int
64 c_disregard_inline_limits (fn)
65 tree fn;
67 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
68 return 1;
70 return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
73 static tree
74 inline_forbidden_p (nodep, walk_subtrees, fn)
75 tree *nodep;
76 int *walk_subtrees ATTRIBUTE_UNUSED;
77 void *fn;
79 tree node = *nodep;
80 tree t;
82 switch (TREE_CODE (node))
84 case CALL_EXPR:
85 t = get_callee_fndecl (node);
87 if (! t)
88 break;
90 /* We cannot inline functions that call setjmp. */
91 if (setjmp_call_p (t))
92 return node;
94 switch (DECL_FUNCTION_CODE (t))
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;
107 default:
108 break;
111 break;
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;
120 case GOTO_STMT:
121 case GOTO_EXPR:
122 t = TREE_OPERAND (node, 0);
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;
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;
137 break;
139 case RECORD_TYPE:
140 case UNION_TYPE:
141 /* We cannot inline a function of the form
143 void F (int i) { struct S { int ar[i]; } s; }
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;
155 default:
156 break;
159 return NULL_TREE;
163 c_cannot_inline_tree_fn (fnp)
164 tree *fnp;
166 tree fn = *fnp;
167 tree t;
169 if (flag_really_no_inline
170 && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
171 return 1;
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;
178 if (! function_attribute_inlinable_p (fn))
179 goto cannot_inline;
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)
185 t = get_pending_sizes ();
186 put_pending_sizes (t);
188 if (t)
189 goto cannot_inline;
192 if (DECL_CONTEXT (fn))
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;
199 else
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;
213 while (t && t != fn)
214 t = DECL_CONTEXT (t);
215 if (! t)
216 return 0;
219 if (walk_tree (&DECL_SAVED_TREE (fn), inline_forbidden_p, fn, NULL))
220 goto cannot_inline;
222 return 0;
224 cannot_inline:
225 DECL_UNINLINABLE (fn) = 1;
226 return 1;
229 /* Called from check_global_declarations. */
231 bool
232 c_warn_unused_global_decl (decl)
233 tree decl;
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;
240 return true;
243 /* Initialization common to C and Objective-C front ends. */
244 bool
245 c_objc_common_init ()
247 static const enum tree_code stmt_codes[] = {
248 c_common_stmt_codes
251 INIT_STATEMENT_CODES (stmt_codes);
253 c_init_decl_processing ();
255 if (c_common_init () == false)
256 return false;
258 lang_expand_decl_stmt = c_expand_decl_stmt;
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;
266 /* If still unspecified, make it match -std=c99
267 (allowing for -pedantic-errors). */
268 if (mesg_implicit_function_declaration < 0)
270 if (flag_isoc99)
271 mesg_implicit_function_declaration = flag_pedantic_errors ? 2 : 1;
272 else
273 mesg_implicit_function_declaration = 0;
276 VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
278 return true;
281 /* Register a function tree, so that its optimization and conversion
282 to RTL is only done at the end of the compilation. */
285 defer_fn (fn)
286 tree fn;
288 VARRAY_PUSH_TREE (deferred_fns, fn);
290 return 1;
293 /* Expand deferred functions for C and ObjC. */
295 static void
296 expand_deferred_fns ()
298 unsigned int i;
300 for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_fns); i++)
302 tree decl = VARRAY_TREE (deferred_fns, i);
304 if (! TREE_ASM_WRITTEN (decl))
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);
314 deferred_fns = 0;
317 static tree
318 start_cdtor (method_type)
319 int method_type;
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;
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 ();
332 current_function_cannot_inline
333 = "static constructors and destructors cannot be inlined";
335 body = c_begin_compound_stmt ();
337 pushlevel (0);
338 clear_last_expr ();
339 add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
341 return body;
344 static void
345 finish_cdtor (body)
346 tree body;
348 tree scope;
349 tree block;
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;
356 RECHAIN_STMTS (body, COMPOUND_BODY (body));
358 finish_function (0, 0);
361 /* Called at end of parsing, but before end-of-file processing. */
363 void
364 c_objc_common_finish_file ()
366 if (pch_file)
367 c_common_write_pch ();
369 if (flag_unit_at_a_time)
371 cgraph_finalize_compilation_unit ();
372 cgraph_optimize ();
374 else
375 expand_deferred_fns ();
377 if (static_ctors)
379 tree body = start_cdtor ('I');
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));
385 finish_cdtor (body);
388 if (static_dtors)
390 tree body = start_cdtor ('D');
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));
396 finish_cdtor (body);
400 int flags;
401 FILE *stream = dump_begin (TDI_all, &flags);
403 if (stream)
405 dump_node (getdecls (), flags & ~TDF_SLIM, stream);
406 dump_end (TDI_all, stream);
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.
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;
427 tree t = va_arg (*text->args_ptr, tree);
429 switch (*text->format_spec)
431 case 'D':
432 case 'F':
433 case 'T':
435 const char *n = DECL_NAME (t)
436 ? (*lang_hooks.decl_printable_name) (t, 2)
437 : "({anonymous})";
438 output_add_string (buffer, n);
440 return true;
442 default:
443 return false;
447 #include "gt-c-objc-common.h"