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