OSDN Git Service

* toplev.c (process_options, parse_options_and_default_flags):
[pf3gnuchains/gcc-fork.git] / gcc / c-objc-common.c
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
35 static int c_tree_printer PARAMS ((output_buffer *));
36 static tree inline_forbidden_p PARAMS ((tree *, int *, void *));
37
38 int
39 c_missing_noreturn_ok_p (decl)
40      tree decl;
41 {
42   /* A missing noreturn is not ok for freestanding implementations and
43      ok for the `main' function in hosted implementations.  */
44   return flag_hosted && MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl));
45 }
46
47 /* We want to inline `extern inline' functions even if this would
48    violate inlining limits.  Some glibc and linux constructs depend on
49    such functions always being inlined when optimizing.  */
50
51 int
52 c_disregard_inline_limits (fn)
53      tree fn;
54 {
55   return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
56 }
57
58 static tree
59 inline_forbidden_p (nodep, walk_subtrees, fn)
60      tree *nodep;
61      int *walk_subtrees ATTRIBUTE_UNUSED;
62      void *fn;
63 {
64   tree node = *nodep;
65   tree t;
66
67   switch (TREE_CODE (node))
68     {
69     case CALL_EXPR:
70       t = get_callee_fndecl (node);
71
72       if (! t)
73         break;
74
75       /* We cannot inline functions that call setjmp.  */
76       if (setjmp_call_p (t))
77         return node;
78
79       switch (DECL_FUNCTION_CODE (t))
80         {
81           /* We cannot inline functions that take a variable number of
82              arguments.  */
83         case BUILT_IN_VARARGS_START:
84         case BUILT_IN_STDARG_START:
85 #if 0
86           /* Functions that need information about the address of the
87              caller can't (shouldn't?) be inlined.  */
88         case BUILT_IN_RETURN_ADDRESS:
89 #endif
90           return node;
91
92         default:
93           break;
94         }
95
96       break;
97
98     case DECL_STMT:
99       /* We cannot inline functions that contain other functions.  */
100       if (TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
101           && DECL_INITIAL (TREE_OPERAND (node, 0)))
102         return node;
103       break;
104
105     case GOTO_STMT:
106     case GOTO_EXPR:
107       t = TREE_OPERAND (node, 0);
108
109       /* We will not inline a function which uses computed goto.  The
110          addresses of its local labels, which may be tucked into
111          global storage, are of course not constant across
112          instantiations, which causes unexpected behaviour.  */
113       if (TREE_CODE (t) != LABEL_DECL)
114         return node;
115
116       /* We cannot inline a nested function that jumps to a nonlocal
117          label.  */
118       if (TREE_CODE (t) == LABEL_DECL
119           && DECL_CONTEXT (t) && DECL_CONTEXT (t) != fn)
120         return node;
121
122       break;
123
124     default:
125       break;
126     }
127
128   return NULL_TREE;
129 }
130
131 int
132 c_cannot_inline_tree_fn (fnp)
133      tree *fnp;
134 {
135   tree fn = *fnp;
136   tree t;
137
138   if (! function_attribute_inlinable_p (fn))
139     {
140       DECL_UNINLINABLE (fn) = 1;
141       return 1;
142     }
143
144   /* If a function has pending sizes, we must not defer its
145      compilation, and we can't inline it as a tree.  */
146   if (fn == current_function_decl)
147     {
148       t = get_pending_sizes ();
149       put_pending_sizes (t);
150
151       if (t)
152         {
153           DECL_UNINLINABLE (fn) = 1;
154           return 1;
155         }
156     }
157
158   if (DECL_CONTEXT (fn))
159     {
160       /* If a nested function has pending sizes, we may have already
161          saved them.  */
162       if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
163         {
164           DECL_UNINLINABLE (fn) = 1;
165           return 1;
166         }
167     }
168   else
169     {
170       /* We rely on the fact that this function is called upfront,
171          just before we start expanding a function.  If FN is active
172          (i.e., it's the current_function_decl or a parent thereof),
173          we have to walk FN's saved tree.  Otherwise, we can safely
174          assume we have done it before and, if we didn't mark it as
175          uninlinable (in which case we wouldn't have been called), it
176          is inlinable.  Unfortunately, this strategy doesn't work for
177          nested functions, because they're only expanded as part of
178          their enclosing functions, so the inlinability test comes in
179          late.  */
180       t = current_function_decl;
181
182       while (t && t != fn)
183         t = DECL_CONTEXT (t);
184       if (! t)
185         return 0;
186     }
187     
188   if (walk_tree (&DECL_SAVED_TREE (fn), inline_forbidden_p, fn, NULL))
189     {
190       DECL_UNINLINABLE (fn) = 1;
191       return 1;
192     }
193
194   return 0;
195 }
196
197 /* Initialization common to C and Objective-C front ends.  */
198 const char *
199 c_objc_common_init (filename)
200      const char *filename;
201 {
202   c_init_decl_processing ();
203
204   filename = c_common_init (filename);
205
206   add_c_tree_codes ();
207
208   save_lang_status = &push_c_function_context;
209   restore_lang_status = &pop_c_function_context;
210   mark_lang_status = &mark_c_function_context;
211   lang_expand_expr = c_expand_expr;
212   lang_expand_decl_stmt = c_expand_decl_stmt;
213
214   /* These were not defined in the Objective-C front end, but I'm
215      putting them here anyway.  The diagnostic format decoder might
216      want an enhanced ObjC implementation.  */
217   diagnostic_format_decoder (global_dc) = &c_tree_printer;
218   lang_missing_noreturn_ok_p = &c_missing_noreturn_ok_p;
219
220   /* If still unspecified, make it match -std=c99
221      (allowing for -pedantic-errors).  */
222   if (mesg_implicit_function_declaration < 0)
223     {
224       if (flag_isoc99)
225         mesg_implicit_function_declaration = flag_pedantic_errors ? 2 : 1;
226       else
227         mesg_implicit_function_declaration = 0;
228     }
229
230   return filename;
231 }
232
233 /* Called during diagnostic message formatting process to print a
234    source-level entity onto BUFFER.  The meaning of the format specifiers
235    is as follows:
236    %D: a general decl,
237    %F: a function declaration,
238    %T: a type.
239
240    These format specifiers form a subset of the format specifiers set used
241    by the C++ front-end.
242    Please notice when called, the `%' part was already skipped by the
243    diagnostic machinery.  */
244 static int
245 c_tree_printer (buffer)
246      output_buffer *buffer;
247 {
248   tree t = va_arg (output_buffer_format_args (buffer), tree);
249
250   switch (*output_buffer_text_cursor (buffer))
251     {
252     case 'D':
253     case 'F':
254     case 'T':
255       {
256         const char *n = DECL_NAME (t)
257           ? (*decl_printable_name) (t, 2)
258           : "({anonymous})";
259         output_add_string (buffer, n);
260       }
261       return 1;
262
263     default:
264       return 0;
265     }
266 }