OSDN Git Service

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