OSDN Git Service

* langhooks.h: New file.
[pf3gnuchains/gcc-fork.git] / gcc / c-lang.c
1 /* Language-specific hook definitions for C front end.
2    Copyright (C) 1991, 1995, 1997, 1998,
3    1999, 2000, 2001 Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22
23 #include "config.h"
24 #include "system.h"
25 #include "tree.h"
26 #include "tree-inline.h"
27 #include "function.h"
28 #include "input.h"
29 #include "toplev.h"
30 #include "diagnostic.h"
31 #include "output.h"
32 #include "flags.h"
33 #include "ggc.h"
34 #include "rtl.h"
35 #include "expr.h"
36 #include "c-tree.h"
37 #include "c-lex.h"
38 #include "cpplib.h"
39 #include "insn-config.h"
40 #include "integrate.h"
41 #include "langhooks.h"
42
43 static int c_tree_printer PARAMS ((output_buffer *));
44 static int c_missing_noreturn_ok_p PARAMS ((tree));
45 static void c_init PARAMS ((void));
46 static void c_init_options PARAMS ((void));
47 static void c_post_options PARAMS ((void));
48 static int c_disregard_inline_limits PARAMS ((tree));
49 static int c_cannot_inline_tree_fn PARAMS ((tree *));
50
51 #undef LANG_HOOKS_INIT
52 #define LANG_HOOKS_INIT c_init
53 #undef LANG_HOOKS_INIT_OPTIONS
54 #define LANG_HOOKS_INIT_OPTIONS c_init_options
55 #undef LANG_HOOKS_DECODE_OPTION
56 #define LANG_HOOKS_DECODE_OPTION c_decode_option
57 #undef LANG_HOOKS_POST_OPTIONS
58 #define LANG_HOOKS_POST_OPTIONS c_post_options
59 #undef LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN
60 #define LANG_HOOKS_TREE_INLINING_CANNOT_INLINE_TREE_FN \
61   c_cannot_inline_tree_fn
62 #undef LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS
63 #define LANG_HOOKS_TREE_INLINING_DISREGARD_INLINE_LIMITS \
64   c_disregard_inline_limits
65 #undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P
66 #define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P \
67   anon_aggr_type_p
68
69 /* Each front end provides its own.  */
70 struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
71
72 /* Post-switch processing.  */
73 static void
74 c_post_options ()
75 {
76   cpp_post_options (parse_in);
77
78   /* Use tree inlining if possible.  Function instrumentation is only
79      done in the RTL level, so we disable tree inlining.  */
80   if (! flag_instrument_function_entry_exit)
81     {
82       if (!flag_no_inline)
83         {
84           flag_inline_trees = 1;
85           flag_no_inline = 1;
86         }
87       if (flag_inline_functions)
88         {
89           flag_inline_trees = 2;
90           flag_inline_functions = 0;
91         }
92     }
93 }
94
95 static void
96 c_init_options ()
97 {
98   /* Make identifier nodes long enough for the language-specific slots.  */
99   set_identifier_size (sizeof (struct lang_identifier));
100
101   parse_in = cpp_create_reader (ident_hash, CLK_GNUC89);
102
103   /* Mark as "unspecified".  */
104   flag_bounds_check = -1;
105 }
106
107 static void
108 c_init ()
109 {
110   c_common_lang_init ();
111
112   /* If still unspecified, make it match -std=c99
113      (allowing for -pedantic-errors).  */
114   if (mesg_implicit_function_declaration < 0)
115     {
116       if (flag_isoc99)
117         mesg_implicit_function_declaration = flag_pedantic_errors ? 2 : 1;
118       else
119         mesg_implicit_function_declaration = 0;
120     }
121
122   save_lang_status = &push_c_function_context;
123   restore_lang_status = &pop_c_function_context;
124   mark_lang_status = &mark_c_function_context;
125   lang_expand_expr = &c_expand_expr;
126   lang_safe_from_p = &c_safe_from_p;
127   diagnostic_format_decoder (global_dc) = &c_tree_printer;
128   lang_expand_decl_stmt = &c_expand_decl_stmt;
129   lang_missing_noreturn_ok_p = &c_missing_noreturn_ok_p;
130
131   c_parse_init ();
132 }
133
134 const char *
135 lang_identify ()
136 {
137   return "c";
138 }
139
140 void
141 print_lang_statistics ()
142 {
143 }
144
145 /* used by print-tree.c */
146
147 void
148 lang_print_xnode (file, node, indent)
149      FILE *file ATTRIBUTE_UNUSED;
150      tree node ATTRIBUTE_UNUSED;
151      int indent ATTRIBUTE_UNUSED;
152 {
153 }
154
155 /* Used by c-lex.c, but only for objc.  */
156
157 tree
158 lookup_interface (arg)
159      tree arg ATTRIBUTE_UNUSED;
160 {
161   return 0;
162 }
163
164 tree
165 is_class_name (arg)
166     tree arg ATTRIBUTE_UNUSED;
167 {
168   return 0;
169 }
170
171 void
172 maybe_objc_check_decl (decl)
173      tree decl ATTRIBUTE_UNUSED;
174 {
175 }
176
177 int
178 maybe_objc_comptypes (lhs, rhs, reflexive)
179      tree lhs ATTRIBUTE_UNUSED;
180      tree rhs ATTRIBUTE_UNUSED;
181      int reflexive ATTRIBUTE_UNUSED;
182 {
183   return -1;
184 }
185
186 tree
187 maybe_building_objc_message_expr ()
188 {
189   return 0;
190 }
191
192 int
193 recognize_objc_keyword ()
194 {
195   return 0;
196 }
197
198 /* Used by c-typeck.c (build_external_ref), but only for objc.  */
199
200 tree
201 lookup_objc_ivar (id)
202      tree id ATTRIBUTE_UNUSED;
203 {
204   return 0;
205 }
206
207 #if !defined(ASM_OUTPUT_CONSTRUCTOR) || !defined(ASM_OUTPUT_DESTRUCTOR)
208 extern tree static_ctors;
209 extern tree static_dtors;
210
211 static tree start_cdtor         PARAMS ((int));
212 static void finish_cdtor        PARAMS ((tree));
213
214 static tree
215 start_cdtor (method_type)
216      int method_type;
217 {
218   tree fnname = get_file_function_name (method_type);
219   tree void_list_node_1 = build_tree_list (NULL_TREE, void_type_node);
220   tree body;
221
222   start_function (void_list_node_1,
223                   build_nt (CALL_EXPR, fnname,
224                             tree_cons (NULL_TREE, NULL_TREE, void_list_node_1),
225                             NULL_TREE),
226                   NULL_TREE);
227   store_parm_decls ();
228
229   current_function_cannot_inline
230     = "static constructors and destructors cannot be inlined";
231
232   body = c_begin_compound_stmt ();
233
234   pushlevel (0);
235   clear_last_expr ();
236   add_scope_stmt (/*begin_p=*/1, /*partial_p=*/0);
237
238   return body;
239 }
240
241 static void
242 finish_cdtor (body)
243      tree body;
244 {
245   tree scope;
246   tree block;
247
248   scope = add_scope_stmt (/*begin_p=*/0, /*partial_p=*/0);
249   block = poplevel (0, 0, 0);
250   SCOPE_STMT_BLOCK (TREE_PURPOSE (scope)) = block;
251   SCOPE_STMT_BLOCK (TREE_VALUE (scope)) = block;
252
253   RECHAIN_STMTS (body, COMPOUND_BODY (body));
254
255   finish_function (0);
256 }
257 #endif
258
259 /* Called at end of parsing, but before end-of-file processing.  */
260
261 void
262 finish_file ()
263 {
264 #ifndef ASM_OUTPUT_CONSTRUCTOR
265   if (static_ctors)
266     {
267       tree body = start_cdtor ('I');
268
269       for (; static_ctors; static_ctors = TREE_CHAIN (static_ctors))
270         c_expand_expr_stmt (build_function_call (TREE_VALUE (static_ctors),
271                                                  NULL_TREE));
272
273       finish_cdtor (body);
274     }
275 #endif
276 #ifndef ASM_OUTPUT_DESTRUCTOR
277   if (static_dtors)
278     {
279       tree body = start_cdtor ('D');
280
281       for (; static_dtors; static_dtors = TREE_CHAIN (static_dtors))
282         c_expand_expr_stmt (build_function_call (TREE_VALUE (static_dtors),
283                                                  NULL_TREE));
284
285       finish_cdtor (body);
286     }
287 #endif
288
289   if (back_end_hook)
290     (*back_end_hook) (getdecls ());
291   
292   {
293     int flags;
294     FILE *stream = dump_begin (TDI_all, &flags);
295
296     if (stream)
297       {
298         dump_node (getdecls (), flags & ~TDF_SLIM, stream);
299         dump_end (TDI_all, stream);
300       }
301   }
302 }
303
304 /* Called during diagnostic message formatting process to print a
305    source-level entity onto BUFFER.  The meaning of the format specifiers
306    is as follows:
307    %D: a general decl,
308    %F: a function declaration,
309    %T: a type.
310
311    These format specifiers form a subset of the format specifiers set used
312    by the C++ front-end.
313    Please notice when called, the `%' part was already skipped by the
314    diagnostic machinery.  */
315 static int
316 c_tree_printer (buffer)
317      output_buffer *buffer;
318 {
319   tree t = va_arg (output_buffer_format_args (buffer), tree);
320
321   switch (*output_buffer_text_cursor (buffer))
322     {
323     case 'D':
324     case 'F':
325     case 'T':
326       {
327         const char *n = DECL_NAME (t)
328           ? (*decl_printable_name) (t, 2)
329           : "({anonymous})";
330         output_add_string (buffer, n);
331       }
332       return 1;
333
334     default:
335       return 0;
336     }
337 }
338
339 static int
340 c_missing_noreturn_ok_p (decl)
341      tree decl;
342 {
343   /* A missing noreturn is not ok for freestanding implementations and
344      ok for the `main' function in hosted implementations.  */
345   return flag_hosted && MAIN_NAME_P (DECL_ASSEMBLER_NAME (decl));
346 }
347
348 /* We want to inline `extern inline' functions even if this would
349    violate inlining limits.  Some glibc and linux constructs depend on
350    such functions always being inlined when optimizing.  */
351
352 static int
353 c_disregard_inline_limits (fn)
354      tree fn;
355 {
356   return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
357 }
358
359 static tree inline_forbidden_p PARAMS ((tree *, int *, void *));
360
361 static tree
362 inline_forbidden_p (nodep, walk_subtrees, fn)
363      tree *nodep;
364      int *walk_subtrees ATTRIBUTE_UNUSED;
365      void *fn;
366 {
367   tree node = *nodep;
368   tree t;
369
370   switch (TREE_CODE (node))
371     {
372     case CALL_EXPR:
373       t = get_callee_fndecl (node);
374
375       if (! t)
376         break;
377
378       /* We cannot inline functions that call setjmp.  */
379       if (setjmp_call_p (t))
380         return node;
381
382       switch (DECL_FUNCTION_CODE (t))
383         {
384           /* We cannot inline functions that take a variable number of
385              arguments.  */
386         case BUILT_IN_VARARGS_START:
387         case BUILT_IN_STDARG_START:
388 #if 0
389           /* Functions that need information about the address of the
390              caller can't (shouldn't?) be inlined.  */
391         case BUILT_IN_RETURN_ADDRESS:
392 #endif
393           return node;
394
395         default:
396           break;
397         }
398
399       break;
400
401     case DECL_STMT:
402       /* We cannot inline functions that contain other functions.  */
403       if (TREE_CODE (TREE_OPERAND (node, 0)) == FUNCTION_DECL
404           && DECL_INITIAL (TREE_OPERAND (node, 0)))
405         return node;
406       break;
407
408     case GOTO_STMT:
409     case GOTO_EXPR:
410       t = TREE_OPERAND (node, 0);
411
412       /* We will not inline a function which uses computed goto.  The
413          addresses of its local labels, which may be tucked into
414          global storage, are of course not constant across
415          instantiations, which causes unexpected behaviour.  */
416       if (TREE_CODE (t) != LABEL_DECL)
417         return node;
418
419       /* We cannot inline a nested function that jumps to a nonlocal
420          label.  */
421       if (TREE_CODE (t) == LABEL_DECL
422           && DECL_CONTEXT (t) && DECL_CONTEXT (t) != fn)
423         return node;
424
425       break;
426
427     default:
428       break;
429     }
430
431   return NULL_TREE;
432 }
433
434 static int
435 c_cannot_inline_tree_fn (fnp)
436      tree *fnp;
437 {
438   tree fn = *fnp;
439   tree t;
440
441   if (! function_attribute_inlinable_p (fn))
442     {
443       DECL_UNINLINABLE (fn) = 1;
444       return 1;
445     }
446
447   /* If a function has pending sizes, we must not defer its
448      compilation, and we can't inline it as a tree.  */
449   if (fn == current_function_decl)
450     {
451       t = get_pending_sizes ();
452       put_pending_sizes (t);
453
454       if (t)
455         {
456           DECL_UNINLINABLE (fn) = 1;
457           return 1;
458         }
459     }
460
461   if (DECL_CONTEXT (fn))
462     {
463       /* If a nested function has pending sizes, we may have already
464          saved them.  */
465       if (DECL_LANG_SPECIFIC (fn)->pending_sizes)
466         {
467           DECL_UNINLINABLE (fn) = 1;
468           return 1;
469         }
470     }
471   else
472     {
473       /* We rely on the fact that this function is called upfront,
474          just before we start expanding a function.  If FN is active
475          (i.e., it's the current_function_decl or a parent thereof),
476          we have to walk FN's saved tree.  Otherwise, we can safely
477          assume we have done it before and, if we didn't mark it as
478          uninlinable (in which case we wouldn't have been called), it
479          is inlinable.  Unfortunately, this strategy doesn't work for
480          nested functions, because they're only expanded as part of
481          their enclosing functions, so the inlinability test comes in
482          late.  */
483       t = current_function_decl;
484
485       while (t && t != fn)
486         t = DECL_CONTEXT (t);
487       if (! t)
488         return 0;
489     }
490     
491   if (walk_tree (&DECL_SAVED_TREE (fn), inline_forbidden_p, fn, NULL))
492     {
493       DECL_UNINLINABLE (fn) = 1;
494       return 1;
495     }
496
497   return 0;
498 }