xref: /openbsd-src/gnu/usr.bin/gcc/gcc/c-objc-common.c (revision 4e43c760ad4cd5f644ec700462679d05749498d8)
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