OSDN Git Service

64b168c650c3cc8ff787a6b2745dd684f2aaf32c
[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, 2004,
3    2005, 2006, 2007 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 3, 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 COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.
20
21 Java and all Java-based marks are trademarks or registered trademarks
22 of Sun Microsystems, Inc. in the United States and other countries.
23 The Free Software Foundation is independent of Sun Microsystems, Inc.  */
24
25 /* Hacked by Per Bothner <bothner@cygnus.com> February 1996. */
26
27 #include "config.h"
28 #include "system.h"
29 #include "coretypes.h"
30 #include "tm.h"
31 #include "tree.h"
32 #include "input.h"
33 #include "rtl.h"
34 #include "expr.h"
35 #include "java-tree.h"
36 #include "jcf.h"
37 #include "toplev.h"
38 #include "langhooks.h"
39 #include "langhooks-def.h"
40 #include "flags.h"
41 #include "ggc.h"
42 #include "diagnostic.h"
43 #include "tree-inline.h"
44 #include "splay-tree.h"
45 #include "tree-dump.h"
46 #include "opts.h"
47 #include "options.h"
48
49 static bool java_init (void);
50 static void java_finish (void);
51 static unsigned int java_init_options (unsigned int, const char **);
52 static bool java_post_options (const char **);
53
54 static int java_handle_option (size_t scode, const char *arg, int value);
55 static void put_decl_string (const char *, int);
56 static void put_decl_node (tree);
57 static void java_print_error_function (diagnostic_context *, const char *);
58 static int merge_init_test_initialization (void * *, void *);
59 static int inline_init_test_initialization (void * *, void *);
60 static bool java_dump_tree (void *, tree);
61 static void dump_compound_expr (dump_info_p, tree);
62 static bool java_decl_ok_for_sibcall (const_tree);
63 static tree java_get_callee_fndecl (const_tree);
64 static void java_clear_binding_stack (void);
65
66 #ifndef TARGET_OBJECT_SUFFIX
67 # define TARGET_OBJECT_SUFFIX ".o"
68 #endif
69
70 /* Table indexed by tree code giving a string containing a character
71    classifying the tree code.  Possibilities are
72    t, d, s, c, r, <, 1 and 2.  See java/java-tree.def for details.  */
73
74 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
75
76 const enum tree_code_class tree_code_type[] = {
77 #include "tree.def"
78   tcc_exceptional,
79 #include "java-tree.def"
80 };
81 #undef DEFTREECODE
82
83 /* Table indexed by tree code giving number of expression
84    operands beyond the fixed part of the node structure.
85    Not used for types or decls.  */
86
87 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
88
89 const unsigned char tree_code_length[] = {
90 #include "tree.def"
91   0,
92 #include "java-tree.def"
93 };
94 #undef DEFTREECODE
95
96 /* Names of tree components.
97    Used for printing out the tree and error messages.  */
98 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
99
100 const char *const tree_code_name[] = {
101 #include "tree.def"
102   "@@dummy",
103 #include "java-tree.def"
104 };
105 #undef DEFTREECODE
106
107 /* Table of machine-independent attributes.  */
108 const struct attribute_spec java_attribute_table[] =
109 {
110  { "nonnull",                0, -1, false, true, true,
111                               NULL },
112   { NULL,                     0, 0, false, false, false, NULL }
113 };
114
115 /* Used to avoid printing error messages with bogus function
116    prototypes.  Starts out false.  */
117 static bool inhibit_error_function_printing;
118
119 const char *resource_name;
120
121 /* When nonzero, -Wall was turned on.  */
122 int flag_wall = 0;
123
124 /* When nonzero, report use of deprecated classes, methods, or fields.  */
125 int flag_deprecated = 1;
126
127 /* When zero, don't optimize static class initialization. This flag shouldn't
128    be tested alone, use STATIC_CLASS_INITIALIZATION_OPTIMIZATION_P instead.  */
129 /* FIXME: Make this work with gimplify.  */
130 /* int flag_optimize_sci = 0;  */
131
132 /* Don't attempt to verify invocations.  */
133 int flag_verify_invocations = 0; 
134
135 /* When nonzero, print extra version information.  */
136 static int v_flag = 0;
137
138 JCF *current_jcf;
139
140 /* Variable controlling how dependency tracking is enabled in
141    java_init.  */
142 static int dependency_tracking = 0;
143
144 /* Flag values for DEPENDENCY_TRACKING.  */
145 #define DEPEND_SET_FILE 1
146 #define DEPEND_ENABLE   2
147 #define DEPEND_TARGET_SET 4
148 #define DEPEND_FILE_ALREADY_SET 8
149
150 struct language_function GTY(())
151 {
152   int unused;
153 };
154
155 #undef LANG_HOOKS_NAME
156 #define LANG_HOOKS_NAME "GNU Java"
157 #undef LANG_HOOKS_INIT
158 #define LANG_HOOKS_INIT java_init
159 #undef LANG_HOOKS_FINISH
160 #define LANG_HOOKS_FINISH java_finish
161 #undef LANG_HOOKS_INIT_OPTIONS
162 #define LANG_HOOKS_INIT_OPTIONS java_init_options
163 #undef LANG_HOOKS_HANDLE_OPTION
164 #define LANG_HOOKS_HANDLE_OPTION java_handle_option
165 #undef LANG_HOOKS_POST_OPTIONS
166 #define LANG_HOOKS_POST_OPTIONS java_post_options
167 #undef LANG_HOOKS_PARSE_FILE
168 #define LANG_HOOKS_PARSE_FILE java_parse_file
169 #undef LANG_HOOKS_MARK_ADDRESSABLE
170 #define LANG_HOOKS_MARK_ADDRESSABLE java_mark_addressable
171 #undef LANG_HOOKS_DUP_LANG_SPECIFIC_DECL
172 #define LANG_HOOKS_DUP_LANG_SPECIFIC_DECL java_dup_lang_specific_decl
173 #undef LANG_HOOKS_DECL_PRINTABLE_NAME
174 #define LANG_HOOKS_DECL_PRINTABLE_NAME lang_printable_name
175 #undef LANG_HOOKS_PRINT_ERROR_FUNCTION
176 #define LANG_HOOKS_PRINT_ERROR_FUNCTION java_print_error_function
177
178 #undef LANG_HOOKS_TYPE_FOR_MODE
179 #define LANG_HOOKS_TYPE_FOR_MODE java_type_for_mode
180 #undef LANG_HOOKS_TYPE_FOR_SIZE
181 #define LANG_HOOKS_TYPE_FOR_SIZE java_type_for_size
182
183 #undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
184 #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN java_dump_tree
185
186 #undef LANG_HOOKS_GIMPLIFY_EXPR
187 #define LANG_HOOKS_GIMPLIFY_EXPR java_gimplify_expr
188
189 #undef LANG_HOOKS_DECL_OK_FOR_SIBCALL
190 #define LANG_HOOKS_DECL_OK_FOR_SIBCALL java_decl_ok_for_sibcall
191
192 #undef LANG_HOOKS_GET_CALLEE_FNDECL
193 #define LANG_HOOKS_GET_CALLEE_FNDECL java_get_callee_fndecl
194
195 #undef LANG_HOOKS_CLEAR_BINDING_STACK
196 #define LANG_HOOKS_CLEAR_BINDING_STACK java_clear_binding_stack
197
198 #undef LANG_HOOKS_SET_DECL_ASSEMBLER_NAME
199 #define LANG_HOOKS_SET_DECL_ASSEMBLER_NAME java_mangle_decl
200
201 #undef LANG_HOOKS_ATTRIBUTE_TABLE
202 #define LANG_HOOKS_ATTRIBUTE_TABLE java_attribute_table
203
204 /* Each front end provides its own.  */
205 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
206
207 /*
208  * process java-specific compiler command-line options
209  * return 0, but do not complain if the option is not recognized.
210  */
211 static int
212 java_handle_option (size_t scode, const char *arg, int value)
213 {
214   enum opt_code code = (enum opt_code) scode;
215
216   switch (code)
217     {
218     case OPT_I:
219       jcf_path_include_arg (arg);
220       break;
221
222     case OPT_M:
223       jcf_dependency_init (1);
224       dependency_tracking |= DEPEND_ENABLE;
225       break;
226
227     case OPT_MD_:
228       jcf_dependency_init (1);
229       dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE;
230       break;
231
232     case OPT_MF:
233       jcf_dependency_set_dep_file (arg);
234       dependency_tracking |= DEPEND_FILE_ALREADY_SET;
235       break;
236
237     case OPT_MM:
238       jcf_dependency_init (0);
239       dependency_tracking |= DEPEND_ENABLE;
240       break;
241
242     case OPT_MMD_:
243       jcf_dependency_init (0);
244       dependency_tracking |= DEPEND_SET_FILE | DEPEND_ENABLE;
245       break;
246
247     case OPT_MP:
248       jcf_dependency_print_dummies ();
249       break;
250
251     case OPT_MT:
252       jcf_dependency_set_target (arg);
253       dependency_tracking |= DEPEND_TARGET_SET;
254       break;
255
256     case OPT_Wall:
257       flag_wall = value;
258       /* When -Wall given, enable -Wunused.  We do this because the C
259          compiler does it, and people expect it.  */
260       set_Wunused (value);
261       break;
262
263     case OPT_fenable_assertions_:
264       add_enable_assert (arg, value);
265       break;
266
267     case OPT_fenable_assertions:
268       add_enable_assert ("", value);
269       break;
270
271     case OPT_fdisable_assertions_:
272       add_enable_assert (arg, !value);
273       break;
274
275     case OPT_fdisable_assertions:
276       add_enable_assert ("", !value);
277       break;
278
279     case OPT_fassume_compiled_:
280       add_assume_compiled (arg, !value);
281       break;
282
283     case OPT_fassume_compiled:
284       add_assume_compiled ("", !value);
285       break;
286
287     case OPT_fbootclasspath_:
288       jcf_path_bootclasspath_arg (arg);
289       break;
290
291     case OPT_faux_classpath:
292     case OPT_fclasspath_:
293     case OPT_fCLASSPATH_:
294       jcf_path_classpath_arg (arg);
295       break;
296
297     case OPT_fcompile_resource_:
298       resource_name = arg;
299       break;
300
301     case OPT_fdump_:
302       if (!dump_switch_p (arg))
303         return 0;
304       break;
305
306     case OPT_fencoding_:
307       /* Nothing.  */
308       break;
309
310     case OPT_fextdirs_:
311       jcf_path_extdirs_arg (arg);
312       break;
313
314     case OPT_foutput_class_dir_:
315       /* FIXME: remove; this is handled by ecj1 now.  */
316       break;
317
318     case OPT_version:
319       v_flag = 1;
320       break;
321       
322     case OPT_fsource_filename_:
323       java_read_sourcefilenames (arg);
324       break;
325       
326     default:
327       if (cl_options[code].flags & CL_Java)
328         break;
329       gcc_unreachable ();
330     }
331
332   return 1;
333 }
334
335 /* Global open file.  */
336 FILE *finput;
337
338 static bool
339 java_init (void)
340 {
341   /* FIXME: Indirect dispatch isn't yet compatible with static class
342      init optimization.  */
343   if (flag_indirect_dispatch)
344     always_initialize_class_p = true;
345
346   if (!flag_indirect_dispatch)
347     flag_indirect_classes = false;
348
349   jcf_path_seal (v_flag);
350
351   java_init_decl_processing ();
352
353   using_eh_for_cleanups ();
354
355   return true;
356 }
357
358 static void
359 java_finish (void)
360 {
361   jcf_dependency_write ();
362 }
363
364 /* Buffer used by lang_printable_name. */
365 static char *decl_buf = NULL;
366
367 /* Allocated size of decl_buf. */
368 static int decl_buflen = 0;
369
370 /* Length of used part of decl_buf;  position for next character. */
371 static int decl_bufpos = 0;
372
373 /* Append the string STR to decl_buf.
374    It length is given by LEN;  -1 means the string is nul-terminated. */
375
376 static void
377 put_decl_string (const char *str, int len)
378 {
379   if (len < 0)
380     len = strlen (str);
381   if (decl_bufpos + len >= decl_buflen)
382     {
383       if (decl_buf == NULL)
384         {
385           decl_buflen = len + 100;
386           decl_buf = XNEWVEC (char, decl_buflen);
387         }
388       else
389         {
390           decl_buflen *= 2;
391           decl_buf = xrealloc (decl_buf, decl_buflen);
392         }
393     }
394   strcpy (decl_buf + decl_bufpos, str);
395   decl_bufpos += len;
396 }
397
398 /* Append to decl_buf a printable name for NODE. */
399
400 static void
401 put_decl_node (tree node)
402 {
403   int was_pointer = 0;
404   if (TREE_CODE (node) == POINTER_TYPE)
405     {
406       node = TREE_TYPE (node);
407       was_pointer = 1;
408     }
409   if (DECL_P (node) && DECL_NAME (node) != NULL_TREE)
410     {
411       if (TREE_CODE (node) == FUNCTION_DECL)
412         {
413           /* We want to print the type the DECL belongs to. We don't do
414              that when we handle constructors. */
415           if (! DECL_CONSTRUCTOR_P (node)
416               && ! DECL_ARTIFICIAL (node) && DECL_CONTEXT (node))
417             {
418               put_decl_node (TYPE_NAME (DECL_CONTEXT (node)));
419               put_decl_string (".", 1);
420             }
421           if (! DECL_CONSTRUCTOR_P (node))
422             put_decl_node (DECL_NAME (node));
423           if (TREE_TYPE (node) != NULL_TREE)
424             {
425               int i = 0;
426               tree args = TYPE_ARG_TYPES (TREE_TYPE (node));
427               if (TREE_CODE (TREE_TYPE (node)) == METHOD_TYPE)
428                 args = TREE_CHAIN (args);
429               put_decl_string ("(", 1);
430               for ( ; args != end_params_node;  args = TREE_CHAIN (args), i++)
431                 {
432                   if (i > 0)
433                     put_decl_string (",", 1);
434                   put_decl_node (TREE_VALUE (args));
435                 }
436               put_decl_string (")", 1);
437             }
438         }
439       else
440         put_decl_node (DECL_NAME (node));
441     }
442   else if (TYPE_P (node) && TYPE_NAME (node) != NULL_TREE)
443     {
444       if (TREE_CODE (node) == RECORD_TYPE && TYPE_ARRAY_P (node))
445         {
446           put_decl_node (TYPE_ARRAY_ELEMENT (node));
447           put_decl_string("[]", 2);
448         }
449       else if (node == promoted_byte_type_node)
450         put_decl_string ("byte", 4);
451       else if (node == promoted_short_type_node)
452         put_decl_string ("short", 5);
453       else if (node == promoted_char_type_node)
454         put_decl_string ("char", 4);
455       else if (node == promoted_boolean_type_node)
456         put_decl_string ("boolean", 7);
457       else if (node == void_type_node && was_pointer)
458         put_decl_string ("null", 4);
459       else
460         put_decl_node (TYPE_NAME (node));
461     }
462   else if (TREE_CODE (node) == IDENTIFIER_NODE)
463     put_decl_string (IDENTIFIER_POINTER (node), IDENTIFIER_LENGTH (node));
464   else
465     put_decl_string ("<unknown>", -1);
466 }
467
468 /* Return a user-friendly name for DECL.
469    The resulting string is only valid until the next call.
470    The value of the hook decl_printable_name is this function,
471    which is also called directly by java_print_error_function. */
472
473 const char *
474 lang_printable_name (tree decl, int v)
475 {
476   decl_bufpos = 0;
477   if (v == 0 && TREE_CODE (decl) == FUNCTION_DECL)
478     put_decl_node (DECL_NAME (decl));
479   else
480     put_decl_node (decl);
481   put_decl_string ("", 1);
482   return decl_buf;
483 }
484
485 /* Print on stderr the current class and method context.  This function
486    is the value of the hook print_error_function. */
487
488 static GTY(()) tree last_error_function_context;
489 static GTY(()) tree last_error_function;
490 static void
491 java_print_error_function (diagnostic_context *context ATTRIBUTE_UNUSED,
492                            const char *file)
493 {
494   /* Don't print error messages with bogus function prototypes.  */
495   if (inhibit_error_function_printing)
496     return;
497
498   if (current_function_decl != NULL
499       && DECL_CONTEXT (current_function_decl) != last_error_function_context)
500     {
501       if (file)
502         fprintf (stderr, "%s: ", file);
503
504       last_error_function_context = DECL_CONTEXT (current_function_decl);
505       fprintf (stderr, "In class '%s':\n",
506                lang_printable_name (last_error_function_context, 0));
507     }
508   if (last_error_function != current_function_decl)
509     {
510       if (file)
511         fprintf (stderr, "%s: ", file);
512
513       if (current_function_decl == NULL)
514         fprintf (stderr, "At top level:\n");
515       else
516         {
517           const char *name = lang_printable_name (current_function_decl, 2);
518           fprintf (stderr, "In %s '%s':\n",
519                    (DECL_CONSTRUCTOR_P (current_function_decl) ? "constructor"
520                     : "method"),
521                    name);
522         }
523
524       last_error_function = current_function_decl;
525     }
526
527 }
528
529 /* Called to install the PRINT_ERROR_FUNCTION hook differently
530    according to LEVEL. LEVEL is 1 during early parsing, when function
531    prototypes aren't fully resolved. java_print_error_function is set
532    so it doesn't print incomplete function prototypes. When LEVEL is
533    2, function prototypes are fully resolved and can be printed when
534    reporting errors.  */
535
536 void
537 lang_init_source (int level)
538 {
539   inhibit_error_function_printing = (level == 1);
540 }
541
542 static unsigned int
543 java_init_options (unsigned int argc ATTRIBUTE_UNUSED,
544                    const char **argv ATTRIBUTE_UNUSED)
545 {
546   flag_bounds_check = 1;
547   flag_exceptions = 1;
548   flag_non_call_exceptions = 1;
549
550   /* In Java floating point operations never trap.  */
551   flag_trapping_math = 0;
552
553   /* In Java arithmetic overflow always wraps around.  */
554   flag_wrapv = 1;
555
556   /* Java requires left-to-right evaluation of subexpressions.  */
557   flag_evaluation_order = 1;
558
559   /* Unit at a time is disabled for Java because it is considered
560      too expensive.  */
561   no_unit_at_a_time_default = 1;
562
563   jcf_path_init ();
564
565   return CL_Java;
566 }
567
568 /* Post-switch processing.  */
569 static bool
570 java_post_options (const char **pfilename)
571 {
572   const char *filename = *pfilename;
573
574   /* Use tree inlining.  */
575   if (!flag_no_inline)
576     flag_no_inline = 1;
577   if (flag_inline_functions)
578     flag_inline_trees = 2;
579
580   /* An absolute requirement: if we're not using indirect dispatch, we
581      must always verify everything.  */
582   if (! flag_indirect_dispatch)
583     flag_verify_invocations = true;
584
585   if (flag_reduced_reflection)
586     {
587       if (flag_indirect_dispatch)
588         error ("-findirect-dispatch is incompatible "
589                "with -freduced-reflection");
590       if (flag_jni)
591         error ("-fjni is incompatible with -freduced-reflection");
592     }
593
594   /* Open input file.  */
595
596   if (filename == 0 || !strcmp (filename, "-"))
597     {
598       finput = stdin;
599       filename = "stdin";
600
601       if (dependency_tracking)
602         error ("can't do dependency tracking with input from stdin");
603     }
604   else
605     {
606       if (dependency_tracking)
607         {
608           char *dot;
609
610           /* If the target is set and the output filename is set, then
611              there's no processing to do here.  Otherwise we must
612              compute one or the other.  */
613           if (! ((dependency_tracking & DEPEND_TARGET_SET)
614                  && (dependency_tracking & DEPEND_FILE_ALREADY_SET)))
615             {
616               dot = strrchr (filename, '.');
617               if (dot == NULL)
618                 error ("couldn't determine target name for dependency tracking");
619               else
620                 {
621                   char *buf = XNEWVEC (char, dot - filename +
622                                        3 + sizeof (TARGET_OBJECT_SUFFIX));
623                   strncpy (buf, filename, dot - filename);
624
625                   /* If emitting class files, we might have multiple
626                      targets.  The class generation code takes care of
627                      registering them.  Otherwise we compute the
628                      target name here.  */
629                   if ((dependency_tracking & DEPEND_TARGET_SET))
630                     ; /* Nothing.  */
631                   else
632                     {
633                       strcpy (buf + (dot - filename), TARGET_OBJECT_SUFFIX);
634                       jcf_dependency_set_target (buf);
635                     }
636
637                   if ((dependency_tracking & DEPEND_FILE_ALREADY_SET))
638                     ; /* Nothing.  */
639                   else if ((dependency_tracking & DEPEND_SET_FILE))
640                     {
641                       strcpy (buf + (dot - filename), ".d");
642                       jcf_dependency_set_dep_file (buf);
643                     }
644                   else
645                     jcf_dependency_set_dep_file ("-");
646
647                   free (buf);
648                 }
649             }
650         }
651     }
652 #ifdef USE_MAPPED_LOCATION
653   linemap_add (line_table, LC_ENTER, false, filename, 0);
654   linemap_add (line_table, LC_RENAME, false, "<built-in>", 0);
655 #endif
656
657   /* Initialize the compiler back end.  */
658   return false;
659 }
660
661 /* Return either DECL or its known constant value (if it has one).  */
662
663 tree
664 decl_constant_value (tree decl)
665 {
666   if (/* Don't change a variable array bound or initial value to a constant
667          in a place where a variable is invalid.  */
668       current_function_decl != 0
669       && ! TREE_THIS_VOLATILE (decl)
670       && TREE_READONLY (decl)
671       && DECL_INITIAL (decl) != 0
672       && TREE_CODE (DECL_INITIAL (decl)) != ERROR_MARK
673       /* This is invalid if initial value is not constant.
674          If it has either a function call, a memory reference,
675          or a variable, then re-evaluating it could give different results.  */
676       && TREE_CONSTANT (DECL_INITIAL (decl))
677       /* Check for cases where this is sub-optimal, even though valid.  */
678       && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)
679     return DECL_INITIAL (decl);
680   return decl;
681 }
682
683 /* Every call to a static constructor has an associated boolean
684    variable which is in the outermost scope of the calling method.
685    This variable is used to avoid multiple calls to the static
686    constructor for each class.
687
688    It looks something like this:
689
690    foo ()
691    {
692       boolean dummy = OtherClass.is_initialized;
693
694      ...
695
696      if (! dummy)
697        OtherClass.initialize();
698
699      ... use OtherClass.data ...
700    }
701
702    Each of these boolean variables has an entry in the
703    DECL_FUNCTION_INIT_TEST_TABLE of a method.  When inlining a method
704    we must merge the DECL_FUNCTION_INIT_TEST_TABLE from the function
705    being inlined and create the boolean variables in the outermost
706    scope of the method being inlined into.  */
707
708 /* Create a mapping from a boolean variable in a method being inlined
709    to one in the scope of the method being inlined into.  */
710
711 static int
712 merge_init_test_initialization (void **entry, void *x)
713 {
714   struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
715   splay_tree decl_map = (splay_tree)x;
716   splay_tree_node n;
717   tree *init_test_decl;
718
719   /* See if we have remapped this declaration.  If we haven't there's
720      a bug in the inliner.  */
721   n = splay_tree_lookup (decl_map, (splay_tree_key) ite->value);
722   gcc_assert (n);
723
724   /* Create a new entry for the class and its remapped boolean
725      variable.  If we already have a mapping for this class we've
726      already initialized it, so don't overwrite the value.  */
727   init_test_decl = java_treetreehash_new
728     (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), ite->key);
729   if (!*init_test_decl)
730     *init_test_decl = (tree)n->value;
731
732   /* This fixes a weird case.
733
734   The front end assumes that once we have called a method that
735   initializes some class, we can assume the class is initialized.  It
736   does this by setting the DECL_INITIAL of the init_test_decl for that
737   class, and no initializations are emitted for that class.
738
739   However, what if the method that is supposed to do the initialization
740   is itself inlined in the caller?  When expanding the called method
741   we'll assume that the class initialization has already been done,
742   because the DECL_INITIAL of the init_test_decl is set.
743
744   To fix this we remove the DECL_INITIAL (in the caller scope) of all
745   the init_test_decls corresponding to classes initialized by the
746   inlined method.  This makes the caller no longer assume that the
747   method being inlined does any class initializations.  */
748   DECL_INITIAL (*init_test_decl) = NULL;
749
750   return true;
751 }
752
753 /* Merge the DECL_FUNCTION_INIT_TEST_TABLE from the function we're
754    inlining.  */
755
756 void
757 java_inlining_merge_static_initializers (tree fn, void *decl_map)
758 {
759   htab_traverse
760     (DECL_FUNCTION_INIT_TEST_TABLE (fn),
761      merge_init_test_initialization, decl_map);
762 }
763
764 /* Lookup a DECL_FUNCTION_INIT_TEST_TABLE entry in the method we're
765    inlining into.  If we already have a corresponding entry in that
766    class we don't need to create another one, so we create a mapping
767    from the variable in the inlined class to the corresponding
768    pre-existing one.  */
769
770 static int
771 inline_init_test_initialization (void **entry, void *x)
772 {
773   struct treetreehash_entry *ite = (struct treetreehash_entry *) *entry;
774   splay_tree decl_map = (splay_tree)x;
775
776   tree h = java_treetreehash_find
777     (DECL_FUNCTION_INIT_TEST_TABLE (current_function_decl), ite->key);
778   if (! h)
779     return true;
780   splay_tree_insert (decl_map,
781                      (splay_tree_key) ite->value,
782                      (splay_tree_value) h);
783   return true;
784 }
785
786 /* Look up the boolean variables in the DECL_FUNCTION_INIT_TEST_TABLE
787    of a method being inlined.  For each hone, if we already have a
788    variable associated with the same class in the method being inlined
789    into, create a new mapping for it.  */
790
791 void
792 java_inlining_map_static_initializers (tree fn, void *decl_map)
793 {
794   htab_traverse
795     (DECL_FUNCTION_INIT_TEST_TABLE (fn),
796      inline_init_test_initialization, decl_map);
797 }
798
799 /* Avoid voluminous output for deep recursion of compound exprs.  */
800
801 static void
802 dump_compound_expr (dump_info_p di, tree t)
803 {
804   int i;
805
806   for (i=0; i<2; i++)
807     {
808       switch (TREE_CODE (TREE_OPERAND (t, i)))
809         {
810         case COMPOUND_EXPR:
811           dump_compound_expr (di, TREE_OPERAND (t, i));
812           break;
813
814         default:
815           dump_child ("expr", TREE_OPERAND (t, i));
816         }
817     }
818 }
819
820 static bool
821 java_dump_tree (void *dump_info, tree t)
822 {
823   enum tree_code code;
824   dump_info_p di = (dump_info_p) dump_info;
825
826   /* Figure out what kind of node this is.  */
827   code = TREE_CODE (t);
828
829   switch (code)
830     {
831     case FUNCTION_DECL:
832       dump_child ("args", DECL_ARGUMENTS (t));
833       if (DECL_EXTERNAL (t))
834         dump_string (di, "undefined");
835       if (TREE_PUBLIC (t))
836         dump_string (di, "extern");
837       else
838         dump_string (di, "static");
839       if (DECL_LANG_SPECIFIC (t))
840         dump_child ("body", DECL_FUNCTION_BODY (t));
841       if (DECL_LANG_SPECIFIC (t) && !dump_flag (di, TDF_SLIM, t))
842         dump_child ("inline body", DECL_SAVED_TREE (t));
843       return true;
844
845     case RETURN_EXPR:
846       dump_child ("expr", TREE_OPERAND (t, 0));
847       return true;
848
849     case GOTO_EXPR:
850       dump_child ("goto", TREE_OPERAND (t, 0));
851       return true;
852
853     case LABEL_EXPR:
854       dump_child ("label", TREE_OPERAND (t, 0));
855       return true;
856
857     case BLOCK:
858       if (BLOCK_EXPR_BODY (t))
859         {
860           tree local = BLOCK_VARS (t);
861           while (local)
862             {
863               tree next = TREE_CHAIN (local);
864               dump_child ("var", local);
865               local = next;
866             }
867
868           {
869             tree block = BLOCK_EXPR_BODY (t);
870             dump_child ("body", block);
871             block = TREE_CHAIN (block);
872           }
873         }
874       return true;
875
876     case COMPOUND_EXPR:
877       if (!dump_flag (di, TDF_SLIM, t))
878         return false;
879       dump_compound_expr (di, t);
880       return true;
881
882     default:
883       break;
884     }
885   return false;
886 }
887
888 /* Java calls can't, in general, be sibcalls because we need an
889    accurate stack trace in order to guarantee correct operation of
890    methods such as Class.forName(String) and
891    SecurityManager.getClassContext().  */
892
893 static bool
894 java_decl_ok_for_sibcall (const_tree decl)
895 {
896   return (decl != NULL && DECL_CONTEXT (decl) == output_class
897           && DECL_INLINE (decl));
898 }
899
900 /* Given a call_expr, try to figure out what its target might be.  In
901    the case of an indirection via the atable, search for the decl.  If
902    the decl is external, we return NULL.  If we don't, the optimizer
903    will replace the indirection with a direct call, which undoes the
904    purpose of the atable indirection.  */
905 static tree
906 java_get_callee_fndecl (const_tree call_expr)
907 {
908   tree method, table, element, atable_methods;
909
910   HOST_WIDE_INT index;
911
912   /* FIXME: This is disabled because we end up passing calls through
913      the PLT, and we do NOT want to do that.  */
914   return NULL;
915
916   if (TREE_CODE (call_expr) != CALL_EXPR)
917     return NULL;
918   method = CALL_EXPR_FN (call_expr);
919   STRIP_NOPS (method);
920   if (TREE_CODE (method) != ARRAY_REF)
921     return NULL;
922   table = TREE_OPERAND (method, 0);
923   if (! DECL_LANG_SPECIFIC(table)
924       || !DECL_OWNER (table)
925       || TYPE_ATABLE_DECL (DECL_OWNER (table)) != table)
926     return NULL;
927
928   atable_methods = TYPE_ATABLE_METHODS (DECL_OWNER (table));
929   index = TREE_INT_CST_LOW (TREE_OPERAND (method, 1));
930
931   /* FIXME: Replace this for loop with a hash table lookup.  */
932   for (element = atable_methods; element; element = TREE_CHAIN (element))
933     {
934       if (index == 1)
935         {
936           tree purpose = TREE_PURPOSE (element);
937           if (TREE_CODE (purpose) == FUNCTION_DECL
938               && ! DECL_EXTERNAL (purpose))
939             return purpose;
940           else
941             return NULL;
942         }
943       --index;
944     }
945
946   return NULL;
947 }
948
949
950 /* Clear the binding stack.  */
951 static void
952 java_clear_binding_stack (void)
953 {
954   while (!global_bindings_p ())
955     poplevel (0, 0, 0);
956 }
957
958 #include "gt-java-lang.h"