c-objc-common.c revision 117395
190075Sobrien/* Some code common to C and ObjC front ends.
290075Sobrien   Copyright (C) 2001 Free Software Foundation, Inc.
390075Sobrien
490075SobrienThis file is part of GCC.
590075Sobrien
690075SobrienGCC is free software; you can redistribute it and/or modify it under
790075Sobrienthe terms of the GNU General Public License as published by the Free
890075SobrienSoftware Foundation; either version 2, or (at your option) any later
990075Sobrienversion.
1090075Sobrien
1190075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1290075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1390075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1490075Sobrienfor more details.
1590075Sobrien
1690075SobrienYou should have received a copy of the GNU General Public License
1790075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
1890075SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA
1990075Sobrien02111-1307, USA.  */
2090075Sobrien
2190075Sobrien#include "config.h"
2290075Sobrien#include "system.h"
2390075Sobrien#include "tree.h"
2490075Sobrien#include "rtl.h"
2590075Sobrien#include "insn-config.h"
2690075Sobrien#include "integrate.h"
2790075Sobrien#include "expr.h"
2890075Sobrien#include "c-tree.h"
2990075Sobrien#include "function.h"
3090075Sobrien#include "flags.h"
3190075Sobrien#include "toplev.h"
3290075Sobrien#include "diagnostic.h"
3390075Sobrien#include "tree-inline.h"
3490075Sobrien#include "varray.h"
3590075Sobrien#include "ggc.h"
36117395Skan#include "langhooks.h"
37117395Skan#include "target.h"
3890075Sobrien
39117395Skanstatic bool c_tree_printer PARAMS ((output_buffer *, text_info *));
4090075Sobrienstatic tree inline_forbidden_p PARAMS ((tree *, int *, void *));
4190075Sobrienstatic void expand_deferred_fns PARAMS ((void));
4290075Sobrienstatic tree start_cdtor	PARAMS ((int));
4390075Sobrienstatic void finish_cdtor PARAMS ((tree));
4490075Sobrien
45117395Skanstatic GTY(()) varray_type deferred_fns;
4690075Sobrien
4790075Sobrienint
4890075Sobrienc_missing_noreturn_ok_p (decl)
4990075Sobrien     tree decl;
5090075Sobrien{
5190075Sobrien  /* A missing noreturn is not ok for freestanding implementations and
5290075Sobrien     ok for the `main' function in hosted implementations.  */
5390075Sobrien  return flag_hosted && MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl));
5490075Sobrien}
5590075Sobrien
5690075Sobrien/* We want to inline `extern inline' functions even if this would
5790075Sobrien   violate inlining limits.  Some glibc and linux constructs depend on
5890075Sobrien   such functions always being inlined when optimizing.  */
5990075Sobrien
6090075Sobrienint
6190075Sobrienc_disregard_inline_limits (fn)
6290075Sobrien     tree fn;
6390075Sobrien{
6496263Sobrien  if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
6596263Sobrien    return 1;
6696263Sobrien
6790075Sobrien  return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
6890075Sobrien}
6990075Sobrien
7090075Sobrienstatic tree
7190075Sobrieninline_forbidden_p (nodep, walk_subtrees, fn)
7290075Sobrien     tree *nodep;
7390075Sobrien     int *walk_subtrees ATTRIBUTE_UNUSED;
7490075Sobrien     void *fn;
7590075Sobrien{
7690075Sobrien  tree node = *nodep;
7790075Sobrien  tree t;
7890075Sobrien
7990075Sobrien  switch (TREE_CODE (node))
8090075Sobrien    {
8190075Sobrien    case CALL_EXPR:
8290075Sobrien      t = get_callee_fndecl (node);
8390075Sobrien
8490075Sobrien      if (! t)
8590075Sobrien	break;
8690075Sobrien
8790075Sobrien      /* We cannot inline functions that call setjmp.  */
8890075Sobrien      if (setjmp_call_p (t))
8990075Sobrien	return node;
9090075Sobrien
9190075Sobrien      switch (DECL_FUNCTION_CODE (t))
9290075Sobrien	{
9390075Sobrien	  /* We cannot inline functions that take a variable number of
9490075Sobrien	     arguments.  */
95117395Skan	case BUILT_IN_VA_START:
9690075Sobrien	case BUILT_IN_STDARG_START:
9790075Sobrien#if 0
9890075Sobrien	  /* Functions that need information about the address of the
9990075Sobrien             caller can't (shouldn't?) be inlined.  */
10090075Sobrien	case BUILT_IN_RETURN_ADDRESS:
10190075Sobrien#endif
10290075Sobrien	  return node;
10390075Sobrien
10490075Sobrien	default:
10590075Sobrien	  break;
10690075Sobrien	}
10790075Sobrien
10890075Sobrien      break;
10990075Sobrien
11090075Sobrien    case DECL_STMT:
11190075Sobrien      /* We cannot inline functions that contain other functions.  */
11290075Sobrien      if (TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
11390075Sobrien	  && DECL_INITIAL (TREE_OPERAND (node, 0)))
11490075Sobrien	return node;
11590075Sobrien      break;
11690075Sobrien
11790075Sobrien    case GOTO_STMT:
11890075Sobrien    case GOTO_EXPR:
11990075Sobrien      t = TREE_OPERAND (node, 0);
12090075Sobrien
12190075Sobrien      /* We will not inline a function which uses computed goto.  The
12290075Sobrien	 addresses of its local labels, which may be tucked into
12390075Sobrien	 global storage, are of course not constant across
124117395Skan	 instantiations, which causes unexpected behavior.  */
12590075Sobrien      if (TREE_CODE (t) != LABEL_DECL)
12690075Sobrien	return node;
12790075Sobrien
12890075Sobrien      /* We cannot inline a nested function that jumps to a nonlocal
12990075Sobrien         label.  */
13090075Sobrien      if (TREE_CODE (t) == LABEL_DECL
13190075Sobrien	  && DECL_CONTEXT (t) && DECL_CONTEXT (t) != fn)
13290075Sobrien	return node;
13390075Sobrien
13490075Sobrien      break;
13590075Sobrien
136107590Sobrien    case RECORD_TYPE:
137107590Sobrien    case UNION_TYPE:
138107590Sobrien      /* We cannot inline a function of the form
139107590Sobrien
140107590Sobrien	   void F (int i) { struct S { int ar[i]; } s; }
141107590Sobrien
142107590Sobrien	 Attempting to do so produces a catch-22 in tree-inline.c.
143107590Sobrien	 If walk_tree examines the TYPE_FIELDS chain of RECORD_TYPE/
144107590Sobrien	 UNION_TYPE nodes, then it goes into infinite recursion on a
145107590Sobrien	 structure containing a pointer to its own type.  If it doesn't,
146107590Sobrien	 then the type node for S doesn't get adjusted properly when
147107590Sobrien	 F is inlined, and we abort in find_function_data.  */
148107590Sobrien      for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
149107590Sobrien	if (variably_modified_type_p (TREE_TYPE (t)))
150107590Sobrien	  return node;
151107590Sobrien
15290075Sobrien    default:
15390075Sobrien      break;
15490075Sobrien    }
15590075Sobrien
15690075Sobrien  return NULL_TREE;
15790075Sobrien}
15890075Sobrien
15990075Sobrienint
16090075Sobrienc_cannot_inline_tree_fn (fnp)
16190075Sobrien     tree *fnp;
16290075Sobrien{
16390075Sobrien  tree fn = *fnp;
16490075Sobrien  tree t;
16590075Sobrien
16696263Sobrien  if (flag_really_no_inline
16796263Sobrien      && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
16896263Sobrien    return 1;
16996263Sobrien
170104752Skan  /* Don't auto-inline anything that might not be bound within
171104752Skan     this unit of translation.  */
172117395Skan  if (!DECL_DECLARED_INLINE_P (fn) && !(*targetm.binds_local_p) (fn))
173117395Skan    goto cannot_inline;
174104752Skan
17590075Sobrien  if (! function_attribute_inlinable_p (fn))
176117395Skan    goto cannot_inline;
17790075Sobrien
17890075Sobrien  /* If a function has pending sizes, we must not defer its
17990075Sobrien     compilation, and we can't inline it as a tree.  */
18090075Sobrien  if (fn == current_function_decl)
18190075Sobrien    {
18290075Sobrien      t = get_pending_sizes ();
18390075Sobrien      put_pending_sizes (t);
18490075Sobrien
18590075Sobrien      if (t)
186117395Skan	goto cannot_inline;
18790075Sobrien    }
18890075Sobrien
18990075Sobrien  if (DECL_CONTEXT (fn))
19090075Sobrien    {
19190075Sobrien      /* If a nested function has pending sizes, we may have already
19290075Sobrien         saved them.  */
19390075Sobrien      if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
194117395Skan	goto cannot_inline;
19590075Sobrien    }
19690075Sobrien  else
19790075Sobrien    {
19890075Sobrien      /* We rely on the fact that this function is called upfront,
19990075Sobrien	 just before we start expanding a function.  If FN is active
20090075Sobrien	 (i.e., it's the current_function_decl or a parent thereof),
20190075Sobrien	 we have to walk FN's saved tree.  Otherwise, we can safely
20290075Sobrien	 assume we have done it before and, if we didn't mark it as
20390075Sobrien	 uninlinable (in which case we wouldn't have been called), it
20490075Sobrien	 is inlinable.  Unfortunately, this strategy doesn't work for
20590075Sobrien	 nested functions, because they're only expanded as part of
20690075Sobrien	 their enclosing functions, so the inlinability test comes in
20790075Sobrien	 late.  */
20890075Sobrien      t = current_function_decl;
20990075Sobrien
21090075Sobrien      while (t && t != fn)
21190075Sobrien	t = DECL_CONTEXT (t);
21290075Sobrien      if (! t)
21390075Sobrien	return 0;
21490075Sobrien    }
21590075Sobrien
216117395Skan  if (walk_tree_without_duplicates
217117395Skan	(&DECL_SAVED_TREE (fn), inline_forbidden_p, fn))
218117395Skan    goto cannot_inline;
21990075Sobrien
22090075Sobrien  return 0;
221117395Skan
222117395Skan cannot_inline:
223117395Skan  DECL_UNINLINABLE (fn) = 1;
224117395Skan  return 1;
22590075Sobrien}
22690075Sobrien
227117395Skan/* Called from check_global_declarations.  */
228117395Skan
229117395Skanbool
230117395Skanc_warn_unused_global_decl (decl)
231117395Skan     tree decl;
232117395Skan{
233117395Skan  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
234117395Skan    return false;
235117395Skan  if (DECL_IN_SYSTEM_HEADER (decl))
236117395Skan    return false;
237117395Skan
238117395Skan  return true;
239117395Skan}
240117395Skan
24190075Sobrien/* Initialization common to C and Objective-C front ends.  */
24290075Sobrienconst char *
24390075Sobrienc_objc_common_init (filename)
24490075Sobrien     const char *filename;
24590075Sobrien{
24690075Sobrien  c_init_decl_processing ();
24790075Sobrien
24890075Sobrien  filename = c_common_init (filename);
249117395Skan  if (filename == NULL)
250117395Skan    return NULL;
25190075Sobrien
25290075Sobrien  lang_expand_decl_stmt = c_expand_decl_stmt;
25390075Sobrien
25490075Sobrien  /* These were not defined in the Objective-C front end, but I'm
25590075Sobrien     putting them here anyway.  The diagnostic format decoder might
25690075Sobrien     want an enhanced ObjC implementation.  */
25790075Sobrien  diagnostic_format_decoder (global_dc) = &c_tree_printer;
25890075Sobrien  lang_missing_noreturn_ok_p = &c_missing_noreturn_ok_p;
25990075Sobrien
26090075Sobrien  /* If still unspecified, make it match -std=c99
26190075Sobrien     (allowing for -pedantic-errors).  */
26290075Sobrien  if (mesg_implicit_function_declaration < 0)
26390075Sobrien    {
26490075Sobrien      if (flag_isoc99)
26590075Sobrien	mesg_implicit_function_declaration = flag_pedantic_errors ? 2 : 1;
26690075Sobrien      else
26790075Sobrien	mesg_implicit_function_declaration = 0;
26890075Sobrien    }
26990075Sobrien
27090075Sobrien  VARRAY_TREE_INIT (deferred_fns, 32, "deferred_fns");
27190075Sobrien
27290075Sobrien  return filename;
27390075Sobrien}
27490075Sobrien
27590075Sobrien/* Register a function tree, so that its optimization and conversion
27690075Sobrien   to RTL is only done at the end of the compilation.  */
27790075Sobrien
27890075Sobrienint
27990075Sobriendefer_fn (fn)
28090075Sobrien     tree fn;
28190075Sobrien{
28290075Sobrien  VARRAY_PUSH_TREE (deferred_fns, fn);
28390075Sobrien
28490075Sobrien  return 1;
28590075Sobrien}
28690075Sobrien
28790075Sobrien/* Expand deferred functions for C and ObjC.  */
28890075Sobrien
28990075Sobrienstatic void
29090075Sobrienexpand_deferred_fns ()
29190075Sobrien{
29290075Sobrien  unsigned int i;
29390075Sobrien
29490075Sobrien  for (i = 0; i < VARRAY_ACTIVE_SIZE (deferred_fns); i++)
29590075Sobrien    {
29690075Sobrien      tree decl = VARRAY_TREE (deferred_fns, i);
29790075Sobrien
29890075Sobrien      if (! TREE_ASM_WRITTEN (decl))
29990075Sobrien	{
30090075Sobrien	  /* For static inline functions, delay the decision whether to
30190075Sobrien	     emit them or not until wrapup_global_declarations.  */
30290075Sobrien	  if (! TREE_PUBLIC (decl))
30390075Sobrien	    DECL_DEFER_OUTPUT (decl) = 1;
30490075Sobrien	  c_expand_deferred_function (decl);
30590075Sobrien	}
30690075Sobrien    }
30790075Sobrien
308117395Skan  deferred_fns = 0;
30990075Sobrien}
31090075Sobrien
31190075Sobrienstatic tree
31290075Sobrienstart_cdtor (method_type)
31390075Sobrien     int method_type;
31490075Sobrien{
31590075Sobrien  tree fnname = get_file_function_name (method_type);
31690075Sobrien  tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
31790075Sobrien  tree body;
31890075Sobrien
31990075Sobrien  start_function (void_list_node_1,
32090075Sobrien		  build_nt (CALL_EXPR, fnname,
32190075Sobrien			    tree_cons (NULL_TREE, NULL_TREE, void_list_node_1),
32290075Sobrien			    NULL_TREE),
32390075Sobrien		  NULL_TREE);
32490075Sobrien  store_parm_decls ();
32590075Sobrien
32690075Sobrien  current_function_cannot_inline
32790075Sobrien    = "static constructors and destructors cannot be inlined";
32890075Sobrien
32990075Sobrien  body = c_begin_compound_stmt ();
33090075Sobrien
33190075Sobrien  pushlevel (0);
33290075Sobrien  clear_last_expr ();
33390075Sobrien  add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
33490075Sobrien
33590075Sobrien  return body;
33690075Sobrien}
33790075Sobrien
33890075Sobrienstatic void
33990075Sobrienfinish_cdtor (body)
34090075Sobrien     tree body;
34190075Sobrien{
34290075Sobrien  tree scope;
34390075Sobrien  tree block;
34490075Sobrien
34590075Sobrien  scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
34690075Sobrien  block = poplevel (0, 0, 0);
34790075Sobrien  SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
34890075Sobrien  SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
34990075Sobrien
35090075Sobrien  RECHAIN_STMTS (body, COMPOUND_BODY (body));
35190075Sobrien
35296263Sobrien  finish_function (0, 0);
35390075Sobrien}
35490075Sobrien
35590075Sobrien/* Called at end of parsing, but before end-of-file processing.  */
35690075Sobrien
35790075Sobrienvoid
35890075Sobrienc_objc_common_finish_file ()
35990075Sobrien{
36090075Sobrien  expand_deferred_fns ();
36190075Sobrien
36290075Sobrien  if (static_ctors)
36390075Sobrien    {
36490075Sobrien      tree body = start_cdtor ('I');
36590075Sobrien
36690075Sobrien      for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
36790075Sobrien	c_expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
36890075Sobrien						 NULL_TREE));
36990075Sobrien
37090075Sobrien      finish_cdtor (body);
37190075Sobrien    }
37290075Sobrien
37390075Sobrien  if (static_dtors)
37490075Sobrien    {
37590075Sobrien      tree body = start_cdtor ('D');
37690075Sobrien
37790075Sobrien      for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
37890075Sobrien	c_expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
37990075Sobrien						 NULL_TREE));
38090075Sobrien
38190075Sobrien      finish_cdtor (body);
38290075Sobrien    }
38390075Sobrien
38490075Sobrien  {
38590075Sobrien    int flags;
38690075Sobrien    FILE *stream = dump_begin (TDI_all, &flags);
38790075Sobrien
38890075Sobrien    if (stream)
38990075Sobrien      {
39090075Sobrien	dump_node (getdecls (), flags & ~TDF_SLIM, stream);
39190075Sobrien	dump_end (TDI_all, stream);
39290075Sobrien      }
39390075Sobrien  }
39490075Sobrien}
39590075Sobrien
39690075Sobrien/* Called during diagnostic message formatting process to print a
39790075Sobrien   source-level entity onto BUFFER.  The meaning of the format specifiers
39890075Sobrien   is as follows:
39990075Sobrien   %D: a general decl,
40090075Sobrien   %F: a function declaration,
40190075Sobrien   %T: a type.
40290075Sobrien
40390075Sobrien   These format specifiers form a subset of the format specifiers set used
40490075Sobrien   by the C++ front-end.
40590075Sobrien   Please notice when called, the `%' part was already skipped by the
40690075Sobrien   diagnostic machinery.  */
407117395Skanstatic bool
408117395Skanc_tree_printer (buffer, text)
40990075Sobrien     output_buffer *buffer;
410117395Skan     text_info *text;
41190075Sobrien{
412117395Skan  tree t = va_arg (*text->args_ptr, tree);
41390075Sobrien
414117395Skan  switch (*text->format_spec)
41590075Sobrien    {
41690075Sobrien    case 'D':
41790075Sobrien    case 'F':
41890075Sobrien    case 'T':
41990075Sobrien      {
42090075Sobrien        const char *n = DECL_NAME (t)
421117395Skan          ? (*lang_hooks.decl_printable_name) (t, 2)
42290075Sobrien          : "({anonymous})";
42390075Sobrien        output_add_string (buffer, n);
42490075Sobrien      }
425117395Skan      return true;
42690075Sobrien
42790075Sobrien    default:
428117395Skan      return false;
42990075Sobrien    }
43090075Sobrien}
431117395Skan
432117395Skan#include "gt-c-objc-common.h"
433