1276607Snp/* Some code common to C and ObjC front ends.
2276598Snp   Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
3276598Snp
4276598SnpThis file is part of GCC.
5276598Snp
6276598SnpGCC is free software; you can redistribute it and/or modify it under
7276598Snpthe terms of the GNU General Public License as published by the Free
8276598SnpSoftware Foundation; either version 2, or (at your option) any later
9276598Snpversion.
10276598Snp
11276598SnpGCC is distributed in the hope that it will be useful, but WITHOUT ANY
12276598SnpWARRANTY; without even the implied warranty of MERCHANTABILITY or
13276598SnpFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14276598Snpfor more details.
15276598Snp
16276598SnpYou should have received a copy of the GNU General Public License
17276598Snpalong with GCC; see the file COPYING.  If not, write to the Free
18276598SnpSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19276598Snp02110-1301, USA.  */
20276598Snp
21276598Snp#include "config.h"
22276598Snp#include "system.h"
23276598Snp#include "coretypes.h"
24276598Snp#include "tm.h"
25276598Snp#include "tree.h"
26276598Snp#include "rtl.h"
27276598Snp#include "insn-config.h"
28276598Snp#include "integrate.h"
29276598Snp#include "c-tree.h"
30276598Snp#include "c-pretty-print.h"
31276598Snp#include "function.h"
32276598Snp#include "flags.h"
33276598Snp#include "toplev.h"
34319390Sngie#include "diagnostic.h"
35276598Snp#include "tree-inline.h"
36276598Snp#include "varray.h"
37276598Snp#include "ggc.h"
38276598Snp#include "langhooks.h"
39276598Snp#include "tree-mudflap.h"
40276598Snp#include "target.h"
41276598Snp#include "c-objc-common.h"
42276598Snp
43276598Snpstatic bool c_tree_printer (pretty_printer *, text_info *, const char *,
44276598Snp			    int, bool, bool, bool);
45276598Snp
46276598Snpbool
47276598Snpc_missing_noreturn_ok_p (tree decl)
48276598Snp{
49276598Snp  /* A missing noreturn is not ok for freestanding implementations and
50276598Snp     ok for the `main' function in hosted implementations.  */
51276598Snp  return flag_hosted && MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl));
52276598Snp}
53276598Snp
54276598Snp/* We want to inline `extern inline' functions even if this would
55276598Snp   violate inlining limits.  Some glibc and linux constructs depend on
56276598Snp   such functions always being inlined when optimizing.  */
57276598Snp
58276598Snpint
59306823Snpc_disregard_inline_limits (tree fn)
60306823Snp{
61306823Snp  if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
62306823Snp    return 1;
63276598Snp
64276598Snp  return (!flag_really_no_inline && DECL_DECLARED_INLINE_P (fn)
65276598Snp	  && DECL_EXTERNAL (fn));
66276598Snp}
67276598Snp
68276598Snpint
69276598Snpc_cannot_inline_tree_fn (tree *fnp)
70276598Snp{
71276598Snp  tree fn = *fnp;
72276598Snp  bool do_warning = (warn_inline
73276598Snp		     && DECL_INLINE (fn)
74276598Snp		     && DECL_DECLARED_INLINE_P (fn)
75276598Snp		     && !DECL_IN_SYSTEM_HEADER (fn));
76276598Snp
77276598Snp  if (flag_really_no_inline
78276598Snp      && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
79276598Snp    {
80276598Snp      if (do_warning)
81276598Snp	warning (OPT_Winline, "function %q+F can never be inlined because it "
82276598Snp		 "is suppressed using -fno-inline", fn);
83276598Snp      goto cannot_inline;
84276598Snp    }
85276598Snp
86276598Snp  /* Don't auto-inline anything that might not be bound within
87276598Snp     this unit of translation.  */
88276598Snp  if (!DECL_DECLARED_INLINE_P (fn) && !targetm.binds_local_p (fn))
89276598Snp    {
90276598Snp      if (do_warning)
91276598Snp	warning (OPT_Winline, "function %q+F can never be inlined because it "
92276598Snp		 "might not be bound within this unit of translation", fn);
93276598Snp      goto cannot_inline;
94276598Snp    }
95276598Snp
96276598Snp  if (!function_attribute_inlinable_p (fn))
97276598Snp    {
98276598Snp      if (do_warning)
99276598Snp	warning (OPT_Winline, "function %q+F can never be inlined because it "
100276607Snp		 "uses attributes conflicting with inlining", fn);
101276598Snp      goto cannot_inline;
102276598Snp    }
103276598Snp
104276598Snp  return 0;
105276598Snp
106276598Snp cannot_inline:
107276598Snp  DECL_UNINLINABLE (fn) = 1;
108276598Snp  return 1;
109276598Snp}
110276598Snp
111276598Snp/* Called from check_global_declarations.  */
112276598Snp
113276598Snpbool
114276598Snpc_warn_unused_global_decl (tree decl)
115276598Snp{
116276598Snp  if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
117276598Snp    return false;
118276598Snp  if (DECL_IN_SYSTEM_HEADER (decl))
119276598Snp    return false;
120276598Snp
121276598Snp  return true;
122276598Snp}
123276598Snp
124276598Snp/* Initialization common to C and Objective-C front ends.  */
125276598Snpbool
126276598Snpc_objc_common_init (void)
127276598Snp{
128276598Snp  c_init_decl_processing ();
129276598Snp
130276598Snp  if (c_common_init () == false)
131276598Snp    return false;
132276598Snp
133276598Snp  /* These were not defined in the Objective-C front end, but I'm
134276598Snp     putting them here anyway.  The diagnostic format decoder might
135276598Snp     want an enhanced ObjC implementation.  */
136319390Sngie  diagnostic_format_decoder (global_dc) = &c_tree_printer;
137319390Sngie
138276598Snp  /* If still unspecified, make it match -std=c99
139276598Snp     (allowing for -pedantic-errors).  */
140276598Snp  if (mesg_implicit_function_declaration < 0)
141276598Snp    {
142276598Snp      if (flag_isoc99)
143276598Snp	mesg_implicit_function_declaration = flag_pedantic_errors ? 2 : 1;
144276598Snp      else
145276598Snp	mesg_implicit_function_declaration = 0;
146276598Snp    }
147276598Snp
148276598Snp  return true;
149276598Snp}
150276598Snp
151276598Snp/* Called during diagnostic message formatting process to print a
152276598Snp   source-level entity onto BUFFER.  The meaning of the format specifiers
153276598Snp   is as follows:
154276598Snp   %D: a general decl,
155276598Snp   %E: an identifier or expression,
156276598Snp   %F: a function declaration,
157276598Snp   %T: a type.
158276598Snp
159276598Snp   These format specifiers form a subset of the format specifiers set used
160276598Snp   by the C++ front-end.
161276598Snp   Please notice when called, the `%' part was already skipped by the
162276598Snp   diagnostic machinery.  */
163276598Snpstatic bool
164276598Snpc_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
165276598Snp		int precision, bool wide, bool set_locus, bool hash)
166276598Snp{
167276598Snp  tree t = va_arg (*text->args_ptr, tree);
168276598Snp  tree name;
169276598Snp  const char *n = "({anonymous})";
170276598Snp  c_pretty_printer *cpp = (c_pretty_printer *) pp;
171276598Snp  pp->padding = pp_none;
172276598Snp
173276598Snp  if (precision != 0 || wide || hash)
174276598Snp    return false;
175276598Snp
176276598Snp  if (set_locus && text->locus)
177276598Snp    *text->locus = DECL_SOURCE_LOCATION (t);
178276598Snp
179276598Snp  switch (*spec)
180276598Snp    {
181276598Snp    case 'D':
182276598Snp      if (DECL_DEBUG_EXPR_IS_FROM (t) && DECL_DEBUG_EXPR (t))
183276598Snp	{
184276598Snp	  t = DECL_DEBUG_EXPR (t);
185276598Snp	  if (!DECL_P (t))
186276598Snp	    {
187276598Snp	      pp_c_expression (cpp, t);
188276598Snp	      return true;
189276598Snp	    }
190276598Snp	}
191276598Snp      /* FALLTHRU */
192276598Snp
193276598Snp    case 'F':
194276598Snp      if (DECL_NAME (t))
195276598Snp	n = lang_hooks.decl_printable_name (t, 2);
196276598Snp      break;
197276598Snp
198276598Snp    case 'T':
199276598Snp      gcc_assert (TYPE_P (t));
200276598Snp      name = TYPE_NAME (t);
201276598Snp
202276598Snp      if (name && TREE_CODE (name) == TYPE_DECL)
203276598Snp	{
204276598Snp	  if (DECL_NAME (name))
205276598Snp	    pp_string (cpp, lang_hooks.decl_printable_name (name, 2));
206276598Snp	  else
207276598Snp	    pp_type_id (cpp, t);
208276598Snp	  return true;
209276598Snp	}
210276598Snp      else
211276598Snp	{
212276598Snp	  pp_type_id (cpp, t);
213276598Snp	  return true;
214276598Snp	}
215276598Snp      break;
216276598Snp
217276598Snp    case 'E':
218276598Snp      if (TREE_CODE (t) == IDENTIFIER_NODE)
219276598Snp	n = IDENTIFIER_POINTER (t);
220276598Snp      else
221276598Snp	{
222276598Snp	  pp_expression (cpp, t);
223276598Snp	  return true;
224276598Snp	}
225276598Snp      break;
226276598Snp
227276598Snp    default:
228276598Snp      return false;
229276598Snp    }
230276598Snp
231276598Snp  pp_string (cpp, n);
232276598Snp  return true;
233276598Snp}
234276598Snp
235276598Snp/* In C and ObjC, all decls have "C" linkage.  */
236276598Snpbool
237276598Snphas_c_linkage (tree decl ATTRIBUTE_UNUSED)
238276598Snp{
239276598Snp  return true;
240276598Snp}
241276598Snp
242276598Snpvoid
243276598Snpc_initialize_diagnostics (diagnostic_context *context)
244276598Snp{
245276598Snp  pretty_printer *base = context->printer;
246276598Snp  c_pretty_printer *pp = XNEW (c_pretty_printer);
247276598Snp  memcpy (pp_base (pp), base, sizeof (pretty_printer));
248276598Snp  pp_c_pretty_printer_init (pp);
249276598Snp  context->printer = (pretty_printer *) pp;
250276598Snp
251276598Snp  /* It is safe to free this object because it was previously XNEW()'d.  */
252276598Snp  XDELETE (base);
253276598Snp}
254276598Snp
255276598Snpint
256276598Snpc_types_compatible_p (tree x, tree y)
257276598Snp{
258276598Snp    return comptypes (TYPE_MAIN_VARIANT (x), TYPE_MAIN_VARIANT (y));
259276598Snp}
260276598Snp
261276598Snp/* Determine if the type is a vla type for the backend.  */
262276598Snp
263276598Snpbool
264276598Snpc_vla_unspec_p (tree x, tree fn ATTRIBUTE_UNUSED)
265276598Snp{
266276598Snp  return c_vla_type_p (x);
267276598Snp}
268276598Snp