]>
Commit | Line | Data |
---|---|---|
e04a16fb AG |
1 | /* Process declarations and variables for the GNU compiler for the |
2 | Java(TM) language. | |
3852e8af | 3 | Copyright (C) 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. |
e04a16fb AG |
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" | |
1f43f4b4 | 29 | #include "system.h" |
e04a16fb | 30 | #include "tree.h" |
e8b22dd1 AH |
31 | #include "toplev.h" |
32 | #include "flags.h" | |
e04a16fb AG |
33 | #include "java-tree.h" |
34 | #include "jcf.h" | |
1f43f4b4 | 35 | #include "toplev.h" |
b384405b | 36 | #include "function.h" |
138657ec | 37 | #include "except.h" |
0ae70c6a | 38 | #include "defaults.h" |
e8b22dd1 AH |
39 | #include "java-except.h" |
40 | ||
41 | #if defined (DEBUG_JAVA_BINDING_LEVELS) | |
42 | extern void indent PROTO((void)); | |
43 | #endif | |
e04a16fb | 44 | |
df32d2ce KG |
45 | static tree push_jvm_slot PARAMS ((int, tree)); |
46 | static tree lookup_name_current_level PARAMS ((tree)); | |
47 | static tree push_promoted_type PARAMS ((const char *, tree)); | |
48 | static struct binding_level *make_binding_level PARAMS ((void)); | |
4bcde32e | 49 | |
3ff9925c AG |
50 | /* Set to non-zero value in order to emit class initilization code |
51 | before static field references. */ | |
52 | extern int always_initialize_class_p; | |
53 | ||
9d45bec2 PB |
54 | #ifndef INT_TYPE_SIZE |
55 | #define INT_TYPE_SIZE BITS_PER_WORD | |
56 | #endif | |
57 | ||
e04a16fb AG |
58 | /* The DECL_MAP is a mapping from (index, type) to a decl node. |
59 | If index < max_locals, it is the index of a local variable. | |
60 | if index >= max_locals, then index-max_locals is a stack slot. | |
61 | The DECL_MAP mapping is represented as a TREE_VEC whose elements | |
62 | are a list of decls (VAR_DECL or PARM_DECL) chained by | |
63 | DECL_LOCAL_SLOT_CHAIN; the index finds the TREE_VEC element, and then | |
64 | we search the chain for a decl with a matching TREE_TYPE. */ | |
65 | ||
66 | tree decl_map; | |
67 | ||
68 | /* A list of local variables VAR_DECLs for this method that we have seen | |
69 | debug information, but we have not reached their starting (byte) PC yet. */ | |
70 | ||
71 | tree pending_local_decls = NULL_TREE; | |
72 | ||
73 | /* Push a local variable or stack slot into the decl_map, | |
74 | and assign it an rtl. */ | |
75 | ||
e8b22dd1 AH |
76 | #if defined(DEBUG_JAVA_BINDING_LEVELS) |
77 | int binding_depth = 0; | |
78 | int is_class_level = 0; | |
79 | int current_pc; | |
80 | ||
81 | void | |
82 | indent () | |
83 | { | |
84 | register unsigned i; | |
85 | ||
86 | for (i = 0; i < binding_depth*2; i++) | |
87 | putc (' ', stderr); | |
88 | } | |
89 | #endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */ | |
90 | ||
4bcde32e | 91 | static tree |
e04a16fb AG |
92 | push_jvm_slot (index, decl) |
93 | int index; | |
94 | tree decl; | |
95 | { | |
96 | struct rtx_def *rtl = NULL; | |
97 | tree type = TREE_TYPE (decl); | |
98 | tree tmp; | |
99 | ||
100 | DECL_CONTEXT (decl) = current_function_decl; | |
101 | layout_decl (decl, 0); | |
102 | ||
103 | /* See if we have an appropriate rtl (i.e. same mode) at this index. | |
104 | If so, we must use it. */ | |
105 | tmp = TREE_VEC_ELT (decl_map, index); | |
106 | while (tmp != NULL_TREE) | |
107 | { | |
108 | if (TYPE_MODE (type) == TYPE_MODE (TREE_TYPE (tmp))) | |
109 | rtl = DECL_RTL (tmp); | |
110 | if (rtl != NULL) | |
111 | break; | |
112 | tmp = DECL_LOCAL_SLOT_CHAIN (tmp); | |
113 | } | |
114 | if (rtl != NULL) | |
115 | DECL_RTL (decl) = rtl; | |
116 | else | |
117 | { | |
118 | if (index >= DECL_MAX_LOCALS (current_function_decl)) | |
119 | DECL_REGISTER (decl) = 1; | |
120 | expand_decl (decl); | |
121 | } | |
122 | ||
123 | /* Now link the decl into the decl_map. */ | |
124 | if (DECL_LANG_SPECIFIC (decl) == NULL) | |
125 | { | |
126 | DECL_LANG_SPECIFIC (decl) | |
127 | = (struct lang_decl *) permalloc (sizeof (struct lang_decl_var)); | |
128 | DECL_LOCAL_START_PC (decl) = 0; | |
129 | DECL_LOCAL_END_PC (decl) = DECL_CODE_LENGTH (current_function_decl); | |
130 | DECL_LOCAL_SLOT_NUMBER (decl) = index; | |
131 | } | |
132 | DECL_LOCAL_SLOT_CHAIN (decl) = TREE_VEC_ELT (decl_map, index); | |
133 | TREE_VEC_ELT (decl_map, index) = decl; | |
134 | return decl; | |
135 | } | |
136 | ||
137 | /* Find a VAR_DECL (or PARM_DECL) at local index INDEX that has type TYPE, | |
138 | that is valid at PC (or -1 if any pc). | |
3fc61836 | 139 | If there is no existing matching decl, allocate one. */ |
e04a16fb AG |
140 | |
141 | tree | |
142 | find_local_variable (index, type, pc) | |
143 | int index; | |
144 | tree type; | |
145 | int pc; | |
146 | { | |
e04a16fb AG |
147 | tree decl = TREE_VEC_ELT (decl_map, index); |
148 | tree best = NULL_TREE; | |
3fc61836 | 149 | |
e04a16fb AG |
150 | while (decl != NULL_TREE) |
151 | { | |
152 | int in_range; | |
153 | in_range = pc < 0 | |
154 | || (pc >= DECL_LOCAL_START_PC (decl) | |
155 | && pc < DECL_LOCAL_END_PC (decl)); | |
156 | ||
157 | if ((TREE_TYPE (decl) == type | |
3fc61836 AG |
158 | || (TREE_CODE (TREE_TYPE (decl)) == TREE_CODE (type) |
159 | && TYPE_PRECISION (TREE_TYPE (decl)) <= 32 | |
160 | && TYPE_PRECISION (type) <= 32 | |
161 | && TREE_CODE (type) != POINTER_TYPE) | |
e04a16fb AG |
162 | || (TREE_CODE (TREE_TYPE (decl)) == POINTER_TYPE |
163 | && type == ptr_type_node)) | |
164 | && in_range) | |
165 | { | |
166 | if (best == NULL_TREE | |
167 | || (TREE_TYPE (decl) == type && TREE_TYPE (best) != type) | |
168 | || DECL_LOCAL_START_PC (decl) > DECL_LOCAL_START_PC (best) | |
169 | || DECL_LOCAL_END_PC (decl) < DECL_LOCAL_START_PC (decl)) | |
170 | best = decl; | |
171 | } | |
172 | decl = DECL_LOCAL_SLOT_CHAIN (decl); | |
173 | } | |
174 | if (best != NULL_TREE) | |
175 | return best; | |
176 | return push_jvm_slot (index, build_decl (VAR_DECL, NULL_TREE, type)); | |
177 | } | |
178 | ||
179 | ||
180 | /* Same as find_local_index, except that INDEX is a stack index. */ | |
181 | ||
182 | tree | |
183 | find_stack_slot (index, type) | |
184 | int index; | |
185 | tree type; | |
186 | { | |
187 | return find_local_variable (index + DECL_MAX_LOCALS (current_function_decl), | |
188 | type, -1); | |
189 | } | |
190 | ||
191 | struct binding_level | |
192 | { | |
193 | /* A chain of _DECL nodes for all variables, constants, functions, | |
194 | * and typedef types. These are in the reverse of the order supplied. | |
195 | */ | |
196 | tree names; | |
197 | ||
198 | /* For each level, a list of shadowed outer-level local definitions | |
199 | to be restored when this level is popped. | |
200 | Each link is a TREE_LIST whose TREE_PURPOSE is an identifier and | |
201 | whose TREE_VALUE is its old definition (a kind of ..._DECL node). */ | |
202 | tree shadowed; | |
203 | ||
204 | /* For each level (except not the global one), | |
205 | a chain of BLOCK nodes for all the levels | |
206 | that were entered and exited one level down. */ | |
207 | tree blocks; | |
208 | ||
209 | /* The BLOCK node for this level, if one has been preallocated. | |
210 | If 0, the BLOCK is allocated (if needed) when the level is popped. */ | |
211 | tree this_block; | |
212 | ||
213 | /* The binding level which this one is contained in (inherits from). */ | |
214 | struct binding_level *level_chain; | |
215 | ||
216 | /* 1 means make a BLOCK for this level regardless of all else. | |
217 | 2 for temporary binding contours created by the compiler. */ | |
218 | char keep; | |
219 | ||
220 | /* Nonzero means make a BLOCK if this level has any subblocks. */ | |
221 | char keep_if_subblocks; | |
222 | ||
223 | /* Nonzero if this level can safely have additional | |
224 | cleanup-needing variables added to it. */ | |
225 | char more_cleanups_ok; | |
226 | char have_cleanups; | |
227 | ||
228 | /* The bytecode PC that marks the end of this level. */ | |
229 | int end_pc; | |
71600a4a | 230 | /* The bytecode PC that marks the start of this level. */ |
e8b22dd1 AH |
231 | int start_pc; |
232 | ||
233 | #if defined(DEBUG_JAVA_BINDING_LEVELS) | |
234 | /* Binding depth at which this level began. */ | |
235 | unsigned binding_depth; | |
236 | #endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */ | |
e04a16fb AG |
237 | }; |
238 | ||
239 | #define NULL_BINDING_LEVEL (struct binding_level *) NULL | |
240 | ||
241 | /* The binding level currently in effect. */ | |
242 | ||
243 | static struct binding_level *current_binding_level; | |
244 | ||
245 | /* A chain of binding_level structures awaiting reuse. */ | |
246 | ||
247 | static struct binding_level *free_binding_level; | |
248 | ||
249 | /* The outermost binding level, for names of file scope. | |
250 | This is created when the compiler is started and exists | |
251 | through the entire run. */ | |
252 | ||
253 | static struct binding_level *global_binding_level; | |
254 | ||
e8b22dd1 AH |
255 | /* A PC value bigger than any PC value we may ever may encounter. */ |
256 | ||
257 | #define LARGEST_PC (( (unsigned int)1 << (HOST_BITS_PER_INT - 1)) - 1) | |
258 | ||
e04a16fb AG |
259 | /* Binding level structures are initialized by copying this one. */ |
260 | ||
261 | static struct binding_level clear_binding_level | |
262 | = {NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, | |
71600a4a | 263 | NULL_BINDING_LEVEL, 0, 0, 0, 0, LARGEST_PC, 0}; |
e04a16fb AG |
264 | |
265 | #if 0 | |
266 | /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function | |
267 | that have names. Here so we can clear out their names' definitions | |
268 | at the end of the function. */ | |
269 | ||
270 | static tree named_labels; | |
271 | ||
272 | /* A list of LABEL_DECLs from outer contexts that are currently shadowed. */ | |
273 | ||
274 | static tree shadowed_labels; | |
275 | #endif | |
276 | ||
277 | int flag_traditional; | |
278 | ||
279 | /* Nonzero means unconditionally make a BLOCK for the next level pushed. */ | |
280 | ||
281 | static int keep_next_level_flag; | |
282 | ||
283 | /* Nonzero means make a BLOCK for the next level pushed | |
284 | if it has subblocks. */ | |
285 | ||
286 | static int keep_next_if_subblocks; | |
287 | ||
e04a16fb | 288 | tree object_type_node; |
c877974e | 289 | tree unqualified_object_id_node; |
e04a16fb AG |
290 | tree object_ptr_type_node; |
291 | tree string_type_node; | |
cd9643f7 | 292 | tree string_ptr_type_node; |
e04a16fb | 293 | tree throwable_type_node; |
b9f7e36c APB |
294 | tree runtime_exception_type_node; |
295 | tree error_exception_type_node; | |
5423609c APB |
296 | tree *predef_filenames; |
297 | int predef_filenames_size; | |
e04a16fb AG |
298 | |
299 | tree boolean_type_node; | |
300 | ||
e04a16fb AG |
301 | tree return_address_type_node; |
302 | ||
e04a16fb AG |
303 | tree byte_type_node; |
304 | tree short_type_node; | |
305 | tree int_type_node; | |
306 | tree long_type_node; | |
307 | ||
308 | tree promoted_byte_type_node; | |
309 | tree promoted_short_type_node; | |
310 | tree promoted_char_type_node; | |
311 | tree promoted_boolean_type_node; | |
312 | ||
313 | tree unsigned_byte_type_node; | |
314 | tree unsigned_short_type_node; | |
315 | tree unsigned_int_type_node; | |
316 | tree unsigned_long_type_node; | |
317 | ||
318 | /* The type for struct methodtable. */ | |
319 | tree methodtable_type; | |
320 | tree methodtable_ptr_type; | |
321 | ||
322 | tree utf8const_type; | |
323 | tree utf8const_ptr_type; | |
324 | tree class_type_node; | |
325 | tree class_ptr_type; | |
326 | tree field_type_node; | |
327 | tree field_ptr_type_node; | |
328 | tree field_info_union_node; | |
329 | tree jexception_type; | |
330 | tree jexception_ptr_type; | |
331 | tree lineNumberEntry_type; | |
332 | tree lineNumbers_type; | |
333 | tree constants_type_node; | |
334 | tree dtable_type; | |
335 | tree dtable_ptr_type; | |
336 | tree method_type_node; | |
337 | tree method_ptr_type_node; | |
338 | tree nativecode_ptr_array_type_node; | |
339 | tree one_elt_array_domain_type; | |
340 | tree access_flags_type_node; | |
341 | tree class_dtable_decl; | |
342 | ||
81b3411c BS |
343 | /* Expressions that are constants with value zero, of types |
344 | `long', `float' and `double'. */ | |
4a5f66c3 APB |
345 | tree long_zero_node; |
346 | tree float_zero_node; | |
347 | tree double_zero_node; | |
348 | ||
9bbc7d9f | 349 | tree empty_stmt_node; |
e04a16fb AG |
350 | |
351 | /* Nodes for boolean constants TRUE and FALSE. */ | |
64aa33dd TT |
352 | tree boolean_true_node; |
353 | tree boolean_false_node; | |
e04a16fb AG |
354 | |
355 | tree TYPE_identifier_node; | |
356 | tree init_identifier_node; | |
357 | tree clinit_identifier_node; | |
22eed1e6 | 358 | tree finit_identifier_node; |
e04a16fb AG |
359 | tree void_signature_node; |
360 | tree length_identifier_node; | |
361 | tree this_identifier_node; | |
362 | tree super_identifier_node; | |
f1b0c0d8 | 363 | tree continue_identifier_node; |
c2952b01 | 364 | tree access0_identifier_node; /* 1.1 */ |
0bd2e6db PB |
365 | tree end_params_node; |
366 | ||
e04a16fb AG |
367 | /* References to internal libjava functions we use. */ |
368 | tree alloc_object_node; | |
369 | tree soft_instanceof_node; | |
370 | tree soft_checkcast_node; | |
371 | tree soft_initclass_node; | |
372 | tree soft_newarray_node; | |
373 | tree soft_anewarray_node; | |
374 | tree soft_multianewarray_node; | |
375 | tree soft_badarrayindex_node; | |
8bbb23b7 | 376 | tree throw_node [2]; |
e04a16fb AG |
377 | tree soft_checkarraystore_node; |
378 | tree soft_monitorenter_node; | |
379 | tree soft_monitorexit_node; | |
380 | tree soft_lookupinterfacemethod_node; | |
381 | tree soft_fmod_node; | |
9d45bec2 | 382 | tree soft_exceptioninfo_call_node; |
aa4759c1 AH |
383 | tree soft_idiv_node; |
384 | tree soft_irem_node; | |
385 | tree soft_ldiv_node; | |
386 | tree soft_lrem_node; | |
387 | ||
e04a16fb AG |
388 | /* Build (and pushdecl) a "promoted type" for all standard |
389 | types shorter than int. */ | |
390 | ||
391 | static tree | |
392 | push_promoted_type (name, actual_type) | |
c8e7d2e6 | 393 | const char *name; |
e04a16fb AG |
394 | tree actual_type; |
395 | { | |
396 | tree type = make_node (TREE_CODE (actual_type)); | |
397 | #if 1 | |
398 | tree in_min = TYPE_MIN_VALUE (int_type_node); | |
399 | tree in_max = TYPE_MAX_VALUE (int_type_node); | |
400 | #else | |
401 | tree in_min = TYPE_MIN_VALUE (actual_type); | |
402 | tree in_max = TYPE_MAX_VALUE (actual_type); | |
403 | #endif | |
665f2503 | 404 | TYPE_MIN_VALUE (type) = copy_node (in_min); |
e04a16fb | 405 | TREE_TYPE (TYPE_MIN_VALUE (type)) = type; |
665f2503 | 406 | TYPE_MAX_VALUE (type) = copy_node (in_max); |
e04a16fb AG |
407 | TREE_TYPE (TYPE_MAX_VALUE (type)) = type; |
408 | TYPE_PRECISION (type) = TYPE_PRECISION (int_type_node); | |
409 | layout_type (type); | |
410 | pushdecl (build_decl (TYPE_DECL, get_identifier (name), type)); | |
411 | return type; | |
412 | } | |
413 | ||
414 | /* Nodes for integer constants. */ | |
64aa33dd TT |
415 | tree integer_two_node; |
416 | tree integer_four_node; | |
e04a16fb AG |
417 | tree integer_negative_one_node; |
418 | ||
419 | /* Return a definition for a builtin function named NAME and whose data type | |
420 | is TYPE. TYPE should be a function type with argument types. | |
421 | FUNCTION_CODE tells later passes how to compile calls to this function. | |
422 | See tree.h for its possible values. | |
423 | ||
424 | If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME, | |
425 | the name to be called if we can't opencode the function. */ | |
426 | ||
26db82d8 BS |
427 | tree |
428 | builtin_function (name, type, function_code, class, library_name) | |
4bcde32e | 429 | const char *name; |
e04a16fb | 430 | tree type; |
26db82d8 BS |
431 | int function_code; |
432 | enum built_in_class class; | |
4bcde32e | 433 | const char *library_name; |
e04a16fb AG |
434 | { |
435 | tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type); | |
436 | DECL_EXTERNAL (decl) = 1; | |
437 | TREE_PUBLIC (decl) = 1; | |
438 | if (library_name) | |
439 | DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name); | |
440 | make_decl_rtl (decl, NULL_PTR, 1); | |
441 | pushdecl (decl); | |
26db82d8 BS |
442 | DECL_BUILT_IN_CLASS (decl) = class; |
443 | DECL_FUNCTION_CODE (decl) = function_code; | |
e04a16fb AG |
444 | return decl; |
445 | } | |
446 | ||
447 | void | |
448 | init_decl_processing () | |
449 | { | |
0bd2e6db | 450 | register tree endlink; |
ab3a6dd6 | 451 | tree field = NULL_TREE; |
e04a16fb AG |
452 | tree t; |
453 | ||
454 | current_function_decl = NULL; | |
455 | current_binding_level = NULL_BINDING_LEVEL; | |
456 | free_binding_level = NULL_BINDING_LEVEL; | |
457 | pushlevel (0); /* make the binding_level structure for global names */ | |
458 | global_binding_level = current_binding_level; | |
459 | ||
460 | error_mark_node = make_node (ERROR_MARK); | |
461 | TREE_TYPE (error_mark_node) = error_mark_node; | |
462 | ||
c2952b01 | 463 | initialize_sizetypes (); |
e04a16fb | 464 | /* Create sizetype first - needed for other types. */ |
4a7f1935 PB |
465 | initialize_sizetypes (); |
466 | set_sizetype (make_unsigned_type (POINTER_SIZE)); | |
e04a16fb AG |
467 | size_zero_node = build_int_2 (0, 0); |
468 | TREE_TYPE (size_zero_node) = sizetype; | |
469 | size_one_node = build_int_2 (1, 0); | |
470 | TREE_TYPE (size_one_node) = sizetype; | |
471 | ||
472 | byte_type_node = make_signed_type (8); | |
473 | pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"), byte_type_node)); | |
474 | short_type_node = make_signed_type (16); | |
475 | pushdecl (build_decl (TYPE_DECL, get_identifier ("short"), short_type_node)); | |
476 | int_type_node = make_signed_type (32); | |
477 | pushdecl (build_decl (TYPE_DECL, get_identifier ("int"), int_type_node)); | |
478 | long_type_node = make_signed_type (64); | |
479 | pushdecl (build_decl (TYPE_DECL, get_identifier ("long"), long_type_node)); | |
480 | ||
481 | unsigned_byte_type_node = make_unsigned_type (8); | |
482 | pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"), | |
483 | unsigned_byte_type_node)); | |
484 | unsigned_short_type_node = make_unsigned_type (16); | |
485 | pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned short"), | |
486 | unsigned_short_type_node)); | |
487 | unsigned_int_type_node = make_unsigned_type (32); | |
488 | pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"), | |
489 | unsigned_int_type_node)); | |
490 | unsigned_long_type_node = make_unsigned_type (64); | |
491 | pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned long"), | |
492 | unsigned_long_type_node)); | |
493 | ||
9d45bec2 | 494 | integer_type_node = type_for_size (INT_TYPE_SIZE, 0); |
e04a16fb AG |
495 | |
496 | integer_zero_node = build_int_2 (0, 0); | |
497 | integer_one_node = build_int_2 (1, 0); | |
498 | integer_two_node = build_int_2 (2, 0); | |
499 | integer_four_node = build_int_2 (4, 0); | |
500 | integer_negative_one_node = build_int_2 (-1, 0); | |
501 | ||
4a5f66c3 APB |
502 | long_zero_node = build_int_2 (0, 0); |
503 | TREE_TYPE (long_zero_node) = long_type_node; | |
504 | ||
e04a16fb AG |
505 | void_type_node = make_node (VOID_TYPE); |
506 | pushdecl (build_decl (TYPE_DECL, get_identifier ("void"), void_type_node)); | |
507 | layout_type (void_type_node); /* Uses size_zero_node */ | |
508 | ptr_type_node = build_pointer_type (void_type_node); | |
509 | t = make_node (VOID_TYPE); | |
510 | layout_type (t); /* Uses size_zero_node */ | |
511 | return_address_type_node = build_pointer_type (t); | |
512 | ||
513 | null_pointer_node = build_int_2 (0, 0); | |
514 | TREE_TYPE (null_pointer_node) = ptr_type_node; | |
515 | ||
9bbc7d9f PB |
516 | /* Used by the parser to represent empty statements and blocks. */ |
517 | empty_stmt_node = build1 (NOP_EXPR, void_type_node, size_zero_node); | |
518 | CAN_COMPLETE_NORMALLY (empty_stmt_node) = 1; | |
519 | ||
e04a16fb AG |
520 | #if 0 |
521 | /* Make a type to be the domain of a few array types | |
522 | whose domains don't really matter. | |
523 | 200 is small enough that it always fits in size_t | |
524 | and large enough that it can hold most function names for the | |
525 | initializations of __FUNCTION__ and __PRETTY_FUNCTION__. */ | |
526 | short_array_type_node = build_prim_array_type (short_type_node, 200); | |
527 | #endif | |
528 | char_type_node = make_node (CHAR_TYPE); | |
529 | TYPE_PRECISION (char_type_node) = 16; | |
530 | fixup_unsigned_type (char_type_node); | |
531 | pushdecl (build_decl (TYPE_DECL, get_identifier ("char"), char_type_node)); | |
532 | ||
533 | boolean_type_node = make_node (BOOLEAN_TYPE); | |
534 | TYPE_PRECISION (boolean_type_node) = 1; | |
535 | fixup_unsigned_type (boolean_type_node); | |
536 | pushdecl (build_decl (TYPE_DECL, get_identifier ("boolean"), | |
537 | boolean_type_node)); | |
538 | boolean_false_node = TYPE_MIN_VALUE (boolean_type_node); | |
539 | boolean_true_node = TYPE_MAX_VALUE (boolean_type_node); | |
540 | ||
541 | promoted_byte_type_node | |
542 | = push_promoted_type ("promoted_byte", byte_type_node); | |
543 | promoted_short_type_node | |
544 | = push_promoted_type ("promoted_short", short_type_node); | |
545 | promoted_char_type_node | |
546 | = push_promoted_type ("promoted_char", char_type_node); | |
547 | promoted_boolean_type_node | |
548 | = push_promoted_type ("promoted_boolean", boolean_type_node); | |
549 | ||
550 | float_type_node = make_node (REAL_TYPE); | |
551 | TYPE_PRECISION (float_type_node) = 32; | |
552 | pushdecl (build_decl (TYPE_DECL, get_identifier ("float"), | |
553 | float_type_node)); | |
554 | layout_type (float_type_node); | |
555 | ||
556 | double_type_node = make_node (REAL_TYPE); | |
557 | TYPE_PRECISION (double_type_node) = 64; | |
558 | pushdecl (build_decl (TYPE_DECL, get_identifier ("double"), | |
559 | double_type_node)); | |
560 | layout_type (double_type_node); | |
561 | ||
4a5f66c3 APB |
562 | float_zero_node = build_real (float_type_node, dconst0); |
563 | double_zero_node = build_real (double_type_node, dconst0); | |
564 | ||
5423609c APB |
565 | /* As your adding items here, please update the code right after |
566 | this section, so that the filename containing the source code of | |
567 | the pre-defined class gets registered correctly. */ | |
c877974e | 568 | unqualified_object_id_node = get_identifier ("Object"); |
e04a16fb AG |
569 | object_type_node = lookup_class (get_identifier ("java.lang.Object")); |
570 | object_ptr_type_node = promote_type (object_type_node); | |
571 | string_type_node = lookup_class (get_identifier ("java.lang.String")); | |
cd9643f7 | 572 | string_ptr_type_node = promote_type (string_type_node); |
e04a16fb AG |
573 | class_type_node = lookup_class (get_identifier ("java.lang.Class")); |
574 | throwable_type_node = lookup_class (get_identifier ("java.lang.Throwable")); | |
b9f7e36c APB |
575 | runtime_exception_type_node = |
576 | lookup_class (get_identifier ("java.lang.RuntimeException")); | |
577 | error_exception_type_node = | |
578 | lookup_class (get_identifier ("java.lang.Error")); | |
e04a16fb | 579 | |
5423609c APB |
580 | /* This section has to be updated as items are added to the previous |
581 | section. */ | |
582 | predef_filenames_size = 6; | |
583 | predef_filenames = (tree *)xmalloc (predef_filenames_size * sizeof (tree)); | |
584 | predef_filenames [0] = get_identifier ("java/lang/Class.java"); | |
585 | predef_filenames [1] = get_identifier ("java/lang/Error.java"); | |
586 | predef_filenames [2] = get_identifier ("java/lang/Object.java"); | |
587 | predef_filenames [3] = get_identifier ("java/lang/RuntimeException.java"); | |
588 | predef_filenames [4] = get_identifier ("java/lang/String.java"); | |
589 | predef_filenames [5] = get_identifier ("java/lang/Throwable.java"); | |
590 | ||
e04a16fb AG |
591 | methodtable_type = make_node (RECORD_TYPE); |
592 | layout_type (methodtable_type); | |
5e942c50 | 593 | build_decl (TYPE_DECL, get_identifier ("methodtable"), methodtable_type); |
e04a16fb AG |
594 | methodtable_ptr_type = build_pointer_type (methodtable_type); |
595 | ||
596 | TYPE_identifier_node = get_identifier ("TYPE"); | |
597 | init_identifier_node = get_identifier ("<init>"); | |
598 | clinit_identifier_node = get_identifier ("<clinit>"); | |
157412f5 | 599 | finit_identifier_node = get_identifier ("$finit$"); |
e04a16fb AG |
600 | void_signature_node = get_identifier ("()V"); |
601 | length_identifier_node = get_identifier ("length"); | |
602 | this_identifier_node = get_identifier ("this"); | |
603 | super_identifier_node = get_identifier ("super"); | |
f1b0c0d8 | 604 | continue_identifier_node = get_identifier ("continue"); |
c2952b01 | 605 | access0_identifier_node = get_identifier ("access$0"); |
e04a16fb AG |
606 | |
607 | /* for lack of a better place to put this stub call */ | |
608 | init_expr_processing(); | |
609 | ||
610 | utf8const_type = make_node (RECORD_TYPE); | |
611 | PUSH_FIELD (utf8const_type, field, "hash", unsigned_short_type_node); | |
612 | PUSH_FIELD (utf8const_type, field, "length", unsigned_short_type_node); | |
613 | FINISH_RECORD (utf8const_type); | |
614 | utf8const_ptr_type = build_pointer_type (utf8const_type); | |
615 | ||
616 | constants_type_node = make_node (RECORD_TYPE); | |
617 | PUSH_FIELD (constants_type_node, field, "size", unsigned_int_type_node); | |
618 | PUSH_FIELD (constants_type_node, field, "tags", ptr_type_node); | |
619 | PUSH_FIELD (constants_type_node, field, "data", ptr_type_node); | |
620 | FINISH_RECORD (constants_type_node); | |
5e942c50 | 621 | build_decl (TYPE_DECL, get_identifier ("constants"), constants_type_node); |
e04a16fb AG |
622 | |
623 | access_flags_type_node = unsigned_short_type_node; | |
624 | ||
625 | dtable_type = make_node (RECORD_TYPE); | |
626 | dtable_ptr_type = build_pointer_type (dtable_type); | |
627 | ||
78857b4e | 628 | PUSH_FIELD (object_type_node, field, "vtable", dtable_ptr_type); |
2c6c322a TT |
629 | /* This isn't exactly true, but it is what we have in the source. |
630 | There is an unresolved issue here, which is whether the vtable | |
631 | should be marked by the GC. */ | |
64aa33dd TT |
632 | if (! flag_hash_synchronization) |
633 | PUSH_FIELD (object_type_node, field, "sync_info", | |
634 | build_pointer_type (object_type_node)); | |
e04a16fb AG |
635 | for (t = TYPE_FIELDS (object_type_node); t != NULL_TREE; t = TREE_CHAIN (t)) |
636 | FIELD_PRIVATE (t) = 1; | |
637 | FINISH_RECORD (object_type_node); | |
638 | ||
639 | class_dtable_decl = build_dtable_decl (class_type_node); | |
640 | TREE_STATIC (class_dtable_decl) = 1; | |
641 | DECL_ARTIFICIAL (class_dtable_decl) = 1; | |
642 | DECL_IGNORED_P (class_dtable_decl) = 1; | |
643 | rest_of_decl_compilation (class_dtable_decl, (char*) 0, 1, 0); | |
644 | ||
645 | field_type_node = make_node (RECORD_TYPE); | |
646 | field_ptr_type_node = build_pointer_type (field_type_node); | |
647 | method_type_node = make_node (RECORD_TYPE); | |
648 | method_ptr_type_node = build_pointer_type (method_type_node); | |
649 | ||
650 | set_super_info (0, class_type_node, object_type_node, 0); | |
651 | set_super_info (0, string_type_node, object_type_node, 0); | |
652 | class_ptr_type = build_pointer_type (class_type_node); | |
653 | ||
654 | PUSH_FIELD (class_type_node, field, "next", class_ptr_type); | |
655 | PUSH_FIELD (class_type_node, field, "name", utf8const_ptr_type); | |
656 | PUSH_FIELD (class_type_node, field, "accflags", access_flags_type_node); | |
657 | PUSH_FIELD (class_type_node, field, "superclass", class_ptr_type); | |
e04a16fb AG |
658 | PUSH_FIELD (class_type_node, field, "constants", constants_type_node); |
659 | PUSH_FIELD (class_type_node, field, "methods", method_ptr_type_node); | |
571d54d5 | 660 | PUSH_FIELD (class_type_node, field, "method_count", short_type_node); |
78857b4e | 661 | PUSH_FIELD (class_type_node, field, "vtable_method_count", short_type_node); |
e04a16fb | 662 | PUSH_FIELD (class_type_node, field, "fields", field_ptr_type_node); |
571d54d5 TT |
663 | PUSH_FIELD (class_type_node, field, "size_in_bytes", int_type_node); |
664 | PUSH_FIELD (class_type_node, field, "field_count", short_type_node); | |
665 | PUSH_FIELD (class_type_node, field, "static_field_count", short_type_node); | |
78857b4e | 666 | PUSH_FIELD (class_type_node, field, "vtable", dtable_ptr_type); |
e04a16fb AG |
667 | PUSH_FIELD (class_type_node, field, "interfaces", |
668 | build_pointer_type (class_ptr_type)); | |
669 | PUSH_FIELD (class_type_node, field, "loader", ptr_type_node); | |
571d54d5 | 670 | PUSH_FIELD (class_type_node, field, "interface_count", short_type_node); |
e04a16fb | 671 | PUSH_FIELD (class_type_node, field, "state", byte_type_node); |
9d45bec2 | 672 | PUSH_FIELD (class_type_node, field, "thread", ptr_type_node); |
173f556c BM |
673 | PUSH_FIELD (class_type_node, field, "depth", short_type_node); |
674 | PUSH_FIELD (class_type_node, field, "ancestors", ptr_type_node); | |
675 | PUSH_FIELD (class_type_node, field, "idt", ptr_type_node); | |
e04a16fb AG |
676 | for (t = TYPE_FIELDS (class_type_node); t != NULL_TREE; t = TREE_CHAIN (t)) |
677 | FIELD_PRIVATE (t) = 1; | |
678 | push_super_field (class_type_node, object_type_node); | |
679 | FINISH_RECORD (class_type_node); | |
5e942c50 | 680 | build_decl (TYPE_DECL, get_identifier ("Class"), class_type_node); |
e04a16fb AG |
681 | |
682 | field_info_union_node = make_node (UNION_TYPE); | |
683 | PUSH_FIELD (field_info_union_node, field, "boffset", int_type_node); | |
684 | PUSH_FIELD (field_info_union_node, field, "addr", ptr_type_node); | |
685 | #if 0 | |
686 | PUSH_FIELD (field_info_union_node, field, "idx", unsigned_short_type_node); | |
687 | #endif | |
688 | layout_type (field_info_union_node); | |
689 | ||
690 | PUSH_FIELD (field_type_node, field, "name", utf8const_ptr_type); | |
691 | PUSH_FIELD (field_type_node, field, "type", class_ptr_type); | |
692 | PUSH_FIELD (field_type_node, field, "accflags", access_flags_type_node); | |
693 | PUSH_FIELD (field_type_node, field, "bsize", unsigned_short_type_node); | |
694 | PUSH_FIELD (field_type_node, field, "info", field_info_union_node); | |
695 | FINISH_RECORD (field_type_node); | |
696 | CLASS_LOADED_P (field_type_node) = 1; | |
5e942c50 | 697 | build_decl (TYPE_DECL, get_identifier ("Field"), field_type_node); |
e04a16fb AG |
698 | |
699 | one_elt_array_domain_type = build_index_type (integer_one_node); | |
700 | nativecode_ptr_array_type_node | |
701 | = build_array_type (nativecode_ptr_type_node, one_elt_array_domain_type); | |
702 | ||
703 | PUSH_FIELD (dtable_type, field, "class", class_ptr_type); | |
704 | PUSH_FIELD (dtable_type, field, "methods", nativecode_ptr_array_type_node); | |
705 | FINISH_RECORD (dtable_type); | |
5e942c50 | 706 | build_decl (TYPE_DECL, get_identifier ("dispatchTable"), dtable_type); |
e04a16fb AG |
707 | |
708 | #define jint_type int_type_node | |
709 | #define jint_ptr_type ptr_type_node | |
710 | ||
711 | jexception_type = make_node (RECORD_TYPE); | |
712 | PUSH_FIELD (jexception_type, field, "start_pc", ptr_type_node); | |
713 | PUSH_FIELD (jexception_type, field, "end_pc", ptr_type_node); | |
714 | PUSH_FIELD (jexception_type, field, "handler_pc", ptr_type_node); | |
715 | PUSH_FIELD (jexception_type, field, "catch_type", class_ptr_type); | |
716 | FINISH_RECORD (jexception_type); | |
5e942c50 | 717 | build_decl (TYPE_DECL, get_identifier ("jexception"), field_type_node); |
e04a16fb AG |
718 | jexception_ptr_type = build_pointer_type (jexception_type); |
719 | ||
720 | lineNumberEntry_type = make_node (RECORD_TYPE); | |
721 | PUSH_FIELD (lineNumberEntry_type, field, "line_nr", unsigned_short_type_node); | |
722 | PUSH_FIELD (lineNumberEntry_type, field, "start_pc", ptr_type_node); | |
723 | FINISH_RECORD (lineNumberEntry_type); | |
724 | ||
725 | lineNumbers_type = make_node (RECORD_TYPE); | |
726 | PUSH_FIELD (lineNumbers_type, field, "length", unsigned_int_type_node); | |
727 | FINISH_RECORD (lineNumbers_type); | |
728 | ||
729 | #define instn_ptr_type_node ptr_type_node /* XXX JH */ | |
730 | ||
731 | #define lineNumbers_ptr_type_node build_pointer_type(lineNumbers_type) | |
732 | ||
733 | PUSH_FIELD (method_type_node, field, "name", utf8const_ptr_type); | |
734 | PUSH_FIELD (method_type_node, field, "signature", utf8const_ptr_type); | |
735 | PUSH_FIELD (method_type_node, field, "accflags", access_flags_type_node); | |
736 | PUSH_FIELD (method_type_node, field, "ncode", nativecode_ptr_type_node); | |
737 | FINISH_RECORD (method_type_node); | |
738 | CLASS_LOADED_P (method_type_node) = 1; | |
5e942c50 | 739 | build_decl (TYPE_DECL, get_identifier ("Method"), method_type_node); |
e04a16fb | 740 | |
0bd2e6db PB |
741 | endlink = end_params_node = tree_cons (NULL_TREE, void_type_node, NULL_TREE); |
742 | ||
e04a16fb | 743 | t = tree_cons (NULL_TREE, class_ptr_type, |
0bd2e6db | 744 | tree_cons (NULL_TREE, int_type_node, endlink)); |
e04a16fb AG |
745 | alloc_object_node = builtin_function ("_Jv_AllocObject", |
746 | build_function_type (ptr_type_node, t), | |
26db82d8 | 747 | 0, NOT_BUILT_IN, NULL_PTR); |
1684f874 | 748 | DECL_IS_MALLOC (alloc_object_node) = 1; |
e04a16fb AG |
749 | soft_initclass_node = builtin_function ("_Jv_InitClass", |
750 | build_function_type (void_type_node, | |
751 | t), | |
26db82d8 BS |
752 | 0, NOT_BUILT_IN, |
753 | NULL_PTR); | |
0bd2e6db | 754 | t = tree_cons (NULL_TREE, ptr_type_node, endlink); |
8bbb23b7 AH |
755 | throw_node[0] = builtin_function ("_Jv_Throw", |
756 | build_function_type (ptr_type_node, t), | |
757 | 0, NOT_BUILT_IN, NULL_PTR); | |
758 | /* Mark throw_nodes as `noreturn' functions with side effects. */ | |
759 | TREE_THIS_VOLATILE (throw_node[0]) = 1; | |
760 | TREE_SIDE_EFFECTS (throw_node[0]) = 1; | |
761 | t = tree_cons (NULL_TREE, ptr_type_node, endlink); | |
762 | throw_node[1] = builtin_function ("_Jv_Sjlj_Throw", | |
763 | build_function_type (ptr_type_node, t), | |
764 | 0, NOT_BUILT_IN, NULL_PTR); | |
765 | TREE_THIS_VOLATILE (throw_node[1]) = 1; | |
766 | TREE_SIDE_EFFECTS (throw_node[1]) = 1; | |
0bd2e6db | 767 | t = build_function_type (int_type_node, endlink); |
e04a16fb | 768 | soft_monitorenter_node |
26db82d8 BS |
769 | = builtin_function ("_Jv_MonitorEnter", t, 0, NOT_BUILT_IN, |
770 | NULL_PTR); | |
e04a16fb | 771 | soft_monitorexit_node |
26db82d8 BS |
772 | = builtin_function ("_Jv_MonitorExit", t, 0, NOT_BUILT_IN, |
773 | NULL_PTR); | |
e04a16fb AG |
774 | |
775 | t = tree_cons (NULL_TREE, int_type_node, | |
0bd2e6db | 776 | tree_cons (NULL_TREE, int_type_node, endlink)); |
e04a16fb AG |
777 | soft_newarray_node |
778 | = builtin_function ("_Jv_NewArray", | |
779 | build_function_type(ptr_type_node, t), | |
26db82d8 | 780 | 0, NOT_BUILT_IN, NULL_PTR); |
1684f874 | 781 | DECL_IS_MALLOC (soft_newarray_node) = 1; |
e04a16fb AG |
782 | |
783 | t = tree_cons (NULL_TREE, int_type_node, | |
784 | tree_cons (NULL_TREE, class_ptr_type, | |
0bd2e6db | 785 | tree_cons (NULL_TREE, object_ptr_type_node, endlink))); |
e04a16fb AG |
786 | soft_anewarray_node |
787 | = builtin_function ("_Jv_NewObjectArray", | |
788 | build_function_type (ptr_type_node, t), | |
26db82d8 | 789 | 0, NOT_BUILT_IN, NULL_PTR); |
1684f874 | 790 | DECL_IS_MALLOC (soft_anewarray_node) = 1; |
e04a16fb AG |
791 | |
792 | t = tree_cons (NULL_TREE, ptr_type_node, | |
0bd2e6db | 793 | tree_cons (NULL_TREE, int_type_node, endlink)); |
e04a16fb AG |
794 | soft_multianewarray_node |
795 | = builtin_function ("_Jv_NewMultiArray", | |
796 | build_function_type (ptr_type_node, t), | |
26db82d8 | 797 | 0, NOT_BUILT_IN, NULL_PTR); |
1684f874 | 798 | DECL_IS_MALLOC (soft_multianewarray_node) = 1; |
e04a16fb | 799 | |
9d45bec2 | 800 | t = build_function_type (void_type_node, |
0bd2e6db | 801 | tree_cons (NULL_TREE, int_type_node, endlink)); |
e04a16fb | 802 | soft_badarrayindex_node |
9d45bec2 | 803 | = builtin_function ("_Jv_ThrowBadArrayIndex", t, |
26db82d8 | 804 | 0, NOT_BUILT_IN, NULL_PTR); |
1684f874 AG |
805 | /* Mark soft_badarrayindex_node as a `noreturn' function with side |
806 | effects. */ | |
e04a16fb AG |
807 | TREE_THIS_VOLATILE (soft_badarrayindex_node) = 1; |
808 | TREE_SIDE_EFFECTS (soft_badarrayindex_node) = 1; | |
809 | ||
810 | t = tree_cons (NULL_TREE, class_ptr_type, | |
0bd2e6db | 811 | tree_cons (NULL_TREE, object_ptr_type_node, endlink)); |
e04a16fb AG |
812 | soft_checkcast_node |
813 | = builtin_function ("_Jv_CheckCast", | |
814 | build_function_type (ptr_type_node, t), | |
26db82d8 | 815 | 0, NOT_BUILT_IN, NULL_PTR); |
e04a16fb | 816 | t = tree_cons (NULL_TREE, object_ptr_type_node, |
0bd2e6db | 817 | tree_cons (NULL_TREE, class_ptr_type, endlink)); |
e04a16fb AG |
818 | soft_instanceof_node |
819 | = builtin_function ("_Jv_IsInstanceOf", | |
99803cd4 | 820 | build_function_type (boolean_type_node, t), |
26db82d8 | 821 | 0, NOT_BUILT_IN, NULL_PTR); |
e04a16fb | 822 | t = tree_cons (NULL_TREE, object_ptr_type_node, |
0bd2e6db | 823 | tree_cons (NULL_TREE, object_ptr_type_node, endlink)); |
e04a16fb AG |
824 | soft_checkarraystore_node |
825 | = builtin_function ("_Jv_CheckArrayStore", | |
826 | build_function_type (void_type_node, t), | |
26db82d8 | 827 | 0, NOT_BUILT_IN, NULL_PTR); |
e04a16fb AG |
828 | t = tree_cons (NULL_TREE, ptr_type_node, |
829 | tree_cons (NULL_TREE, ptr_type_node, | |
173f556c | 830 | tree_cons (NULL_TREE, int_type_node, endlink))); |
e04a16fb | 831 | soft_lookupinterfacemethod_node |
173f556c | 832 | = builtin_function ("_Jv_LookupInterfaceMethodIdx", |
9d45bec2 | 833 | build_function_type (ptr_type_node, t), |
26db82d8 | 834 | 0, NOT_BUILT_IN, NULL_PTR); |
e04a16fb | 835 | t = tree_cons (NULL_TREE, double_type_node, |
0bd2e6db | 836 | tree_cons (NULL_TREE, double_type_node, endlink)); |
e04a16fb AG |
837 | soft_fmod_node |
838 | = builtin_function ("__builtin_fmod", | |
839 | build_function_type (double_type_node, t), | |
26db82d8 | 840 | BUILT_IN_FMOD, BUILT_IN_NORMAL, "fmod"); |
9d45bec2 | 841 | |
9d45bec2 PB |
842 | soft_exceptioninfo_call_node |
843 | = build (CALL_EXPR, | |
844 | ptr_type_node, | |
845 | build_address_of | |
846 | (builtin_function ("_Jv_exception_info", | |
0bd2e6db | 847 | build_function_type (ptr_type_node, endlink), |
26db82d8 | 848 | 0, NOT_BUILT_IN, NULL_PTR)), |
9d45bec2 PB |
849 | NULL_TREE, NULL_TREE); |
850 | TREE_SIDE_EFFECTS (soft_exceptioninfo_call_node) = 1; | |
e04a16fb AG |
851 | #if 0 |
852 | t = tree_cons (NULL_TREE, float_type_node, | |
0bd2e6db | 853 | tree_cons (NULL_TREE, float_type_node, endlink)); |
e04a16fb AG |
854 | soft_fmodf_node |
855 | = builtin_function ("__builtin_fmodf", | |
856 | build_function_type (float_type_node, t), | |
26db82d8 | 857 | BUILT_IN_FMOD, BUILT_IN_NORMAL, "fmodf"); |
e04a16fb AG |
858 | #endif |
859 | ||
aa4759c1 AH |
860 | soft_idiv_node |
861 | = builtin_function ("_Jv_divI", | |
862 | build_function_type (int_type_node, t), | |
26db82d8 | 863 | 0, NOT_BUILT_IN, NULL_PTR); |
aa4759c1 AH |
864 | |
865 | soft_irem_node | |
866 | = builtin_function ("_Jv_remI", | |
867 | build_function_type (int_type_node, t), | |
26db82d8 | 868 | 0, NOT_BUILT_IN, NULL_PTR); |
aa4759c1 AH |
869 | |
870 | soft_ldiv_node | |
871 | = builtin_function ("_Jv_divJ", | |
872 | build_function_type (long_type_node, t), | |
26db82d8 | 873 | 0, NOT_BUILT_IN, NULL_PTR); |
aa4759c1 AH |
874 | |
875 | soft_lrem_node | |
876 | = builtin_function ("_Jv_remJ", | |
877 | build_function_type (long_type_node, t), | |
26db82d8 | 878 | 0, NOT_BUILT_IN, NULL_PTR); |
aa4759c1 | 879 | |
e04a16fb AG |
880 | init_class_processing (); |
881 | } | |
882 | ||
883 | ||
884 | /* Look up NAME in the current binding level and its superiors | |
885 | in the namespace of variables, functions and typedefs. | |
886 | Return a ..._DECL node of some kind representing its definition, | |
887 | or return 0 if it is undefined. */ | |
888 | ||
889 | tree | |
890 | lookup_name (name) | |
891 | tree name; | |
892 | { | |
893 | register tree val; | |
894 | if (current_binding_level != global_binding_level | |
895 | && IDENTIFIER_LOCAL_VALUE (name)) | |
896 | val = IDENTIFIER_LOCAL_VALUE (name); | |
897 | else | |
898 | val = IDENTIFIER_GLOBAL_VALUE (name); | |
899 | return val; | |
900 | } | |
901 | ||
902 | /* Similar to `lookup_name' but look only at current binding level and | |
903 | the previous one if its the parameter level. */ | |
904 | ||
4bcde32e | 905 | static tree |
e04a16fb AG |
906 | lookup_name_current_level (name) |
907 | tree name; | |
908 | { | |
909 | register tree t; | |
910 | ||
911 | if (current_binding_level == global_binding_level) | |
912 | return IDENTIFIER_GLOBAL_VALUE (name); | |
913 | ||
914 | if (IDENTIFIER_LOCAL_VALUE (name) == 0) | |
915 | return 0; | |
916 | ||
917 | for (t = current_binding_level->names; t; t = TREE_CHAIN (t)) | |
918 | if (DECL_NAME (t) == name) | |
919 | break; | |
920 | ||
921 | return t; | |
922 | } | |
923 | ||
924 | /* Use a binding level to record a labeled block declaration */ | |
925 | ||
926 | void | |
927 | push_labeled_block (lb) | |
928 | tree lb; | |
929 | { | |
930 | register tree name = DECL_NAME (LABELED_BLOCK_LABEL (lb)); | |
931 | register struct binding_level *b = current_binding_level; | |
932 | tree oldlocal = IDENTIFIER_LOCAL_VALUE (name); | |
933 | if (oldlocal != 0) | |
934 | b->shadowed = tree_cons (name, oldlocal, b->shadowed); | |
935 | TREE_CHAIN (lb) = b->names; | |
936 | b->names = lb; | |
937 | IDENTIFIER_LOCAL_VALUE (name) = lb; | |
938 | } | |
939 | ||
940 | /* Pop the current binding level, reinstalling values for the previous | |
941 | labeled block */ | |
942 | ||
943 | void | |
944 | pop_labeled_block () | |
945 | { | |
946 | struct binding_level *b = current_binding_level; | |
947 | tree label = b->names; | |
948 | IDENTIFIER_LOCAL_VALUE (DECL_NAME (LABELED_BLOCK_LABEL (label))) = | |
949 | NULL_TREE; | |
950 | if (b->shadowed) | |
951 | IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (b->shadowed)) = | |
952 | TREE_VALUE (b->shadowed); | |
953 | ||
954 | /* Pop the current level, and free the structure for reuse. */ | |
955 | current_binding_level = current_binding_level->level_chain; | |
956 | b->level_chain = free_binding_level; | |
957 | free_binding_level = b; | |
958 | } | |
959 | ||
960 | /* Record a decl-node X as belonging to the current lexical scope. | |
961 | Check for errors (such as an incompatible declaration for the same | |
962 | name already seen in the same scope). | |
963 | ||
964 | Returns either X or an old decl for the same name. | |
965 | If an old decl is returned, it may have been smashed | |
966 | to agree with what X says. */ | |
967 | ||
968 | tree | |
969 | pushdecl (x) | |
970 | tree x; | |
971 | { | |
972 | register tree t; | |
973 | register tree name = DECL_NAME (x); | |
974 | register struct binding_level *b = current_binding_level; | |
c2952b01 APB |
975 | |
976 | if (TREE_CODE (x) != TYPE_DECL) | |
977 | DECL_CONTEXT (x) = current_function_decl; | |
e04a16fb AG |
978 | if (name) |
979 | { | |
c8e7d2e6 | 980 | const char *file; |
e04a16fb | 981 | int line; |
e04a16fb AG |
982 | |
983 | t = lookup_name_current_level (name); | |
984 | if (t != 0 && t == error_mark_node) | |
985 | /* error_mark_node is 0 for a while during initialization! */ | |
986 | { | |
987 | t = 0; | |
988 | error_with_decl (x, "`%s' used prior to declaration"); | |
989 | } | |
990 | ||
991 | if (t != 0) | |
992 | { | |
993 | file = DECL_SOURCE_FILE (t); | |
994 | line = DECL_SOURCE_LINE (t); | |
995 | } | |
996 | ||
997 | /* If we're naming a hitherto-unnamed type, set its TYPE_NAME | |
998 | to point to the TYPE_DECL. | |
999 | Since Java does not have typedefs, a type can only have | |
1000 | one (true) name, given by a class, interface, or builtin. */ | |
1001 | if (TREE_CODE (x) == TYPE_DECL | |
1002 | && TYPE_NAME (TREE_TYPE (x)) == 0 | |
1003 | && TREE_TYPE (x) != error_mark_node) | |
1004 | { | |
1005 | TYPE_NAME (TREE_TYPE (x)) = x; | |
1006 | TYPE_STUB_DECL (TREE_TYPE (x)) = x; | |
1007 | } | |
1008 | ||
1009 | /* This name is new in its binding level. | |
1010 | Install the new declaration and return it. */ | |
1011 | if (b == global_binding_level) | |
1012 | { | |
1013 | /* Install a global value. */ | |
1014 | ||
1015 | IDENTIFIER_GLOBAL_VALUE (name) = x; | |
1016 | } | |
1017 | else | |
1018 | { | |
1019 | /* Here to install a non-global value. */ | |
1020 | tree oldlocal = IDENTIFIER_LOCAL_VALUE (name); | |
e04a16fb AG |
1021 | IDENTIFIER_LOCAL_VALUE (name) = x; |
1022 | ||
1023 | #if 0 | |
1024 | /* Warn if shadowing an argument at the top level of the body. */ | |
1025 | if (oldlocal != 0 && !DECL_EXTERNAL (x) | |
1026 | /* This warning doesn't apply to the parms of a nested fcn. */ | |
1027 | && ! current_binding_level->parm_flag | |
1028 | /* Check that this is one level down from the parms. */ | |
1029 | && current_binding_level->level_chain->parm_flag | |
1030 | /* Check that the decl being shadowed | |
1031 | comes from the parm level, one level up. */ | |
1032 | && chain_member (oldlocal, current_binding_level->level_chain->names)) | |
1033 | { | |
1034 | if (TREE_CODE (oldlocal) == PARM_DECL) | |
1035 | pedwarn ("declaration of `%s' shadows a parameter", | |
1036 | IDENTIFIER_POINTER (name)); | |
1037 | else | |
1038 | pedwarn ("declaration of `%s' shadows a symbol from the parameter list", | |
1039 | IDENTIFIER_POINTER (name)); | |
1040 | } | |
1041 | ||
1042 | /* Maybe warn if shadowing something else. */ | |
1043 | else if (warn_shadow && !DECL_EXTERNAL (x) | |
1044 | /* No shadow warnings for internally generated vars. */ | |
1045 | && DECL_SOURCE_LINE (x) != 0 | |
1046 | /* No shadow warnings for vars made for inlining. */ | |
1047 | && ! DECL_FROM_INLINE (x)) | |
1048 | { | |
c8e7d2e6 | 1049 | const char *warnstring = 0; |
e04a16fb AG |
1050 | |
1051 | if (TREE_CODE (x) == PARM_DECL | |
1052 | && current_binding_level->level_chain->parm_flag) | |
1053 | /* Don't warn about the parm names in function declarator | |
1054 | within a function declarator. | |
1055 | It would be nice to avoid warning in any function | |
1056 | declarator in a declaration, as opposed to a definition, | |
1057 | but there is no way to tell it's not a definition. */ | |
1058 | ; | |
1059 | else if (oldlocal != 0 && TREE_CODE (oldlocal) == PARM_DECL) | |
1060 | warnstring = "declaration of `%s' shadows a parameter"; | |
1061 | else if (oldlocal != 0) | |
1062 | warnstring = "declaration of `%s' shadows previous local"; | |
1063 | else if (IDENTIFIER_GLOBAL_VALUE (name) != 0 | |
1064 | && IDENTIFIER_GLOBAL_VALUE (name) != error_mark_node) | |
1065 | warnstring = "declaration of `%s' shadows global declaration"; | |
1066 | ||
1067 | if (warnstring) | |
1068 | warning (warnstring, IDENTIFIER_POINTER (name)); | |
1069 | } | |
1070 | #endif | |
1071 | ||
1072 | /* If storing a local value, there may already be one (inherited). | |
1073 | If so, record it for restoration when this binding level ends. */ | |
1074 | if (oldlocal != 0) | |
1075 | b->shadowed = tree_cons (name, oldlocal, b->shadowed); | |
1076 | } | |
1077 | } | |
1078 | ||
1079 | /* Put decls on list in reverse order. | |
1080 | We will reverse them later if necessary. */ | |
1081 | TREE_CHAIN (x) = b->names; | |
1082 | b->names = x; | |
1083 | ||
1084 | return x; | |
1085 | } | |
64aa33dd | 1086 | |
e04a16fb AG |
1087 | void |
1088 | pushdecl_force_head (x) | |
1089 | tree x; | |
1090 | { | |
1091 | current_binding_level->names = x; | |
1092 | } | |
1093 | ||
1094 | /* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */ | |
1095 | ||
1096 | tree | |
1097 | pushdecl_top_level (x) | |
1098 | tree x; | |
1099 | { | |
1100 | register tree t; | |
1101 | register struct binding_level *b = current_binding_level; | |
1102 | ||
1103 | current_binding_level = global_binding_level; | |
1104 | t = pushdecl (x); | |
1105 | current_binding_level = b; | |
1106 | return t; | |
1107 | } | |
1108 | ||
1109 | /* Nonzero if we are currently in the global binding level. */ | |
1110 | ||
1111 | int | |
1112 | global_bindings_p () | |
1113 | { | |
1114 | return current_binding_level == global_binding_level; | |
1115 | } | |
1116 | ||
1117 | /* Return the list of declarations of the current level. | |
1118 | Note that this list is in reverse order unless/until | |
1119 | you nreverse it; and when you do nreverse it, you must | |
1120 | store the result back using `storedecls' or you will lose. */ | |
1121 | ||
1122 | tree | |
1123 | getdecls () | |
1124 | { | |
1125 | return current_binding_level->names; | |
1126 | } | |
1127 | ||
1128 | /* Create a new `struct binding_level'. */ | |
1129 | ||
64aa33dd | 1130 | static struct binding_level * |
e04a16fb AG |
1131 | make_binding_level () |
1132 | { | |
1133 | /* NOSTRICT */ | |
1134 | return (struct binding_level *) xmalloc (sizeof (struct binding_level)); | |
1135 | } | |
1136 | ||
1137 | void | |
1138 | pushlevel (unused) | |
d4476be2 | 1139 | int unused ATTRIBUTE_UNUSED; |
e04a16fb AG |
1140 | { |
1141 | register struct binding_level *newlevel = NULL_BINDING_LEVEL; | |
1142 | ||
1143 | #if 0 | |
1144 | /* If this is the top level of a function, | |
1145 | just make sure that NAMED_LABELS is 0. */ | |
1146 | ||
1147 | if (current_binding_level == global_binding_level) | |
1148 | named_labels = 0; | |
1149 | #endif | |
1150 | ||
1151 | /* Reuse or create a struct for this binding level. */ | |
1152 | ||
1153 | if (free_binding_level) | |
1154 | { | |
1155 | newlevel = free_binding_level; | |
1156 | free_binding_level = free_binding_level->level_chain; | |
1157 | } | |
1158 | else | |
1159 | { | |
1160 | newlevel = make_binding_level (); | |
1161 | } | |
1162 | ||
1163 | /* Add this level to the front of the chain (stack) of levels that | |
1164 | are active. */ | |
1165 | ||
1166 | *newlevel = clear_binding_level; | |
1167 | newlevel->level_chain = current_binding_level; | |
1168 | current_binding_level = newlevel; | |
1169 | newlevel->keep = keep_next_level_flag; | |
1170 | keep_next_level_flag = 0; | |
1171 | newlevel->keep_if_subblocks = keep_next_if_subblocks; | |
1172 | keep_next_if_subblocks = 0; | |
e8b22dd1 AH |
1173 | #if defined(DEBUG_JAVA_BINDING_LEVELS) |
1174 | newlevel->binding_depth = binding_depth; | |
1175 | indent (); | |
1176 | fprintf (stderr, "push %s level 0x%08x pc %d\n", | |
1177 | (is_class_level) ? "class" : "block", newlevel, current_pc); | |
1178 | is_class_level = 0; | |
1179 | binding_depth++; | |
1180 | #endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */ | |
e04a16fb AG |
1181 | } |
1182 | ||
1183 | /* Exit a binding level. | |
1184 | Pop the level off, and restore the state of the identifier-decl mappings | |
1185 | that were in effect when this level was entered. | |
1186 | ||
1187 | If KEEP is nonzero, this level had explicit declarations, so | |
1188 | and create a "block" (a BLOCK node) for the level | |
1189 | to record its declarations and subblocks for symbol table output. | |
1190 | ||
1191 | If FUNCTIONBODY is nonzero, this level is the body of a function, | |
1192 | so create a block as if KEEP were set and also clear out all | |
1193 | label names. | |
1194 | ||
1195 | If REVERSE is nonzero, reverse the order of decls before putting | |
1196 | them into the BLOCK. */ | |
1197 | ||
1198 | tree | |
1199 | poplevel (keep, reverse, functionbody) | |
1200 | int keep; | |
1201 | int reverse; | |
1202 | int functionbody; | |
1203 | { | |
1204 | register tree link; | |
1205 | /* The chain of decls was accumulated in reverse order. | |
1206 | Put it into forward order, just for cleanliness. */ | |
1207 | tree decls; | |
1208 | tree subblocks = current_binding_level->blocks; | |
1209 | tree block = 0; | |
1210 | tree decl; | |
1211 | int block_previously_created; | |
1212 | ||
e8b22dd1 AH |
1213 | #if defined(DEBUG_JAVA_BINDING_LEVELS) |
1214 | binding_depth--; | |
1215 | indent (); | |
1216 | if (current_binding_level->end_pc != LARGEST_PC) | |
1217 | fprintf (stderr, "pop %s level 0x%08x pc %d (end pc %d)\n", | |
1218 | (is_class_level) ? "class" : "block", current_binding_level, current_pc, | |
1219 | current_binding_level->end_pc); | |
1220 | else | |
1221 | fprintf (stderr, "pop %s level 0x%08x pc %d\n", | |
1222 | (is_class_level) ? "class" : "block", current_binding_level, current_pc); | |
1223 | #if 0 | |
1224 | if (is_class_level != (current_binding_level == class_binding_level)) | |
1225 | { | |
1226 | indent (); | |
1227 | fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n"); | |
1228 | } | |
1229 | is_class_level = 0; | |
1230 | #endif | |
1231 | #endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */ | |
1232 | ||
e04a16fb AG |
1233 | keep |= current_binding_level->keep; |
1234 | ||
1235 | /* Get the decls in the order they were written. | |
1236 | Usually current_binding_level->names is in reverse order. | |
1237 | But parameter decls were previously put in forward order. */ | |
1238 | ||
1239 | if (reverse) | |
1240 | current_binding_level->names | |
1241 | = decls = nreverse (current_binding_level->names); | |
1242 | else | |
1243 | decls = current_binding_level->names; | |
1244 | ||
1245 | /* Output any nested inline functions within this block | |
1246 | if they weren't already output. */ | |
1247 | ||
1248 | for (decl = decls; decl; decl = TREE_CHAIN (decl)) | |
1249 | if (TREE_CODE (decl) == FUNCTION_DECL | |
1250 | && ! TREE_ASM_WRITTEN (decl) | |
1251 | && DECL_INITIAL (decl) != 0 | |
1252 | && TREE_ADDRESSABLE (decl)) | |
1253 | { | |
1254 | /* If this decl was copied from a file-scope decl | |
1255 | on account of a block-scope extern decl, | |
1256 | propagate TREE_ADDRESSABLE to the file-scope decl. | |
1257 | ||
1258 | DECL_ABSTRACT_ORIGIN can be set to itself if warn_return_type is | |
1259 | true, since then the decl goes through save_for_inline_copying. */ | |
1260 | if (DECL_ABSTRACT_ORIGIN (decl) != 0 | |
1261 | && DECL_ABSTRACT_ORIGIN (decl) != decl) | |
1262 | TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1; | |
1263 | else | |
1264 | { | |
1265 | push_function_context (); | |
1266 | output_inline_function (decl); | |
1267 | pop_function_context (); | |
1268 | } | |
1269 | } | |
1270 | ||
1271 | /* If there were any declarations in that level, | |
1272 | or if this level is a function body, | |
1273 | create a BLOCK to record them for the life of this function. */ | |
1274 | ||
1275 | block = 0; | |
1276 | block_previously_created = (current_binding_level->this_block != 0); | |
1277 | if (block_previously_created) | |
1278 | block = current_binding_level->this_block; | |
1279 | else if (keep || functionbody | |
1280 | || (current_binding_level->keep_if_subblocks && subblocks != 0)) | |
1281 | block = make_node (BLOCK); | |
1282 | if (block != 0) | |
1283 | { | |
1284 | BLOCK_VARS (block) = decls; | |
e04a16fb | 1285 | BLOCK_SUBBLOCKS (block) = subblocks; |
e04a16fb AG |
1286 | } |
1287 | ||
1288 | /* In each subblock, record that this is its superior. */ | |
1289 | ||
1290 | for (link = subblocks; link; link = TREE_CHAIN (link)) | |
1291 | BLOCK_SUPERCONTEXT (link) = block; | |
1292 | ||
1293 | /* Clear out the meanings of the local variables of this level. */ | |
1294 | ||
1295 | for (link = decls; link; link = TREE_CHAIN (link)) | |
1296 | { | |
1297 | tree name = DECL_NAME (link); | |
1298 | if (name != 0 && IDENTIFIER_LOCAL_VALUE (name) == link) | |
1299 | { | |
1300 | /* If the ident. was used or addressed via a local extern decl, | |
1301 | don't forget that fact. */ | |
1302 | if (DECL_EXTERNAL (link)) | |
1303 | { | |
1304 | if (TREE_USED (link)) | |
1305 | TREE_USED (name) = 1; | |
1306 | if (TREE_ADDRESSABLE (link)) | |
1307 | TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1; | |
1308 | } | |
1309 | IDENTIFIER_LOCAL_VALUE (name) = 0; | |
1310 | } | |
1311 | } | |
1312 | ||
1313 | /* Restore all name-meanings of the outer levels | |
1314 | that were shadowed by this level. */ | |
1315 | ||
1316 | for (link = current_binding_level->shadowed; link; link = TREE_CHAIN (link)) | |
1317 | IDENTIFIER_LOCAL_VALUE (TREE_PURPOSE (link)) = TREE_VALUE (link); | |
1318 | ||
1319 | /* If the level being exited is the top level of a function, | |
1320 | check over all the labels, and clear out the current | |
1321 | (function local) meanings of their names. */ | |
1322 | ||
1323 | if (functionbody) | |
1324 | { | |
1325 | /* If this is the top level block of a function, | |
1326 | the vars are the function's parameters. | |
1327 | Don't leave them in the BLOCK because they are | |
1328 | found in the FUNCTION_DECL instead. */ | |
1329 | ||
1330 | BLOCK_VARS (block) = 0; | |
1331 | ||
1332 | /* Clear out the definitions of all label names, | |
1333 | since their scopes end here, | |
1334 | and add them to BLOCK_VARS. */ | |
1335 | ||
1336 | #if 0 | |
1337 | for (link = named_labels; link; link = TREE_CHAIN (link)) | |
1338 | { | |
1339 | register tree label = TREE_VALUE (link); | |
1340 | ||
1341 | if (DECL_INITIAL (label) == 0) | |
1342 | { | |
1343 | error_with_decl (label, "label `%s' used but not defined"); | |
1344 | /* Avoid crashing later. */ | |
1345 | define_label (input_filename, lineno, | |
1346 | DECL_NAME (label)); | |
1347 | } | |
1348 | else if (warn_unused && !TREE_USED (label)) | |
1349 | warning_with_decl (label, "label `%s' defined but not used"); | |
1350 | IDENTIFIER_LABEL_VALUE (DECL_NAME (label)) = 0; | |
1351 | ||
1352 | /* Put the labels into the "variables" of the | |
1353 | top-level block, so debugger can see them. */ | |
1354 | TREE_CHAIN (label) = BLOCK_VARS (block); | |
1355 | BLOCK_VARS (block) = label; | |
1356 | } | |
1357 | #endif | |
1358 | } | |
1359 | ||
1360 | /* Pop the current level, and free the structure for reuse. */ | |
1361 | ||
1362 | { | |
1363 | register struct binding_level *level = current_binding_level; | |
1364 | current_binding_level = current_binding_level->level_chain; | |
1365 | ||
1366 | level->level_chain = free_binding_level; | |
1367 | free_binding_level = level; | |
1368 | } | |
1369 | ||
1370 | /* Dispose of the block that we just made inside some higher level. */ | |
1371 | if (functionbody) | |
1372 | DECL_INITIAL (current_function_decl) = block; | |
1373 | else if (block) | |
1374 | { | |
1375 | if (!block_previously_created) | |
1376 | current_binding_level->blocks | |
1377 | = chainon (current_binding_level->blocks, block); | |
1378 | } | |
1379 | /* If we did not make a block for the level just exited, | |
1380 | any blocks made for inner levels | |
1381 | (since they cannot be recorded as subblocks in that level) | |
1382 | must be carried forward so they will later become subblocks | |
1383 | of something else. */ | |
1384 | else if (subblocks) | |
1385 | current_binding_level->blocks | |
1386 | = chainon (current_binding_level->blocks, subblocks); | |
1387 | ||
1388 | /* Set the TYPE_CONTEXTs for all of the tagged types belonging to this | |
1389 | binding contour so that they point to the appropriate construct, i.e. | |
1390 | either to the current FUNCTION_DECL node, or else to the BLOCK node | |
1391 | we just constructed. | |
1392 | ||
1393 | Note that for tagged types whose scope is just the formal parameter | |
1394 | list for some function type specification, we can't properly set | |
1395 | their TYPE_CONTEXTs here, because we don't have a pointer to the | |
1396 | appropriate FUNCTION_TYPE node readily available to us. For those | |
1397 | cases, the TYPE_CONTEXTs of the relevant tagged type nodes get set | |
1398 | in `grokdeclarator' as soon as we have created the FUNCTION_TYPE | |
1399 | node which will represent the "scope" for these "parameter list local" | |
1400 | tagged types. | |
1401 | */ | |
1402 | ||
1403 | if (block) | |
1404 | TREE_USED (block) = 1; | |
1405 | return block; | |
1406 | } | |
1407 | ||
1408 | void | |
1409 | maybe_pushlevels (pc) | |
1410 | int pc; | |
1411 | { | |
e8b22dd1 AH |
1412 | #if defined(DEBUG_JAVA_BINDING_LEVELS) |
1413 | current_pc = pc; | |
1414 | #endif | |
1415 | ||
e04a16fb AG |
1416 | while (pending_local_decls != NULL_TREE && |
1417 | DECL_LOCAL_START_PC (pending_local_decls) <= pc) | |
1418 | { | |
1419 | tree *ptr = &pending_local_decls; | |
1420 | tree decl = *ptr; | |
1421 | int end_pc = DECL_LOCAL_END_PC (decl); | |
1422 | ||
1423 | while (*ptr != NULL_TREE | |
1424 | && DECL_LOCAL_START_PC (*ptr) <= pc | |
1425 | && DECL_LOCAL_END_PC (*ptr) == end_pc) | |
1426 | ptr = &TREE_CHAIN (*ptr); | |
1427 | pending_local_decls = *ptr; | |
1428 | *ptr = NULL_TREE; | |
1429 | ||
1430 | /* Force non-nested range to be nested in current range. */ | |
1431 | if (end_pc > current_binding_level->end_pc) | |
1432 | end_pc = current_binding_level->end_pc; | |
1433 | ||
e8b22dd1 AH |
1434 | maybe_start_try (pc, end_pc); |
1435 | ||
e04a16fb AG |
1436 | pushlevel (1); |
1437 | expand_start_bindings (0); | |
e8b22dd1 | 1438 | |
e04a16fb | 1439 | current_binding_level->end_pc = end_pc; |
e8b22dd1 | 1440 | current_binding_level->start_pc = pc; |
e04a16fb AG |
1441 | current_binding_level->names = decl; |
1442 | for ( ; decl != NULL_TREE; decl = TREE_CHAIN (decl)) | |
1443 | { | |
1444 | push_jvm_slot (DECL_LOCAL_SLOT_NUMBER (decl), decl); | |
1445 | } | |
e8b22dd1 AH |
1446 | } |
1447 | ||
1448 | maybe_start_try (pc, 0); | |
e04a16fb AG |
1449 | } |
1450 | ||
1451 | void | |
1452 | maybe_poplevels (pc) | |
1453 | int pc; | |
1454 | { | |
e8b22dd1 AH |
1455 | #if defined(DEBUG_JAVA_BINDING_LEVELS) |
1456 | current_pc = pc; | |
1457 | #endif | |
1458 | ||
e04a16fb AG |
1459 | while (current_binding_level->end_pc <= pc) |
1460 | { | |
e8b22dd1 AH |
1461 | expand_end_bindings (getdecls (), 1, 0); |
1462 | maybe_end_try (current_binding_level->start_pc, pc); | |
1463 | poplevel (1, 0, 0); | |
1464 | } | |
1465 | maybe_end_try (0, pc); | |
1466 | } | |
1467 | ||
1468 | /* Terminate any binding which began during the range beginning at | |
1469 | start_pc. This tidies up improperly nested local variable ranges | |
1470 | and exception handlers; a variable declared within an exception | |
1471 | range is forcibly terminated when that exception ends. */ | |
1472 | ||
1473 | void | |
1474 | force_poplevels (start_pc) | |
1475 | int start_pc; | |
1476 | { | |
1477 | while (current_binding_level->start_pc > start_pc) | |
1478 | { | |
e8b22dd1 AH |
1479 | if (pedantic && current_binding_level->start_pc > start_pc) |
1480 | warning_with_decl (current_function_decl, | |
1481 | "In %s: overlapped variable and exception ranges at %d", | |
1482 | current_binding_level->start_pc); | |
e04a16fb AG |
1483 | expand_end_bindings (getdecls (), 1, 0); |
1484 | poplevel (1, 0, 0); | |
1485 | } | |
1486 | } | |
1487 | ||
1488 | /* Insert BLOCK at the end of the list of subblocks of the | |
1489 | current binding level. This is used when a BIND_EXPR is expanded, | |
1490 | to handle the BLOCK node inside the BIND_EXPR. */ | |
1491 | ||
1492 | void | |
1493 | insert_block (block) | |
1494 | tree block; | |
1495 | { | |
1496 | TREE_USED (block) = 1; | |
e04a16fb AG |
1497 | current_binding_level->blocks |
1498 | = chainon (current_binding_level->blocks, block); | |
1499 | } | |
1500 | ||
1501 | /* Set the BLOCK node for the innermost scope | |
1502 | (the one we are currently in). */ | |
1503 | ||
1504 | void | |
1505 | set_block (block) | |
1506 | register tree block; | |
1507 | { | |
1508 | current_binding_level->this_block = block; | |
1509 | } | |
1510 | ||
1511 | /* integrate_decl_tree calls this function. */ | |
1512 | ||
1513 | void | |
1514 | copy_lang_decl (node) | |
1515 | tree node; | |
1516 | { | |
1517 | int lang_decl_size | |
1518 | = TREE_CODE (node) == VAR_DECL ? sizeof (struct lang_decl_var) | |
1519 | : sizeof (struct lang_decl); | |
1520 | struct lang_decl *x = (struct lang_decl *) oballoc (lang_decl_size); | |
4504ead1 | 1521 | bcopy ((PTR) DECL_LANG_SPECIFIC (node), (PTR) x, lang_decl_size); |
e04a16fb AG |
1522 | DECL_LANG_SPECIFIC (node) = x; |
1523 | } | |
1524 | ||
1525 | /* If DECL has a cleanup, build and return that cleanup here. | |
1526 | This is a callback called by expand_expr. */ | |
1527 | ||
1528 | tree | |
1529 | maybe_build_cleanup (decl) | |
d4476be2 | 1530 | tree decl ATTRIBUTE_UNUSED; |
e04a16fb AG |
1531 | { |
1532 | /* There are no cleanups in Java (I think). */ | |
1533 | return NULL_TREE; | |
1534 | } | |
1535 | ||
1536 | void | |
1537 | give_name_to_locals (jcf) | |
1538 | JCF *jcf; | |
1539 | { | |
1540 | int i, n = DECL_LOCALVARIABLES_OFFSET (current_function_decl); | |
1541 | tree parm; | |
1542 | pending_local_decls = NULL_TREE; | |
1543 | if (n == 0) | |
1544 | return; | |
1545 | JCF_SEEK (jcf, n); | |
1546 | n = JCF_readu2 (jcf); | |
1547 | for (i = 0; i < n; i++) | |
1548 | { | |
1549 | int start_pc = JCF_readu2 (jcf); | |
1550 | int length = JCF_readu2 (jcf); | |
1551 | int name_index = JCF_readu2 (jcf); | |
1552 | int signature_index = JCF_readu2 (jcf); | |
1553 | int slot = JCF_readu2 (jcf); | |
1554 | tree name = get_name_constant (jcf, name_index); | |
9d45bec2 | 1555 | tree type = parse_signature (jcf, signature_index); |
e04a16fb AG |
1556 | if (slot < DECL_ARG_SLOT_COUNT (current_function_decl) |
1557 | && start_pc == 0 | |
1558 | && length == DECL_CODE_LENGTH (current_function_decl)) | |
1559 | { | |
1560 | tree decl = TREE_VEC_ELT (decl_map, slot); | |
1561 | DECL_NAME (decl) = name; | |
1562 | DECL_ASSEMBLER_NAME (decl) = name; | |
1563 | if (TREE_CODE (decl) != PARM_DECL || TREE_TYPE (decl) != type) | |
1564 | warning ("bad type in parameter debug info"); | |
1565 | } | |
1566 | else | |
1567 | { | |
1568 | tree *ptr; | |
1569 | int end_pc = start_pc + length; | |
1570 | tree decl = build_decl (VAR_DECL, name, type); | |
1571 | if (end_pc > DECL_CODE_LENGTH (current_function_decl)) | |
1572 | { | |
1573 | warning_with_decl (decl, | |
1574 | "bad PC range for debug info for local `%s'"); | |
1575 | end_pc = DECL_CODE_LENGTH (current_function_decl); | |
1576 | } | |
1577 | DECL_LANG_SPECIFIC (decl) | |
1578 | = (struct lang_decl *) permalloc (sizeof (struct lang_decl_var)); | |
1579 | DECL_LOCAL_SLOT_NUMBER (decl) = slot; | |
1580 | DECL_LOCAL_START_PC (decl) = start_pc; | |
e8b22dd1 AH |
1581 | #if 0 |
1582 | /* FIXME: The range used internally for exceptions and local | |
1583 | variable ranges, is a half-open interval: | |
1584 | start_pc <= pc < end_pc. However, the range used in the | |
1585 | Java VM spec is inclusive at both ends: | |
1586 | start_pc <= pc <= end_pc. */ | |
1587 | end_pc++; | |
1588 | #endif | |
e04a16fb AG |
1589 | DECL_LOCAL_END_PC (decl) = end_pc; |
1590 | ||
1591 | /* Now insert the new decl in the proper place in | |
1592 | pending_local_decls. We are essentially doing an insertion sort, | |
1593 | which works fine, since the list input will normally already | |
1594 | be sorted. */ | |
1595 | ptr = &pending_local_decls; | |
1596 | while (*ptr != NULL_TREE | |
1597 | && (DECL_LOCAL_START_PC (*ptr) > start_pc | |
1598 | || (DECL_LOCAL_START_PC (*ptr) == start_pc | |
1599 | && DECL_LOCAL_END_PC (*ptr) < end_pc))) | |
1600 | ptr = &TREE_CHAIN (*ptr); | |
1601 | TREE_CHAIN (decl) = *ptr; | |
1602 | *ptr = decl; | |
1603 | } | |
1604 | } | |
1605 | ||
1606 | pending_local_decls = nreverse (pending_local_decls); | |
1607 | ||
1608 | /* Fill in default names for the parameters. */ | |
1609 | for (parm = DECL_ARGUMENTS (current_function_decl), i = 0; | |
1610 | parm != NULL_TREE; parm = TREE_CHAIN (parm), i++) | |
1611 | { | |
1612 | if (DECL_NAME (parm) == NULL_TREE) | |
1613 | { | |
1614 | int arg_i = METHOD_STATIC (current_function_decl) ? i+1 : i; | |
1615 | if (arg_i == 0) | |
1616 | DECL_NAME (parm) = get_identifier ("this"); | |
1617 | else | |
1618 | { | |
1619 | char buffer[12]; | |
1620 | sprintf (buffer, "ARG_%d", arg_i); | |
1621 | DECL_NAME (parm) = get_identifier (buffer); | |
1622 | } | |
1623 | DECL_ASSEMBLER_NAME (parm) = DECL_NAME (parm); | |
1624 | } | |
1625 | } | |
1626 | } | |
1627 | ||
939d7216 PB |
1628 | tree |
1629 | build_result_decl (fndecl) | |
e04a16fb AG |
1630 | tree fndecl; |
1631 | { | |
9d45bec2 PB |
1632 | tree restype = TREE_TYPE (TREE_TYPE (fndecl)); |
1633 | /* To be compatible with C_PROMOTING_INTEGER_TYPE_P in cc1/cc1plus. */ | |
1634 | if (INTEGRAL_TYPE_P (restype) | |
1635 | && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node)) | |
1636 | restype = integer_type_node; | |
939d7216 PB |
1637 | return (DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, restype)); |
1638 | } | |
e04a16fb | 1639 | |
3ff9925c AG |
1640 | /* Called for every element in DECL_FUNCTION_INIT_TEST_TABLE in order |
1641 | to emit initialization code for each test flag. */ | |
1642 | ||
1643 | static boolean | |
1644 | emit_init_test_initialization (entry, key) | |
1645 | struct hash_entry *entry; | |
05bccae2 | 1646 | hash_table_key key ATTRIBUTE_UNUSED; |
3ff9925c AG |
1647 | { |
1648 | struct init_test_hash_entry *ite = (struct init_test_hash_entry *) entry; | |
1649 | expand_decl (ite->init_test_decl); | |
1650 | ||
1651 | expand_expr_stmt (build (MODIFY_EXPR, boolean_type_node, | |
1652 | ite->init_test_decl, boolean_false_node)); | |
1653 | ||
1654 | return true; | |
1655 | } | |
1656 | ||
939d7216 PB |
1657 | void |
1658 | complete_start_java_method (fndecl) | |
1659 | tree fndecl; | |
1660 | { | |
e04a16fb AG |
1661 | if (! flag_emit_class_files) |
1662 | { | |
1663 | /* Initialize the RTL code for the function. */ | |
1664 | init_function_start (fndecl, input_filename, lineno); | |
1665 | ||
1666 | /* Set up parameters and prepare for return, for the function. */ | |
1667 | expand_function_start (fndecl, 0); | |
3ff9925c AG |
1668 | |
1669 | /* Emit initialization code for test flags. */ | |
1670 | if (! always_initialize_class_p) | |
1671 | hash_traverse (&DECL_FUNCTION_INIT_TEST_TABLE (fndecl), | |
1672 | emit_init_test_initialization, 0); | |
e04a16fb AG |
1673 | } |
1674 | ||
1675 | /* Allocate further tree nodes temporarily during compilation | |
1676 | of this function only. */ | |
1677 | temporary_allocation (); | |
1678 | ||
1679 | #if 0 | |
1680 | /* If this fcn was already referenced via a block-scope `extern' decl (or | |
1681 | an implicit decl), propagate certain information about the usage. */ | |
1682 | if (TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (current_function_decl))) | |
1683 | TREE_ADDRESSABLE (current_function_decl) = 1; | |
1684 | ||
1685 | #endif | |
1686 | ||
d640220c | 1687 | if (METHOD_STATIC (fndecl) && ! METHOD_PRIVATE (fndecl) |
7f1d4866 APB |
1688 | && ! flag_emit_class_files |
1689 | && ! CLASS_INTERFACE (TYPE_NAME (current_class))) | |
9d45bec2 PB |
1690 | { |
1691 | tree clas = DECL_CONTEXT (fndecl); | |
1692 | tree init = build (CALL_EXPR, void_type_node, | |
1693 | build_address_of (soft_initclass_node), | |
1694 | build_tree_list (NULL_TREE, build_class_ref (clas)), | |
1695 | NULL_TREE); | |
1696 | TREE_SIDE_EFFECTS (init) = 1; | |
1697 | expand_expr_stmt (init); | |
1698 | } | |
1699 | ||
37a08adb PB |
1700 | /* Push local variables. Function compiled from source code are |
1701 | using a different local variables management, and for them, | |
1702 | pushlevel shouldn't be called from here. */ | |
1703 | if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (fndecl))) | |
1704 | { | |
1705 | pushlevel (2); | |
1706 | if (! flag_emit_class_files) | |
1707 | expand_start_bindings (1); | |
1708 | } | |
1709 | ||
1710 | if (METHOD_SYNCHRONIZED (fndecl) && ! flag_emit_class_files) | |
e04a16fb | 1711 | { |
939d7216 | 1712 | /* Warp function body with a monitorenter plus monitorexit cleanup. */ |
939d7216 PB |
1713 | tree enter, exit, lock; |
1714 | if (METHOD_STATIC (fndecl)) | |
1715 | lock = build_class_ref (DECL_CONTEXT (fndecl)); | |
1716 | else | |
1717 | lock = DECL_ARGUMENTS (fndecl); | |
1718 | BUILD_MONITOR_ENTER (enter, lock); | |
1719 | BUILD_MONITOR_EXIT (exit, lock); | |
37a08adb PB |
1720 | if (!CLASS_FROM_SOURCE_P (DECL_CONTEXT (fndecl))) |
1721 | { | |
1722 | expand_expr_stmt (enter); | |
1723 | expand_decl_cleanup (NULL_TREE, exit); | |
1724 | } | |
1725 | else | |
1726 | { | |
1727 | tree function_body = DECL_FUNCTION_BODY (fndecl); | |
1728 | tree body = BLOCK_EXPR_BODY (function_body); | |
1729 | lock = build (WITH_CLEANUP_EXPR, void_type_node, | |
1730 | enter, NULL_TREE, exit); | |
1731 | TREE_SIDE_EFFECTS (lock) = 1; | |
1732 | lock = build (COMPOUND_EXPR, TREE_TYPE (body), lock, body); | |
1733 | TREE_SIDE_EFFECTS (lock) = 1; | |
1734 | lock = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (body), lock); | |
1735 | TREE_SIDE_EFFECTS (lock) = 1; | |
1736 | BLOCK_EXPR_BODY (function_body) = lock; | |
1737 | } | |
e04a16fb AG |
1738 | } |
1739 | } | |
1740 | ||
1741 | void | |
1742 | start_java_method (fndecl) | |
1743 | tree fndecl; | |
1744 | { | |
1745 | tree tem, *ptr; | |
1746 | int i; | |
1747 | ||
1748 | current_function_decl = fndecl; | |
1749 | announce_function (fndecl); | |
1750 | ||
1751 | i = DECL_MAX_LOCALS(fndecl) + DECL_MAX_STACK(fndecl); | |
1752 | decl_map = make_tree_vec (i); | |
1753 | type_map = (tree *) oballoc (i * sizeof (tree)); | |
1754 | ||
e8b22dd1 AH |
1755 | #if defined(DEBUG_JAVA_BINDING_LEVELS) |
1756 | fprintf (stderr, "%s:\n", (*decl_printable_name) (fndecl, 2)); | |
1757 | current_pc = 0; | |
1758 | #endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */ | |
e04a16fb AG |
1759 | pushlevel (1); /* Push parameters. */ |
1760 | ||
1761 | ptr = &DECL_ARGUMENTS (fndecl); | |
1762 | for (tem = TYPE_ARG_TYPES (TREE_TYPE (fndecl)), i = 0; | |
0bd2e6db | 1763 | tem != end_params_node; tem = TREE_CHAIN (tem), i++) |
e04a16fb AG |
1764 | { |
1765 | tree parm_name = NULL_TREE, parm_decl; | |
9d45bec2 | 1766 | tree parm_type = TREE_VALUE (tem); |
e04a16fb AG |
1767 | if (i >= DECL_MAX_LOCALS(fndecl)) |
1768 | fatal ("function has more parameters than local slots"); | |
1769 | ||
9d45bec2 | 1770 | parm_decl = build_decl (PARM_DECL, parm_name, parm_type); |
e04a16fb | 1771 | DECL_CONTEXT (parm_decl) = fndecl; |
e438e1b7 JJ |
1772 | if (PROMOTE_PROTOTYPES |
1773 | && TYPE_PRECISION (parm_type) < TYPE_PRECISION (integer_type_node) | |
9d45bec2 PB |
1774 | && INTEGRAL_TYPE_P (parm_type)) |
1775 | parm_type = integer_type_node; | |
9d45bec2 | 1776 | DECL_ARG_TYPE (parm_decl) = parm_type; |
e04a16fb AG |
1777 | |
1778 | *ptr = parm_decl; | |
1779 | ptr = &TREE_CHAIN (parm_decl); | |
1780 | ||
1781 | /* Add parm_decl to the decl_map. */ | |
1782 | push_jvm_slot (i, parm_decl); | |
1783 | ||
1784 | type_map[i] = TREE_TYPE (parm_decl); | |
1785 | if (TYPE_IS_WIDE (TREE_TYPE (parm_decl))) | |
1786 | { | |
1787 | i++; | |
1788 | type_map[i] = void_type_node; | |
1789 | } | |
1790 | } | |
1791 | *ptr = NULL_TREE; | |
1792 | DECL_ARG_SLOT_COUNT (current_function_decl) = i; | |
1793 | ||
1794 | while (i < DECL_MAX_LOCALS(fndecl)) | |
1795 | type_map[i++] = NULL_TREE; | |
1796 | ||
939d7216 | 1797 | build_result_decl (fndecl); |
e04a16fb AG |
1798 | complete_start_java_method (fndecl); |
1799 | } | |
1800 | ||
1801 | void | |
1802 | end_java_method () | |
1803 | { | |
1804 | tree fndecl = current_function_decl; | |
138657ec | 1805 | int flag_asynchronous_exceptions = asynchronous_exceptions; |
e04a16fb AG |
1806 | |
1807 | expand_end_bindings (getdecls (), 1, 0); | |
1808 | /* pop out of function */ | |
1809 | poplevel (1, 1, 0); | |
1810 | ||
1811 | /* pop out of its parameters */ | |
1812 | poplevel (1, 0, 1); | |
1813 | ||
1814 | BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; | |
1815 | ||
1816 | emit_handlers (); | |
1817 | ||
1818 | /* Generate rtl for function exit. */ | |
1819 | expand_function_end (input_filename, lineno, 0); | |
1820 | ||
138657ec AH |
1821 | /* FIXME: If the current method contains any exception handlers, |
1822 | force asynchronous_exceptions: this is necessary because signal | |
1823 | handlers in libjava may throw exceptions. This is far from being | |
1824 | a perfect solution, but it's better than doing nothing at all.*/ | |
1825 | if (catch_clauses) | |
1826 | asynchronous_exceptions = 1; | |
1827 | ||
e04a16fb AG |
1828 | /* Run the optimizers and output assembler code for this function. */ |
1829 | rest_of_compilation (fndecl); | |
1830 | ||
1831 | current_function_decl = NULL_TREE; | |
1832 | permanent_allocation (1); | |
138657ec | 1833 | asynchronous_exceptions = flag_asynchronous_exceptions; |
e04a16fb | 1834 | } |