]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/c-objc-common.c
Merge basic-improvements-branch to trunk
[thirdparty/gcc.git] / gcc / c-objc-common.c
CommitLineData
0abc6a6a
NB
1/* Some code common to C and ObjC front ends.
2 Copyright (C) 2001 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 2, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING. If not, write to the Free
18Software Foundation, 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include "config.h"
22#include "system.h"
4977bab6
ZW
23#include "coretypes.h"
24#include "tm.h"
0abc6a6a
NB
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"
3b27886e
NB
36#include "varray.h"
37#include "ggc.h"
7afff7cf 38#include "langhooks.h"
38ec83b1 39#include "target.h"
0abc6a6a 40
47b69537 41static bool c_tree_printer PARAMS ((output_buffer *, text_info *));
0abc6a6a 42static tree inline_forbidden_p PARAMS ((tree *, int *, void *));
3b27886e
NB
43static void expand_deferred_fns PARAMS ((void));
44static tree start_cdtor PARAMS ((int));
45static void finish_cdtor PARAMS ((tree));
46
e2500fed 47static GTY(()) varray_type deferred_fns;
0abc6a6a
NB
48
49int
50c_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
62int
63c_disregard_inline_limits (fn)
64 tree fn;
65{
6aa77e6c
AH
66 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
67 return 1;
68
0abc6a6a
NB
69 return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
70}
71
72static tree
73inline_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. */
6c535c69 97 case BUILT_IN_VA_START:
0abc6a6a
NB
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
8d9afc4e 126 instantiations, which causes unexpected behavior. */
0abc6a6a
NB
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
f3763a44
ZW
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
0abc6a6a
NB
154 default:
155 break;
156 }
157
158 return NULL_TREE;
159}
160
161int
162c_cannot_inline_tree_fn (fnp)
163 tree *fnp;
164{
165 tree fn = *fnp;
166 tree t;
167
2cb921f4 168 if (flag_really_no_inline
6aa77e6c
AH
169 && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
170 return 1;
171
38ec83b1
RH
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
0abc6a6a 177 if (! function_attribute_inlinable_p (fn))
38ec83b1 178 goto cannot_inline;
0abc6a6a
NB
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)
38ec83b1 188 goto cannot_inline;
0abc6a6a
NB
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)
38ec83b1 196 goto cannot_inline;
0abc6a6a
NB
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))
38ec83b1 219 goto cannot_inline;
0abc6a6a
NB
220
221 return 0;
38ec83b1
RH
222
223 cannot_inline:
224 DECL_UNINLINABLE (fn) = 1;
225 return 1;
0abc6a6a
NB
226}
227
ef4f94ac
RH
228/* Called from check_global_declarations. */
229
230bool
231c_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
0abc6a6a
NB
242/* Initialization common to C and Objective-C front ends. */
243const char *
244c_objc_common_init (filename)
245 const char *filename;
246{
247 c_init_decl_processing ();
248
249 filename = c_common_init (filename);
aaf93206
NB
250 if (filename == NULL)
251 return NULL;
0abc6a6a 252
0abc6a6a
NB
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
3b27886e 271 VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
3b27886e 272
0abc6a6a
NB
273 return filename;
274}
275
3b27886e
NB
276/* Register a function tree, so that its optimization and conversion
277 to RTL is only done at the end of the compilation. */
278
279int
280defer_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
290static void
291expand_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
e2500fed 309 deferred_fns = 0;
3b27886e
NB
310}
311
312static tree
313start_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
339static void
340finish_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
619708cc 353 finish_function (0, 0);
3b27886e
NB
354}
355
356/* Called at end of parsing, but before end-of-file processing. */
357
358void
359c_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
0abc6a6a
NB
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. */
47b69537
GDR
408static bool
409c_tree_printer (buffer, text)
0abc6a6a 410 output_buffer *buffer;
47b69537 411 text_info *text;
0abc6a6a 412{
47b69537 413 tree t = va_arg (*text->args_ptr, tree);
0abc6a6a 414
47b69537 415 switch (*text->format_spec)
0abc6a6a
NB
416 {
417 case 'D':
418 case 'F':
419 case 'T':
420 {
421 const char *n = DECL_NAME (t)
7afff7cf 422 ? (*lang_hooks.decl_printable_name) (t, 2)
0abc6a6a
NB
423 : "({anonymous})";
424 output_add_string (buffer, n);
425 }
47b69537 426 return true;
0abc6a6a
NB
427
428 default:
47b69537 429 return false;
0abc6a6a
NB
430 }
431}
e2500fed
GK
432
433#include "gt-c-objc-common.h"