1 /* Some code common to C and ObjC front ends.
2 Copyright (C) 2001 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 "tree.h"
24 #include "rtl.h"
25 #include "insn-config.h"
26 #include "integrate.h"
27 #include "expr.h"
28 #include "c-tree.h"
29 #include "function.h"
30 #include "flags.h"
31 #include "toplev.h"
32 #include "diagnostic.h"
33 #include "tree-inline.h"
34 #include "varray.h"
35 #include "ggc.h"
36 #include "langhooks.h"
37 #include "target.h"
38
39 static bool c_tree_printer PARAMS ((output_buffer *, text_info *));
40 static tree inline_forbidden_p PARAMS ((tree *, int *, void *));
41 static void expand_deferred_fns PARAMS ((void));
42 static tree start_cdtor PARAMS ((int));
43 static void finish_cdtor PARAMS ((tree));
44
45 static GTY(()) varray_type deferred_fns;
46
47 int
c_missing_noreturn_ok_p(decl)48 c_missing_noreturn_ok_p (decl)
49 tree decl;
50 {
51 /* A missing noreturn is not ok for freestanding implementations and
52 ok for the `main' function in hosted implementations. */
53 return flag_hosted && MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl));
54 }
55
56 /* We want to inline `extern inline' functions even if this would
57 violate inlining limits. Some glibc and linux constructs depend on
58 such functions always being inlined when optimizing. */
59
60 int
c_disregard_inline_limits(fn)61 c_disregard_inline_limits (fn)
62 tree fn;
63 {
64 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
65 return 1;
66
67 return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
68 }
69
70 static tree
inline_forbidden_p(nodep,walk_subtrees,fn)71 inline_forbidden_p (nodep, walk_subtrees, fn)
72 tree *nodep;
73 int *walk_subtrees ATTRIBUTE_UNUSED;
74 void *fn;
75 {
76 tree node = *nodep;
77 tree t;
78
79 switch (TREE_CODE (node))
80 {
81 case CALL_EXPR:
82 t = get_callee_fndecl (node);
83
84 if (! t)
85 break;
86
87 /* We cannot inline functions that call setjmp. */
88 if (setjmp_call_p (t))
89 return node;
90
91 if (DECL_BUILT_IN (t))
92 switch (DECL_FUNCTION_CODE (t))
93 {
94 /* We cannot inline functions that take a variable number of
95 arguments. */
96 case BUILT_IN_VA_START:
97 case BUILT_IN_STDARG_START:
98 case BUILT_IN_NEXT_ARG:
99 case BUILT_IN_VA_END:
100 return node;
101
102 default:
103 break;
104 }
105
106 break;
107
108 case DECL_STMT:
109 /* We cannot inline functions that contain other functions. */
110 if (TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
111 && DECL_INITIAL (TREE_OPERAND (node, 0)))
112 return node;
113 break;
114
115 case GOTO_STMT:
116 case GOTO_EXPR:
117 t = TREE_OPERAND (node, 0);
118
119 /* We will not inline a function which uses computed goto. The
120 addresses of its local labels, which may be tucked into
121 global storage, are of course not constant across
122 instantiations, which causes unexpected behavior. */
123 if (TREE_CODE (t) != LABEL_DECL)
124 return node;
125
126 /* We cannot inline a nested function that jumps to a nonlocal
127 label. */
128 if (TREE_CODE (t) == LABEL_DECL
129 && DECL_CONTEXT (t) && DECL_CONTEXT (t) != fn)
130 return node;
131
132 break;
133
134 case RECORD_TYPE:
135 case UNION_TYPE:
136 /* We cannot inline a function of the form
137
138 void F (int i) { struct S { int ar[i]; } s; }
139
140 Attempting to do so produces a catch-22 in tree-inline.c.
141 If walk_tree examines the TYPE_FIELDS chain of RECORD_TYPE/
142 UNION_TYPE nodes, then it goes into infinite recursion on a
143 structure containing a pointer to its own type. If it doesn't,
144 then the type node for S doesn't get adjusted properly when
145 F is inlined, and we abort in find_function_data. */
146 for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
147 if (variably_modified_type_p (TREE_TYPE (t)))
148 return node;
149
150 default:
151 break;
152 }
153
154 return NULL_TREE;
155 }
156
157 int
c_cannot_inline_tree_fn(fnp)158 c_cannot_inline_tree_fn (fnp)
159 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_CONTEXT (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_without_duplicates
215 (&DECL_SAVED_TREE (fn), inline_forbidden_p, fn))
216 goto cannot_inline;
217
218 return 0;
219
220 cannot_inline:
221 DECL_UNINLINABLE (fn) = 1;
222 return 1;
223 }
224
225 /* Called from check_global_declarations. */
226
227 bool
c_warn_unused_global_decl(decl)228 c_warn_unused_global_decl (decl)
229 tree decl;
230 {
231 if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
232 return false;
233 if (DECL_IN_SYSTEM_HEADER (decl))
234 return false;
235
236 return true;
237 }
238
239 /* Initialization common to C and Objective-C front ends. */
240 const char *
c_objc_common_init(filename)241 c_objc_common_init (filename)
242 const char *filename;
243 {
244 c_init_decl_processing ();
245
246 filename = c_common_init (filename);
247 if (filename == NULL)
248 return NULL;
249
250 lang_expand_decl_stmt = c_expand_decl_stmt;
251
252 /* These were not defined in the Objective-C front end, but I'm
253 putting them here anyway. The diagnostic format decoder might
254 want an enhanced ObjC implementation. */
255 diagnostic_format_decoder (global_dc) = &c_tree_printer;
256 lang_missing_noreturn_ok_p = &c_missing_noreturn_ok_p;
257
258 /* If still unspecified, make it match -std=c99
259 (allowing for -pedantic-errors). */
260 if (mesg_implicit_function_declaration < 0)
261 {
262 if (flag_isoc99)
263 mesg_implicit_function_declaration = flag_pedantic_errors ? 2 : 1;
264 else
265 mesg_implicit_function_declaration = 0;
266 }
267
268 VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
269
270 return filename;
271 }
272
273 /* Register a function tree, so that its optimization and conversion
274 to RTL is only done at the end of the compilation. */
275
276 int
defer_fn(fn)277 defer_fn (fn)
278 tree fn;
279 {
280 VARRAY_PUSH_TREE (deferred_fns, fn);
281
282 return 1;
283 }
284
285 /* Expand deferred functions for C and ObjC. */
286
287 static void
expand_deferred_fns()288 expand_deferred_fns ()
289 {
290 unsigned int i;
291
292 for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_fns); i++)
293 {
294 tree decl = VARRAY_TREE (deferred_fns, i);
295
296 if (! TREE_ASM_WRITTEN (decl))
297 {
298 /* For static inline functions, delay the decision whether to
299 emit them or not until wrapup_global_declarations. */
300 if (! TREE_PUBLIC (decl))
301 DECL_DEFER_OUTPUT (decl) = 1;
302 c_expand_deferred_function (decl);
303 }
304 }
305
306 deferred_fns = 0;
307 }
308
309 static tree
start_cdtor(method_type)310 start_cdtor (method_type)
311 int method_type;
312 {
313 tree fnname = get_file_function_name (method_type);
314 tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
315 tree body;
316
317 start_function (void_list_node_1,
318 build_nt (CALL_EXPR, fnname,
319 tree_cons (NULL_TREE, NULL_TREE, void_list_node_1),
320 NULL_TREE),
321 NULL_TREE);
322 store_parm_decls ();
323
324 current_function_cannot_inline
325 = "static constructors and destructors cannot be inlined";
326
327 body = c_begin_compound_stmt ();
328
329 pushlevel (0);
330 clear_last_expr ();
331 add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
332
333 return body;
334 }
335
336 static void
finish_cdtor(body)337 finish_cdtor (body)
338 tree body;
339 {
340 tree scope;
341 tree block;
342
343 scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
344 block = poplevel (0, 0, 0);
345 SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
346 SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
347
348 RECHAIN_STMTS (body, COMPOUND_BODY (body));
349
350 finish_function (0, 0);
351 }
352
353 /* Called at end of parsing, but before end-of-file processing. */
354
355 void
c_objc_common_finish_file()356 c_objc_common_finish_file ()
357 {
358 expand_deferred_fns ();
359
360 if (static_ctors)
361 {
362 tree body = start_cdtor ('I');
363
364 for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
365 c_expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
366 NULL_TREE));
367
368 finish_cdtor (body);
369 }
370
371 if (static_dtors)
372 {
373 tree body = start_cdtor ('D');
374
375 for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
376 c_expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
377 NULL_TREE));
378
379 finish_cdtor (body);
380 }
381
382 {
383 int flags;
384 FILE *stream = dump_begin (TDI_all, &flags);
385
386 if (stream)
387 {
388 dump_node (getdecls (), flags & ~TDF_SLIM, stream);
389 dump_end (TDI_all, stream);
390 }
391 }
392 }
393
394 /* Called during diagnostic message formatting process to print a
395 source-level entity onto BUFFER. The meaning of the format specifiers
396 is as follows:
397 %D: a general decl,
398 %F: a function declaration,
399 %T: a type.
400
401 These format specifiers form a subset of the format specifiers set used
402 by the C++ front-end.
403 Please notice when called, the `%' part was already skipped by the
404 diagnostic machinery. */
405 static bool
c_tree_printer(buffer,text)406 c_tree_printer (buffer, text)
407 output_buffer *buffer;
408 text_info *text;
409 {
410 tree t = va_arg (*text->args_ptr, tree);
411
412 switch (*text->format_spec)
413 {
414 case 'D':
415 case 'F':
416 case 'T':
417 {
418 const char *n = DECL_NAME (t)
419 ? (*lang_hooks.decl_printable_name) (t, 2)
420 : "({anonymous})";
421 output_add_string (buffer, n);
422 }
423 return true;
424
425 default:
426 return false;
427 }
428 }
429
430 #include "gt-c-objc-common.h"
431