OSDN Git Service

* Make-lang.in, boehm.c, buffer.c,
[pf3gnuchains/gcc-fork.git] / gcc / java / lang.c
1 /* Java(TM) language-specific utility routines.
2    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3    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
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License 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
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. 
21
22 Java and all Java-based marks are trademarks or registered trademarks
23 of Sun Microsystems, Inc. in the United States and other countries.
24 The Free Software Foundation is independent of Sun Microsystems, Inc.  */
25
26 /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
27
28 #include "config.h"
29 #include "system.h"
30 #include "coretypes.h"
31 #include "tm.h"
32 #include "tree.h"
33 #include "input.h"
34 #include "rtl.h"
35 #include "expr.h"
36 #include "java-tree.h"
37 #include "jcf.h"
38 #include "toplev.h"
39 #include "langhooks.h"
40 #include "langhooks-def.h"
41 #include "flags.h"
42 #include "xref.h"
43 #include "ggc.h"
44 #include "diagnostic.h"
45 #include "tree-inline.h"
46 #include "splay-tree.h"
47 #include "tree-dump.h"
48
49 struct string_option
50 {
51   const char *const string;
52   int *const variable;
53   const int on_value;
54 };
55
56 static const char *java_init PARAMS ((const char *));
57 static void java_finish PARAMS ((void));
58 static void java_init_options PARAMS ((void));
59 static bool java_post_options PARAMS ((void));
60
61 static int java_decode_option PARAMS ((int, char **));
62 static void put_decl_string PARAMS ((const char *, int));
63 static void put_decl_node PARAMS ((tree));
64 static void java_print_error_function PARAMS ((diagnostic_context *,
65                                                const char *));
66 static int process_option_with_no PARAMS ((const char *,
67                                            const struct string_option *,
68                                            int));
69 static tree java_tree_inlining_walk_subtrees PARAMS ((tree *,
70                                                       int *,
71                                                       walk_tree_fn,
72                                                       void *,
73                                                       void *));
74 static int java_unsafe_for_reeval PARAMS ((tree));
75 static int merge_init_test_initialization PARAMS ((void * *, 
76                                                    void *));
77 static int inline_init_test_initialization PARAMS ((void * *, 
78                                                     void *));
79 static bool java_can_use_bit_fields_p PARAMS ((void));
80 static int java_dump_tree PARAMS ((void *, tree));
81
82 #ifndef TARGET_OBJECT_SUFFIX
83 # define TARGET_OBJECT_SUFFIX ".o"
84 #endif
85
86 /* Table indexed by tree code giving a string containing a character
87    classifying the tree code.  Possibilities are
88    t, d, s, c, r, <, 1 and 2.  See java/java-tree.def for details.  */
89
90 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
91
92 const char tree_code_type[] = {
93 #include "tree.def"
94   'x',
95 #include "java-tree.def"
96 };
97 #undef DEFTREECODE
98
99 /* Table indexed by tree code giving number of expression
100    operands beyond the fixed part of the node structure.
101    Not used for types or decls.  */
102
103 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
104
105 const unsigned char tree_code_length[] = {
106 #include "tree.def"
107   0,
108 #include "java-tree.def"
109 };
110 #undef DEFTREECODE
111
112 /* Names of tree components.
113    Used for printing out the tree and error messages.  */
114 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
115
116 const char *const tree_code_name[] = {
117 #include "tree.def"
118   "@@dummy",
119 #include "java-tree.def"
120 };
121 #undef DEFTREECODE
122
123 /* Used to avoid printing error messages with bogus function
124    prototypes.  Starts out false.  */
125 static bool inhibit_error_function_printing;
126
127 int compiling_from_source;
128
129 char * resource_name;
130
131 int flag_emit_class_files = 0;
132
133 /* Nonzero if input file is a file with a list of filenames to compile. */
134
135 int flag_filelist_file = 0;
136
137 /* When nonzero, we emit xref strings. Values of the flag for xref
138    backends are defined in xref_flag_table, xref.c.  */
139
140 int flag_emit_xref = 0;
141
142 /* When nonzero, -Wall was turned on.  */
143 int flag_wall = 0;
144
145 /* When nonzero, check for redundant modifier uses.  */
146 int flag_redundant = 0;
147
148 /* When nonzero, call a library routine to do integer divisions. */
149 int flag_use_divide_subroutine = 1;
150
151 /* When nonzero, generate code for the Boehm GC.  */
152 int flag_use_boehm_gc = 0;
153
154 /* When nonzero, assume the runtime uses a hash table to map an
155    object to its synchronization structure.  */
156 int flag_hash_synchronization;
157
158 /* When nonzero, permit the use of the assert keyword.  */
159 int flag_assert = 1;
160
161 /* When nonzero, assume all native functions are implemented with
162    JNI, not CNI.  */
163 int flag_jni = 0;
164
165 /* When nonzero, warn when source file is newer than matching class
166    file.  */
167 int flag_newer = 1;
168
169 /* When nonzero, generate checks for references to NULL.  */
170 int flag_check_references = 0;
171
172 /* The encoding of the source file.  */
173 const char *current_encoding = NULL;
174
175 /* When nonzero, report the now deprecated empty statements.  */
176 int flag_extraneous_semicolon;
177
178 /* When nonzero, always check for a non gcj generated classes archive.  */
179 int flag_force_classes_archive_check;
180
181 /* When zero, don't optimize static class initialization. This flag shouldn't
182    be tested alone, use STATIC_CLASS_INITIALIZATION_OPTIMIZATION_P instead.  */
183 int flag_optimize_sci = 1;
184
185 /* When nonzero, use offset tables for virtual method calls
186    in order to improve binary compatibility. */
187 int flag_indirect_dispatch = 0;
188
189 /* When zero, don't generate runtime array store checks. */
190 int flag_store_check = 1;
191
192 /* When nonzero, print extra version information.  */
193 static int version_flag = 0;
194
195 /* Set nonzero if the user specified -finline-functions on the command
196    line.  */
197 int flag_really_inline = 0;
198
199 /* Table of language-dependent -f options.
200    STRING is the option name.  VARIABLE is the address of the variable.
201    ON_VALUE is the value to store in VARIABLE
202     if `-fSTRING' is seen as an option.
203    (If `-fno-STRING' is seen as an option, the opposite value is stored.)  */
204
205 static const struct string_option
206 lang_f_options[] =
207 {
208   {"emit-class-file", &flag_emit_class_files, 1},
209   {"emit-class-files", &flag_emit_class_files, 1},
210   {"filelist-file", &flag_filelist_file, 1},
211   {"use-divide-subroutine", &flag_use_divide_subroutine, 1},
212   {"use-boehm-gc", &flag_use_boehm_gc, 1},
213   {"hash-synchronization", &flag_hash_synchronization, 1},
214   {"jni", &flag_jni, 1},
215   {"check-references", &flag_check_references, 1},
216   {"force-classes-archive-check", &flag_force_classes_archive_check, 1},
217   {"optimize-static-class-initialization", &flag_optimize_sci, 1 },
218   {"indirect-dispatch", &flag_indirect_dispatch, 1},
219   {"store-check", &flag_store_check, 1},
220   {"assert", &flag_assert, 1}
221 };
222
223 static const struct string_option
224 lang_W_options[] =
225 {
226   { "redundant-modifiers", &flag_redundant, 1 },
227   { "extraneous-semicolon", &flag_extraneous_semicolon, 1 },
228   { "out-of-date", &flag_newer, 1 }
229 };
230
231 JCF *current_jcf;
232
233 /* Variable controlling how dependency tracking is enabled in
234    java_init.  */
235 static int dependency_tracking = 0;
236
237 /* Flag values for DEPENDENCY_TRACKING.  */
238 #define DEPEND_SET_FILE 1
239 #define DEPEND_ENABLE   2
240 #define DEPEND_TARGET_SET 4
241 #define DEPEND_FILE_ALREADY_SET 8
242
243 struct language_function GTY(())
244 {
245   int unused;
246 };
247
248 #undef LANG_HOOKS_NAME
249 #define LANG_HOOKS_NAME "GNU Java"
250 #undef LANG_HOOKS_INIT
251 #define LANG_HOOKS_INIT java_init
252 #undef LANG_HOOKS_FINISH
253 #define LANG_HOOKS_FINISH java_finish
254 #undef LANG_HOOKS_INIT_OPTIONS
255 #define LANG_HOOKS_INIT_OPTIONS java_init_options
256 #undef LANG_HOOKS_DECODE_OPTION
257 #define LANG_HOOKS_DECODE_OPTION java_decode_option
258 #undef LANG_HOOKS_POST_OPTIONS
259 #define LANG_HOOKS_POST_OPTIONS java_post_options
260 #undef LANG_HOOKS_PARSE_FILE
261 #define LANG_HOOKS_PARSE_FILE java_parse_file
262 #undef LANG_HOOKS_UNSAFE_FOR_REEVAL
263 #define LANG_HOOKS_UNSAFE_FOR_REEVAL java_unsafe_for_reeval
264 #undef LANG_HOOKS_MARK_ADDRESSABLE
265 #define LANG_HOOKS_MARK_ADDRESSABLE java_mark_addressable
266 #undef LANG_HOOKS_EXPAND_EXPR
267 #define LANG_HOOKS_EXPAND_EXPR java_expand_expr
268 #undef LANG_HOOKS_TRUTHVALUE_CONVERSION
269 #define LANG_HOOKS_TRUTHVALUE_CONVERSION java_truthvalue_conversion
270 #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
271 #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL java_dup_lang_specific_decl
272 #undef LANG_HOOKS_DECL_PRINTABLE_NAME
273 #define LANG_HOOKS_DECL_PRINTABLE_NAME lang_printable_name
274 #undef LANG_HOOKS_PRINT_ERROR_FUNCTION
275 #define LANG_HOOKS_PRINT_ERROR_FUNCTION java_print_error_function
276 #undef LANG_HOOKS_CAN_USE_BIT_FIELDS_P
277 #define LANG_HOOKS_CAN_USE_BIT_FIELDS_P java_can_use_bit_fields_p
278
279 #undef LANG_HOOKS_TYPE_FOR_MODE
280 #define LANG_HOOKS_TYPE_FOR_MODE java_type_for_mode
281 #undef LANG_HOOKS_TYPE_FOR_SIZE
282 #define LANG_HOOKS_TYPE_FOR_SIZE java_type_for_size
283 #undef LANG_HOOKS_SIGNED_TYPE
284 #define LANG_HOOKS_SIGNED_TYPE java_signed_type
285 #undef LANG_HOOKS_UNSIGNED_TYPE
286 #define LANG_HOOKS_UNSIGNED_TYPE java_unsigned_type
287 #undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
288 #define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE java_signed_or_unsigned_type
289
290 #undef LANG_HOOKS_TREE_INLINING_WALK_SUBTREES
291 #define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES java_tree_inlining_walk_subtrees
292
293 #undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
294 #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN java_dump_tree
295
296 /* Each front end provides its own.  */
297 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
298
299 /* Process an option that can accept a `no-' form.
300    Return 1 if option found, 0 otherwise.  */
301 static int
302 process_option_with_no (p, table, table_size)
303      const char *p;
304      const struct string_option *table;
305      int table_size;
306 {
307   int j;
308
309   for (j = 0; j < table_size; j++)
310     {
311       if (!strcmp (p, table[j].string))
312         {
313           *table[j].variable = table[j].on_value;
314           return 1;
315         }
316       if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
317           && ! strcmp (p+3, table[j].string))
318         {
319           *table[j].variable = ! table[j].on_value;
320           return 1;
321         }
322     }
323
324   return 0;
325 }
326
327 /*
328  * process java-specific compiler command-line options
329  * return 0, but do not complain if the option is not recognized.
330  */
331 static int
332 java_decode_option (argc, argv)
333      int argc __attribute__ ((__unused__));
334      char **argv;
335 {
336   char *p = argv[0];
337
338   jcf_path_init ();
339
340   if (strcmp (p, "-version") == 0)
341     {
342       version_flag = 1;
343       /* We return 0 so that the caller can process this.  */
344       return 0;
345     }
346
347 #define CLARG "-fcompile-resource="
348   if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
349     {
350       resource_name = p + sizeof (CLARG) - 1;
351       return 1;
352     }
353 #undef CLARG
354 #define CLARG "-fassume-compiled="
355   if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
356     {
357       add_assume_compiled (p + sizeof (CLARG) - 1, 0);
358       return 1;
359     }
360 #undef CLARG
361 #define CLARG "-fno-assume-compiled="
362   if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
363     {
364       add_assume_compiled (p + sizeof (CLARG) - 1, 1);
365       return 1;
366     }
367 #undef CLARG
368 #define CLARG "-fassume-compiled"
369   if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
370     {
371       add_assume_compiled ("", 0);
372       return 1;
373     }
374 #undef CLARG
375 #define CLARG "-fno-assume-compiled"
376   if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
377     {
378       add_assume_compiled ("", 1);
379       return 1;
380     }
381 #undef CLARG
382 #define CLARG "-fCLASSPATH="
383   if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
384     {
385       jcf_path_classpath_arg (p + sizeof (CLARG) - 1);
386       return 1;
387     }
388 #undef CLARG
389 #define CLARG "-fclasspath="
390   if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
391     {
392       jcf_path_classpath_arg (p + sizeof (CLARG) - 1);
393       return 1;
394     }
395 #undef CLARG
396 #define CLARG "-fbootclasspath="
397   if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
398     {
399       jcf_path_bootclasspath_arg (p + sizeof (CLARG) - 1);
400       return 1;
401     }
402 #undef CLARG
403 #define CLARG "-fextdirs="
404   if (strncmp (p, CLARG, sizeof (CLARG) - 1) == 0)
405     {
406       jcf_path_extdirs_arg (p + sizeof (CLARG) - 1);
407       return 1;
408     }
409 #undef CLARG
410   else if (strncmp (p, "-I", 2) == 0)
411     {
412       jcf_path_include_arg (p + 2);
413       return 1;
414     }
415
416 #define ARG "-foutput-class-dir="
417   if (strncmp (p, ARG, sizeof (ARG) - 1) == 0)
418     {
419       jcf_write_base_directory = p + sizeof (ARG) - 1;
420       return 1;
421     }
422 #undef ARG
423 #define ARG "-fencoding="
424   if (strncmp (p, ARG, sizeof (ARG) - 1) == 0)
425     {
426       current_encoding = p + sizeof (ARG) - 1;
427       return 1;
428     }
429 #undef ARG
430 #define ARG "-finline-functions"
431   if (strncmp (p, ARG, sizeof (ARG) - 1) == 0)
432     {
433       flag_inline_functions = 1;
434       flag_really_inline = 1;
435       return 1;
436     }
437 #undef ARG
438
439   if (p[0] == '-' && p[1] == 'f')
440     {
441       /* Some kind of -f option.
442          P's value is the option sans `-f'.
443          Search for it in the table of options.  */
444       p += 2;
445       if (process_option_with_no (p, lang_f_options,
446                                   ARRAY_SIZE (lang_f_options)))
447         return 1;
448       return dump_switch_p (p);
449     }
450
451   if (strcmp (p, "-Wall") == 0)
452     {
453       flag_wall = 1;
454       flag_redundant = 1;
455       flag_extraneous_semicolon = 1;
456       /* When -Wall given, enable -Wunused.  We do this because the C
457          compiler does it, and people expect it.  */
458       set_Wunused (1);
459       return 1;
460     }
461
462   if (p[0] == '-' && p[1] == 'W')
463     {
464       /* Skip `-W' and see if we accept the option or its `no-' form.  */
465       p += 2;
466       return process_option_with_no (p, lang_W_options,
467                                      ARRAY_SIZE (lang_W_options));
468     }
469
470   if (strcmp (p, "-MD") == 0)
471     {
472       jcf_dependency_init (1);
473       dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE;
474       return 1;
475     }
476   else if (strcmp (p, "-MMD") == 0)
477     {
478       jcf_dependency_init (0);
479       dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE;
480       return 1;
481     }
482   else if (strcmp (p, "-M") == 0)
483     {
484       jcf_dependency_init (1);
485       dependency_tracking |= DEPEND_ENABLE;
486       return 1;
487     }
488   else if (strcmp (p, "-MM") == 0)
489     {
490       jcf_dependency_init (0);
491       dependency_tracking |= DEPEND_ENABLE;
492       return 1;
493     }
494   else if (strcmp (p, "-MP") == 0)
495     {
496       jcf_dependency_print_dummies ();
497       return 1;
498     }
499   else if (strcmp (p, "-MT") == 0)
500     {
501       jcf_dependency_set_target (argv[1]);
502       dependency_tracking |= DEPEND_TARGET_SET;
503       return 2;
504     }
505   else if (strcmp (p, "-MF") == 0)
506     {
507       jcf_dependency_set_dep_file (argv[1]);
508       dependency_tracking |= DEPEND_FILE_ALREADY_SET;
509       return 2;
510     }
511
512   return 0;
513 }
514
515 /* Global open file.  */
516 FILE *finput;
517
518 static const char *
519 java_init (filename)
520      const char *filename;
521 {
522 #if 0
523   extern int flag_minimal_debug;
524   flag_minimal_debug = 0;
525 #endif
526
527   if (flag_inline_functions)
528     flag_inline_trees = 1;
529
530   /* Force minimum function alignment if g++ uses the least significant
531      bit of function pointers to store the virtual bit. This is required
532      to keep vtables compatible.  */
533   if (TARGET_PTRMEMFUNC_VBIT_LOCATION == ptrmemfunc_vbit_in_pfn
534       && force_align_functions_log < 1)
535     force_align_functions_log = 1;
536
537   /* Open input file.  */
538
539   if (filename == 0 || !strcmp (filename, "-"))
540     {
541       finput = stdin;
542       filename = "stdin";
543
544       if (dependency_tracking)
545         error ("can't do dependency tracking with input from stdin");
546     }
547   else
548     {
549       if (dependency_tracking)
550         {
551           char *dot;
552
553           /* If the target is set and the output filename is set, then
554              there's no processing to do here.  Otherwise we must
555              compute one or the other.  */
556           if (! ((dependency_tracking & DEPEND_TARGET_SET)
557                  && (dependency_tracking & DEPEND_FILE_ALREADY_SET)))
558             {
559               dot = strrchr (filename, '.');
560               if (dot == NULL)
561                 error ("couldn't determine target name for dependency tracking");
562               else
563                 {
564                   char *buf = xmalloc (dot - filename +
565                                        3 + sizeof (TARGET_OBJECT_SUFFIX));
566                   strncpy (buf, filename, dot - filename);
567
568                   /* If emitting class files, we might have multiple
569                      targets.  The class generation code takes care of
570                      registering them.  Otherwise we compute the
571                      target name here.  */
572                   if ((dependency_tracking & DEPEND_TARGET_SET))
573                     ; /* Nothing.  */
574                   else if (flag_emit_class_files)
575                     jcf_dependency_set_target (NULL);
576                   else
577                     {
578                       strcpy (buf + (dot - filename), TARGET_OBJECT_SUFFIX);
579                       jcf_dependency_set_target (buf);
580                     }
581
582                   if ((dependency_tracking & DEPEND_FILE_ALREADY_SET))
583                     ; /* Nothing.  */
584                   else if ((dependency_tracking & DEPEND_SET_FILE))
585                     {
586                       strcpy (buf + (dot - filename), ".d");
587                       jcf_dependency_set_dep_file (buf);
588                     }
589                   else
590                     jcf_dependency_set_dep_file ("-");
591
592                   free (buf);
593                 }
594             }
595         }
596     }
597
598   jcf_path_init ();
599   jcf_path_seal (version_flag);
600
601   java_init_decl_processing ();
602
603   using_eh_for_cleanups ();
604
605   return filename;
606 }
607
608 static void
609 java_finish ()
610 {
611   jcf_dependency_write ();
612 }
613
614 /* Buffer used by lang_printable_name. */
615 static char *decl_buf = NULL;
616
617 /* Allocated size of decl_buf. */
618 static int decl_buflen = 0;
619
620 /* Length of used part of decl_buf;  position for next character. */
621 static int decl_bufpos = 0;
622
623 /* Append the string STR to decl_buf.
624    It length is given by LEN;  -1 means the string is nul-terminated. */
625
626 static void
627 put_decl_string (str, len)
628      const char *str;
629      int len;
630 {
631   if (len < 0)
632     len = strlen (str);
633   if (decl_bufpos + len >= decl_buflen)
634     {
635       if (decl_buf == NULL)
636         {
637           decl_buflen = len + 100;
638           decl_buf = xmalloc (decl_buflen);
639         }
640       else
641         {
642           decl_buflen *= 2;
643           decl_buf = xrealloc (decl_buf, decl_buflen);
644         }
645     }
646   strcpy (decl_buf + decl_bufpos, str);
647   decl_bufpos += len;
648 }
649
650 /* Append to decl_buf a printable name for NODE. */
651
652 static void
653 put_decl_node (node)
654      tree node;
655 {
656   int was_pointer = 0;
657   if (TREE_CODE (node) == POINTER_TYPE)
658     {
659       node = TREE_TYPE (node);
660       was_pointer = 1;
661     }
662   if (TREE_CODE_CLASS (TREE_CODE (node)) == 'd'
663       && DECL_NAME (node) != NULL_TREE)
664     {
665       if (TREE_CODE (node) == FUNCTION_DECL)
666         {
667           /* We want to print the type the DECL belongs to. We don't do
668              that when we handle constructors. */
669           if (! DECL_CONSTRUCTOR_P (node)
670               && ! DECL_ARTIFICIAL (node) && DECL_CONTEXT (node))
671             {
672               put_decl_node (TYPE_NAME (DECL_CONTEXT (node)));
673               put_decl_string (".", 1);
674             }
675           if (! DECL_CONSTRUCTOR_P (node))
676             put_decl_node (DECL_NAME (node));
677           if (TREE_TYPE (node) != NULL_TREE)
678             {
679               int i = 0;
680               tree args = TYPE_ARG_TYPES (TREE_TYPE (node));
681               if (TREE_CODE (TREE_TYPE (node)) == METHOD_TYPE)
682                 args = TREE_CHAIN (args);
683               put_decl_string ("(", 1);
684               for ( ; args != end_params_node;  args = TREE_CHAIN (args), i++)
685                 {
686                   if (i > 0)
687                     put_decl_string (",", 1);
688                   put_decl_node (TREE_VALUE (args));
689                 }
690               put_decl_string (")", 1);
691             }
692         }
693       else
694         put_decl_node (DECL_NAME (node));
695     }
696   else if (TREE_CODE_CLASS (TREE_CODE (node)) == 't'
697       && TYPE_NAME (node) != NULL_TREE)
698     {
699       if (TREE_CODE (node) == RECORD_TYPE && TYPE_ARRAY_P (node))
700         {
701           put_decl_node (TYPE_ARRAY_ELEMENT (node));
702           put_decl_string("[]", 2);
703         }
704       else if (node == promoted_byte_type_node)
705         put_decl_string ("byte", 4);
706       else if (node == promoted_short_type_node)
707         put_decl_string ("short", 5);
708       else if (node == promoted_char_type_node)
709         put_decl_string ("char", 4);
710       else if (node == promoted_boolean_type_node)
711         put_decl_string ("boolean", 7);
712       else if (node == void_type_node && was_pointer)
713         put_decl_string ("null", 4);
714       else
715         put_decl_node (TYPE_NAME (node));
716     }
717   else if (TREE_CODE (node) == IDENTIFIER_NODE)
718     put_decl_string (IDENTIFIER_POINTER (node), IDENTIFIER_LENGTH (node));
719   else
720     put_decl_string ("<unknown>", -1);
721 }
722
723 /* Return a user-friendly name for DECL.
724    The resulting string is only valid until the next call.
725    The value of the hook decl_printable_name is this function,
726    which is also called directly by java_print_error_function. */
727
728 const char *
729 lang_printable_name (decl, v)
730      tree decl;
731      int v  __attribute__ ((__unused__));
732 {
733   decl_bufpos = 0;
734   put_decl_node (decl);
735   put_decl_string ("", 1);
736   return decl_buf;
737 }
738
739 /* Does the same thing that lang_printable_name, but add a leading
740    space to the DECL name string -- With Leading Space.  */
741
742 const char *
743 lang_printable_name_wls (decl, v)
744      tree decl;
745      int v  __attribute__ ((__unused__));
746 {
747   decl_bufpos = 1;
748   put_decl_node (decl);
749   put_decl_string ("", 1);
750   decl_buf [0] = ' ';
751   return decl_buf;
752 }
753
754 /* Print on stderr the current class and method context.  This function
755    is the value of the hook print_error_function. */
756
757 static GTY(()) tree last_error_function_context;
758 static GTY(()) tree last_error_function;
759 static void
760 java_print_error_function (context, file)
761      diagnostic_context *context __attribute__((__unused__));
762      const char *file;
763 {
764   /* Don't print error messages with bogus function prototypes.  */
765   if (inhibit_error_function_printing)
766     return;
767
768   if (current_function_decl != NULL
769       && DECL_CONTEXT (current_function_decl) != last_error_function_context)
770     {
771       if (file)
772         fprintf (stderr, "%s: ", file);
773
774       last_error_function_context = DECL_CONTEXT (current_function_decl);
775       fprintf (stderr, "In class `%s':\n",
776                lang_printable_name (last_error_function_context, 0));
777     }
778   if (last_error_function != current_function_decl)
779     {
780       if (file)
781         fprintf (stderr, "%s: ", file);
782
783       if (current_function_decl == NULL)
784         fprintf (stderr, "At top level:\n");
785       else
786         {
787           const char *name = lang_printable_name (current_function_decl, 2);
788           fprintf (stderr, "In %s `%s':\n",
789                    (DECL_CONSTRUCTOR_P (current_function_decl) ? "constructor" 
790                     : "method"),
791                    name);
792         }
793
794       last_error_function = current_function_decl;
795     }
796
797 }
798
799 /* Called to install the PRINT_ERROR_FUNCTION hook differently
800    according to LEVEL. LEVEL is 1 during early parsing, when function
801    prototypes aren't fully resolved. java_print_error_function is set
802    so it doesn't print incomplete function prototypes. When LEVEL is
803    2, function prototypes are fully resolved and can be printed when
804    reporting errors.  */
805
806 void lang_init_source (level)
807      int level;
808 {
809   inhibit_error_function_printing = (level == 1);
810 }
811
812 static void
813 java_init_options ()
814 {
815   flag_bounds_check = 1;
816   flag_exceptions = 1;
817   flag_non_call_exceptions = 1;
818
819   /* In Java floating point operations never trap.  */
820   flag_trapping_math = 0;
821 }
822
823 static bool
824 java_can_use_bit_fields_p ()
825 {
826   /* The bit-field optimizations cause problems when generating class
827      files.  */
828   return flag_emit_class_files ? false : true;
829 }
830
831 /* Post-switch processing.  */
832 static bool
833 java_post_options ()
834 {
835  /* Use tree inlining if possible.  Function instrumentation is only
836      done in the RTL level, so we disable tree inlining.  */
837   if (! flag_instrument_function_entry_exit)
838     {
839       if (!flag_no_inline)
840         flag_no_inline = 1;
841       if (flag_inline_functions)
842         {
843           flag_inline_trees = 2;
844           flag_inline_functions = 0;
845         }
846     }
847
848   /* Initialize the compiler back end.  */
849   return false;
850 }
851
852 /* Return either DECL or its known constant value (if it has one).  */
853
854 tree
855 decl_constant_value (decl)
856      tree decl;
857 {
858   if (/* Don't change a variable array bound or initial value to a constant
859          in a place where a variable is invalid.  */
860       current_function_decl != 0
861       && ! TREE_THIS_VOLATILE (decl)
862       && TREE_READONLY (decl)
863       && DECL_INITIAL (decl) != 0
864       && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
865       /* This is invalid if initial value is not constant.
866          If it has either a function call, a memory reference,
867          or a variable, then re-evaluating it could give different results.  */
868       && TREE_CONSTANT (DECL_INITIAL (decl))
869       /* Check for cases where this is sub-optimal, even though valid.  */
870       && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)
871     return DECL_INITIAL (decl);
872   return decl;
873 }
874
875 /* Walk the language specific tree nodes during inlining.  */
876
877 static tree
878 java_tree_inlining_walk_subtrees (tp,subtrees,func,data,htab)
879      tree *tp ATTRIBUTE_UNUSED;
880      int *subtrees ATTRIBUTE_UNUSED;
881      walk_tree_fn func ATTRIBUTE_UNUSED;
882      void *data ATTRIBUTE_UNUSED;
883      void *htab ATTRIBUTE_UNUSED;
884 {
885   enum tree_code code;
886   tree result;
887
888 #define WALK_SUBTREE(NODE)                              \
889   do                                                    \
890     {                                                   \
891       result = walk_tree (&(NODE), func, data, htab);   \
892       if (result)                                       \
893         return result;                                  \
894     }                                                   \
895   while (0)
896
897   tree t = *tp;
898   if (!t)
899     return NULL_TREE;
900
901   code = TREE_CODE (t);
902   switch (code)
903     {
904     case BLOCK:
905       if (BLOCK_EXPR_BODY (t))
906         {
907           tree *prev = &BLOCK_EXPR_BODY (*tp);
908           while (*prev)
909             {
910               WALK_SUBTREE (*prev);
911               prev = &TREE_CHAIN (*prev);
912             }       
913         }
914       return NULL_TREE;
915       break;
916
917     default:
918       return NULL_TREE;
919     }
920 }
921
922 /* Called from unsafe_for_reeval.  */
923 static int
924 java_unsafe_for_reeval (t)
925      tree t;
926 {
927   switch (TREE_CODE (t))
928     {
929     case BLOCK:
930       /* Our expander tries to expand the variables twice.  Boom.  */
931       if (BLOCK_EXPR_DECLS (t) != NULL)
932         return 2;
933       return unsafe_for_reeval (BLOCK_EXPR_BODY (t));
934
935     default:
936       break;
937     }
938
939   return -1;
940 }
941
942 /* Every call to a static constructor has an associated boolean
943    variable which is in the outermost scope of the calling method.
944    This variable is used to avoid multiple calls to the static
945    constructor for each class.  
946
947    It looks somthing like this:
948
949    foo ()
950    {
951       boolean dummy = OtherClass.is_initialized;
952   
953      ...
954   
955      if (! dummy)
956        OtherClass.initialize();
957
958      ... use OtherClass.data ...
959    }
960
961    Each of these boolean variables has an entry in the
962    DECL_FUNCTION_INIT_TEST_TABLE of a method.  When inlining a method
963    we must merge the DECL_FUNCTION_INIT_TEST_TABLE from the function
964    being linlined and create the boolean variables in the outermost
965    scope of the method being inlined into.  */
966
967 /* Create a mapping from a boolean variable in a method being inlined
968    to one in the scope of the method being inlined into.  */
969
970 static int
971 merge_init_test_initialization (entry, x)
972      void * * entry;
973      void * x;
974 {
975   struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
976   splay_tree decl_map = (splay_tree)x;
977   splay_tree_node n;
978   tree *init_test_decl;
979   
980   /* See if we have remapped this declaration.  If we haven't there's
981      a bug in the inliner.  */
982   n = splay_tree_lookup (decl_map, (splay_tree_key) ite->value);
983   if (! n)
984     abort ();
985
986   /* Create a new entry for the class and its remapped boolean
987      variable.  If we already have a mapping for this class we've
988      already initialized it, so don't overwrite the value.  */
989   init_test_decl = java_treetreehash_new
990     (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), ite->key);
991   if (!*init_test_decl)
992     *init_test_decl = (tree)n->value;
993
994   return true;
995 }
996
997 /* Merge the DECL_FUNCTION_INIT_TEST_TABLE from the function we're
998    inlining.  */
999
1000 void
1001 java_inlining_merge_static_initializers (fn, decl_map)
1002      tree fn;
1003      void *decl_map;
1004 {
1005   htab_traverse 
1006     (DECL_FUNCTION_INIT_TEST_TABLE (fn),
1007      merge_init_test_initialization, decl_map);
1008 }
1009
1010 /* Lookup a DECL_FUNCTION_INIT_TEST_TABLE entry in the method we're
1011    inlining into.  If we already have a corresponding entry in that
1012    class we don't need to create another one, so we create a mapping
1013    from the variable in the inlined class to the corresponding
1014    pre-existing one.  */
1015
1016 static int
1017 inline_init_test_initialization (entry, x)
1018      void * * entry;
1019      void * x;
1020 {
1021   struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
1022   splay_tree decl_map = (splay_tree)x;
1023   
1024   tree h = java_treetreehash_find 
1025     (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), ite->key);
1026   if (! h)
1027     return true;
1028
1029   splay_tree_insert (decl_map,
1030                      (splay_tree_key) ite->value,
1031                      (splay_tree_value) h);
1032
1033   return true;
1034 }
1035
1036 /* Look up the boolean variables in the DECL_FUNCTION_INIT_TEST_TABLE
1037    of a method being inlined.  For each hone, if we already have a
1038    variable associated with the same class in the method being inlined
1039    into, create a new mapping for it.  */
1040
1041 void
1042 java_inlining_map_static_initializers (fn, decl_map)
1043      tree fn;
1044      void *decl_map;
1045 {
1046   htab_traverse 
1047     (DECL_FUNCTION_INIT_TEST_TABLE (fn),
1048      inline_init_test_initialization, decl_map);
1049 }
1050
1051 /* Avoid voluminous output for deep recursion of compound exprs.  */
1052
1053 static void
1054 dump_compound_expr (di, t)
1055      dump_info_p di;
1056      tree t;
1057 {
1058   int i;
1059
1060   for (i=0; i<2; i++)
1061     {
1062       switch (TREE_CODE (TREE_OPERAND (t, i)))
1063         {
1064         case COMPOUND_EXPR:
1065           dump_compound_expr (di, TREE_OPERAND (t, i));
1066           break;
1067
1068         case EXPR_WITH_FILE_LOCATION:
1069             {
1070               tree wfl_node = EXPR_WFL_NODE (TREE_OPERAND (t, i));
1071               dump_child ("expr", wfl_node);
1072               break;
1073             }
1074
1075         default:
1076           dump_child ("expr", TREE_OPERAND (t, i));
1077         }
1078     }
1079 }
1080   
1081 static int
1082 java_dump_tree (dump_info, t)
1083      void *dump_info;
1084      tree t;
1085 {
1086   enum tree_code code;
1087   dump_info_p di = (dump_info_p) dump_info;
1088
1089   /* Figure out what kind of node this is.  */
1090   code = TREE_CODE (t);
1091
1092   switch (code)
1093     {
1094     case FUNCTION_DECL:
1095       dump_child ("args", DECL_ARGUMENTS (t));
1096       if (DECL_EXTERNAL (t))
1097         dump_string (di, "undefined");
1098       if (TREE_PUBLIC (t))
1099         dump_string (di, "extern");
1100       else
1101         dump_string (di, "static");
1102       if (DECL_LANG_SPECIFIC (t))
1103         dump_child ("body", DECL_FUNCTION_BODY (t));
1104       if (DECL_LANG_SPECIFIC (t) && !dump_flag (di, TDF_SLIM, t))
1105         dump_child ("inline body", DECL_SAVED_TREE (t));
1106       return 1;
1107
1108     case RETURN_EXPR:
1109       dump_child ("expr", TREE_OPERAND (t, 0));
1110       return 1;
1111
1112     case GOTO_EXPR:
1113       dump_child ("goto", TREE_OPERAND (t, 0));
1114       return 1;
1115
1116     case LABEL_EXPR:
1117       dump_child ("label", TREE_OPERAND (t, 0));
1118       return 1;
1119
1120     case LABELED_BLOCK_EXPR:
1121       dump_child ("label", TREE_OPERAND (t, 0));
1122       dump_child ("block", TREE_OPERAND (t, 1));
1123       return 1;
1124
1125     case EXIT_BLOCK_EXPR:
1126       dump_child ("block", TREE_OPERAND (t, 0));
1127       dump_child ("val", TREE_OPERAND (t, 1));
1128       return 1;
1129
1130     case BLOCK:
1131       if (BLOCK_EXPR_BODY (t))
1132         {
1133           tree local = BLOCK_VARS (t);
1134           while (local)
1135             {
1136               tree next = TREE_CHAIN (local);
1137               dump_child ("var", local);
1138               local = next;
1139             }
1140           
1141           {
1142             tree block = BLOCK_EXPR_BODY (t);
1143             dump_child ("body", block);
1144             block = TREE_CHAIN (block);
1145           }
1146         }
1147       return 1;
1148       
1149     case COMPOUND_EXPR:
1150       if (!dump_flag (di, TDF_SLIM, t))
1151         return 0;
1152       dump_compound_expr (di, t);
1153       return 1;
1154
1155     default:
1156       break;
1157     }
1158   return 0;
1159 }
1160 #include "gt-java-lang.h"