OSDN Git Service

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