]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/java/lang.c
Merge basic-improvements-branch to trunk
[thirdparty/gcc.git] / gcc / java / lang.c
1 /* Java(TM) language-specific utility routines.
2 Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC 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 GNU CC 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 GNU CC; 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"